docs: link subpackages to architecture map #383
Workflow file for this run
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
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| schedule: | |
| - cron: "0 3 * * *" | |
| workflow_dispatch: | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| # Least privilege by default; jobs that need more (nightly alert issue, | |
| # coverage-badge push) declare their own elevated permissions. | |
| permissions: | |
| contents: read | |
| jobs: | |
| quality-fast: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install | |
| run: | | |
| python -m pip install --upgrade pip | |
| # mypy targets Python 3.10; NumPy 2.5+ stubs require Python 3.12. | |
| pip install -e ".[dev,ml]" "numpy<2.5" | |
| - name: Lint | |
| run: ruff check . | |
| - name: Typecheck | |
| run: mypy src/freshdata | |
| - name: Test (required fast lane) | |
| run: pytest -m "not online and not large" | |
| truthbench: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev,ml]" | |
| - name: TruthBench PR ratchet | |
| # PRs must not regress any gate that passes in the committed | |
| # baseline.json; the known-red gates are release blockers and are | |
| # enforced absolutely by the release workflow (make truthbench-release), | |
| # so they are reported here as KNOWN-RED without failing every | |
| # unrelated PR. Infrastructure errors and partial runs still fail. | |
| run: make truthbench-pr | |
| - name: Upload run artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: truthbench-results | |
| path: benchmarks/truthbench/results/ | |
| test-matrix: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] | |
| include: | |
| - python-version: "3.9" | |
| pandas: "pandas>=1.5,<2" | |
| numpy: "numpy<2" | |
| - python-version: "3.13" | |
| pandas: "pandas" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: pip | |
| - name: Install | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev,ml]" | |
| if [ -n "${{ matrix.pandas }}" ]; then pip install "${{ matrix.pandas }}"; fi | |
| if [ -n "${{ matrix.numpy }}" ]; then pip install "${{ matrix.numpy }}"; fi | |
| - name: Test (fast marker set) | |
| run: pytest -m "not online and not large" | |
| nightly-online-large: | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| # NO continue-on-error here: when this lane runs, a failure is a real | |
| # failure. Visibility is guaranteed by the alert step below (a pinned | |
| # issue), so a red nightly can't scroll by unnoticed. | |
| permissions: | |
| issues: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev,ml]" | |
| - name: Nightly online/large drift checks | |
| # --no-cov: this lane deliberately runs ~20 tests, so the repo-wide | |
| # --cov-fail-under=93 inherited from addopts can never be met here. | |
| # The coverage gate is enforced by the full fast lane (quality-fast). | |
| run: pytest -m "online or large or tier1" --no-cov | |
| - name: Open/refresh alert issue on failure | |
| if: failure() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const title = "nightly large-data lane failing"; | |
| const body = `The scheduled online/large test lane failed.\n\n` + | |
| `Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}` + | |
| `/actions/runs/${context.runId}\n\n` + | |
| `This lane does not run on push/PR — a failure here is only ` + | |
| `visible through this issue and the Actions tab.`; | |
| const open = await github.rest.issues.listForRepo({ | |
| ...context.repo, state: "open", labels: "nightly-failure", | |
| }); | |
| const existing = open.data.find(i => i.title === title); | |
| if (existing) { | |
| await github.rest.issues.createComment({ | |
| ...context.repo, issue_number: existing.number, body, | |
| }); | |
| } else { | |
| await github.rest.issues.create({ | |
| ...context.repo, title, body, labels: ["nightly-failure"], | |
| }); | |
| } | |
| # Runs on every push/PR: makes the *existence and status* of the large-data | |
| # lane visible where a green checkmark would otherwise hide it. Fails if the | |
| # large/online markers stop collecting any tests (a silently-rotted lane). | |
| large-data-status: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev,ml]" | |
| - name: Assert the large/online lane still collects tests | |
| run: | | |
| N=$(pytest -m "online or large or tier1" --collect-only -q -o addopts="" \ | |
| 2>/dev/null | grep -c "::" || true) | |
| echo "large/online/tier1 tests collected: $N" | |
| if [ "$N" -eq 0 ]; then | |
| echo "::error::the large/online test lane collects zero tests — it has rotted" | |
| exit 1 | |
| fi | |
| { | |
| echo "## Large-data test lane" | |
| echo "" | |
| echo "**$N** large/online/tier1 test(s) exist. They do **not** run on this" | |
| echo "push/PR — they run on the nightly schedule (see the *nightly-online-large*" | |
| echo "job in scheduled runs; failures open a pinned \`nightly-failure\` issue)." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| build: | |
| needs: quality-fast | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Build distributions | |
| run: | | |
| python -m pip install build twine | |
| python -m build | |
| twine check dist/* | |
| coverage-badge: | |
| # Publish a self-hosted shields endpoint badge to the `badges` branch | |
| # (no third-party account needed). Runs only on main. | |
| if: github.ref == 'refs/heads/main' | |
| needs: quality-fast | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev,ml]" | |
| - name: Compute coverage and write badge JSON | |
| run: | | |
| pytest -m "not online and not large and not tier1" \ | |
| --cov=freshdata --cov-report=json -o addopts="" | |
| python - <<'PY' | |
| import json | |
| pct = round(json.load(open("coverage.json"))["totals"]["percent_covered"]) | |
| color = ("brightgreen" if pct >= 90 else "green" if pct >= 80 | |
| else "yellow" if pct >= 70 else "orange" if pct >= 60 else "red") | |
| json.dump( | |
| {"schemaVersion": 1, "label": "coverage", "message": f"{pct}%", "color": color}, | |
| open("coverage.json", "w"), | |
| ) | |
| print("coverage badge:", pct, "%", color) | |
| PY | |
| - name: Push badge to `badges` branch | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| mkdir -p /tmp/badges && cp coverage.json /tmp/badges/coverage.json | |
| cd /tmp/badges | |
| git init -q | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git checkout -q -b badges | |
| git add coverage.json | |
| git commit -q -m "Update coverage badge" | |
| git push -q --force \ | |
| "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" badges |