Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
98a9a65
Add coverage env propagation sequence diagram
leynos Apr 16, 2026
a32012c
Document Rust coverage env override design
leynos Apr 16, 2026
20b64e0
Handle manifest-level Cranelift coverage overrides
leynos Apr 16, 2026
b4740ec
Honor workspace Cranelift coverage overrides
leynos Apr 16, 2026
77be693
Fix README env symbol in coverage sequence diagram
leynos Apr 16, 2026
827e03c
Align Cranelift coverage behavior with docs
leynos Apr 17, 2026
25a7bc2
Use tomllib for manifest Cranelift detection
leynos Apr 17, 2026
df789d6
Exercise and honor coverage env unsets
leynos Apr 17, 2026
948ec36
Document env_unsets in cargo runner docstring
leynos Apr 17, 2026
ef8598c
Tighten Cranelift coverage env handling
leynos Apr 17, 2026
5a1c7ff
Reuse cached cargo env and enforce pump timeout
leynos Apr 17, 2026
2f9c894
Flatten cargo output pump selector handling
leynos Apr 17, 2026
1bf7d59
Extract cucumber spy helper for test length
leynos Apr 17, 2026
95dfe41
Validate cargo timeout before spawn and on Windows
leynos Apr 17, 2026
9a6f449
Silence unused echo monkeypatch args
leynos Apr 17, 2026
6ec8f9e
Extract Windows cargo pump helpers
leynos Apr 17, 2026
f5f6f92
Deduplicate cargo call assert and echo stubs
leynos Apr 17, 2026
e0374f0
Split run_rust into cargo and cranelift modules
leynos Apr 17, 2026
553c267
Harden cargo timeout parsing and enforcement
leynos Apr 17, 2026
4aed49e
Share cargo timeout deadline across phases
leynos Apr 17, 2026
112fbc7
Introduce cargo process context for pump helpers
leynos Apr 17, 2026
2996a80
Extract POSIX cargo pump dispatcher path
leynos Apr 17, 2026
057856c
Extract cargo config cranelift probe
leynos Apr 17, 2026
2e6b0e9
Use monotonic cargo timeout deadlines
leynos Apr 17, 2026
f811709
Add generate-coverage docstrings
leynos Apr 17, 2026
bf0fa07
Tighten cargo pump cleanup and test helpers
leynos Apr 17, 2026
88dd716
Extract Windows pump proc test double
leynos Apr 17, 2026
3f4d644
Use shared cargo context for POSIX pump
leynos Apr 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 105 additions & 14 deletions .github/actions/generate-coverage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ installed automatically. If both configuration files are present, coverage is
run for each language and the Cobertura reports are merged using
`uvx merge-cobertura`.

If a Rust project enables Cranelift — via `.cargo/config.toml`,
`.cargo/config`, or a `[profile.*].codegen-backend` key in `Cargo.toml` —
the action automatically exports `CARGO_PROFILE_DEV_CODEGEN_BACKEND=llvm`
and `CARGO_PROFILE_TEST_CODEGEN_BACKEND=llvm` for the coverage runs so
`cargo llvm-cov` and its child Cargo processes stay on LLVM.

## Flow

```mermaid
Expand All @@ -41,6 +35,92 @@ flowchart TD
K --> L[End]
```

## Rust coverage environment propagation

Figure: sequence diagram showing how `run_rust.py` derives coverage-specific
Cargo environment overrides for Cranelift-configured projects and passes them
into `_run_cargo`, including the optional cucumber.rs follow-up run. Internally
`_run_cargo` starts from the current process environment, removes inherited
codegen-backend-related variables first, and then merges
`get_cargo_coverage_env(manifest_path)` on top so workflow-level Cranelift
exports are not treated as the default coverage behaviour.

