Repository navigation
fix(wire): recover nested file_id and stop doubling reusable fileTabl… #380
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: ci | |
| permissions: | |
| contents: read | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| paths-ignore: | |
| - "**.md" | |
| schedule: | |
| - cron: "0 2 * * *" | |
| workflow_dispatch: | |
| inputs: | |
| profile: | |
| description: "Property profile: fast (default) or intensive" | |
| required: false | |
| default: "fast" | |
| jobs: | |
| rust-lint: | |
| runs-on: [self-hosted, preloop-cpane] | |
| timeout-minutes: 20 | |
| env: | |
| CARGO_BUILD_JOBS: "6" | |
| RUSTFLAGS: "-C link-arg=-fuse-ld=lld" | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| persist-credentials: false | |
| lfs: false | |
| - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable | |
| with: | |
| toolchain: "1.97" | |
| components: rustfmt,clippy | |
| - name: Install lld linker | |
| run: sudo apt-get update && sudo apt-get install -y --no-install-recommends lld | |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 | |
| with: | |
| # A failing lint run still primes the cache for the next one; the | |
| # default skips the save step on failure, so nothing is ever stored | |
| # while a break is being fixed. | |
| cache-on-failure: true | |
| - run: cargo fmt --all --check | |
| - run: | | |
| cargo clippy --locked -p preloop-gha-protocol -p preloop-gha-parser -p preloop-gha-expressions -p preloop-cache -p preloop-artifacts -p runner-watch -p preloop-conformance --all-targets -- -D warnings | |
| cargo clippy --locked -p preloop-runner -p preloop-runner-server -p preloop-runner-client -p preloop-dap --all-targets | |
| # nextest does not run doctests; keep them on the lint job (seconds). | |
| - run: cargo test --locked --workspace --doc | |
| env: | |
| RUSTFLAGS: "-A warnings -C link-arg=-fuse-ld=lld" | |
| rust-test: | |
| # Sharded unit/integration suite. Each shard runs 1/4 of the tests (split | |
| # by test-name hash, so no manual bookkeeping) on its own runner; wall | |
| # clock is setup + slowest shard instead of setup + everything. | |
| # NOTE: these display names are load-bearing — the `main` ruleset gates | |
| # on them. Renaming a shard name requires updating the ruleset to match. | |
| name: rust shard ${{ matrix.shard }} of 4 | |
| runs-on: [self-hosted, preloop-cpane] | |
| timeout-minutes: 60 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4] | |
| env: | |
| CARGO_BUILD_JOBS: "6" | |
| PROPTEST_CASES: "8" | |
| RUST_TEST_THREADS: "6" | |
| RUSTFLAGS: "-C link-arg=-fuse-ld=lld" | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| persist-credentials: false | |
| lfs: false | |
| - name: Materialize conformance goldens | |
| run: | | |
| # Only these nine captures are read by workspace tests: | |
| # eight acquirejob parser fixtures plus runner-watch's scenario-07 | |
| # replay metadata. Fetch each flow directly instead of the complete | |
| # pinned corpus (which also contains 100+ MB container captures). | |
| version=$(python3 -c 'import tomllib; print(tomllib.load(open("versions.toml", "rb"))["runner_version"])') | |
| git lfs install --local --force | |
| includes="" | |
| for scenario in \ | |
| 06-multi-step 07-step-failure 08-job-outputs-needs \ | |
| 10-uses-checkout 11-cache-roundtrip 12-artifact \ | |
| 13-composite-action 14-annotations 15-oidc-id-token; do | |
| path=".runner-watch/golden/v${version}/${scenario}/flows.jsonl" | |
| includes="${includes:+$includes,}$path" | |
| done | |
| git lfs pull --include="$includes" | |
| for scenario in \ | |
| 06-multi-step 07-step-failure 08-job-outputs-needs \ | |
| 10-uses-checkout 11-cache-roundtrip 12-artifact \ | |
| 13-composite-action 14-annotations 15-oidc-id-token; do | |
| fixture=".runner-watch/golden/v${version}/${scenario}/flows.jsonl" | |
| test -s "$fixture" | |
| if grep -q '^version https://git-lfs.github.com/spec/' "$fixture"; then | |
| echo "LFS fixture was not materialized: $fixture" >&2 | |
| exit 1 | |
| fi | |
| done | |
| - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable | |
| with: | |
| toolchain: "1.97" | |
| components: rustfmt,clippy | |
| - name: Install lld linker | |
| run: sudo apt-get update && sudo apt-get install -y --no-install-recommends lld | |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 | |
| with: | |
| # All four shards build the same workspace and differ only in which | |
| # tests they select, so they share one cache entry instead of each | |
| # keying on its own job name and starting cold. | |
| shared-key: rust-test | |
| # Shards fail while a regression is being fixed. The save step is | |
| # skipped on failure by default, so nothing was ever cached and the | |
| # next run recompiled from scratch. | |
| cache-on-failure: true | |
| - name: Install cargo-nextest | |
| run: | | |
| # `cargo install` built nextest from source on every cold cache | |
| # (~300s per shard). Install the published binary, pinned by version | |
| # and verified by digest. | |
| set -euo pipefail | |
| version=0.9.144 | |
| case "$(uname -m)" in | |
| x86_64) | |
| asset=linux | |
| digest=8a4f726272b0a1c499bd87ca3978bfbb1a8c20bb08ccf075b9996e2081bd1e1e | |
| ;; | |
| aarch64|arm64) | |
| asset=linux-arm | |
| digest=7fecfd431b810c05c589d800524286b8f80ce2fe9fb1fef05caf16d095cea407 | |
| ;; | |
| *) | |
| echo "no pinned cargo-nextest build for $(uname -m)" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
| archive="$RUNNER_TEMP/cargo-nextest.tar.gz" | |
| curl -fsSL --retry 3 -o "$archive" "https://get.nexte.st/${version}/${asset}" | |
| echo "${digest} ${archive}" | sha256sum -c - | |
| mkdir -p "$HOME/.local/bin" | |
| tar -xzf "$archive" -C "$HOME/.local/bin" cargo-nextest | |
| "$HOME/.local/bin/cargo-nextest" --version | |
| echo "$HOME/.local/bin" >> "$GITHUB_PATH" | |
| - run: cargo nextest run --locked --workspace --partition hash:${{ matrix.shard }}/4 | |
| env: | |
| RUSTFLAGS: "-A warnings -C link-arg=-fuse-ld=lld" | |
| property-tests-fast: | |
| runs-on: [self-hosted, preloop-cpane] | |
| timeout-minutes: 30 | |
| if: github.event_name != 'schedule' | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable | |
| with: | |
| toolchain: "1.97" | |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 | |
| with: | |
| cache-on-failure: true | |
| - name: Verify property filters match tests | |
| run: | | |
| # One `--list` pass per crate. Keep each server filter separate so | |
| # removing a property module cannot hide behind a broad match. | |
| server_list=$(PROPTEST_CASES=1 cargo test -p preloop-runner-server -- --list 2>/dev/null) | |
| legacy=$(printf '%s\n' "$server_list" | grep -Ec '^concurrency::properties(:|$)' || true) | |
| pure=$(printf '%s\n' "$server_list" | grep -Ec '^concurrency_properties::pure(:|$)' || true) | |
| scheduler=$(printf '%s\n' "$server_list" | grep -Ec '^concurrency_properties::state_machine(:|$)' || true) | |
| http=$(printf '%s\n' "$server_list" | grep -Ec '^concurrency_http_properties(:|$)' || true) | |
| runner=$(cargo test -p preloop-runner -- --list 2>/dev/null | grep -c 'timespan_tests' || true) | |
| parser=$(cargo test -p preloop-gha-parser -- --list 2>/dev/null | grep -c 'concurrency_' || true) | |
| if [ "$legacy" -eq 0 ] || [ "$pure" -eq 0 ] || [ "$scheduler" -eq 0 ] || [ "$http" -eq 0 ] || [ "$runner" -eq 0 ] || [ "$parser" -eq 0 ]; then | |
| echo "ERROR: zero matching tests (legacy=$legacy pure=$pure scheduler=$scheduler http=$http runner=$runner parser=$parser)" >&2 | |
| exit 1 | |
| fi | |
| echo "server filters: legacy=$legacy pure=$pure scheduler=$scheduler http=$http; runner=$runner parser=$parser" | |
| - name: Check no sleep() in property test files | |
| run: | | |
| files="crates/preloop-runner-server/src/concurrency_properties.rs crates/preloop-runner-server/src/concurrency_http_properties.rs" | |
| bad=0 | |
| for f in $files; do | |
| if [ -f "$f" ] && grep -q 'sleep(' "$f"; then | |
| echo "ERROR: sleep() found in $f" >&2 | |
| bad=1 | |
| fi | |
| done | |
| if [ "$bad" -ne 0 ]; then exit 1; fi | |
| echo "Sleep guard: OK" | |
| - name: Pure concurrency properties | |
| run: | | |
| PROPTEST_CASES=256 cargo test -p preloop-runner-server \ | |
| 'concurrency::properties' -- --test-threads=1 | |
| PROPTEST_CASES=256 cargo test -p preloop-runner-server \ | |
| concurrency_properties::pure -- --test-threads=1 | |
| - name: Scheduler model properties | |
| run: | | |
| PROPTEST_CASES=256 cargo test -p preloop-runner-server \ | |
| concurrency_properties::state_machine -- --test-threads=1 | |
| - name: Expression and parser properties | |
| run: | | |
| PROPTEST_CASES=256 cargo test -p preloop-gha-expressions -- --test-threads=1 | |
| cargo test -p preloop-gha-parser concurrency_ -- --test-threads=1 | |
| - name: Runner dispatcher properties | |
| run: | | |
| cargo test -p preloop-runner timespan_tests -- --test-threads=1 | |
| - name: HTTP sequence properties | |
| run: | | |
| PROPTEST_CASES=64 cargo test -p preloop-runner-server \ | |
| concurrency_http_properties -- --test-threads=1 | |
| - name: Differential harness dry-run (schema + algebraic validation) | |
| run: | | |
| python3 benchmarks/real-world/run-concurrency-property-probes.py \ | |
| --dry-run \ | |
| --corpus benchmarks/real-world/concurrency-property-cases.json | |
| - name: Differential harness rejects contaminated fixture | |
| run: | | |
| set +e | |
| python3 benchmarks/real-world/run-concurrency-property-probes.py \ | |
| --dry-run \ | |
| --corpus benchmarks/real-world/fixtures/contaminated-case.json | |
| status=$? | |
| set -e | |
| if [ "$status" -eq 0 ]; then | |
| echo "ERROR: harness did not reject contaminated fixture (expected nonzero exit)" >&2 | |
| exit 1 | |
| fi | |
| echo "Contamination rejection: OK (exit $status)" | |
| - name: Upload proptest regressions | |
| if: failure() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: proptest-regressions-fast | |
| path: | | |
| crates/**/proptest-regressions/ | |
| if-no-files-found: ignore | |
| property-tests-intensive: | |
| runs-on: [self-hosted, preloop-cpane] | |
| timeout-minutes: 120 | |
| if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.profile == 'intensive') | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable | |
| with: | |
| toolchain: "1.97" | |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 | |
| with: | |
| cache-on-failure: true | |
| - name: Verify property filters match tests | |
| run: | | |
| server_list=$(PROPTEST_CASES=1 cargo test -p preloop-runner-server -- --list 2>/dev/null) | |
| legacy=$(printf '%s\n' "$server_list" | grep -Ec '^concurrency::properties(:|$)' || true) | |
| properties=$(printf '%s\n' "$server_list" | grep -Ec '^concurrency_properties(:|$)' || true) | |
| http=$(printf '%s\n' "$server_list" | grep -Ec '^concurrency_http_properties(:|$)' || true) | |
| runner=$(cargo test -p preloop-runner -- --list 2>/dev/null | grep -c 'timespan_tests' || true) | |
| parser=$(cargo test -p preloop-gha-parser -- --list 2>/dev/null | grep -c 'concurrency_' || true) | |
| if [ "$legacy" -eq 0 ] || [ "$properties" -eq 0 ] || [ "$http" -eq 0 ] || [ "$runner" -eq 0 ] || [ "$parser" -eq 0 ]; then | |
| echo "ERROR: zero matching tests (legacy=$legacy properties=$properties http=$http runner=$runner parser=$parser)" >&2 | |
| exit 1 | |
| fi | |
| echo "server filters: legacy=$legacy properties=$properties http=$http; runner=$runner parser=$parser" | |
| - name: Check no sleep() in property test files | |
| run: | | |
| bad=0 | |
| for f in \ | |
| crates/preloop-runner-server/src/concurrency_properties.rs \ | |
| crates/preloop-runner-server/src/concurrency_http_properties.rs; do | |
| if [ -f "$f" ] && grep -q 'sleep(' "$f"; then | |
| echo "ERROR: sleep() found in $f" >&2 | |
| bad=1 | |
| fi | |
| done | |
| if [ "$bad" -ne 0 ]; then exit 1; fi | |
| - name: Intensive property profile (release) | |
| run: | | |
| PROPTEST_CASES=10000 PROPTEST_MAX_SHRINK_ITERS=100000 \ | |
| cargo test -p preloop-runner-server 'concurrency::properties' \ | |
| --release -- --test-threads=1 | |
| PROPTEST_CASES=10000 PROPTEST_MAX_SHRINK_ITERS=100000 \ | |
| cargo test -p preloop-runner-server concurrency_properties \ | |
| --release -- --test-threads=1 | |
| - name: Intensive runner timing profile (release) | |
| run: cargo test -p preloop-runner timespan_tests --release -- --test-threads=1 | |
| - name: Intensive expression / parser profile (release) | |
| run: | | |
| PROPTEST_CASES=10000 cargo test -p preloop-gha-expressions \ | |
| --release -- --test-threads=1 | |
| cargo test -p preloop-gha-parser concurrency_ \ | |
| --release -- --test-threads=1 | |
| - name: Intensive HTTP sequence profile (release) | |
| run: | | |
| PROPTEST_CASES=1000 PROPTEST_MAX_SHRINK_ITERS=100000 \ | |
| cargo test -p preloop-runner-server concurrency_http_properties \ | |
| --release -- --test-threads=1 | |
| - name: Differential harness dry-run | |
| run: | | |
| python3 benchmarks/real-world/run-concurrency-property-probes.py \ | |
| --dry-run \ | |
| --corpus benchmarks/real-world/concurrency-property-cases.json | |
| - name: Differential harness rejects contaminated fixture | |
| run: | | |
| set +e | |
| python3 benchmarks/real-world/run-concurrency-property-probes.py \ | |
| --dry-run \ | |
| --corpus benchmarks/real-world/fixtures/contaminated-case.json | |
| status=$? | |
| set -e | |
| if [ "$status" -eq 0 ]; then | |
| echo "ERROR: harness did not reject contaminated fixture" >&2 | |
| exit 1 | |
| fi | |
| - name: Upload proptest regressions | |
| if: failure() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: proptest-regressions-intensive | |
| path: | | |
| crates/**/proptest-regressions/ | |
| if-no-files-found: ignore |