Skip to content

merge-command

merge-command #697

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 }}