fix(upstream-docs): the watcher cannot push to a protected main - #67
Merged
Conversation
The weekly run ended red on its first outing. It fetches the watched vendor documents, rewrites upstream-docs-state.json, and pushed the result straight to main -- which is protected, so the push came back "GH006: Protected branch update failed... 5 of 5 required status checks are expected". The baseline could never advance, and it would have failed the same way on the week a document actually moved, which is the week the tool exists for. The baseline now moves the way everything else here moves: as a pull request on one branch, force-pushed so the newest proposal replaces the previous one rather than stacking on it -- the baseline is a whole snapshot, not a delta. [skip ci] is gone from the commit message, because the required checks are now the point. A pull request opened with GITHUB_TOKEN starts no workflow run, so the step dispatches validate against the branch head; workflow_dispatch is the documented exception to that rule, and validate already accepts it. That run also had nothing to say: zero alerts, and 31 insertions and 31 deletions in a 31-line file. upstream-docs-state.json was the only file in the repository committed with CRLF, written by a Windows checkout through write_text's text mode. Every Linux run rewrote all 31 lines, so the watcher would have proposed a baseline every single week whether or not a document changed. The writer now pins LF, the file is normalized, and .gitattributes keeps the whole class shut -- the same translation would land in index.yaml, devices.yaml and support-status.json, which CI compares with git diff --exit-code, and in the Lua that gets hashed into the signed artifacts. Two tests hold the line: what the tool writes, and what is committed. The second is the one that catches this in CI, since on Linux the first passes even against the old code. Signed-off-by: HuggeK <48095810+HuggeK@users.noreply.github.com> Co-authored-by: HuggeK <48095810+HuggeK@users.noreply.github.com>
HuggeK
marked this pull request as ready for review
August 3, 2026 09:57
The step claimed the dispatched run made the required checks green. It does not, and this branch is the measurement: run 30804965042 put six successful check runs on the head of #67 -- drivers, packages, public-boundary, history-secret-scan, the channel preflight, and dco skipped -- and the pull request still reads BLOCKED with an empty status rollup, while #66, which got its run from a pull_request event, reads CLEAN with five. A commit whose only check suite came from a dispatch has no rollup for branch protection to read. The dispatch is still worth keeping: without it nothing runs against a bot's proposal at all, and a verdict a maintainer can read before spending attention on the diff is the whole ask. It just is not the thing that unblocks the merge, so neither the comment nor the pull request body says it is. Reopening the proposal is what starts the checks that count, and the body now says so where the maintainer will be standing when they need it. Signed-off-by: HuggeK <48095810+HuggeK@users.noreply.github.com> Co-authored-by: HuggeK <48095810+HuggeK@users.noreply.github.com>
miravoss26
reviewed
Aug 3, 2026
miravoss26
left a comment
There was a problem hiding this comment.
what it does: the weekly watch-upstream-docs run can't push its baseline to a protected main, so the baseline now advances as a force-pushed PR on one branch, and generated files are pinned to LF so a Windows-authored baseline stops reading as a whole-file change.
- correctness: solid. PR-instead-of-push is the right move, and force-pushing a single
upstream-docs-baselinebranch is fine because the baseline is a whole snapshot, not a delta.newline="\n"inwrite_state, plus.gitattributes, plus the two LF tests close the CRLF churn at both ends (tool output and committed baseline). - security (scopes): the workflow token gains
pull-requests: writeandactions: writeinwatch-upstream-docs.yml. both are actually used (open/refresh the PR, thengh workflow run validate.yml), so it's minimal for the new flow. flagging it only becauseactions: writelets the token dispatch workflows, which is the one line worth a conscious human nod. - nit: the PR-body heredoc is de-indented to column 0 so
BODYterminates correctly inside the YAMLrun:block. correct, and an easy one to get wrong.
safe to merge from my read. the only judgement call for a human is granting those two token scopes, and they're correctly scoped to what the step needs.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The weekly
watch-upstream-docsrun failed on its first outing. It fetched the watched vendor documents, rewroteupstream-docs-state.json, and pushed the result straight tomain:mainis protected, so that push can never land. The baseline could never advance — and it would have failed the same way on the week a watched document actually moved, which is the week the tool exists for.The baseline now moves the way everything else here moves: as a pull request, on one branch that is force-pushed so the newest proposal replaces the previous one rather than stacking on it. The baseline is a whole snapshot, not a delta, so replacing it is the correct merge.
What this does not fix
A bot's proposal still needs a human to start its checks, and the workflow now says so rather than pretending otherwise.
What was measured, on this pull request
A pull request opened with
GITHUB_TOKENstarts no workflow run.workflow_dispatchis the documented exception, so the first version of this branch dispatchedvalidateagainst the branch head and claimed that satisfied the required checks.It does not, and this branch is the measurement. Run 30804965042 put six successful check runs on this PR's head commit —
drivers,packages,public-boundary,history-secret-scan,signed channel accepts this tree, anddcoskipped. The REST API lists all six on the SHA and links the suite to this PR. GraphQL nonetheless reportsstatusCheckRollup: null, and the PR readsBLOCKED. PR #66, whose run came from apull_requestevent, reports five checks andCLEAN.So a commit whose only check suite came from a dispatch has no rollup for branch protection to read. The dispatch is kept, because without it nothing runs against a bot's proposal and a maintainer has no verdict to read before spending attention on the diff — but the comment and the generated PR body now both say it is not what unblocks the merge. Reopening the proposal is what starts the checks that count.
Making this fully automatic needs a PAT or GitHub App token in a repo secret, which is a decision for whoever owns the repo, not something this branch should quietly assume.
The run also had nothing to say
Zero alerts, and
1 file changed, 31 insertions(+), 31 deletions(-)in a 31-line file.upstream-docs-state.jsonwas the only file in the repository committed with CRLF — written by a Windows checkout throughwrite_text's text mode, which translates every\nto the platform's line ending. Every Linux run rewrote all 31 lines, so the watcher would have proposed a baseline every single week whether or not a document changed.The writer now pins LF, the file is normalized, and
.gitattributeskeeps the whole class shut.Why
.gitattributescovers more than this one fileThe same translation would land in
index.yaml,devices.yamlandsupport-status.json— which CI compares withgit diff --exit-codeafter regenerating them — and in the Lua that gets hashed byte for byte into the signed artifacts. Any of those regenerated on a Windows checkout would read as a whole-file change on a tree where nothing moved.It costs nothing to add:
git ls-files --eolreports every other tracked file as already LF in the index, so nothing is renormalized by this.Verification
validatesuite green on this branch, including the two new tests and thegit diff --exit-codecomparisons that.gitattributescould have disturbed.python tools/check_upstream_docs.py --check— 2 watched docs, 0 problems.git/ghin all three states — baseline unchanged, changed with no open proposal, changed with one already open — confirming the heredoc renders the body flush at column 0 and each path exits 0.Two tests hold the line: what the tool writes, and what is committed. The second is the one that catches this in CI, since on Linux the first passes even against the old code.