@@ -15,14 +15,24 @@ jobs:
1515 version-consistency :
1616 # Also the check name the release PR's footer tells maintainers to wait for.
1717 name : Release PR version
18- # Only the platform's release PR carries a version in its title; every other pull request
19- # skips this job, which GitHub reports as neutral. The release may be presented from
20- # scalar-next itself or from the release-please branch rendered off it, so both heads
21- # count as the release PR.
18+ # A release-shaped title against the release branch is the whole test here, with no clause
19+ # on who opened the pull request or what branch it is rendered onto. This job only reads,
20+ # and a pull request claiming to be a release is worth checking against the committed
21+ # version whoever opened it. Every other pull request skips this job, which GitHub reports
22+ # as neutral.
23+ #
24+ # Loose on purpose: the prefix, not the full semver pattern the script matches. A version
25+ # typo'd into the title still reaches the script and fails there, rather than falling out
26+ # of the guard and leaving no check at all — a missing check is not a failing one, and this
27+ # is the check the release PR's footer tells maintainers to wait for before merging.
28+ #
29+ # It is also what keeps the workflow from failing silently if the platform ever opens
30+ # release PRs from a different account: the bridge below stops firing, but this check still
31+ # runs, the retitled version and the committed one disagree, and it turns red. The merge is
32+ # blocked loudly instead of releasing the old version.
2233 if : >-
2334 ${{ github.event.pull_request.base.ref == 'main'
24- && (github.event.pull_request.head.ref == 'scalar-next'
25- || startsWith(github.event.pull_request.head.ref, 'release-please--branches--scalar-next--')) }}
35+ && startsWith(github.event.pull_request.title, 'release: ') }}
2636 runs-on : ubuntu-latest
2737 steps :
2838 - uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
@@ -60,14 +70,30 @@ jobs:
6070 # release PR from). `changes.title` is only set when the title itself changed, and bot
6171 # senders are ignored so the platform's own retitles cannot bounce back into another
6272 # commit.
73+ #
74+ # Both signals are required here, unlike the read-only check above, and each covers what the
75+ # other cannot. The author, because this job pushes with `contents: write` and a title is
76+ # free text — anyone able to open a pull request against main could otherwise
77+ # name a version and have it committed to scalar-next. `user.login` is set by GitHub when
78+ # the pull request is opened and cannot be forged by whoever edits the title afterwards.
79+ # The title, because those accounts open pull requests other than release PRs, and retitling
80+ # one of those must not push a release.
81+ #
82+ # One login per platform deployment, since a repo generated by staging carries staging's
83+ # app. Parenthesised because the group is ANDed with the title clause below: without the
84+ # parens that `&&` would bind to the last login alone, letting the other accounts push a
85+ # release off any title. Listed rather than matched on the shared `scalar-docs` stem — a
86+ # prefix test would also admit any future `scalar-docs-*[bot]`, including someone else's.
6387 if : >-
6488 ${{ github.event.action == 'edited'
6589 && github.event.changes.title != null
6690 && github.event.sender.type != 'Bot'
6791 && github.event.pull_request.state == 'open'
6892 && github.event.pull_request.base.ref == 'main'
69- && (github.event.pull_request.head.ref == 'scalar-next'
70- || startsWith(github.event.pull_request.head.ref, 'release-please--branches--scalar-next--')) }}
93+ && (github.event.pull_request.user.login == 'scalar-docs[bot]'
94+ || github.event.pull_request.user.login == 'scalar-docs-staging[bot]'
95+ || github.event.pull_request.user.login == 'scalar-docs-development[bot]')
96+ && startsWith(github.event.pull_request.title, 'release: ') }}
7197 # One bridge run at a time per pull request, newest retitle wins. Two retitles in quick
7298 # succession (a version typo corrected seconds later) would otherwise start two runs that
7399 # both read the version committed on the PR head, both get past the no-op guard, and both
0 commit comments