From 4978fec49104e96114eaaf025d7714df5453c33a Mon Sep 17 00:00:00 2001 From: MarketDataApp Date: Tue, 22 Sep 2026 19:43:00 -0400 Subject: [PATCH] fix: the audit's token scope was one folded string, so both tokens were empty The first real run of the fleet audit failed, and it failed for the whole run rather than for one repository. `repositories: >-` is a FOLDED scalar: YAML joins its lines with spaces. The action splits that input on newlines and commas, never on spaces, so it read the list as a single repository name and asked GitHub for "MarketData-App/api code-review-bot". That is a 404, both token steps failed, and the audit then ran with GITHUB_TOKEN empty: Failed to create token for "MarketData-App/api code-review-bot": Not Found reviewbot: error: GITHUB_TOKEN is not set `|` keeps the newlines, which is what the action expects. The bug arrived with the `repositories:` scoping and no test caught it, because the test split the value on WHITESPACE -- which yields the right set for the broken form and the correct form alike. It now splits the way the action does, on newlines and commas, and additionally rejects any entry containing a space. Reverting the workflow to `>-` fails that test. Caught by the push-to-main trigger added in the same pull request, on its first run, which is the trigger doing exactly what it was added for. --- .github/workflows/audit-callers.yml | 4 ++-- tests/test_callers.py | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/audit-callers.yml b/.github/workflows/audit-callers.yml index bd415a6..3d0b8e7 100644 --- a/.github/workflows/audit-callers.yml +++ b/.github/workflows/audit-callers.yml @@ -108,7 +108,7 @@ jobs: # code-review-bot is here as well as `api` because BOTH audits # resolve each caller's pinned ref against this repository's # .github/workflows/review.yml. - repositories: >- + repositories: | api code-review-bot @@ -119,7 +119,7 @@ jobs: app-id: ${{ secrets.CODE_REVIEW_APP_ID }} private-key: ${{ secrets.CODE_REVIEW_APP_PRIVATE_KEY }} owner: MarketDataApp - repositories: >- + repositories: | sdk-py sdk-go sdk-js diff --git a/tests/test_callers.py b/tests/test_callers.py index 4b90dc2..07e5d28 100644 --- a/tests/test_callers.py +++ b/tests/test_callers.py @@ -571,11 +571,29 @@ def test_the_tokens_are_scoped_to_the_audited_repositories(audit_workflow): steps = audit_workflow["jobs"]["audit"]["steps"] tokens = [s for s in steps if "create-github-app-token" in str(s.get("uses", ""))] assert tokens, "no token steps found" + + # SPLIT THE WAY THE ACTION DOES -- on newlines and commas, never on + # spaces. `repositories: >-` folds its lines into one space-joined string, + # which the action reads as a SINGLE repository name; it asked GitHub for + # "MarketData-App/api code-review-bot" and got a 404, leaving both tokens + # empty. Splitting on whitespace here passed for the broken form and the + # correct one alike, so the test has to use the action's own separators. + def as_action_reads_it(value): + parts = str(value).replace(",", "\n").split("\n") + return {p.strip() for p in parts if p.strip()} + scoped = { - s["with"]["owner"]: set(str(s["with"]["repositories"]).split()) + s["with"]["owner"]: as_action_reads_it(s["with"]["repositories"]) for s in tokens if s["with"].get("repositories") } + for step in tokens: + value = str(step["with"].get("repositories", "")) + for line in value.replace(",", "\n").split("\n"): + assert " " not in line.strip(), ( + f"{step['with']['owner']}: {line.strip()!r} is not one repository name; " + f"`>-` folds the list into a single string" + ) assert len(scoped) == len(tokens), "a token step has no `repositories:` restriction" env = audit_workflow["env"] for owner, key in (("MarketData-App", "ORG_REPOS"), ("MarketDataApp", "USER_REPOS")):