Skip to content

file: Add more tests #26

file: Add more tests

file: Add more tests #26

Workflow file for this run

name: Code Coverage
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
pages: write
id-token: write
pull-requests: write
concurrency:
group: coverage-${{ github.ref }}
cancel-in-progress: true
jobs:
coverage:
name: Generate Coverage Report
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Install cargo-tarpaulin
uses: taiki-e/install-action@v2
with:
tool: cargo-tarpaulin
- name: Install system dependencies and setup D-Bus
run: |
sudo apt-get update
sudo apt-get install -y libssl-dev pkg-config gnome-keyring dbus-x11
# Start D-Bus session
mkdir -p ~/.local/share/keyrings
eval $(dbus-launch --sh-syntax)
export DBUS_SESSION_BUS_ADDRESS
echo "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS" >> $GITHUB_ENV
# Initialize and unlock the default keyring
printf '\n' | gnome-keyring-daemon --unlock --daemonize --login
# Give the service time to start
sleep 3
- name: Run coverage for native-tokio
run: |
mkdir -p coverage-raw
cargo tarpaulin \
--package oo7 \
--lib \
--no-default-features \
--features "tracing,tokio,native_crypto" \
--ignore-panics \
--out Lcov \
--output-dir coverage-raw
mv coverage-raw/lcov.info coverage-raw/native-tokio.info
- name: Run coverage for openssl-async-std
run: |
cargo tarpaulin \
--package oo7 \
--lib \
--no-default-features \
--features "tracing,async-std,openssl_crypto" \
--ignore-panics \
--out Lcov \
--output-dir coverage-raw
mv coverage-raw/lcov.info coverage-raw/openssl-async-std.info
- name: Generate coverage summary for PR comparison
if: github.event_name == 'pull_request'
run: |
# Extract PR coverage percentage using the same method as main branch
PR_COVERAGE=$(cargo tarpaulin \
--package oo7 \
--lib \
--no-default-features \
--features "tracing,tokio,native_crypto" \
--ignore-panics \
--skip-clean 2>&1 | grep "% coverage" | grep -o '[0-9]\+\.[0-9]\+' | head -1 || echo "0.00")
echo "PR_COVERAGE=$PR_COVERAGE" >> $GITHUB_ENV
echo "PR coverage: $PR_COVERAGE%"
- name: Install grcov for merging coverage
uses: taiki-e/install-action@v2
with:
tool: grcov
- name: Merge coverage and generate HTML report
run: |
mkdir -p site/coverage
# Merge LCOV files
cat coverage-raw/*.info > coverage-raw/combined.info
# Generate HTML report with grcov
grcov coverage-raw/combined.info \
--binary-path target/debug/ \
--source-dir . \
--output-type html \
--output-path site/coverage \
--branch \
--ignore-not-existing \
--ignore "**/tests/*" \
--ignore "**/examples/*" \
--ignore "**/target/*"
- name: Store coverage percentage for main branch
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: |
# Run tarpaulin and extract coverage percentage from the summary line
CURRENT_COVERAGE=$(cargo tarpaulin \
--package oo7 \
--lib \
--no-default-features \
--features "tracing,tokio,native_crypto" \
--ignore-panics \
--skip-clean 2>&1 | grep "% coverage" | grep -o '[0-9]\+\.[0-9]\+' | head -1 || echo "0.00")
echo "Main branch coverage: $CURRENT_COVERAGE%"
# Store in a simple text file artifact for PR comparisons
mkdir -p coverage-baseline
echo "$CURRENT_COVERAGE" > coverage-baseline/main-coverage.txt
# Generate coverage badge
COVERAGE_INT=$(echo "$CURRENT_COVERAGE" | cut -d. -f1)
if [ "$COVERAGE_INT" -ge 80 ]; then
COLOR="brightgreen"
elif [ "$COVERAGE_INT" -ge 60 ]; then
COLOR="yellow"
else
COLOR="red"
fi
# Create badge SVG using shields.io format
curl -s "https://img.shields.io/badge/coverage-${CURRENT_COVERAGE}%25-${COLOR}" > site/coverage/badge.svg
- name: Upload baseline coverage
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: coverage-baseline
path: coverage-baseline/main-coverage.txt
retention-days: 90
- name: Get main branch coverage for comparison
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
// Find the latest successful coverage run on main that has the baseline artifact
const { data: runs } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'coverage.yml',
status: 'completed',
conclusion: 'success',
branch: 'main',
per_page: 10
});
for (const run of runs.workflow_runs) {
try {
const { data: artifacts } = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: run.id
});
const baselineArtifact = artifacts.artifacts.find(a => a.name === 'coverage-baseline');
if (baselineArtifact) {
core.exportVariable('BASELINE_RUN_ID', run.id.toString());
console.log(`Found baseline artifact in run ${run.id}`);
return;
}
} catch (error) {
console.log(`Error checking run ${run.id}: ${error.message}`);
}
}
console.log('No baseline artifact found in recent main branch runs');
core.exportVariable('BASELINE_RUN_ID', '');
- name: Download baseline artifact
if: github.event_name == 'pull_request' && env.BASELINE_RUN_ID != ''
uses: actions/download-artifact@v4
with:
name: coverage-baseline
path: coverage-baseline/
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ env.BASELINE_RUN_ID }}
continue-on-error: true
- name: Set main coverage for comparison
if: github.event_name == 'pull_request'
run: |
if [ -f coverage-baseline/main-coverage.txt ]; then
MAIN_COVERAGE=$(cat coverage-baseline/main-coverage.txt)
echo "MAIN_COVERAGE=$MAIN_COVERAGE" >> $GITHUB_ENV
echo "Using stored main branch coverage: $MAIN_COVERAGE%"
else
echo "MAIN_COVERAGE=0.00" >> $GITHUB_ENV
echo "No baseline coverage found, using 0.00%"
fi
- name: Post coverage comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const prCoverage = parseFloat(process.env.PR_COVERAGE || '0.00');
const mainCoverage = parseFloat(process.env.MAIN_COVERAGE || '0.00');
const diff = prCoverage - mainCoverage;
const diffText = diff > 0 ? `+${diff.toFixed(2)}%` : `${diff.toFixed(2)}%`;
const emoji = diff > 0 ? '📈' : diff < 0 ? '📉' : '➡️';
const body = `## 📊 Code Coverage Report
| Metric | Value |
|--------|-------|
| **Current PR Coverage** | ${prCoverage.toFixed(2)}% |
| **Main Branch Coverage** | ${mainCoverage.toFixed(2)}% |
| **Coverage Change** | ${emoji} ${diffText} |
${diff < -1 ? '⚠️ **Warning**: Coverage decreased by more than 1%' : ''}
${diff > 1 ? '🎉 **Great**: Coverage increased by more than 1%!' : ''}
*Coverage report generated by [cargo-tarpaulin](https://github.com/xd009642/tarpaulin)*`;
// Find existing coverage comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existingComment = comments.find(comment =>
comment.body.includes('## 📊 Code Coverage Report')
);
if (existingComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body: body
});
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}
- name: Upload coverage artifacts
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: coverage-reports
path: site/coverage/html/
retention-days: 30