mirror of
https://github.com/CHN-beta/nixpkgs.git
synced 2026-01-11 18:32:23 +08:00
Some jobs purposefully only run on certain base or head branches. By
centralizing the logic, parts of it can easily be re-used later. Also,
this gives them an explicit name and thus makes them easier to
understand.
(cherry picked from commit 7763be5a80)
162 lines
5.8 KiB
YAML
162 lines
5.8 KiB
YAML
name: Check
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
baseBranch:
|
|
required: true
|
|
type: string
|
|
|
|
permissions: {}
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
jobs:
|
|
no-channel-base:
|
|
name: no channel base
|
|
if: contains(fromJSON(inputs.baseBranch).type, 'channel')
|
|
runs-on: ubuntu-24.04-arm
|
|
steps:
|
|
- run: |
|
|
cat <<EOF
|
|
The nixos-* and nixpkgs-* branches are pushed to by the channel
|
|
release script and should not be merged into directly.
|
|
|
|
Please target the equivalent release-* branch or master instead.
|
|
EOF
|
|
exit 1
|
|
|
|
cherry-pick:
|
|
if: |
|
|
github.event_name == 'pull_request' ||
|
|
fromJSON(inputs.baseBranch).stable
|
|
permissions:
|
|
pull-requests: write
|
|
runs-on: ubuntu-24.04-arm
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
filter: tree:0
|
|
path: trusted
|
|
|
|
- name: Check cherry-picks
|
|
id: check
|
|
continue-on-error: true
|
|
env:
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
run: |
|
|
./trusted/ci/check-cherry-picks.sh "$BASE_SHA" "$HEAD_SHA" checked-cherry-picks.md
|
|
|
|
- name: Log current API rate limits
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: gh api /rate_limit | jq
|
|
|
|
- name: Prepare review
|
|
if: steps.check.outcome == 'failure'
|
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
|
with:
|
|
script: |
|
|
const { readFile, writeFile } = require('node:fs/promises')
|
|
|
|
const job_url = (await github.rest.actions.listJobsForWorkflowRun({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
run_id: context.runId
|
|
})).data.jobs[0].html_url + '?pr=' + context.payload.pull_request.number
|
|
|
|
const header = await readFile('trusted/ci/check-cherry-picks.md')
|
|
const body = await readFile('checked-cherry-picks.md')
|
|
const footer =
|
|
`\n_Hint: The full diffs are also available in the [runner logs](${job_url}) with slightly better highlighting._`
|
|
|
|
const review = header + body + footer
|
|
await writeFile('review.md', review)
|
|
core.summary.addRaw(review)
|
|
core.summary.write()
|
|
|
|
- name: Request changes
|
|
if: ${{ github.event_name == 'pull_request_target' && steps.check.outcome == 'failure' }}
|
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
|
with:
|
|
script: |
|
|
const { readFile } = require('node:fs/promises')
|
|
const body = await readFile('review.md', 'utf-8')
|
|
|
|
const pendingReview = (await github.paginate(github.rest.pulls.listReviews, {
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: context.payload.pull_request.number
|
|
})).find(review =>
|
|
review.user.login == 'github-actions[bot]' && (
|
|
// If a review is still pending, we can just update this instead
|
|
// of posting a new one.
|
|
review.state == 'CHANGES_REQUESTED' ||
|
|
// No need to post a new review, if an older one with the exact
|
|
// same content had already been dismissed.
|
|
review.body == body
|
|
)
|
|
)
|
|
|
|
// Either of those two requests could fail for very long comments. This can only happen
|
|
// with multiple commits all hitting the truncation limit for the diff. If you ever hit
|
|
// this case, consider just splitting up those commits into multiple PRs.
|
|
if (pendingReview) {
|
|
await github.rest.pulls.updateReview({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: context.payload.pull_request.number,
|
|
review_id: pendingReview.id,
|
|
body
|
|
})
|
|
} else {
|
|
await github.rest.pulls.createReview({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: context.payload.pull_request.number,
|
|
event: 'REQUEST_CHANGES',
|
|
body
|
|
})
|
|
}
|
|
|
|
- name: Dismiss old reviews
|
|
if: ${{ github.event_name == 'pull_request_target' && steps.check.outcome == 'success' }}
|
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
|
with:
|
|
script: |
|
|
await Promise.all(
|
|
(await github.paginate(github.rest.pulls.listReviews, {
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: context.payload.pull_request.number
|
|
})).filter(review =>
|
|
review.user.login == 'github-actions[bot]'
|
|
).map(async (review) => {
|
|
if (review.state == 'CHANGES_REQUESTED') {
|
|
await github.rest.pulls.dismissReview({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: context.payload.pull_request.number,
|
|
review_id: review.id,
|
|
message: 'All cherry-picks are good now, thank you!'
|
|
})
|
|
}
|
|
await github.graphql(`mutation($node_id:ID!) {
|
|
minimizeComment(input: {
|
|
classifier: RESOLVED,
|
|
subjectId: $node_id
|
|
})
|
|
{ clientMutationId }
|
|
}`, { node_id: review.node_id })
|
|
})
|
|
)
|
|
|
|
- name: Log current API rate limits
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: gh api /rate_limit | jq
|