From 18084bc9558ab90595407c16e7161f0681f343b6 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 30 Sep 2026 08:49:42 +0200 Subject: [PATCH 1/2] chore(ci): fix the security findings reported by zizmor - Pin every third-party action to a commit hash (with the version tag as a comment) instead of a mutable tag. - Set `persist-credentials: false` on every checkout, as none of the jobs push back to the repository. - Restrict permissions to `contents: read` at the job level, with an empty top-level block, instead of relying on the defaults. - Pass `github.base_ref`, the base branch step output and `matrix.toolchain` through environment variables rather than expanding them directly into shell scripts. --- .github/workflows/iai-callgrind.yml | 25 ++++++++---- .github/workflows/pre-commit.yaml | 12 ++++-- .github/workflows/tests.yml | 62 ++++++++++++++++++++++------- 3 files changed, 73 insertions(+), 26 deletions(-) diff --git a/.github/workflows/iai-callgrind.yml b/.github/workflows/iai-callgrind.yml index 07734a94..d89372ed 100644 --- a/.github/workflows/iai-callgrind.yml +++ b/.github/workflows/iai-callgrind.yml @@ -4,6 +4,8 @@ on: pull_request: merge_group: +permissions: {} + jobs: benchmarks: name: Run iai-callgrind benchmarks @@ -13,10 +15,11 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 name: Checkout PR branch with: fetch-depth: 0 + persist-credentials: false - name: Install Rust toolchain run: | @@ -27,32 +30,38 @@ jobs: run: sudo apt-get update && sudo apt-get install -y valgrind - name: Install iai-callgrind-runner - uses: baptiste0928/cargo-install@v3 + uses: baptiste0928/cargo-install@8195d4f734a149db85385bb4102b42efcd373759 # v3.5.0 with: crate: iai-callgrind-runner - - uses: Swatinem/rust-cache@v2 + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: iai-callgrind - name: Get base branch name id: base_branch + env: + BASE_REF: ${{ github.base_ref }} run: | if [ "${{ github.event_name }}" = "pull_request" ]; then - echo "name=${{ github.base_ref }}" >> "$GITHUB_OUTPUT" + echo "name=$BASE_REF" >> "$GITHUB_OUTPUT" else echo "name=main" >> "$GITHUB_OUTPUT" fi - name: Checkout base branch + env: + BASE_BRANCH: ${{ steps.base_branch.outputs.name }} run: | - git fetch origin ${{ steps.base_branch.outputs.name }} - git checkout origin/${{ steps.base_branch.outputs.name }} + git fetch origin "$BASE_BRANCH" + git checkout "origin/$BASE_BRANCH" - name: Run benchmarks on base branch continue-on-error: true + env: + BASE_BRANCH: ${{ steps.base_branch.outputs.name }} run: | - echo "Running benchmarks on base branch: ${{ steps.base_branch.outputs.name }}" + echo "Running benchmarks on base branch: $BASE_BRANCH" cargo bench --features iai --bench iai_algos --bench iai_edmondskarp --bench iai_kuhn_munkres --bench iai_separate_components 2>&1 | tee baseline-output.txt - name: Checkout PR branch @@ -188,7 +197,7 @@ jobs: # keep benchmark results in the job summary there instead of failing CI. if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository continue-on-error: true - uses: actions/github-script@v9 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const fs = require('fs'); diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index e33f82fb..ba306765 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -4,10 +4,16 @@ on: pull_request: merge_group: +permissions: {} + jobs: pre-commit: runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v7 - - uses: actions/setup-python@v7 - - uses: pre-commit/action@v3.0.1 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 43cef2fb..eea36caa 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,46 +4,62 @@ on: name: Continuous integration +permissions: {} + jobs: check: name: Check runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - run: sh tests/check-msrv-consistency.sh - run: | rustup install --profile minimal nightly rustup default nightly - - uses: Swatinem/rust-cache@v2 + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 - run: cargo check --all-targets cargo-deny: name: cargo deny runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v7 - - uses: embarkStudios/cargo-deny-action@v2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: embarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1 test: name: Test suite runs-on: ubuntu-latest + permissions: + contents: read needs: check strategy: matrix: toolchain: [stable, beta, nightly, msrv] steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 name: Checkout + with: + persist-credentials: false - name: Install Rust toolchain + env: + TOOLCHAIN: ${{ matrix.toolchain }} run: | - if [ ${{ matrix.toolchain }} = msrv ]; then + if [ "$TOOLCHAIN" = msrv ]; then toolchain=$(awk -F '"' '/^rust-version =/ {print $2}' Cargo.toml) else - toolchain=${{ matrix.toolchain }} + toolchain=$TOOLCHAIN fi rustup install --profile minimal $toolchain rustup default $toolchain - - uses: Swatinem/rust-cache@v2 + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 - name: Test documentation in debug mode run: cargo test --doc - name: Test in debug mode @@ -52,15 +68,19 @@ jobs: test-release: name: Extra tests in release mode runs-on: ubuntu-latest + permissions: + contents: read needs: check steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 name: Checkout + with: + persist-credentials: false - run: | rustup install --profile minimal nightly rustup default nightly name: Install Rust toolchain - - uses: Swatinem/rust-cache@v2 + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 - name: Test documentation in release mode run: cargo test --doc --release - name: Test in release mode @@ -69,10 +89,14 @@ jobs: test-minimal-versions: name: Test with minimal versions runs-on: ubuntu-latest + permissions: + contents: read needs: check steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 name: Checkout + with: + persist-credentials: false - name: Install nightly (for -Z) and stable Rust toolchains run: | rustup install --profile minimal nightly @@ -80,27 +104,35 @@ jobs: rustup default stable - name: Set dependencies to the minimal version allowed run: cargo +nightly update -Zminimal-versions - - uses: Swatinem/rust-cache@v2 + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 - name: Test with minimal version dependencies and stable compiler run: cargo +stable test --tests --benches fmt: name: Rustfmt runs-on: ubuntu-latest + permissions: + contents: read needs: check steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - run: rustup install --profile default stable - run: cargo +stable fmt --all -- --check clippy: name: Clippy runs-on: ubuntu-latest + permissions: + contents: read needs: check steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - run: | rustup install --profile default nightly rustup default nightly - - uses: Swatinem/rust-cache@v2 + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 - run: cargo clippy --all-targets -- -D warnings From bf3f0584d97d6818f132a270a69004ba5a1927a5 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 30 Sep 2026 08:50:17 +0200 Subject: [PATCH 2/2] chore(ci): run zizmor on pull requests Audit the GitHub Actions workflows with zizmor so that new security findings are reported on pull requests through code scanning. --- .github/workflows/zizmor.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 00000000..5fa535dc --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,20 @@ +name: zizmor + +on: + pull_request: + merge_group: + +permissions: {} + +jobs: + zizmor: + name: GitHub Actions security analysis + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4