Skip to content

Combined Coverage Report #93

Combined Coverage Report

Combined Coverage Report #93

name: Combined Coverage Report
on:
workflow_run:
workflows: ["Integration Tests"]
types:
- completed
workflow_dispatch:
permissions:
actions: read
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
combine-and-deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event.workflow_run.conclusion == 'failure' || github.event_name == 'workflow_dispatch' }}
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install coverage tools
run: |
python -m pip install --upgrade pip
pip install coverage[toml] genbadge[coverage]
- name: Download coverage artifacts
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
let runId;
if (context.eventName === 'workflow_run') {
runId = context.payload.workflow_run.id;
} else {
const runs = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'integration-tests.yml',
per_page: 1,
status: 'completed',
});
if (runs.data.workflow_runs.length === 0) {
throw new Error('No completed integration test runs found');
}
runId = runs.data.workflow_runs[0].id;
}
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: runId,
});
const coverageArtifacts = artifacts.data.artifacts.filter(
artifact => artifact.name.startsWith('coverage-')
);
const coverageDir = 'coverage-reports';
fs.mkdirSync(coverageDir, { recursive: true });
for (const artifact of coverageArtifacts) {
const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: artifact.id,
archive_format: 'zip',
});
const zipPath = path.join(coverageDir, `${artifact.name}.zip`);
fs.writeFileSync(zipPath, Buffer.from(download.data));
const artifactDir = path.join(coverageDir, artifact.name);
fs.mkdirSync(artifactDir, { recursive: true });
execSync(`unzip -q "${zipPath}" -d "${artifactDir}"`);
fs.unlinkSync(zipPath);
}
- name: Combine coverage reports
id: combine
shell: bash
run: |
mkdir -p site
if [ ! -d "coverage-reports" ] || [ -z "$(find coverage-reports -type f -name '.coverage*' -print -quit)" ]; then
echo "has_coverage=false" >> "$GITHUB_OUTPUT"
cat > site/index.html <<'EOF'
<!DOCTYPE html>
<html>
<body>
<h1>No Coverage Data</h1>
<p>No coverage artifacts were available from the integration workflow.</p>
</body>
</html>
EOF
exit 0
fi
cd coverage-reports
for dir in */; do
if [ -f "$dir/.coverage" ]; then
job_name=$(basename "$dir")
mv "$dir/.coverage" ".coverage.$job_name"
fi
done
cd ..
coverage combine coverage-reports/.coverage.*
coverage xml -o coverage.xml
coverage html -d site/coverage
echo "has_coverage=true" >> "$GITHUB_OUTPUT"
- name: Generate coverage badge
if: steps.combine.outputs.has_coverage == 'true'
run: genbadge coverage -i coverage.xml -o site/coverage.svg -n "coverage"
- name: Create site index
shell: bash
run: |
if [ "${{ steps.combine.outputs.has_coverage }}" = "true" ]; then
cat > site/index.html <<'EOF'
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0; url=./coverage/">
<title>Redirecting to coverage report...</title>
</head>
<body>
<p>Redirecting to coverage report... <a href="./coverage/">Click here if not redirected</a></p>
</body>
</html>
EOF
fi
cat > site/README.md <<'EOF'
# Nominal Refactor Advisor Coverage Reports
This site contains the combined coverage reports for the Nominal Refactor Advisor project.
- [Coverage Report](./coverage/)
EOF
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: site
retention-days: 1
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4