fix(ci): make timings report fork-safe (missed by #66577)

#66373 swapped GITHUB_TOKEN -> AUTOFIX_BOT_PAT across the workflows and
#66577 restored the `|| github.token` fork fallback for detect-changes and
the label gates -- but it missed the ci-timings "Collect timings and
generate report" step, which still passes a bare AUTOFIX_BOT_PAT. On fork
PRs that PAT is empty, so timings_report.py hard-fails at
expect_env("GITHUB_TOKEN") before it can reach its own "degraded run must
never redden the PR" soft-fail path. Every fork PR gets a red run from this
advisory job (e.g. #66573).

- ci.yml: apply the same `secrets.AUTOFIX_BOT_PAT || github.token` fallback
  to the timings step. github.token has `actions: read`, enough to read the
  run's job/step durations on forks.
- timings_report.py: treat a missing/empty GITHUB_TOKEN as a degraded run
  (TimingsUnavailable) instead of a hard ValueError, so this whole class of
  failure can never redden a PR again even if a future workflow drops the
  token. Still writes no JSON, so no empty baseline is ever cached.
This commit is contained in:
Brooklyn Nicholson 2026-07-18 01:06:36 -04:00
parent 126559d6bb
commit ecd54a001e
2 changed files with 11 additions and 2 deletions

View file

@ -226,7 +226,10 @@ jobs:
- name: Collect timings and generate report
env:
GITHUB_TOKEN: ${{ secrets.AUTOFIX_BOT_PAT }}
# Forks get no repo secrets (AUTOFIX_BOT_PAT is empty); fall back to
# the built-in read-only token so the timings API read still works
# there instead of hard-failing this advisory job on every fork PR.
GITHUB_TOKEN: ${{ secrets.AUTOFIX_BOT_PAT || github.token }}
run: |
python3 scripts/ci/timings_report.py \
--baseline ci-timings-baseline.json \

View file

@ -923,11 +923,17 @@ def main():
with open(args.from_json, encoding="utf-8") as f:
timings = json.load(f)
else:
token = expect_env("GITHUB_TOKEN")
repo = expect_env("GITHUB_REPOSITORY")
run_id = expect_env("GITHUB_RUN_ID")
head_sha = expect_env("GITHUB_SHA")
try:
# A missing token (e.g. an empty PAT on a fork PR, where repo
# secrets are unavailable) is a degraded run, not a hard error:
# route it through the same soft-fail path so this advisory job
# never reddens the PR.
token = os.environ.get("GITHUB_TOKEN")
if not token:
raise TimingsUnavailable("GITHUB_TOKEN is empty")
timings = collect_timings(token, repo, run_id, head_sha)
except TimingsUnavailable as e:
# Observability job: a missing report must never redden the PR.