Skip to content

ci: call the fleet release-please workflow instead of hardcoding the action - #736

Merged
forkwright merged 1 commit into
mainfrom
ci/release-please-reusable
Aug 25, 2026
Merged

ci: call the fleet release-please workflow instead of hardcoding the action#736
forkwright merged 1 commit into
mainfrom
ci/release-please-reusable

Conversation

@forkwright

Copy link
Copy Markdown
Owner

Finding

Every release-please PR in this repo is permanently stuck, and the cause is not in this repo's workflow logic.

A GitHub platform policy in force since 2026-06-11 ("Bot-created pull requests can run workflows if approved") holds any workflow run triggered by a PR authored via the default GITHUB_TOKEN — the github-actions[bot] identity — pending manual approval. This includes same-repo PRs, not only forks.

Evidence

A blocked run on harmonia#733 (32795920085):

conclusion       = action_required
actor            = github-actions[bot]
triggering_actor = github-actions[bot]
jobs.total_count = 0

Zero jobs are ever created, so no workflow if: condition evaluates. All five workflows on the PR went action_required simultaneously.

The discriminating case: aletheia's release run looks clean, but its triggering_actor is forkwright — a human approval, not a differing configuration. There is no exempt setup to copy.

Probed for an opt-out: actions/permissions/access returns 404 "only applies to internal and private repositories" on public repos; the private-repo controls that do exist govern cross-repo access, PR creation and token scope, none of which gate run execution.

The fix

Run release-please under a token that is not GITHUB_TOKEN. The fleet reusable already does:

token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}

This repo hardcoded googleapis/release-please-action with no token: input at all — one of four copies of a thing the fleet already publishes, correctly, one repo away.

Why this is safe to land before the secret exists

An undefined repository secret resolves to an empty string, which is falsy, so the reusable's || fallback preserves today's behaviour exactly. Provisioning RELEASE_PLEASE_TOKEN then unblocks every migrated repo at once, with no further edits.

Decisions made deliberately

secrets: inherit not used. The reusable declares RELEASE_PLEASE_TOKEN by name in its workflow_call.secrets block, so it is passed by name. inherit forwards every repository secret to a workflow hosted in another repo, for no capability gain.

Pinned @main, not by SHA. forkwright/.github publishes no tags, so a SHA pin there is one nothing can bump — akroasis froze exactly that way on a revision predating a fix.

Everything repo-specific is carried over verbatim — trigger, permissions block, concurrency (including this repo's own cancel-in-progress choice), and any downstream attestation job. Those jobs' needs.release-please.outputs.* references still resolve, because the reusable's job id and output names match.

One thing does not survive

timeout-minutes cannot be set on a job that calls a reusable workflow (GitHub rejects it: Unexpected value 'timeout-minutes'). A hung run now falls back to GitHub's 360-minute default instead of being killed at 10. Fixing that means adding a timeout inside the reusable's own job definition, which is not this repo's to change.

Related

typikon was deliberately not migrated: its release-please job passes skip-github-release: true as part of a gated publication design, and the reusable has no input for it. Migrating would have silently started creating real GitHub Releases on every push.

…action

Every release-please PR in this repo is permanently stuck. A GitHub platform
policy in force since 2026-06-11 holds any workflow run triggered by a PR
authored via the default GITHUB_TOKEN -- the github-actions[bot] identity --
pending manual approval, same-repo PRs included. There is no repository or
organization setting to disable it; that was probed and does not exist. Measured
on a blocked run: jobs.total_count is 0, so no workflow condition ever evaluates.

The fix is to run release-please under a token that is not GITHUB_TOKEN, and the
fleet reusable already does exactly that:

    token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}

This repo hardcoded the action instead, with no token input at all -- one of four
copies of something the fleet already publishes correctly.

The secret is passed explicitly rather than by `secrets: inherit`, because
inherit forwards EVERY repository secret to a workflow hosted in another repo for
no capability gain. The reusable declares this one by name.

Safe to land before the secret exists: an undefined repo secret resolves to an
empty string, which is falsy, so the reusable's fallback keeps today's behaviour
until it is provisioned. Provisioning then lights up every migrated repo at once.

Pinned @main, not by SHA. forkwright/.github publishes no tags, so a SHA pin
there is one nothing can bump.

One thing does not survive: `timeout-minutes` cannot be set on a job that calls a
reusable workflow, so a hung run now falls back to GitHub's 360-minute default
rather than being killed at 10. Fixing that means adding a timeout inside the
reusable's own job, which is not this repo's to change.
@forkwright
forkwright merged commit 50cbd7a into main Aug 25, 2026
16 checks passed
@forkwright
forkwright deleted the ci/release-please-reusable branch August 25, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant