Skip to content

Update Badges

Update Badges #70

Workflow file for this run

# .github/workflows/update-badges.yml
#
# Automatically updates the test-count badge in README.md after
# every successful CI run on master. Runs pytest once on Python 3.12,
# parses the JUnit XML for passed/failed counts, and commits the
# updated badge URL back to the repo.
#
# Only the "Tests: N passed" badge is updated automatically.
# "Overall Progress" and "Phase" are project-management numbers
# that change infrequently and are updated manually.
name: Update Badges
on:
workflow_run:
workflows: ["CI"]
types: [completed]
branches: [master]
permissions:
contents: write
jobs:
update-test-badge:
runs-on: ubuntu-latest
# Only run when CI succeeded on master
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v4
with:
ref: master
# Need a token with push rights (default GITHUB_TOKEN works
# for same-repo pushes when permissions.contents = write)
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: 'pip'
- name: Install system dependencies (Qt)
run: |
sudo apt-get update
sudo apt-get install -y libegl1 libxcb-xinerama0 \
libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 \
libxcb-render-util0 libxcb-shape0 libxcb-sync1 libxcb-xfixes0 \
libxcb-xkb1 libxkbcommon-x11-0 libgl1
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
- name: Run tests and generate JUnit XML
run: pytest tests/ -q --junitxml=test-results.xml
- name: Parse test results and update badge
run: |
# Extract passed/failed counts from JUnit XML
# pytest wraps results in <testsuites><testsuite tests="N" ...>
# so we must read attributes from the <testsuite> child, not root.
TESTS_ATTR=$(python3 -c "
import xml.etree.ElementTree as ET
tree = ET.parse('test-results.xml')
root = tree.getroot()
ts = root.find('testsuite') if root.tag == 'testsuites' else root
total = int(ts.attrib.get('tests', 0))
failures = int(ts.attrib.get('failures', 0))
errors = int(ts.attrib.get('errors', 0))
skipped = int(ts.attrib.get('skipped', 0))
passed = total - failures - errors - skipped
print(f'{passed}')
")
echo "Tests passed: $TESTS_ATTR"
# URL-encode the badge value (spaces become %20)
BADGE_VALUE="${TESTS_ATTR}%20passed"
# Current badge pattern in README (matches any number before %20passed)
# Example: Tests-1319%20passed-FDE100
sed -i "s|Tests-[0-9]*%20passed-FDE100|Tests-${BADGE_VALUE}-FDE100|g" README.md
# Check if anything changed
if git diff --quiet README.md; then
echo "Badge already up to date ($TESTS_ATTR passed)"
echo "BADGE_CHANGED=false" >> "$GITHUB_ENV"
else
echo "Badge updated to $TESTS_ATTR passed"
echo "BADGE_CHANGED=true" >> "$GITHUB_ENV"
fi
- name: Commit updated badge
if: env.BADGE_CHANGED == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add README.md
git commit -m "Update test badge to $(python3 -c "
import xml.etree.ElementTree as ET
root = ET.parse('test-results.xml').getroot()
ts = root.find('testsuite') if root.tag == 'testsuites' else root
t = int(ts.attrib.get('tests',0))
f = int(ts.attrib.get('failures',0))
e = int(ts.attrib.get('errors',0))
s = int(ts.attrib.get('skipped',0))
print(t - f - e - s)
") passed [skip ci]"
# Rebase on latest master to avoid conflicts with concurrent pushes
git pull --rebase origin master
git push