Skip to content

specsmith: add bdd scenarios for gate and cockpit 🧪 #1517

specsmith: add bdd scenarios for gate and cockpit 🧪

specsmith: add bdd scenarios for gate and cockpit 🧪 #1517

Workflow file for this run

name: Coverage
on:
push:
branches: ["main"]
paths:
- "crates/**"
- "xtask/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/coverage.yml"
- "codecov.yml"
pull_request:
types: [opened, synchronize, reopened, labeled]
branches: ["main"]
paths:
- "crates/**"
- "xtask/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/coverage.yml"
- "codecov.yml"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: coverage-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' && github.event.action == 'synchronize' }}
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: "0"
RUSTFLAGS: -C debuginfo=0
jobs:
coverage:
name: Codecov Coverage
runs-on: ubuntu-latest
timeout-minutes: 45
if: >-
github.event_name == 'push' ||
github.event_name == 'workflow_dispatch' ||
contains(github.event.pull_request.labels.*.name, 'coverage') ||
contains(github.event.pull_request.labels.*.name, 'full-ci')
steps:
- uses: actions/checkout@v6.0.2
with:
fetch-depth: 0
- name: Fetch base ref
if: github.event_name == 'pull_request'
run: git fetch origin "${{ github.base_ref }}":"refs/remotes/origin/${{ github.base_ref }}" || true
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.92"
components: llvm-tools-preview
- name: Use larger target dir
run: echo "CARGO_TARGET_DIR=${RUNNER_TEMP}/target" >> "$GITHUB_ENV"
- uses: Swatinem/rust-cache@v2
with:
cache-directories: ${{ runner.temp }}/target
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Generate coverage route receipt
env:
LABELS_JSON: ${{ github.event_name == 'pull_request' && toJson(github.event.pull_request.labels) || '[]' }}
PUSH_BEFORE: ${{ github.event.before || '' }}
run: |
set -euo pipefail
mkdir -p target/ci
if [ "${{ github.event_name }}" = "pull_request" ]; then
base_ref="origin/${{ github.base_ref }}"
elif [ "${{ github.event_name }}" = "push" ] && [ -n "${PUSH_BEFORE}" ] && ! printf '%s' "${PUSH_BEFORE}" | grep -Eq '^0+$'; then
base_ref="${PUSH_BEFORE}"
elif git rev-parse --verify HEAD^ >/dev/null 2>&1; then
base_ref="HEAD^"
else
base_ref="HEAD"
fi
cargo xtask ci-plan \
--base "${base_ref}" \
--head HEAD \
--labels-json "${LABELS_JSON}" \
--lanes policy/ci-lane-whitelist.toml \
--risk-packs policy/ci-risk-packs.toml \
--no-budget-annotations \
--json-out target/ci/coverage-plan.json \
--route-json-out target/ci/proof-pack-route.json
- name: Verify coverage route receipts
if: always()
run: |
status=0
for receipt in target/ci/coverage-plan.json target/ci/proof-pack-route.json; do
if [ ! -s "$receipt" ]; then
echo "::error::Missing or empty coverage route receipt: $receipt"
status=1
fi
done
exit "$status"
- name: Upload coverage route receipts
if: always()
uses: actions/upload-artifact@v7
with:
name: coverage-route
path: |
target/ci/coverage-plan.json
target/ci/proof-pack-route.json
if-no-files-found: error
retention-days: 14
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- id: coverage_run
name: Generate coverage
env:
CI: true
run: |
set +e
mkdir -p target/coverage
cargo llvm-cov clean --workspace
clean_status=$?
test_status=skipped
json_status=skipped
lcov_status=skipped
text_status=skipped
if [ "${clean_status}" -eq 0 ]; then
cargo llvm-cov test \
--workspace \
--all-features \
--locked \
--no-report
test_status=$?
fi
if [ "${test_status}" = "0" ]; then
cargo llvm-cov report --json --output-path coverage.json
json_status=$?
cargo llvm-cov report --lcov --output-path lcov.info
lcov_status=$?
cargo llvm-cov report --text | tee coverage.txt
text_status=${PIPESTATUS[0]}
fi
overall_status=0
for status in "${clean_status}" "${test_status}" "${json_status}" "${lcov_status}" "${text_status}"; do
if [ "${status}" != "0" ]; then
overall_status=1
fi
done
{
echo "clean_status=${clean_status}"
echo "test_status=${test_status}"
echo "json_status=${json_status}"
echo "lcov_status=${lcov_status}"
echo "text_status=${text_status}"
echo "overall_status=${overall_status}"
} > target/coverage/status.env
export CLEAN_STATUS="${clean_status}"
export TEST_STATUS="${test_status}"
export JSON_STATUS="${json_status}"
export LCOV_STATUS="${lcov_status}"
export TEXT_STATUS="${text_status}"
export OVERALL_STATUS="${overall_status}"
python - <<'PY'
import json
import os
from pathlib import Path
def command(name, env_name):
raw = os.environ[env_name]
if raw == "skipped":
return {"name": name, "status": "skipped", "exit_code": None}
code = int(raw)
return {
"name": name,
"status": "success" if code == 0 else "failure",
"exit_code": code,
}
artifacts = []
for path, kind in [
("coverage.json", "json"),
("coverage.txt", "text"),
("lcov.info", "lcov"),
]:
item = Path(path)
exists = item.exists()
size = item.stat().st_size if exists else 0
artifacts.append(
{
"path": path,
"kind": kind,
"exists": exists,
"bytes": size,
"non_empty": exists and size > 0,
}
)
payload = {
"schema": "tokmd.coverage_workflow_status.v1",
"schema_version": 1,
"overall_status": "success"
if os.environ["OVERALL_STATUS"] == "0"
else "failure",
"commands": [
command("cargo llvm-cov clean --workspace", "CLEAN_STATUS"),
command("cargo llvm-cov test", "TEST_STATUS"),
command("cargo llvm-cov report --json", "JSON_STATUS"),
command("cargo llvm-cov report --lcov", "LCOV_STATUS"),
command("cargo llvm-cov report --text", "TEXT_STATUS"),
],
"artifacts": artifacts,
}
out = Path("target/coverage/coverage-status.json")
out.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8")
PY
{
echo "## Coverage"
echo ""
echo "| Command | Exit |"
echo "| --- | ---: |"
echo "| llvm-cov clean | ${clean_status} |"
echo "| llvm-cov test | ${test_status} |"
echo "| report json | ${json_status} |"
echo "| report lcov | ${lcov_status} |"
echo "| report text | ${text_status} |"
echo ""
echo "Status receipt: \`target/coverage/coverage-status.json\`"
} >> "$GITHUB_STEP_SUMMARY"
echo "overall_status=${overall_status}" >> "$GITHUB_OUTPUT"
- name: Validate coverage output
if: steps.coverage_run.outputs.overall_status == '0'
run: |
set -euo pipefail
test -s coverage.json
test -s lcov.info
test -s coverage.txt
- name: Generate coverage receipt
if: steps.coverage_run.outputs.overall_status == '0'
run: |
cargo xtask coverage-receipt \
--coverage-json coverage.json \
--coverage-text coverage.txt \
--lcov lcov.info \
--output target/coverage/coverage-receipt.json
- name: Detect Codecov token
id: codecov-token
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: |
if [ -n "${CODECOV_TOKEN:-}" ]; then
echo "present=true" >> "$GITHUB_OUTPUT"
else
echo "present=false" >> "$GITHUB_OUTPUT"
fi
- name: Upload coverage to Codecov
if: ${{ steps.coverage_run.outputs.overall_status == '0' && steps.codecov-token.outputs.present == 'true' }}
uses: codecov/codecov-action@v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info
flags: rust
name: tokmd-rust
fail_ci_if_error: ${{ github.event_name == 'push' }}
- name: Upload coverage artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: |
coverage.json
coverage.txt
lcov.info
target/coverage/status.env
target/coverage/coverage-status.json
target/coverage/coverage-receipt.json
retention-days: 14
- name: Fail on coverage command failure
if: always() && steps.coverage_run.outputs.overall_status == '1'
run: |
echo "::error::Coverage command failed; see target/coverage/coverage-status.json in the coverage-report artifact."
exit 1