Skip to content

Instantly share code, notes, and snippets.

@imaitland
Created May 19, 2026 14:55
Show Gist options
  • Select an option

  • Save imaitland/1f82c1837450f627239f4223984f5fa4 to your computer and use it in GitHub Desktop.

Select an option

Save imaitland/1f82c1837450f627239f4223984f5fa4 to your computer and use it in GitHub Desktop.
Run codecov as a github action - sans external services
name: Update Coverage Badge
on:
push:
branches: [main]
paths-ignore:
- 'README.md'
- 'pytest.xml'
permissions:
contents: write
pull-requests: write
jobs:
update-badge:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Install dependencies
run: uv sync --dev
- name: Run tests with coverage
run: |
uv run pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=. | tee pytest-coverage.txt
- name: Coverage comment
id: coverage
uses: MishaKav/pytest-coverage-comment@main
with:
pytest-coverage-path: ./pytest-coverage.txt
junitxml-path: ./pytest.xml
hide-comment: true
- name: Update README
run: |
sed -i '/<!-- Pytest Coverage Comment:Begin -->/,/<!-- Pytest Coverage Comment:End -->/c\<!-- Pytest Coverage Comment:Begin -->\n${{ steps.coverage.outputs.coverageHtml }}\n<!-- Pytest Coverage Comment:End -->' ./README.md
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
commit-message: 'docs: update coverage badge'
title: 'Update coverage badge'
body: 'Automated coverage badge update from test run'
branch: update-coverage-badge
delete-branch: true
@imaitland
Copy link
Copy Markdown
Author

This action runs codecov, and makes a change to the project's README.md. It submits this change as a PR. The change consists of a code report (e.g. uncovered lines, coverage percent), and a badge.

There is a gotcha - merging the PR created by the action can be tricky if you have other actions that must report a 'pass' status on PRs in order for them to be eligible for merge. Generally PRs created by actions don't trigger downstream actions in order to prevent recursive (and therefore potentially expensive) action workflows...

This gotcha seems like it should be resolvable using one of the following workarounds, ideally one that can be incorporated inside this action itself...

Primary Causes & Solutions

    Default GITHUB_TOKEN Restriction: If the action that creates the PR uses the automatically generated GITHUB_TOKEN, any subsequent on: pull_request workflows will not trigger for that PR.
        Fix: Use a Personal Access Token (PAT) or a GitHub App token with the necessary permissions (contents: write and pull-requests: write) when running the PR creation action. This makes the PR appear as if it were created by a user or app, allowing workflows to trigger normally.
    Skip CI Keywords: Check if the commit message or PR title contains strings like [skip ci], [ci skip], or [skip actions].
        Fix: Ensure the PR creation action is not automatically adding these tags to the commit messages or titles.
    Path Filtering: Your unit test workflow might be configured with on: pull_request: paths:, which skips runs if only specific files (like documentation) are changed.
        Fix: Verify that the files modified by the action are included in the workflow's path filters or remove the filters to ensure it runs on every PR.
    Draft PRs: Some workflows are configured to skip execution when a PR is in "Draft" status.
        Fix: Check if the action is creating the PR as a draft and adjust the workflow to trigger on types: [opened, synchronize, reopened, ready_for_review]. 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment