Skip to content

Fix coverage workflow #772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
52 changes: 12 additions & 40 deletions .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
@@ -4,35 +4,25 @@ on:
push:
branches:
- develop
pull_request_target:
branches:
- develop

env:
CARGO_TERM_COLOR: always

jobs:
report:
name: Report
name: Generate Coverage Report
environment: coverage
runs-on: ubuntu-latest
env:
CARGO_INCREMENTAL: "0"
RUSTFLAGS: "-Z profile -C codegen-units=1 -C opt-level=0 -C link-dead-code -C overflow-checks=off -Z panic_abort_tests -C panic=abort"
RUSTDOCFLAGS: "-Z profile -C codegen-units=1 -C opt-level=0 -C link-dead-code -C overflow-checks=off -Z panic_abort_tests -C panic=abort"
RUSTFLAGS: "-Cinstrument-coverage"

steps:
- id: checkout_push
if: github.event_name == 'push'
name: Checkout Repository (Push)
- name: Checkout repository
uses: actions/checkout@v4

- id: checkout_pull_request_target
if: github.event_name == 'pull_request_target'
name: Checkout Repository (Pull Request Target)
uses: actions/checkout@v4
with:
ref: "refs/pull/${{ github.event.pull_request.number }}/head"
- name: Install LLVM tools
run: sudo apt-get update && sudo apt-get install -y llvm

- id: setup
name: Setup Toolchain
@@ -49,41 +39,23 @@ jobs:
name: Install Tools
uses: taiki-e/install-action@v2
with:
tool: grcov
tool: grcov,cargo-llvm-cov

- id: imdl
name: Install Intermodal
run: cargo install imdl

- id: check
name: Run Build Checks
run: cargo check --tests --benches --examples --workspace --all-targets --all-features

- id: clean
name: Clean Build Directory
run: cargo clean

- id: build
name: Pre-build Main Project
run: cargo build --workspace --all-targets --all-features --jobs 2

- id: build_tests
name: Pre-build Tests
run: cargo build --workspace --all-targets --all-features --tests --jobs 2

- id: test
name: Run Unit Tests
run: cargo test --tests --workspace --all-targets --all-features

- id: coverage
name: Generate Coverage Report
uses: alekitto/[email protected]
run: |
cargo clean
cargo llvm-cov --all-features --workspace --codecov --output-path ./codecov.json

- id: upload
name: Upload Coverage Report
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ${{ steps.coverage.outputs.report }}
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}
files: ${{ github.workspace }}/codecov.json
fail_ci_if_error: true
88 changes: 88 additions & 0 deletions .github/workflows/generate_coverage_pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Generate Coverage Report (PR)

on:
pull_request:
branches:
- develop

env:
CARGO_TERM_COLOR: always

jobs:
coverage:
name: Generate Coverage Report
environment: coverage
runs-on: ubuntu-latest
env:
CARGO_INCREMENTAL: "0"
RUSTFLAGS: "-Cinstrument-coverage"

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install LLVM tools
run: sudo apt-get update && sudo apt-get install -y llvm

- id: setup
name: Setup Toolchain
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
components: llvm-tools-preview

- id: cache
name: Enable Workflow Cache
uses: Swatinem/rust-cache@v2

- id: tools
name: Install Tools
uses: taiki-e/install-action@v2
with:
tool: grcov,cargo-llvm-cov

- id: imdl
name: Install Intermodal
run: cargo install imdl

- id: coverage
name: Generate Coverage Report
run: |
cargo clean
cargo llvm-cov --all-features --workspace --codecov --output-path ./codecov.json

- name: Store PR number and commit SHA
run: |
echo "Storing PR number ${{ github.event.number }}"
echo "${{ github.event.number }}" > pr_number.txt

echo "Storing commit SHA ${{ github.event.pull_request.head.sha }}"
echo "${{ github.event.pull_request.head.sha }}" > commit_sha.txt

# Workaround for https://github.com/orgs/community/discussions/25220
# Triggered sub-workflow is not able to detect the original commit/PR which is available
# in this workflow.
- name: Store PR number
uses: actions/upload-artifact@v4
with:
name: pr_number
path: pr_number.txt

- name: Store commit SHA
uses: actions/upload-artifact@v4
with:
name: commit_sha
path: commit_sha.txt

# This stores the coverage report in artifacts. The actual upload to Codecov
# is executed by a different workflow `upload_coverage.yml`. The reason for this
# split is because `on.pull_request` workflows don't have access to secrets.
- name: Store coverage report in artifacts
uses: actions/upload-artifact@v4
with:
name: codecov_report
path: ./codecov.json

- run: |
echo "The coverage report was stored in Github artifacts."
echo "It will be uploaded to Codecov using [upload_coverage.yml] workflow shortly."
119 changes: 119 additions & 0 deletions .github/workflows/upload_coverage_pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Upload Coverage Report (PR)

on:
# This workflow is triggered after every successfull execution
# of `Generate Coverage Report` workflow.
workflow_run:
workflows: ["Generate Coverage Report (PR)"]
types:
- completed

permissions:
actions: write
contents: write
issues: write
pull-requests: write

jobs:
coverage:
name: Upload Coverage Report
environment: coverage
runs-on: ubuntu-latest
steps:
- name: "Download existing coverage report"
id: prepare_report
uses: actions/github-script@v7
with:
script: |
var fs = require('fs');

// List artifacts of the workflow run that triggered this workflow
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});

let codecovReport = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "codecov_report";
});

if (codecovReport.length != 1) {
throw new Error("Unexpected number of {codecov_report} artifacts: " + codecovReport.length);
}

var download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: codecovReport[0].id,
archive_format: 'zip',
});
fs.writeFileSync('codecov_report.zip', Buffer.from(download.data));

let prNumber = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "pr_number";
});

if (prNumber.length != 1) {
throw new Error("Unexpected number of {pr_number} artifacts: " + prNumber.length);
}

var download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: prNumber[0].id,
archive_format: 'zip',
});
fs.writeFileSync('pr_number.zip', Buffer.from(download.data));

let commitSha = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "commit_sha";
});

if (commitSha.length != 1) {
throw new Error("Unexpected number of {commit_sha} artifacts: " + commitSha.length);
}

var download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: commitSha[0].id,
archive_format: 'zip',
});
fs.writeFileSync('commit_sha.zip', Buffer.from(download.data));

- id: parse_previous_artifacts
run: |
unzip codecov_report.zip
unzip pr_number.zip
unzip commit_sha.zip

echo "Detected PR is: $(<pr_number.txt)"
echo "Detected commit_sha is: $(<commit_sha.txt)"

# Make the params available as step output
echo "override_pr=$(<pr_number.txt)" >> "$GITHUB_OUTPUT"
echo "override_commit=$(<commit_sha.txt)" >> "$GITHUB_OUTPUT"

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ steps.parse_previous_artifacts.outputs.override_commit || '' }}
path: repo_root

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}
files: ${{ github.workspace }}/codecov.json
fail_ci_if_error: true
# Manual overrides for these parameters are needed because automatic detection
# in codecov-action does not work for non-`pull_request` workflows.
# In `main` branch push, these default to empty strings since we want to run
# the analysis on HEAD.
override_commit: ${{ steps.parse_previous_artifacts.outputs.override_commit || '' }}
override_pr: ${{ steps.parse_previous_artifacts.outputs.override_pr || '' }}
working-directory: ${{ github.workspace }}/repo_root
# Location where coverage report files are searched for
directory: ${{ github.workspace }}