Record leases from the pre-tool hook, three CLI paper cuts, and the fork/exclude finding #119
Workflow file for this run
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 | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| # A new push to the same PR (or to main) supersedes the run in flight; | |
| # stop paying for the old one. release.yml deliberately does not cancel. | |
| concurrency: | |
| group: ci-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| FUSE_T_VERSION: 1.2.7 | |
| CARGO_TERM_COLOR: always | |
| # acyclic-fs is fetched from its own git repo (see Cargo.toml); cargo's | |
| # built-in libgit2 fetcher can't resolve a pinned commit SHA that isn't a | |
| # branch tip on that host, so delegate to the system git CLI instead. | |
| CARGO_NET_GIT_FETCH_WITH_CLI: true | |
| jobs: | |
| # Three cheap jobs (changes, deny, lint) run in parallel; the expensive | |
| # test matrix (FUSE-T install, release build, acceptance suite on two | |
| # OSes) only starts once deny and lint pass, so a formatting slip or a | |
| # banned crate is reported in about a minute instead of after a full | |
| # matrix run — and it is skipped outright when nothing that could change | |
| # a test result was touched. | |
| # Which parts of the tree a change touches. A job-level filter rather | |
| # than a workflow-level `paths-ignore` because branch protection on main | |
| # requires the `test (...)` checks: a workflow that never runs leaves | |
| # them "expected" forever and blocks the merge, whereas a job skipped by | |
| # `if:` reports as skipped, which counts as passing. | |
| changes: | |
| runs-on: ubuntu-24.04 | |
| # paths-filter lists a PR's files through the API; the default token | |
| # here is read-only on contents and nothing else. | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| # On a push to main the filter diffs against the pre-push commit, | |
| # which a depth-1 checkout does not have. | |
| fetch-depth: 0 | |
| - id: filter | |
| uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 | |
| with: | |
| # "some file changed that is not docs/prose": a negation-only list | |
| # matches nothing, so the positive `**` is required, and | |
| # some-with-excludes makes the negations apply to it. | |
| predicate-quantifier: some-with-excludes | |
| filters: | | |
| code: | |
| - '**' | |
| - '!**/*.md' | |
| - '!docs/**' | |
| - '!LICENSE' | |
| - '!.github/CODEOWNERS' | |
| # Licenses, advisories, and sources per deny.toml. Keeps the published | |
| # SBOM inside the permissive allowlist and fails on known-vulnerable or | |
| # yanked crates. Always runs: the secrets scan applies to docs too. | |
| deny: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| - name: Product name is single-sourced (product.toml) | |
| run: bash scripts/check-product-name.sh | |
| - name: No forbidden files or credential patterns | |
| run: bash scripts/check-no-secrets.sh | |
| - name: Code quality (line width, TODO format, comment blocks, duplication) | |
| run: bash scripts/check-code-quality.sh | |
| - uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1 | |
| with: | |
| command: check | |
| arguments: --locked | |
| log-level: warn | |
| # Formatting and lint. Fast and toolchain-only (no FUSE-T needed). | |
| lint: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| - name: Install toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal --component rustfmt --component clippy | |
| rustup default stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: lint-cargo-${{ hashFiles('Cargo.lock') }} | |
| - name: cargo fmt --check | |
| run: cargo fmt --all --check | |
| - name: cargo clippy | |
| run: cargo clippy --workspace --all-targets --all-features -- -D warnings | |
| # Line coverage of the unit and integration tests, as a job summary and | |
| # an lcov artifact, with a floor so a change can't quietly delete tests. | |
| # The daemon, client, and MCP server are exercised by the acceptance | |
| # scripts rather than `cargo test`, so they read as 0% here; raise the | |
| # floor as unit coverage of those grows, not by counting the scripts. | |
| coverage: | |
| needs: [changes, deny, lint] | |
| if: needs.changes.outputs.code == 'true' | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| - name: Install toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal --component llvm-tools-preview | |
| rustup default stable | |
| - uses: taiki-e/install-action@3f74d7c16a4242f1c95561e98edc25d36adb4375 # v2.87.12 | |
| with: | |
| tool: cargo-llvm-cov | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: coverage-cargo-${{ hashFiles('Cargo.lock') }} | |
| - name: cargo llvm-cov | |
| run: | | |
| cargo llvm-cov --workspace --all-features --lcov --output-path lcov.info --fail-under-lines 48 | |
| { | |
| echo '## Test coverage (lines)' | |
| echo '```' | |
| cargo llvm-cov report --summary-only | |
| echo '```' | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: lcov | |
| path: lcov.info | |
| # Windows, which nothing else in this file covers. The lint job runs on | |
| # Linux, so every `#[cfg(windows)]` block in the tree is invisible to it — | |
| # a Windows-only arm can stop compiling and no other check notices. This | |
| # job builds and lints those arms, runs the workspace tests, and drives | |
| # the parts of the product whose behaviour genuinely differs there | |
| # (named-pipe transport, UTF-16LE names, renaming the repo root, copy | |
| # forks). The POSIX acceptance suite is not run: it assumes mount tooling, | |
| # symlinks and modes that Windows does not have. | |
| windows: | |
| needs: [changes, deny, lint] | |
| if: >- | |
| always() | |
| && needs.deny.result == 'success' | |
| && needs.lint.result == 'success' | |
| && (needs.changes.result != 'success' || needs.changes.outputs.code == 'true') | |
| runs-on: windows-2022 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| - name: Install toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal --component rustfmt --component clippy | |
| rustup default stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: windows-cargo-${{ hashFiles('Cargo.lock') }} | |
| - name: cargo fmt --check | |
| run: cargo fmt --all --check | |
| # The point of the job: lint the cfg(windows) arms the Linux lint job | |
| # never compiles. | |
| - name: cargo clippy | |
| run: cargo clippy --workspace --all-targets --all-features -- -D warnings | |
| - name: Unit and integration tests | |
| run: cargo test --workspace | |
| - name: Release build | |
| run: cargo build --release --locked -p acyclic | |
| - name: Windows end-to-end smoke | |
| shell: bash | |
| env: | |
| ACYCLIC_BIN: ${{ github.workspace }}/target/release/acyclic.exe | |
| run: bash tests/acceptance/windows-smoke.sh | |
| test: | |
| needs: [changes, deny, lint] | |
| # Fail closed: run when the change filter says code moved, and also | |
| # when the filter job itself failed (an empty output must not read as | |
| # "nothing to test", since a skipped required check counts as passing). | |
| # deny and lint failing still skip this job; those are required checks | |
| # in their own right, so the PR stays red. | |
| if: >- | |
| always() | |
| && needs.deny.result == 'success' | |
| && needs.lint.result == 'success' | |
| && (needs.changes.result != 'success' || needs.changes.outputs.code == 'true') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [macos-14, ubuntu-24.04] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout plugin | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| path: graphcoder-plugin | |
| - name: Install FUSE-T (macOS) | |
| if: runner.os == 'macOS' | |
| run: | | |
| set -euo pipefail | |
| curl --fail --location --retry 5 \ | |
| "https://github.com/macos-fuse-t/fuse-t/releases/download/${FUSE_T_VERSION}/fuse-t-macos-installer-${FUSE_T_VERSION}.pkg" \ | |
| --output /tmp/fuse-t.pkg | |
| sudo installer -pkg /tmp/fuse-t.pkg -target / | |
| test -d /usr/local/include/fuse3 | |
| - name: Install toolchain | |
| run: rustup toolchain install stable --profile minimal && rustup default stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| graphcoder-plugin/target | |
| key: ${{ matrix.os }}-cargo-${{ hashFiles('graphcoder-plugin/Cargo.lock') }} | |
| - name: Unit and integration tests | |
| working-directory: graphcoder-plugin | |
| run: cargo test --workspace | |
| - name: Release build (acceptance + latency gate run against it) | |
| working-directory: graphcoder-plugin | |
| run: cargo build --release | |
| - name: Acceptance suite | |
| working-directory: graphcoder-plugin | |
| env: | |
| ACYCLIC_BIN: ${{ github.workspace }}/graphcoder-plugin/target/release/acyclic | |
| ACYCLIC_QUAL: ${{ github.workspace }}/graphcoder-plugin/target/release/acyclic-qual | |
| # Smaller corpus keeps CI wall-clock sane; the budget is unchanged. | |
| ACYCLIC_LAT_FILES: "5000" | |
| ACYCLIC_LAT_MB: "64" | |
| ACYCLIC_SOAK_ROUNDS: "30" | |
| run: bash tests/acceptance/run-all.sh |