Skip to content

fix(ci): stop handing the checkout token to untrusted workflow code #3609

fix(ci): stop handing the checkout token to untrusted workflow code

fix(ci): stop handing the checkout token to untrusted workflow code #3609

Workflow file for this run

#
# Keep coverage generation separate from Codecov upload.
# Mirrors Monty's CI shape so upload uses the existing CODECOV_TOKEN secret
# without mixing tokened steps into the report-generation job.
# Rust unit coverage still comes from tarpaulin; Python and Node binding jobs
# add Rust coverage exercised through those language integrations via
# cargo-llvm-cov.
name: Coverage
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
LLVM_COV_IGNORE_FILENAME_REGEX: "(tests/|test_cases/|/tests\\.rs$)"
RG_VERSION: 15.1.0
jobs:
coverage:
name: Generate Rust Coverage
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- name: Install cargo-tarpaulin
uses: taiki-e/install-action@3f74d7c16a4242f1c95561e98edc25d36adb4375 # v2
with:
tool: cargo-tarpaulin
# `rg` differential tests compare against real ripgrep. Pin the
# binary so coverage does not depend on the runner image package set.
- name: Install pinned ripgrep for differential tests
run: scripts/install-ripgrep-ci.sh "$RG_VERSION"
- name: Generate coverage report
run: |
cargo tarpaulin --features http_client \
--workspace \
--exclude bashkit-python \
--out xml \
--out html \
--output-dir coverage \
--exclude-files "crates/bashkit-bench/*" \
--exclude-files "crates/bashkit-cli/*" \
--exclude-files "crates/bashkit-python/*" \
--timeout 300 \
--skip-clean \
--engine llvm
- name: Upload coverage artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: rust-coverage-report
path: coverage/
retention-days: 30
python-coverage:
name: Generate Python Binding Coverage
runs-on: ubuntu-latest
# Bounded so a hung test fails fast instead of occupying a runner for
# GitHub's 6 h default (a GIL deadlock once did exactly that).
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@3f74d7c16a4242f1c95561e98edc25d36adb4375 # v2
with:
tool: cargo-llvm-cov
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
- name: Generate Python-driven Rust coverage
run: |
set -euxo pipefail
mkdir -p coverage
eval "$(cargo llvm-cov show-env --export-prefix)"
cargo llvm-cov clean --workspace
uv venv
uv pip install maturin pytest pytest-asyncio langchain-core langgraph fastapi httpx
uv run maturin develop --release -m crates/bashkit-python/Cargo.toml
uv run maturin develop --release -m crates/bashkit-python/test-fixtures/random-fs/Cargo.toml
uv run pytest crates/bashkit-python/tests -v
cargo llvm-cov report \
--release \
--codecov \
--output-path coverage/python-rust-coverage.json \
--ignore-filename-regex "$LLVM_COV_IGNORE_FILENAME_REGEX"
- name: Upload Python coverage artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: python-rust-coverage-report
path: coverage/python-rust-coverage.json
retention-days: 30
node-coverage:
name: Generate Node Binding Coverage
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@3f74d7c16a4242f1c95561e98edc25d36adb4375 # v2
with:
tool: cargo-llvm-cov
- name: Setup pnpm
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
with:
version: 10.33.0
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version: "22"
cache: pnpm
cache-dependency-path: crates/bashkit-js/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
working-directory: crates/bashkit-js
- name: Generate Node-driven Rust coverage
working-directory: crates/bashkit-js
run: |
set -euxo pipefail
mkdir -p "$GITHUB_WORKSPACE/coverage"
eval "$(cargo llvm-cov show-env --export-prefix)"
cargo llvm-cov clean --workspace
cargo build -p bashkit-js --release
pnpm run build
pnpm test
node --test __test__/runtime-compat/*.test.mjs
cargo llvm-cov report \
--release \
--codecov \
--output-path "$GITHUB_WORKSPACE/coverage/node-rust-coverage.json" \
--ignore-filename-regex "$LLVM_COV_IGNORE_FILENAME_REGEX"
- name: Upload Node coverage artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: node-rust-coverage-report
path: coverage/node-rust-coverage.json
retention-days: 30
coverage-upload:
name: Upload Coverage
needs: [coverage, python-coverage, node-coverage]
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
actions: read
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: "*-coverage-report"
merge-multiple: true
path: coverage
- name: List coverage artifacts
run: ls -lh coverage
- name: Upload coverage to Codecov
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage/cobertura.xml,coverage/python-rust-coverage.json,coverage/node-rust-coverage.json
disable_search: true
flags: unittests
fail_ci_if_error: false
verbose: true