name: ci on: pull_request: merge_group: concurrency: group: >- ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.merge_group.head_ref }} cancel-in-progress: true permissions: {} jobs: test: strategy: fail-fast: ${{ github.event_name == 'merge_group' }} matrix: build: [linux-x86_64-gnu, linux-aarch64-gnu, macos-x86_64, macos-aarch64, windows-x86_64, windows-aarch64] include: - build: linux-x86_64-gnu os: ubuntu-24.04 cargo_flags: "--all-features" extra_targets: "" - build: linux-aarch64-gnu os: ubuntu-24.04-arm cargo_flags: "--all-features" extra_targets: "" - build: macos-x86_64 os: macos-15 cargo_flags: "--target x86_64-apple-darwin" extra_targets: "x86_64-apple-darwin" - build: macos-aarch64 os: macos-15 cargo_flags: "" extra_targets: "" - build: windows-x86_64 os: windows-2022 cargo_flags: "" extra_targets: "" - build: windows-aarch64 os: windows-11-arm cargo_flags: "" extra_targets: "" runs-on: ${{ matrix.os }} # TODO FIXME (aseipp): keep the timeout limit to ~20 minutes. this is long # enough to give us runway for the future, but also once we hit it, we're at # the "builds are taking too long" stage and we should start looking at ways # to optimize the CI, or the CI is flaking out on some weird spiked machine # # at the same time, this avoids some issues where some flaky, bugged tests # seem to be causing multi-hour runs on Windows (GPG signing issues), which # is a problem we should fix. in the mean time, this will make these flakes # less harmful, as it won't cause builds to spin for multiple hours, requiring # manual cancellation. # # keep a log of updates (along with committed date) below: # # 2025-03-20 (aseipp): peak p99 builds seemed to be long, bump 15m -> 20m # 2025-10-06 (aseipp): x86 macos runners consistently slower, bump 20m -> 25m timeout-minutes: 25 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - name: Set up Windows Builders if: startswith(matrix.os, 'windows-x86_64') # FIXME: aarch64 doesn't have D:\ yet uses: ./.github/actions/setup-windows - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 with: toolchain: 1.89 # comma-separated list of extra targets to install targets: ${{ matrix.extra_targets }} - uses: taiki-e/install-action@50708e9ba8d7b6587a2cb575ddaa9a62e927bc06 with: tool: nextest - name: Install mold uses: rui314/setup-mold@725a8794d15fc7563f59595bd9556495c0564878 with: make-default: false - name: Build run: >- cargo build --config .cargo/config-ci.toml --workspace --all-targets --verbose ${{ matrix.cargo_flags }} - name: Test run: >- cargo nextest run --config .cargo/config-ci.toml --workspace --all-targets --verbose --profile ci ${{ matrix.cargo_flags }} env: RUST_BACKTRACE: 1 CARGO_TERM_COLOR: always no-git: name: build (no git) runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 with: toolchain: 1.89 - name: Build run: cargo build -p jj-cli --no-default-features --verbose build-nix: name: nix flake strategy: fail-fast: ${{ github.event_name == 'merge_group' }} matrix: os: [ubuntu-24.04, ubuntu-24.04-arm, macos-14] runs-on: ${{ matrix.os }} timeout-minutes: 15 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: fetch-depth: 0 persist-credentials: false - uses: cachix/install-nix-action@0b0e072294b088b73964f1d72dfdac0951439dbd - run: nix flake check -L --show-trace check-protos: name: check (protos) runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 with: toolchain: stable - run: sudo apt update && sudo apt-get -y install protobuf-compiler - name: Generate Rust code from .proto files run: cargo run -p gen-protos - name: Check for uncommitted changes run: git diff --exit-code check-rustfmt: name: check (rustfmt) runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 with: toolchain: nightly components: rustfmt - run: cargo +nightly fmt --all -- --check check-clippy: name: check (clippy) permissions: checks: write runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 with: toolchain: stable components: clippy - run: cargo +stable clippy --all-features --workspace --all-targets -- -D warnings check-cargo-deny: runs-on: ubuntu-24.04 strategy: matrix: checks: - advisories - bans - licenses - sources # Prevent sudden announcement of a new advisory from failing ci: continue-on-error: ${{ matrix.checks == 'advisories' }} name: check (cargo-deny, ${{ matrix.checks }}) steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - uses: EmbarkStudios/cargo-deny-action@76cd80eb775d7bbbd2d80292136d74d39e1b4918 with: command: check ${{ matrix.checks }} check-codespell: name: check (codespell) runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 with: python-version: 3.11 - name: Install uv uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a with: # If you bump the version, also update docs/contributing.md # and all other workflows that install uv version: "0.5.1" - name: Run Codespell run: uv run -- codespell && echo Codespell exited successfully check-doctests: name: check (doctests) runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 with: toolchain: 1.89 # NOTE: We need to run `cargo test --doc` separately from normal tests: # - `cargo build --all-targets` specifies: "Build all targets" # - `cargo test --all-targets` specifies: "Test all targets (does not include doctests)" - name: Run doctests run: cargo test --workspace --doc env: RUST_BACKTRACE: 1 - name: Check `cargo doc` for lint issues env: RUSTDOCFLAGS: "--deny warnings" run: cargo doc --workspace --no-deps check-mkdocs: name: check (mkdocs) runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 with: python-version: 3.11 - name: Install uv uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a with: # If you bump the version, also update docs/contributing.md # and all other workflows that install uv version: "0.5.1" - name: Check that `mkdocs` can build the docs run: uv run -- mkdocs build --strict # An optional job to alert us when uv updates break the build check-mkdocs-latest: name: check (latest mkdocs, optional) runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - name: Install uv uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a # 'only-managed' means that uv will always download Python, even # if the runner happens to provide a compatible version - name: Check that `mkdocs` can build the docs run: uv run --python-preference=only-managed -- mkdocs build --strict check-zizmor: name: check (zizmor) runs-on: ubuntu-latest permissions: security-events: write steps: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - name: Install the latest version of uv uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a - name: Run zizmor run: uvx zizmor --format sarif . > results.sarif env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload SARIF file uses: github/codeql-action/upload-sarif@cf1bb45a277cb3c205638b2cd5c984db1c46a412 with: sarif_file: results.sarif category: zizmor # Count the (very approximate) number of dependencies in Cargo.lock and bail at a certain limit. check-cargo-lock-bloat: name: check (Cargo.lock dependency count) runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: persist-credentials: false - name: Check total dependency count in Cargo.lock run: | total_deps=$(./.github/scripts/count-cargo-lock-packages) if [ "$total_deps" -gt "${TOTAL_DEP_LIMIT}" ]; then ./.github/scripts/dragon-bureaucrat \ "Cargo.lock has too many dependencies ($total_deps > ${TOTAL_DEP_LIMIT}). The Dragon banishes thee! You can raise the limit in \`.github/workflows/ci.yml\` if necessary, but consider whether it’s possible to trim things down first." else echo "Counted $total_deps Cargo.lock dependencies." \ "This is within the allowed limit of ${TOTAL_DEP_LIMIT}." fi env: # This limit *can* be raised, we just want to be aware if we exceed it TOTAL_DEP_LIMIT: 550 # Block the merge if required checks fail, but only in the merge # queue. See also `required-checks-hack.yml`. required-checks: name: required checks (merge queue) if: ${{ always() && github.event_name == 'merge_group' }} needs: - test - no-git - build-nix - check-protos - check-rustfmt - check-clippy - check-cargo-deny - check-codespell - check-doctests - check-mkdocs # - check-mkdocs-latest # - check-zizmor - check-cargo-lock-bloat runs-on: ubuntu-latest steps: - name: Block merge if required checks fail if: >- ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} run: exit 1