Skip to content

Document the environment with env.default, and tell agents not to rea… #15

Document the environment with env.default, and tell agents not to rea…

Document the environment with env.default, and tell agents not to rea… #15

Workflow file for this run

# Runs the full validation suite against every environment daily, then builds
# and deploys the dashboard website to GitHub Pages.
name: Test dashboard
on:
schedule:
- cron: '30 6 * * *'
workflow_dispatch:
# Temporary, remove before merge: workflow_dispatch only works once this file
# is on the default branch, so pre-merge runs of the redesign trigger on push.
# Development moved here from #118, which carried the same trigger on its own
# branch; only one branch should have it at a time, since each run takes
# 20-35 minutes and force-pushes gh-pages.
push:
branches: [redesign-dashboard]
permissions:
contents: write # the deploy action pushes to the gh-pages branch
issues: read # the GitHub issue tests read this repo's issues
concurrency:
group: dashboard-deploy
# Only a manual dispatch supersedes what is already running: you press Run
# workflow because you want fresh output now, and the run it cancels would have
# produced the same two files, so nothing is lost by killing it. A scheduled run
# never cancels anything — a cron run must not be able to kill a slower one that
# is mid-flight, because that is the run that appends the day's history line —
# and neither does a push, which queues behind whatever is deploying rather than
# racing it.
cancel-in-progress: ${{ github.event_name == 'workflow_dispatch' }}
jobs:
test-and-deploy:
runs-on: ubuntu-latest
timeout-minutes: 350
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Run the test suite against every target
env:
GITHUB_TOKEN: ${{ github.token }}
# The Google Sheet IDs are secrets: they must never be checked in or
# appear in anything this workflow publishes.
BABEL_VALIDATION_SHEET_ID: ${{ secrets.BABEL_VALIDATION_SHEET_ID }}
BABEL_VALIDATION_BLOCKLIST_SHEET_ID: ${{ secrets.BABEL_VALIDATION_BLOCKLIST_SHEET_ID }}
# A nonzero pytest exit (failing tests) is normal here: the report is
# the artifact. `timeout 45m` caps the damage from a hung or down
# environment, whose per-test timeouts would otherwise add up.
# ponytail: sequential loop; split into a matrix job with artifact
# merging if total runtime ever approaches the 6h job limit.
# The explicit `tests` path is required: without a path argument,
# pytest-xdist workers do not load tests/conftest.py early enough to
# know --target/--report-jsonl, and every worker dies at argparse.
run: |
mkdir -p raw
# Ask the report generator which targets exist rather than keeping a
# second list here. The two silently disagreed once already: adding
# [test-redis] to targets.ini put it in every table on the site — as a
# permanently unreachable environment, sorted after prod, and as an
# always-empty column in every ?sig= signature — because read_targets
# takes every section but localhost while this loop did not run it.
targets=$(uv run python -c "from src.babel_validation.tools.generate_report import read_targets; print(' '.join(read_targets('tests/targets.ini')[0]))")
echo "Running against: $targets"
for t in $targets; do
timeout 45m uv run pytest tests --target "$t" -n 8 -m "not unit" \
--report-jsonl "raw/$t.jsonl" || echo "target $t exited $?"
done
- name: Fetch the previous run history
# The published file is the source of truth: the deploy action
# force-pushes gh-pages as a single commit, so the branch is not an
# append log. The Pages CDN caches for ~10 minutes, so a manual
# dispatch right after a deploy could drop one history line — fine at
# a daily cadence.
run: |
curl -fsSL -o old_history.jsonl \
https://translatorsri.github.io/babel-validation/data/history.jsonl \
|| : > old_history.jsonl
- name: Generate the report
run: |
uv run python -m src.babel_validation.tools.generate_report \
--raw-dir raw --targets-ini tests/targets.ini \
--history-in old_history.jsonl --out-dir website/public/data
# Node 24 for npm 11 — see the note in tests.yaml. Without this the job
# gets the runner's default Node and fails at npm ci, four hours into the
# run, after every test has already been paid for.
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
cache-dependency-path: website/package-lock.json
- name: Build the website
working-directory: website
run: |
npm ci
npm run build
touch dist/.nojekyll
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: website/dist
- name: Upload raw outcomes for debugging
if: always()
uses: actions/upload-artifact@v4
with:
name: raw-jsonl
path: raw/
retention-days: 14