Skip to content

Commit 40d8532

Browse files
ci/github-script/prepare: identify real base branch (#435596)
2 parents aa0f176 + 87d9b08 commit 40d8532

File tree

12 files changed

+296
-256
lines changed

12 files changed

+296
-256
lines changed

.github/workflows/check.yml

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,7 @@ defaults:
3131
shell: bash
3232

3333
jobs:
34-
no-channel-base:
35-
name: no channel base
36-
if: contains(fromJSON(inputs.baseBranch).type, 'channel')
37-
runs-on: ubuntu-24.04-arm
38-
steps:
39-
- run: |
40-
cat <<EOF
41-
The nixos-* and nixpkgs-* branches are pushed to by the channel
42-
release script and should not be merged into directly.
43-
44-
Please target the equivalent release-* branch or master instead.
45-
EOF
46-
exit 1
47-
48-
cherry-pick:
49-
if: |
50-
github.event_name == 'pull_request' ||
51-
(fromJSON(inputs.baseBranch).stable && !contains(fromJSON(inputs.headBranch).type, 'development'))
34+
commits:
5235
permissions:
5336
pull-requests: write
5437
runs-on: ubuntu-24.04-arm
@@ -68,16 +51,20 @@ jobs:
6851
GH_TOKEN: ${{ github.token }}
6952
run: gh api /rate_limit | jq
7053

71-
- name: Check cherry-picks
54+
- name: Check commits
7255
id: check
7356
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
57+
env:
58+
TARGETS_STABLE: ${{ fromJSON(inputs.baseBranch).stable && !contains(fromJSON(inputs.headBranch).type, 'development') }}
7459
with:
7560
script: |
61+
const targetsStable = JSON.parse(process.env.TARGETS_STABLE)
7662
require('./trusted/ci/github-script/commits.js')({
7763
github,
7864
context,
7965
core,
8066
dry: context.eventName == 'pull_request',
67+
cherryPicks: context.eventName == 'pull_request' || targetsStable,
8168
})
8269
8370
- name: Log current API rate limits

.github/workflows/pr.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ permissions: {}
2323
jobs:
2424
prepare:
2525
runs-on: ubuntu-24.04-arm
26+
permissions:
27+
# wrong branch review comment
28+
pull-requests: write
2629
outputs:
2730
baseBranch: ${{ steps.prepare.outputs.base }}
2831
headBranch: ${{ steps.prepare.outputs.head }}
@@ -44,6 +47,7 @@ jobs:
4447
github,
4548
context,
4649
core,
50+
dry: context.eventName == 'pull_request',
4751
})
4852
4953
check:

.github/workflows/push.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ name: Push
22

33
on:
44
push:
5-
# Keep this synced with ci/request-reviews/dev-branches.txt
65
branches:
76
- master
87
- staging

ci/github-script/commits.js

Lines changed: 18 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
module.exports = async ({ github, context, core, dry }) => {
1+
module.exports = async ({ github, context, core, dry, cherryPicks }) => {
22
const { execFileSync } = require('node:child_process')
33
const { classify } = require('../supportedBranches.js')
44
const withRateLimit = require('./withRateLimit.js')
5+
const { dismissReviews, postReview } = require('./reviews.js')
56

67
await withRateLimit({ github, core }, async (stats) => {
78
stats.prs = 1
@@ -16,7 +17,7 @@ module.exports = async ({ github, context, core, dry }) => {
1617
run_id: context.runId,
1718
per_page: 100,
1819
})
19-
).find(({ name }) => name.endsWith('Check / cherry-pick')).html_url +
20+
).find(({ name }) => name.endsWith('Check / commits')).html_url +
2021
'?pr=' +
2122
pull_number
2223

@@ -137,10 +138,14 @@ module.exports = async ({ github, context, core, dry }) => {
137138
}
138139
}
139140

140-
const commits = await github.paginate(github.rest.pulls.listCommits, {
141-
...context.repo,
142-
pull_number,
143-
})
141+
// For now we short-circuit the list of commits when cherryPicks should not be checked.
142+
// This will not run any checks, but still trigger the "dismiss reviews" part below.
143+
const commits = !cherryPicks
144+
? []
145+
: await github.paginate(github.rest.pulls.listCommits, {
146+
...context.repo,
147+
pull_number,
148+
})
144149

145150
const extracted = await Promise.all(commits.map(extract))
146151

@@ -185,38 +190,10 @@ module.exports = async ({ github, context, core, dry }) => {
185190

186191
// Only create step summary below in case of warnings or errors.
187192
// Also clean up older reviews, when all checks are good now.
193+
// An empty results array will always trigger this condition, which is helpful
194+
// to clean up reviews created by the prepare step when on the wrong branch.
188195
if (results.every(({ severity }) => severity === 'info')) {
189-
if (!dry) {
190-
await Promise.all(
191-
(
192-
await github.paginate(github.rest.pulls.listReviews, {
193-
...context.repo,
194-
pull_number,
195-
})
196-
)
197-
.filter((review) => review.user.login === 'github-actions[bot]')
198-
.map(async (review) => {
199-
if (review.state === 'CHANGES_REQUESTED') {
200-
await github.rest.pulls.dismissReview({
201-
...context.repo,
202-
pull_number,
203-
review_id: review.id,
204-
message: 'All cherry-picks are good now, thank you!',
205-
})
206-
}
207-
await github.graphql(
208-
`mutation($node_id:ID!) {
209-
minimizeComment(input: {
210-
classifier: RESOLVED,
211-
subjectId: $node_id
212-
})
213-
{ clientMutationId }
214-
}`,
215-
{ node_id: review.node_id },
216-
)
217-
}),
218-
)
219-
}
196+
await dismissReviews({ github, context, dry })
220197
return
221198
}
222199

@@ -336,45 +313,9 @@ module.exports = async ({ github, context, core, dry }) => {
336313
const body = core.summary.stringify()
337314
core.summary.write()
338315

339-
const pendingReview = (
340-
await github.paginate(github.rest.pulls.listReviews, {
341-
...context.repo,
342-
pull_number,
343-
})
344-
).find(
345-
(review) =>
346-
review.user.login === 'github-actions[bot]' &&
347-
// If a review is still pending, we can just update this instead
348-
// of posting a new one.
349-
(review.state === 'CHANGES_REQUESTED' ||
350-
// No need to post a new review, if an older one with the exact
351-
// same content had already been dismissed.
352-
review.body === body),
353-
)
354-
355-
if (dry) {
356-
if (pendingReview)
357-
core.info(`pending review found: ${pendingReview.html_url}`)
358-
else core.info('no pending review found')
359-
} else {
360-
// Either of those two requests could fail for very long comments. This can only happen
361-
// with multiple commits all hitting the truncation limit for the diff. If you ever hit
362-
// this case, consider just splitting up those commits into multiple PRs.
363-
if (pendingReview) {
364-
await github.rest.pulls.updateReview({
365-
...context.repo,
366-
pull_number,
367-
review_id: pendingReview.id,
368-
body,
369-
})
370-
} else {
371-
await github.rest.pulls.createReview({
372-
...context.repo,
373-
pull_number,
374-
event: 'REQUEST_CHANGES',
375-
body,
376-
})
377-
}
378-
}
316+
// Posting a review could fail for very long comments. This can only happen with
317+
// multiple commits all hitting the truncation limit for the diff. If you ever hit
318+
// this case, consider just splitting up those commits into multiple PRs.
319+
await postReview({ github, context, core, dry, body })
379320
})
380321
}

0 commit comments

Comments
 (0)