```mermaid
sequenceDiagram
actor GitHubActions
participant run_rust_py as run_rust.py
participant get_cargo_coverage_env
participant _run_cargo
participant env_unsets
participant cargo

GitHubActions->>run_rust_py: main(manifest_path, fmt, use_nextest, ...)
run_rust_py->>get_cargo_coverage_env: get_cargo_coverage_env(manifest_path)
get_cargo_coverage_env-->>run_rust_py: cargo_env
run_rust_py->>_run_cargo: _run_cargo(args, env_overrides=cargo_env, env_unsets=...)
_run_cargo->>env_unsets: scrub inherited backend vars
alt env_overrides is not None
_run_cargo->>_run_cargo: merge scrubbed os.environ with env_overrides
else
_run_cargo->>_run_cargo: use scrubbed os.environ unchanged
end
Comment thread
coderabbitai[bot] marked this conversation as resolved.
_run_cargo->>cargo: invoke cargo llvm-cov with env
cargo-->>_run_cargo: stdout
_run_cargo-->>run_rust_py: stdout

opt with_cucumber_rs
run_rust_py->>get_cargo_coverage_env: get_cargo_coverage_env(manifest_path)
get_cargo_coverage_env-->>run_rust_py: cargo_env
run_rust_py->>_run_cargo: _run_cargo(cucumber_args, env_overrides=cargo_env, env_unsets=...)
_run_cargo->>env_unsets: scrub inherited backend vars
_run_cargo->>cargo: invoke cargo test with env
Comment thread
coderabbitai[bot] marked this conversation as resolved.
cargo-->>_run_cargo: stdout
_run_cargo-->>run_rust_py: stdout
end
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## Cranelift codegen backend support

The action automatically detects when a Rust repository configures the
Cranelift codegen backend in `.cargo/config.toml`, `.cargo/config`, or the
selected `Cargo.toml` profile sections. You do not need to enable a separate
input for this behaviour.

When Cranelift is detected, coverage runs set
`CARGO_PROFILE_DEV_CODEGEN_BACKEND=llvm` and
`CARGO_PROFILE_TEST_CODEGEN_BACKEND=llvm` as environment overrides before
launching `cargo-llvm-cov`. That ensures nested `cargo` processes inherit LLVM,
which is required by `-Cinstrument-coverage`. Normal non-coverage builds are
not changed by the action.

For a Cranelift-configured repository, the standard coverage invocation is
still enough:

```yaml
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
format: cobertura
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.

```yaml
- uses: leynos/shared-actions/.github/actions/generate-coverage@v1
with:
output-path: coverage.xml
format: cobertura
```

Known limitations:

- Profile sections in the workspace root `Cargo.toml` are only detected when
`cargo-manifest` points to the workspace root manifest. If `cargo-manifest`
points to a workspace member, Cranelift configured solely in the workspace
root manifest profile will not be detected; use `.cargo/config.toml` in that
case.
- Detection uses two approaches: `.cargo/config.toml` and `.cargo/config`
scanning remains text/regex-based, and selected `Cargo.toml` profile
detection also uses a lightweight text scan.

## Inputs

| Name | Description | Required | Default |
Expand Down Expand Up @@ -74,7 +154,14 @@ supported for Python projects. Mixed projects must use `cobertura`.
## Example

```yaml
- uses: ./.github/actions/generate-coverage@v1
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
format: cobertura
```

```yaml
- uses: leynos/shared-actions/.github/actions/generate-coverage@v1
with:
output-path: coverage.xml
format: cobertura
Expand All @@ -83,7 +170,7 @@ supported for Python projects. Mixed projects must use `cobertura`.
For a single feature:

```yaml
- uses: ./.github/actions/generate-coverage@v1
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
features: logging
Expand All @@ -92,7 +179,7 @@ For a single feature:
For multiple features:

```yaml
- uses: ./.github/actions/generate-coverage@v1
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
features: logging tracing
Expand All @@ -102,7 +189,7 @@ For multiple features:
Comma-separated feature list:

```yaml
- uses: ./.github/actions/generate-coverage@v1
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
features: logging,tracing
Expand All @@ -111,7 +198,7 @@ Comma-separated feature list:
Enable ratcheting:

```yaml
- uses: ./.github/actions/generate-coverage@v1
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
with-ratchet: true
Expand All @@ -120,7 +207,7 @@ Enable ratcheting:
Enable cucumber-rs:

```yaml
- uses: ./.github/actions/generate-coverage@v1
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
with-cucumber-rs: true
Expand All @@ -131,7 +218,7 @@ Enable cucumber-rs:
Disable cargo-nextest:

```yaml
- uses: ./.github/actions/generate-coverage@v1
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
use-cargo-nextest: false
Expand All @@ -140,7 +227,7 @@ Disable cargo-nextest:
Use a nested Cargo manifest:

```yaml
- uses: ./.github/actions/generate-coverage@v1
- uses: ./.github/actions/generate-coverage
with:
output-path: coverage.xml
cargo-manifest: rust-toy-app/Cargo.toml
Expand All @@ -156,4 +243,8 @@ Coverage reports are archived as workflow artefacts named
`<os>-<arch>` segment. This prevents collisions across matrix jobs and
distinguishes runs on different platforms.

Developer-facing design notes, including the rationale for Cranelift coverage
environment overrides, are available in
[`docs/generate-coverage-design.md`](../../../docs/generate-coverage-design.md).

Release history is available in [CHANGELOG](CHANGELOG.md).
Loading
Loading