merge-command #741
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: /merge handler | |
on: | |
repository_dispatch: | |
types: [merge-command] | |
permissions: | |
pull-requests: write | |
concurrency: merge-handler-${{ github.event.client_payload.pull_request.node_id || github.run_id }} | |
jobs: | |
merge: | |
if: github.event.client_payload.pull_request != null | |
name: Trim description and merge | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
sparse-checkout: | | |
tools/ci_format_pr_description.js | |
- id: pr-data | |
name: Get PR data and trim PR body | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const pull_id = context.payload.client_payload.pull_request.node_id; | |
core.debug(`Pull request ID: ${pull_id}.`); | |
const query = `query($id: ID!) { | |
node(id: $id) { | |
... on PullRequest { | |
autoMergeRequest { | |
mergeMethod | |
} | |
mergeQueueEntry { | |
state | |
} | |
closed | |
body | |
} | |
} | |
}`; | |
const { node: pr_info } = await github.graphql(query, { id: pull_id }); | |
core.debug(`PR data: ${JSON.stringify(pr_info)}`); | |
if (pr_info.closed) { | |
core.notice('PR is already merged or closed.'); | |
return; | |
} | |
if (pr_info.autoMergeRequest || pr_info.mergeQueueEntry) { | |
core.notice('PR is already queued for merging.'); | |
return; | |
} | |
const formatPR = require('./tools/ci_format_pr_description.js'); | |
let [ body, body_tail ] = pr_info.body.split(/^---\s*$/m, 2); | |
body = formatPR.formatPRdescription(body, 72); | |
body = body.trimEnd(); | |
body_tail = body_tail?.trimEnd() || ''; | |
// Only runs when the PR is still open and is not staged for merging. | |
core.setOutput('run', 'true'); | |
core.setOutput('body', body); | |
core.setOutput('body-tail', body_tail); | |
if (pr_info.body !== body) { | |
// Only attempt PR description update if there are changes to be made | |
core.setOutput('update-body', 'true'); | |
} | |
- if: steps.pr-data.outputs.run | |
id: find-comment | |
name: Find previously generated informational comment | |
uses: peter-evans/find-comment@v3 | |
with: | |
issue-number: ${{ github.event.client_payload.pull_request.number }} | |
comment-author: github-actions[bot] | |
body-includes: <!-- /merge info comment --> | |
direction: last | |
# Only update the comment if there's a tail. This prevents the | |
# tail from being replaced due to multiple /merge calls. | |
- if: >- | |
steps.pr-data.outputs.run | |
&& !(steps.find-comment.outputs.comment-id | |
&& steps.pr-data.outputs.body-tail == '') | |
name: Create or update informational comment | |
uses: peter-evans/create-or-update-comment@v4 | |
with: | |
comment-id: ${{ steps.find-comment.outputs.comment-id }} | |
issue-number: ${{ github.event.client_payload.pull_request.number }} | |
body: | | |
<!-- /merge info comment --> | |
<!-- Autogenerated by merge-command. DO NOT EDIT --> | |
Merge requested by: @${{ github.event.client_payload.github.payload.comment.user.login }} | |
Contents after the first section break of the PR description has been removed and preserved below: | |
--- | |
<blockquote> | |
${{ steps.pr-data.outputs.body-tail }} | |
</blockquote> | |
edit-mode: replace | |
- if: steps.pr-data.outputs.run && steps.pr-data.outputs.update-body | |
name: Update PR description | |
env: | |
PR_URL: ${{ github.event.client_payload.pull_request.html_url }} | |
NEW_PR_BODY: ${{ steps.pr-data.outputs.body }} | |
GH_TOKEN: ${{ github.token }} | |
run: gh pr edit "$PR_URL" --body "$NEW_PR_BODY" | |
# An app token is required for CI to trigger | |
- if: steps.pr-data.outputs.run | |
id: token | |
name: Create app token for merges | |
uses: actions/create-github-app-token@v1 | |
with: | |
app-id: ${{ secrets.CHORE_APP_ID }} | |
private-key: ${{ secrets.CHORE_APP_KEY }} | |
# TODO: Switch to GitHub CLI once | |
# https://github.com/cli/cli/issues/7213 is solved. | |
- if: steps.pr-data.outputs.run | |
name: Queue for merging | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const pull_id = context.payload.client_payload.pull_request.node_id; | |
const queue = `mutation ($input: EnablePullRequestAutoMergeInput!) { | |
enablePullRequestAutoMerge(input: $input) { | |
clientMutationId | |
} | |
}`; | |
await github.graphql(queue, { | |
input: { | |
pullRequestId: pull_id | |
} | |
}); | |
github-token: ${{ steps.token.outputs.token }} |