From ac2e557181ad5364bc39f867de8a4d7401e688ba Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Fri, 4 Sep 2026 22:11:18 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=F0=9F=94=A7=EF=BC=9Amake?= =?UTF-8?q?=20the=20queue=20say=20why=20it=20could=20not=20start?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every step that reports back to a pull request is gated on the app token, because reporting takes one. So a token that never minted reports nothing at all: a bare red check, no comment, and the label still sitting there as though the queue had yet to look. That is the first failure a queue nobody has run before will produce, and the two things that cause it -- an app not installed on the repository, and a private key that lost its BEGIN and END lines on the way into a secret -- are indistinguishable from the outside. A workflow annotation needs no token and no permission, so it is the one report that survives having no credentials at all. It names both causes and says the label has to come off by hand, since `unlabeled` is not a trigger and reapplying it would otherwise start nothing. The note above the two reporting steps also claimed they need only the app's pull request permission. They do not: labels and comments are issue endpoints even when the number belongs to a pull request, so they need `Issues: write`. Left uncorrected that is an hour spent wondering why a queue that merges cannot comment. Signed-off-by: Derek Lewis Assisted-by: Claude-Code:claude-opus-5 --- .github/workflows/commit-queue.yml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml index a59140bc..c7fe8b61 100644 --- a/.github/workflows/commit-queue.yml +++ b/.github/workflows/commit-queue.yml @@ -84,9 +84,9 @@ jobs: # permissions neither task needs. The app happens to satisfy them today; # tightening its permissions, or installing it somewhere with fewer, # would break these silently behind the `|| true`. The endpoints below - # need only the pull request permission the app already has, and the - # label one names a single label rather than trusting a flag to be - # subtractive. + # need the app's `Issues: write` -- labels and comments are issue + # endpoints even when the number is a pull request's -- and the label one + # names a single label rather than trusting a flag to be subtractive. - name: Take the label back off if: always() && steps.token.outcome == 'success' env: @@ -100,6 +100,22 @@ jobs: "repos/${GITHUB_REPOSITORY}/issues/${NUMBER}/labels/$(jq -rn --arg l "$LABEL" '$l|@uri')" \ || true + # Everything that reports back needs the app's token, so a token that + # never minted leaves a bare red check and no reason for it -- the label + # still on, nothing said, in the one failure that greets a queue nobody + # has run yet. An annotation needs no token and no permission, so this is + # the one report that always survives. + - name: Say why no token could be minted + if: failure() && steps.token.outcome != 'success' + run: | + echo '::error title=The commit queue could not authenticate::' \ + 'No installation token could be minted, so nothing was read and' \ + 'nothing was merged. Either the app is not installed on this' \ + 'repository, or LAND_APP_ID / LAND_APP_PRIVATE_KEY is wrong --' \ + 'the private key must be the whole PEM, BEGIN and END lines' \ + 'included. The label is still on this pull request, and' \ + 'reapplying it starts nothing until it is taken off first.' + - name: Say why it did not land if: failure() && steps.token.outcome == 'success' env: