Skip to content

fix(python): restore deterministic teardown for async-callback machinery #2630

fix(python): restore deterministic teardown for async-callback machinery

fix(python): restore deterministic teardown for async-callback machinery #2630

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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Install cargo-tarpaulin
uses: taiki-e/install-action@3d6bdc41132a93ae9dbd2217ccd2bcb56d84eaa8 # 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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@4bc351f7f2614e48088386e2a0ad917ca3a7e4ba # v2
with:
tool: cargo-llvm-cov
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: "3.12"
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
- 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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@4bc351f7f2614e48088386e2a0ad917ca3a7e4ba # v2
with:
tool: cargo-llvm-cov
- name: Setup pnpm
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6
with:
version: 10.33.0
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # 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@e79a6962e0d4c0c17b229090214935d2e33f8354 # 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