Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .github/actions/ratchet-coverage/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## v1.0.0

- Initial version with caching and baseline ratcheting.
Comment thread
leynos marked this conversation as resolved.
40 changes: 40 additions & 0 deletions .github/actions/ratchet-coverage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Ratchet coverage

Generate code coverage using `cargo tarpaulin` and fail the workflow if the
coverage percentage falls below a stored baseline.

## Inputs

| Name | Description | Required | Default |
| --- | --- | --- | --- |
| baseline-file | File used to persist the baseline coverage percentage between runs | no | `.coverage-baseline` |
| args | Additional arguments passed to `cargo tarpaulin` | no | *(none)* |

Comment on lines +8 to +12
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Documentation out of sync with action.yml inputs

The inputs table includes args, but the action manifest doesn’t declare this input. Workflows using args will fail.

Ensure action.yml and README inputs are aligned.

🤖 Prompt for AI Agents
In .github/actions/ratchet-coverage/README.md lines 8 to 12, the README lists an
input named 'args' that is not declared in the action.yml file, causing workflow
failures. To fix this, update the action.yml file to include the 'args' input
with the appropriate description, required flag, and default value matching the
README, or remove 'args' from the README if it is not supported. Ensure both
files have consistent input declarations.

## Outputs

| Name | Description |
| --- | --- |
| percent | Coverage percentage reported by `cargo tarpaulin` |

## Example

```yaml
- uses: ./.github/actions/setup-rust@v1
- uses: ./.github/actions/ratchet-coverage@v1
with:
baseline-file: .cache/coverage-baseline
args: --workspace
```

`cargo tarpaulin` only runs on Linux hosts, so use this action on
`ubuntu-latest` runners.

### How it works

The action restores the previous coverage baseline using `actions/cache` and
installs `cargo-tarpaulin` if necessary. After running the coverage command, it
compares the new percentage with the stored baseline. The job fails if coverage
has dropped. On success, the baseline file is updated and saved back to the
cache using a branch-specific key for future runs.

Release history is available in [CHANGELOG](CHANGELOG.md).
84 changes: 84 additions & 0 deletions .github/actions/ratchet-coverage/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Ratchet coverage
description: Run cargo tarpaulin and fail if coverage decreases
inputs:
baseline-file:
description: Path to store the coverage baseline
required: false
default: .coverage-baseline
args:
description: Additional arguments passed to cargo tarpaulin
required: false
default: ''
outputs:
percent:
description: Coverage percentage reported by cargo tarpaulin
value: ${{ steps.cov.outputs.percent }}
runs:
using: composite
steps:
- name: Restore baseline
uses: actions/cache@v4
with:
path: ${{ inputs.baseline-file }}
key: ratchet-baseline-${{ runner.os }}-${{ github.ref_name }}
- name: Cache cargo artifacts
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/cargo-tarpaulin
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-tarpaulin-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-tarpaulin-
- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin
shell: bash
- name: Run coverage
id: cov
run: |
set -euo pipefail
output=$(cargo tarpaulin ${{ inputs.args }} --out lcov 2>&1)
echo "$output"
percent=$(echo "$output" | grep -oP '[0-9]+(?:\.[0-9]+)?(?=%)' | head -n1)
if [ -z "$percent" ]; then
echo "Unable to extract coverage percentage" >&2
exit 1
fi
echo "percent=$percent" >> "$GITHUB_OUTPUT"
shell: bash
- name: Ratchet coverage
run: |
set -euo pipefail
file="${{ inputs.baseline-file }}"
current="${{ steps.cov.outputs.percent }}"
baseline=0
if [ -f "$file" ]; then
baseline=$(cat "$file")
fi
echo "Current coverage: $current%"
echo "Baseline coverage: $baseline%"
if ! [[ "$current" =~ ^[0-9]+(\.[0-9]+)?$ ]] || \
! [[ "$baseline" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
echo "Invalid coverage values" >&2
exit 1
fi
# Ensure we're on Linux where `bc` is guaranteed to be installed
if [[ "$RUNNER_OS" != "Linux" ]]; then
echo "This action only supports Linux runners for float comparisons." >&2
exit 1
fi

if [ "$(echo "$current < $baseline" | bc -l)" = "1" ]; then
Comment thread
leynos marked this conversation as resolved.
echo "Coverage decreased" >&2
exit 1
fi
Comment on lines +73 to +76
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Ensure bc availability or restrict to Linux runners
bc may not be installed on Windows or macOS runners, causing failures. Consider either installing bc or adding an OS check.

For example, prepend in the Ratchet coverage step:

+        if [[ "$RUNNER_OS" != "Linux" ]]; then
+          echo "This action only supports Linux runners for float comparisons." >&2
+          exit 1
+        fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ "$(echo "$current < $baseline" | bc -l)" = "1" ]; then
echo "Coverage decreased" >&2
exit 1
fi
# Ensure we're on Linux where `bc` is guaranteed to be installed
if [[ "$RUNNER_OS" != "Linux" ]]; then
echo "This action only supports Linux runners for float comparisons." >&2
exit 1
fi
if [ "$(echo "$current < $baseline" | bc -l)" = "1" ]; then
echo "Coverage decreased" >&2
exit 1
fi
🤖 Prompt for AI Agents
In .github/actions/ratchet-coverage/action.yml around lines 67 to 70, the script
uses `bc` for floating-point comparison, but `bc` may not be installed on
Windows or macOS runners, causing failures. Fix this by adding a check for the
operating system before running the comparison or ensure `bc` is installed on
the runner. Alternatively, restrict the action to run only on Linux runners
where `bc` is available.

printf '%.2f' "$current" > "$file"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Overwriting the baseline file may cause issues in concurrent runs.

Parallel workflow runs could overwrite the same baseline file, causing race conditions. Use a branch- or run-specific cache key to avoid conflicts.

shell: bash
- name: Save baseline
if: success()
uses: actions/cache@v4
with:
path: ${{ inputs.baseline-file }}
key: ratchet-baseline-${{ runner.os }}-${{ github.ref_name }}
5 changes: 5 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.github/actions/export-postgres-url/ @leynos
.github/actions/generate-coverage/ @leynos
.github/actions/setup-rust/ @leynos
.github/actions/upload-codescene-coverage/ @leynos
.github/actions/ratchet-coverage/ @leynos
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ GitHub Actions
| Generate coverage | `.github/actions/generate-coverage` | v1 |
| Setup Rust | `.github/actions/setup-rust` | v1 |
| Upload CodeScene Coverage | `.github/actions/upload-codescene-coverage` | v1 |
| Ratchet coverage | `.github/actions/ratchet-coverage` | v1 |