Skip to content

Commit aaddaf5

Browse files
ralyodioclaude
andcommitted
Grant the distribute job the permissions it asks for
A reusable workflow can only hold a subset of its caller's permissions. submit-packages.yml requests `pull-requests: write` to open the PR carrying the refreshed distribution/ manifests, but release.yml granted only `contents: write`, so the push would succeed and the PR creation be denied. The script also swallowed that denial with a bare `||`, reporting success with no PR behind it. It now distinguishes an already-open PR, which is expected on a re-run, from a real failure, which exits non-zero. A silent success here is precisely how this pipeline spent three months looking healthy while publishing nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 491e0fb commit aaddaf5

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ on:
99
description: 'Version to release (e.g. 0.1.0)'
1010
required: true
1111

12+
# A called workflow can only ever hold a subset of its caller's permissions, so
13+
# the distribute job's `pull-requests: write` has to be granted here too — it
14+
# opens the PR carrying the refreshed distribution/ manifests. Without this the
15+
# push succeeds and `gh pr create` is denied, which the script swallows, so the
16+
# branch would appear with no PR behind it.
1217
permissions:
1318
contents: write
19+
pull-requests: write
1420

1521
jobs:
1622
# 1) Create the GitHub Release (draft) up front so each per-platform build job

‎scripts/open-distribution-pr.sh‎

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,29 @@ else
3737
git push origin "${BRANCH}"
3838
fi
3939

40-
# `gh pr create` fails if one is already open for the branch, which is fine.
41-
gh pr create \
40+
# An already-open PR for this branch is fine and expected on a re-run. Anything
41+
# else — a denied token, a missing base — is a real failure and must not be
42+
# swallowed: a silent success here is precisely how this pipeline went three
43+
# months looking healthy while publishing nothing.
44+
set +e
45+
OUT="$(gh pr create \
4246
--base main \
4347
--head "${BRANCH}" \
4448
--title "chore(distribution): refresh manifests for v${VERSION}" \
4549
--body "Automated manifest refresh from the release pipeline for v${VERSION}.
4650
4751
Version strings and sha256 checksums are rewritten from the published release
48-
assets by \`scripts/submit-packages.mjs\`." \
49-
|| echo "a PR for ${BRANCH} already exists; branch updated in place"
52+
assets by \`scripts/submit-packages.mjs\`." 2>&1)"
53+
RC=$?
54+
set -e
55+
56+
echo "${OUT}"
57+
58+
if [ "${RC}" -ne 0 ]; then
59+
if echo "${OUT}" | grep -qi "already exists"; then
60+
echo "a PR for ${BRANCH} already exists; branch updated in place"
61+
else
62+
echo "gh pr create failed for ${BRANCH}" >&2
63+
exit "${RC}"
64+
fi
65+
fi

0 commit comments

Comments
 (0)