chore(deps): refresh cargo lock file #8208
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: | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| security-events: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUSTC_WRAPPER: "" | |
| CARGO_INCREMENTAL: "0" | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| detect-changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 2 | |
| outputs: | |
| docs-only: ${{ steps.classify.outputs.docs-only }} | |
| specs-only: ${{ steps.classify.outputs.specs-only }} | |
| run-full-ci: ${{ steps.classify.outputs.run-full-ci }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Filter changed paths | |
| uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 | |
| id: filter | |
| with: | |
| filters: | | |
| docs: | |
| - 'book/src/**' | |
| - 'docs/**' | |
| - '**.md' | |
| - '.local/testing/**' | |
| specs: | |
| - 'specs/**' | |
| code: | |
| - 'crates/**' | |
| - 'src/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'build.rs' | |
| - 'docker/**' | |
| workflows: | |
| - '.github/workflows/**' | |
| - '.github/nextest.toml' | |
| - '.github/testcontainers-images.txt' | |
| - '.cargo/**' | |
| shell: | |
| - 'install/**' | |
| - name: Classify changes | |
| id: classify | |
| run: | | |
| DOCS="${{ steps.filter.outputs.docs }}" | |
| SPECS="${{ steps.filter.outputs.specs }}" | |
| CODE="${{ steps.filter.outputs.code }}" | |
| WORKFLOWS="${{ steps.filter.outputs.workflows }}" | |
| SHELL_SCRIPTS="${{ steps.filter.outputs.shell }}" | |
| # docs-only: docs or specs changed, nothing that requires building | |
| if [[ "$CODE" == "false" && "$WORKFLOWS" == "false" && "$SHELL_SCRIPTS" == "false" && ("$DOCS" == "true" || "$SPECS" == "true") ]]; then | |
| echo "docs-only=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "docs-only=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| # specs-only: specs changed, no code or workflow changes | |
| if [[ "$SPECS" == "true" && "$CODE" == "false" && "$WORKFLOWS" == "false" && "$SHELL_SCRIPTS" == "false" && "$DOCS" == "false" ]]; then | |
| echo "specs-only=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "specs-only=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| # run-full-ci: any code, workflow, or shell change triggers full CI | |
| if [[ "$CODE" == "true" || "$WORKFLOWS" == "true" || "$SHELL_SCRIPTS" == "true" ]]; then | |
| echo "run-full-ci=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "run-full-ci=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| cla: | |
| name: CLA Check | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1 | |
| with: | |
| path-to-signatures: cla-signatures.json | |
| path-to-document: https://github.com/bug-ops/zeph/blob/main/.github/CLA.md | |
| branch: cla-signatures | |
| allowlist: bug-ops,dependabot[bot],github-actions[bot],renovate[bot] | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| lint-shellcheck: | |
| name: Lint (shellcheck) | |
| needs: detect-changes | |
| # Run when shell scripts changed, or when doing full CI (workflows changed) | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Run shellcheck | |
| uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0 | |
| with: | |
| scandir: install | |
| - name: Transcript-integrity audit gate (issue #6360) | |
| run: bash .github/scripts/check_integrity_audit.sh | |
| - name: ACP permission-gate test-isolation guard (issue #6515) | |
| run: bash .github/scripts/check_acp_permission_gate.sh | |
| lint-fmt: | |
| name: Lint (fmt) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4fd1da8b0805d2d2e936788875a7d65dbd677dc2 # nightly | |
| with: | |
| toolchain: nightly | |
| components: rustfmt | |
| - name: Check formatting | |
| run: cargo +nightly fmt --check | |
| lint-clippy: | |
| name: Lint (clippy, ${{ matrix.label }}) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - features: "desktop,ide,server,chat,pdf,scheduler,registry,testing,deep-link" | |
| label: desktop-ide-server-chat-pdf-scheduler | |
| - features: bench | |
| label: bench | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| components: clippy | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| shared-key: "ci" | |
| - name: Clippy | |
| run: cargo clippy --profile ci --workspace --all-targets --features ${{ matrix.features }} -- -D warnings | |
| msrv: | |
| name: MSRV check (1.97, ${{ matrix.label }}) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - features: "desktop,ide,server,chat,pdf,scheduler,registry,deep-link" | |
| label: desktop-ide-server-chat-pdf-scheduler | |
| - features: bench | |
| label: bench | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: "1.97" | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| shared-key: "msrv-${{ matrix.label }}" | |
| - name: cargo check (MSRV, --all-targets) | |
| run: cargo check --workspace --all-targets --features ${{ matrix.features }} --locked | |
| build-tests: | |
| # Linux-only: macOS/Windows builds live in the on-demand ci-non-linux.yml | |
| # workflow. The artifact name keeps the -ubuntu-latest suffix for naming | |
| # parity with the per-OS archives produced there. | |
| name: Build Tests | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 25 | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| cache-targets: "false" | |
| shared-key: "ci" | |
| - uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| - uses: taiki-e/install-action@37ba67210166984a515120020147f0b4ae3b8667 # nextest | |
| - name: Build and archive tests | |
| run: cargo nextest archive --config-file .github/nextest.toml --cargo-profile ci --workspace --features "desktop,ide,server,chat,pdf,scheduler,registry,deep-link" --lib --bins --tests --archive-file nextest-archive.tar.zst | |
| - name: Upload test archive | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: nextest-archive-ubuntu-latest | |
| path: nextest-archive.tar.zst | |
| retention-days: 1 | |
| - name: Upload binary | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: zeph-binary | |
| path: target/ci/zeph | |
| retention-days: 1 | |
| build-tests-postgres: | |
| # The four postgres archives build RUNNABLE test binaries (with | |
| # test-utils = testcontainers) consumed by the integration matrix. They do | |
| # not duplicate the build-postgres job, which is check-only: it type-checks | |
| # the whole workspace under the postgres backend and produces no artifacts. | |
| # Split out of build-tests so they compile in parallel with the (longer) | |
| # main workspace archive instead of serially after it — integration jobs | |
| # start as soon as the slower of the two build jobs finishes. | |
| name: Build Tests (postgres archives) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| cache-targets: "false" | |
| shared-key: "ci" | |
| - uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| - uses: taiki-e/install-action@37ba67210166984a515120020147f0b4ae3b8667 # nextest | |
| - name: Build and archive zeph-db postgres integration tests | |
| run: cargo nextest archive --config-file .github/nextest.toml --cargo-profile ci -p zeph-db --no-default-features --features test-utils --tests --archive-file nextest-archive-zeph-db-postgres.tar.zst | |
| - name: Upload zeph-db postgres test archive | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: nextest-archive-zeph-db-postgres | |
| path: nextest-archive-zeph-db-postgres.tar.zst | |
| retention-days: 1 | |
| - name: Build and archive zeph-memory postgres integration tests | |
| # sqlite and postgres are mutually exclusive (zeph-db's compile_error! | |
| # fires if both are active), so default features (which include "sqlite") | |
| # must be disabled here; "jsonschema" is re-added explicitly since it was | |
| # previously pulled in via zeph-memory's default feature set. | |
| # --lib --bins (not just --tests) is required so cfg!(feature = "postgres") | |
| # branches inside src/ (e.g. dialect-selected SQL literals) get archived too — | |
| # see the "Run zeph-memory postgres unit tests" step in the integration | |
| # job (#5540). | |
| run: cargo nextest archive --config-file .github/nextest.toml --cargo-profile ci -p zeph-memory --no-default-features --features test-utils,jsonschema --lib --bins --tests --archive-file nextest-archive-zeph-memory-postgres.tar.zst | |
| - name: Upload zeph-memory postgres test archive | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: nextest-archive-zeph-memory-postgres | |
| path: nextest-archive-zeph-memory-postgres.tar.zst | |
| retention-days: 1 | |
| - name: Build and archive zeph-index postgres integration tests | |
| # sqlite and postgres are mutually exclusive; default features (which | |
| # include "sqlite") must be disabled so only postgres is active. | |
| run: cargo nextest archive --config-file .github/nextest.toml --cargo-profile ci -p zeph-index --no-default-features --features test-utils --tests --archive-file nextest-archive-zeph-index-postgres.tar.zst | |
| - name: Upload zeph-index postgres test archive | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: nextest-archive-zeph-index-postgres | |
| path: nextest-archive-zeph-index-postgres.tar.zst | |
| retention-days: 1 | |
| - name: Build and archive zeph-orchestration postgres integration tests | |
| # sqlite and postgres are mutually exclusive; default features (which | |
| # include "sqlite") must be disabled so only postgres is active. | |
| # test-utils implies llm-planning: tests/postgres_integration.rs exercises | |
| # PlanCache, which lives behind that feature gate (#5839). | |
| run: cargo nextest archive --config-file .github/nextest.toml --cargo-profile ci -p zeph-orchestration --no-default-features --features test-utils --tests --archive-file nextest-archive-zeph-orchestration-postgres.tar.zst | |
| - name: Upload zeph-orchestration postgres test archive | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: nextest-archive-zeph-orchestration-postgres | |
| path: nextest-archive-zeph-orchestration-postgres.tar.zst | |
| retention-days: 1 | |
| test: | |
| name: "Test (shard ${{ matrix.partition }})" | |
| needs: [detect-changes, lint-fmt, lint-clippy, build-tests] | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| partition: ["1/8", "2/8", "3/8", "4/8", "5/8", "6/8", "7/8", "8/8"] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: taiki-e/install-action@37ba67210166984a515120020147f0b4ae3b8667 # nextest | |
| - name: Download test archive | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: nextest-archive-ubuntu-latest | |
| - name: "Run tests (shard ${{ matrix.partition }})" | |
| run: | | |
| cargo nextest run \ | |
| --config-file .github/nextest.toml \ | |
| --archive-file nextest-archive.tar.zst \ | |
| --workspace-remap . \ | |
| --profile ci-partition \ | |
| --partition hash:${{ matrix.partition }} | |
| integration: | |
| # One job per container-backed suite so the suites run in parallel instead | |
| # of serially — the job was the tail of the critical path. Non-ignored | |
| # tests in *integration* binaries (e.g. zeph-acp's stdio tests) already run | |
| # in the sharded test job; only #[ignore]d container-backed tests run here. | |
| name: Integration Tests (${{ matrix.suite }}) | |
| needs: [detect-changes, lint-fmt, lint-clippy, build-tests, build-tests-postgres] | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - suite: qdrant | |
| # qdrant_integration and document_integration are both Qdrant-backed | |
| # (document_integration fakes embeddings in-test — no extra services); | |
| # without the second binary those #[ignore]d tests would run nowhere | |
| # in CI. Container concurrency is capped by the qdrant-containers | |
| # test-group in .github/nextest.toml. | |
| archive: nextest-archive-ubuntu-latest | |
| file: nextest-archive.tar.zst | |
| run_args: "-E 'binary(qdrant_integration) or binary(document_integration)'" | |
| - suite: zeph-db-postgres | |
| archive: nextest-archive-zeph-db-postgres | |
| file: nextest-archive-zeph-db-postgres.tar.zst | |
| run_args: "" | |
| - suite: zeph-memory-postgres | |
| # Scoped to the postgres_integration binary: zeph-memory's archive also | |
| # contains hela_spreading_activation.rs (SQLite `:memory:` ignored tests, | |
| # unrelated to postgres). This archive is built postgres-only (sqlite is | |
| # disabled, see the archive step's comment in build-tests-postgres) — the | |
| # vast majority of zeph-memory's tests use a `SqliteStore::new(":memory:")` | |
| # fixture unconditionally (not gated on `#[cfg(feature = "sqlite")]`), so | |
| # they'd try to parse ":memory:" as a Postgres URL and fail; running | |
| # crate-wide would hit those unrelated failures. | |
| archive: nextest-archive-zeph-memory-postgres | |
| file: nextest-archive-zeph-memory-postgres.tar.zst | |
| run_args: "-E 'binary(postgres_integration)'" | |
| - suite: zeph-index-postgres | |
| archive: nextest-archive-zeph-index-postgres | |
| file: nextest-archive-zeph-index-postgres.tar.zst | |
| run_args: "-E 'binary(postgres_integration)'" | |
| - suite: zeph-orchestration-postgres | |
| archive: nextest-archive-zeph-orchestration-postgres | |
| file: nextest-archive-zeph-orchestration-postgres.tar.zst | |
| run_args: "-E 'binary(postgres_integration)'" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: taiki-e/install-action@37ba67210166984a515120020147f0b4ae3b8667 # nextest | |
| - uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Restore testcontainer image cache | |
| id: tc-image-cache | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: /tmp/testcontainer-images | |
| key: testcontainer-images-${{ hashFiles('.github/testcontainers-images.txt') }} | |
| - name: Pull and save testcontainer images (cache miss) | |
| if: steps.tc-image-cache.outputs.cache-hit != 'true' | |
| run: | | |
| mkdir -p /tmp/testcontainer-images | |
| while IFS= read -r image; do | |
| [ -z "$image" ] && continue | |
| echo "Pulling $image" | |
| docker pull "$image" | |
| fname=$(echo "$image" | tr '/:' '__') | |
| docker save "$image" | zstd -T0 -3 -o /tmp/testcontainer-images/"$fname".tar.zst | |
| done < .github/testcontainers-images.txt | |
| ls -lh /tmp/testcontainer-images/ | |
| - name: Load testcontainer images (cache hit) | |
| if: steps.tc-image-cache.outputs.cache-hit == 'true' | |
| run: | | |
| for f in /tmp/testcontainer-images/*.tar.zst; do | |
| echo "Loading $f" | |
| zstd -d -c "$f" | docker load | |
| done | |
| docker image ls | |
| - name: Download test archive | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ${{ matrix.archive }} | |
| - name: Run integration tests (testcontainers) | |
| run: cargo nextest run --config-file .github/nextest.toml --archive-file ${{ matrix.file }} --workspace-remap . --profile ci --run-ignored ignored-only ${{ matrix.run_args }} | |
| - name: Run zeph-memory postgres unit tests (#5540) | |
| if: matrix.suite == 'zeph-memory-postgres' | |
| # Runs the --lib/--bins portion of the same archive (built postgres-only | |
| # via test-utils, see the archive step in build-tests-postgres), so | |
| # cfg!(feature = "postgres") branches inside src/ get unit-test coverage in | |
| # CI, not just integration-test coverage that depends on happening to exercise | |
| # the right code path. Scoped by name (not `kind(lib) + kind(bin)`) because the | |
| # vast majority of zeph-memory's ~1500 lib unit tests open a `SqliteStore::new( | |
| # ":memory:")` fixture unconditionally — under this postgres-only build, those | |
| # unrelated tests would try to parse ":memory:" as a Postgres URL and fail. | |
| # `_matches_active_dialect` is this codebase's established naming convention | |
| # (see store/overflow.rs) for pure dialect-literal pinning tests that take no | |
| # DB connection and are safe to run under either feature build. | |
| run: cargo nextest run --config-file .github/nextest.toml --archive-file nextest-archive-zeph-memory-postgres.tar.zst --workspace-remap . --profile ci -E 'kind(lib) and test(matches_active_dialect)' | |
| - name: Reap orphaned testcontainers | |
| # Defense-in-depth, not a fix: testcontainers-rs 0.27.3 (pinned) has no Ryuk | |
| # reaper and can leak containers on SIGKILL or a StartupTimeout cancel under | |
| # concurrent load (#5546, #5547). Runs even if a prior step failed/timed out. | |
| if: always() | |
| run: docker ps -aq --filter "label=org.testcontainers.managed-by=testcontainers" | xargs -r docker rm -f | |
| coverage: | |
| name: Coverage | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.detect-changes.outputs.run-full-ci == 'true' | |
| needs: [detect-changes, lint-fmt, lint-clippy] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| # coverage uses -C instrument-coverage which produces different artifacts than | |
| # normal builds; sccache still helps for unchanged crates between main pushes. | |
| # This job also builds with `--features full`, which includes crates (classifiers, | |
| # profiling, sandbox, gonka, cocoon) outside the lint-clippy matrix, so a warning | |
| # could appear here that lint-clippy never sees. CARGO_BUILD_WARNINGS overrides the | |
| # repo-wide `.cargo/config.toml` deny-by-default to prevent that from promoting | |
| # workspace lint warnings to errors during instrumented compilation — linting is | |
| # enforced by the dedicated lint-clippy job. | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| CARGO_BUILD_WARNINGS: "allow" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| cache-targets: "false" | |
| shared-key: "coverage" | |
| - uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| - uses: taiki-e/install-action@ea361d59ff285fa3ab7cc40dcba421e91017d586 # cargo-llvm-cov | |
| - uses: taiki-e/install-action@37ba67210166984a515120020147f0b4ae3b8667 # nextest | |
| - name: Generate coverage | |
| run: cargo llvm-cov nextest --config-file .github/nextest.toml --cargo-profile ci --workspace --features full --lib --bins --lcov --output-path lcov.info | |
| - name: Upload coverage | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: lcov.info | |
| fail_ci_if_error: false | |
| docker-build-and-scan: | |
| name: Docker Build and Security Scan | |
| needs: [detect-changes, lint-fmt, lint-clippy, build-tests] | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Download binary | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: zeph-binary | |
| path: target/ci | |
| - name: Prepare binaries for Docker | |
| run: | | |
| mkdir -p binaries | |
| cp target/ci/zeph binaries/zeph-amd64 | |
| cp target/ci/zeph binaries/zeph-arm64 | |
| - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 | |
| - name: Build Docker image | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7 | |
| with: | |
| context: . | |
| file: docker/Dockerfile | |
| load: true | |
| tags: zeph:local | |
| push: false | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 | |
| # continue-on-error: trivy exits 1 when vulnerabilities are found; without | |
| # this the upload step would be skipped and findings lost from the dashboard. | |
| continue-on-error: true | |
| with: | |
| image-ref: zeph:local | |
| format: sarif | |
| output: trivy-results.sarif | |
| severity: CRITICAL,HIGH | |
| exit-code: '1' | |
| limit-severities-for-sarif: true | |
| - name: Upload Trivy results to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@e0647621c2984b5ed2f768cb892365bf2a616ad1 # v4 | |
| with: | |
| sarif_file: trivy-results.sarif | |
| bundle-check: | |
| name: Bundle Check (${{ matrix.bundle }}) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| bundle: [desktop, ide, server, chat, ml, bench, full] | |
| include: | |
| - bundle: ml | |
| allow_failure: true | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| shared-key: "ci" | |
| - name: Check bundle | |
| continue-on-error: ${{ matrix.allow_failure == true }} | |
| run: cargo check --features ${{ matrix.bundle }} | |
| release-build: | |
| name: Release Build Check | |
| needs: [detect-changes, lint-fmt, lint-clippy] | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' && github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| cache-targets: "false" | |
| shared-key: "release-build" | |
| - uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| - name: cargo build (release, --all-targets) | |
| # `cargo check --release` does not reproduce the release-profile query-depth overflow | |
| # class of bug fixed by #5407/#5408 (verified empirically: it passes even without the | |
| # `#![recursion_limit]` fix) because it skips codegen/LTO layout finalization. Only a | |
| # real `cargo build --release` with this workspace's `[profile.release]` (lto = true, | |
| # codegen-units = 1) exercises the same query depth CI is meant to gate on. | |
| run: cargo build --release --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,registry,testing,deep-link" | |
| release-build-full: | |
| name: Release Build Check (full) | |
| needs: [detect-changes, lint-fmt, lint-clippy] | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' && github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| cache-targets: "false" | |
| shared-key: "release-build-full" | |
| - uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| - name: cargo build (release, --all-targets, full) | |
| # Best-effort candle/ml coverage under the release profile, mirroring the | |
| # bundle-check `ml` matrix leg (#5418): step-level continue-on-error keeps | |
| # this job's overall result `success` so it never blocks ci-status, while | |
| # still surfacing genuine full-feature release-build breakage in the logs. | |
| continue-on-error: true | |
| run: cargo build --release --workspace --all-targets --features full | |
| build-postgres: | |
| name: Build (postgres) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| shared-key: "ci" | |
| - name: Verify sqlite+postgres compile_error guard | |
| # Intentionally attempts the forbidden both-enabled combination and asserts it | |
| # fails with the expected compile_error! message. Guards against a future | |
| # accidental deletion of the mutual-exclusivity guard in zeph-db/src/lib.rs — | |
| # this exact regression (guard silently dropped for #5377) is how #5571 happened. | |
| # `cargo check` here is EXPECTED to fail (exit 101, the compile_error firing). | |
| # GitHub Actions runs `run:` blocks under `bash -eo pipefail`, so piping that | |
| # exit code directly into `grep` would poison the pipeline status regardless of | |
| # whether grep matches — `|| true` swallows the expected failure so only the | |
| # grep result (checked separately against the redirected log) determines pass/fail. | |
| run: | | |
| cargo check -p zeph-db --features postgres > /tmp/guard.log 2>&1 || true | |
| if grep -q "mutually exclusive for \`zeph-db\`" /tmp/guard.log; then | |
| echo "guard fired as expected" | |
| else | |
| echo "::error::compile_error! guard did not fire — sqlite+postgres both-enabled regression" | |
| cat /tmp/guard.log | |
| exit 1 | |
| fi | |
| - name: Check postgres build (workspace) | |
| # `full` is backend-agnostic (does not include sqlite or postgres); the default | |
| # sqlite feature must be disabled explicitly since Cargo features are | |
| # additive-only and cannot "override" an already-active default. Every | |
| # "sqlite"/"postgres"-gated crate's workspace-dependency entry in the root | |
| # Cargo.toml has `default-features = false` (with explicit forwarding through | |
| # each crate's own `sqlite`/`postgres` feature) precisely so this cascades | |
| # cleanly instead of silently pulling in a conflicting default via a | |
| # `foo.workspace = true` edge somewhere in the graph. | |
| run: cargo check --workspace --all-targets --no-default-features --features full,postgres | |
| - name: Check sqlite build (workspace, no-default-features parity) | |
| run: cargo check --workspace --all-targets --no-default-features --features full,sqlite | |
| rustdoc: | |
| name: Rustdoc | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run-full-ci == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| # `build.warnings` (repo-wide .cargo/config.toml) denies ALL local-package rustdoc | |
| # warnings, not just what RUSTDOCFLAGS explicitly denies below — overriding to "allow" | |
| # here keeps this job's enforcement scoped to exactly the three lints RUSTDOCFLAGS names, | |
| # unchanged from before this migration (#5873). `rustdoc::private_intra_doc_links` and | |
| # `rustdoc::redundant_explicit_links` are denied explicitly (not just left to | |
| # `build.warnings`, which this env var disables) so the 39-site cleanup from #5894 has a | |
| # forward regression guardrail in both CI and local dev, not just a one-time sweep. | |
| env: | |
| RUSTDOCFLAGS: "--deny rustdoc::broken_intra_doc_links --deny rustdoc::private_intra_doc_links --deny rustdoc::redundant_explicit_links" | |
| CARGO_BUILD_WARNINGS: "allow" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| shared-key: "ci" | |
| - name: Build docs (all features except candle) | |
| run: cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler,registry,deep-link" | |
| - name: Doc-tests | |
| run: cargo test --doc --workspace --features "desktop,ide,server,chat,pdf,scheduler,registry,deep-link" | |
| validate-specs: | |
| name: Validate Specs | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.specs-only == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 2 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Check spec structure | |
| run: | | |
| echo "Spec files found:" | |
| find specs -name "*.md" -type f | sort | |
| echo "Total: $(find specs -name "*.md" -type f | wc -l)" | |
| # Verify README index exists | |
| test -f specs/README.md || (echo "::error::specs/README.md index is missing" && exit 1) | |
| ci-status: | |
| name: CI Status | |
| if: always() | |
| needs: [detect-changes, cla, lint-shellcheck, lint-fmt, lint-clippy, msrv, build-tests, build-tests-postgres, test, integration, coverage, docker-build-and-scan, bundle-check, validate-specs, build-postgres, rustdoc, release-build, release-build-full] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 1 | |
| steps: | |
| - name: Check all jobs | |
| run: | | |
| results=( | |
| "${{ needs.detect-changes.result }}" | |
| "${{ needs.cla.result }}" | |
| "${{ needs.lint-shellcheck.result }}" | |
| "${{ needs.lint-fmt.result }}" | |
| "${{ needs.lint-clippy.result }}" | |
| "${{ needs.msrv.result }}" | |
| "${{ needs.build-tests.result }}" | |
| "${{ needs.build-tests-postgres.result }}" | |
| "${{ needs.test.result }}" | |
| "${{ needs.integration.result }}" | |
| "${{ needs.coverage.result }}" | |
| "${{ needs.docker-build-and-scan.result }}" | |
| "${{ needs.bundle-check.result }}" | |
| "${{ needs.validate-specs.result }}" | |
| "${{ needs.build-postgres.result }}" | |
| "${{ needs.rustdoc.result }}" | |
| "${{ needs.release-build.result }}" | |
| "${{ needs.release-build-full.result }}" | |
| ) | |
| for r in "${results[@]}"; do | |
| if [[ "$r" != "success" && "$r" != "skipped" ]]; then | |
| echo "::error::One or more jobs failed or were cancelled" | |
| exit 1 | |
| fi | |
| done | |
| echo "All jobs passed" |