|
10 | 10 | # Notes: - Action pins follow the project standard: checkout@v6, |
11 | 11 | # upload-artifact@v6 |
12 | 12 | # - Concurrency cancels superseded runs per ref |
13 | | -# Version: 1.6.0 |
| 13 | +# Version: 1.6.2 |
14 | 14 | # ============================================================================== |
15 | 15 |
|
16 | 16 | name: CI |
|
96 | 96 | cache: pip |
97 | 97 |
|
98 | 98 | - name: Install dev dependencies |
99 | | - run: pip3 install pytest pytest-cov |
| 99 | + # PyYAML is required by the CI meta-suite (tests/ci); without it those |
| 100 | + # tests skip silently and the suite total drops below the documented count |
| 101 | + run: pip3 install pytest pytest-cov pyyaml |
100 | 102 |
|
101 | 103 | - name: Run test suite with coverage |
102 | 104 | run: | |
@@ -146,11 +148,85 @@ jobs: |
146 | 148 | python-version: "3.12" |
147 | 149 | cache: pip |
148 | 150 |
|
149 | | - - name: Install pytest (used by docs validator test-count check) |
150 | | - run: pip3 install pytest |
| 151 | + - name: Install pytest and PyYAML |
| 152 | + # The docs validator verifies the collected suite total; PyYAML must be |
| 153 | + # present or the CI meta-suite is excluded from collection and the |
| 154 | + # documented count cannot match |
| 155 | + run: pip3 install pytest pyyaml |
151 | 156 |
|
152 | 157 | - name: Verify version consistency |
153 | 158 | run: python3 scripts/check_version_consistency.py |
154 | 159 |
|
155 | 160 | - name: Verify documentation accuracy |
156 | 161 | run: python3 scripts/validate_docs.py |
| 162 | + |
| 163 | + # ============================================================================ |
| 164 | + # Badge Publication (main only, after all gates pass) |
| 165 | + # ============================================================================ |
| 166 | + badges: |
| 167 | + name: Publish Badge Data |
| 168 | + if: github.event_name == 'push' && github.ref == 'refs/heads/main' |
| 169 | + needs: [lint, typecheck, test, security, consistency] |
| 170 | + runs-on: ubuntu-latest |
| 171 | + permissions: |
| 172 | + contents: write |
| 173 | + steps: |
| 174 | + - uses: actions/checkout@v6 |
| 175 | + |
| 176 | + - name: Set up Python 3.12 |
| 177 | + uses: actions/setup-python@v6 |
| 178 | + with: |
| 179 | + python-version: "3.12" |
| 180 | + cache: pip |
| 181 | + |
| 182 | + - name: Install pytest and PyYAML |
| 183 | + run: pip3 install pytest pyyaml |
| 184 | + |
| 185 | + - name: Download coverage artifact |
| 186 | + uses: actions/download-artifact@v6 |
| 187 | + with: |
| 188 | + name: coverage-py3.12 |
| 189 | + path: . |
| 190 | + |
| 191 | + - name: Generate badge endpoint JSON |
| 192 | + # mypy passes by gate (needs: typecheck); test count from collection; |
| 193 | + # coverage percent parsed from the matrix job's coverage.xml artifact |
| 194 | + run: | |
| 195 | + mkdir -p badge-data |
| 196 | + COUNT=$(python3 -m pytest tests/ --collect-only -q 2>/dev/null | grep -oP '\d+(?= tests collected)') |
| 197 | + COVERAGE=$(python3 -c "import xml.etree.ElementTree as ET; print(f\"{float(ET.parse('coverage.xml').getroot().get('line-rate'))*100:.0f}\")") |
| 198 | + python3 - "$COUNT" "$COVERAGE" << 'PYEOF' |
| 199 | + import json |
| 200 | + import sys |
| 201 | +
|
| 202 | + count, coverage = sys.argv[1], sys.argv[2] |
| 203 | + badges = { |
| 204 | + "mypy.json": { |
| 205 | + "schemaVersion": 1, "label": "mypy", |
| 206 | + "message": "strict passing", "color": "brightgreen", |
| 207 | + }, |
| 208 | + "tests.json": { |
| 209 | + "schemaVersion": 1, "label": "pytest", |
| 210 | + "message": f"{count} passing", "color": "brightgreen", |
| 211 | + }, |
| 212 | + "coverage.json": { |
| 213 | + "schemaVersion": 1, "label": "coverage", |
| 214 | + "message": f"{coverage}%", "color": "brightgreen", |
| 215 | + }, |
| 216 | + } |
| 217 | + for name, payload in badges.items(): |
| 218 | + with open(f"badge-data/{name}", "w", encoding="utf-8") as f: |
| 219 | + json.dump(payload, f) |
| 220 | + PYEOF |
| 221 | +
|
| 222 | + - name: Publish to badges branch |
| 223 | + run: | |
| 224 | + cd badge-data |
| 225 | + git init -q -b badges |
| 226 | + git config user.name "github-actions[bot]" |
| 227 | + git config user.email "github-actions[bot]@users.noreply.github.com" |
| 228 | + git add . |
| 229 | + git commit -qm "Update badge data for ${GITHUB_SHA}" |
| 230 | + git push -f "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" badges |
| 231 | + env: |
| 232 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
0 commit comments