Skip to content

chore(deps): refresh cargo lock file #8208

chore(deps): refresh cargo lock file

chore(deps): refresh cargo lock file #8208

Workflow file for this run

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"