Update Badges #62
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # .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 |