Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .github/workflows/force-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: "Force merge automation"
description: Merge a pull request when N committers post a comment with the command /force-merge

on:
issue_comment:
types: [created, edited]

permissions:
contents: write
pull-requests: write
issues: read

env:
quorum: 3

jobs:
force_merge:
runs-on: ubuntu-latest

steps:
- name: Check pull request
id: should-run
uses: actions/github-script@v7
with:
script: |
const issue = await github.rest.issues.get({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
})

const isPR = issue.data.pull_request != null
const isClosed = issue.data.closed_at != null
const isDraft = issue.data.draft

return isPR && !isClosed && !isDraft

- name: Count votes
id: count-votes
if: ${{ steps.should-run.outputs.result == 'true' }}
uses: actions/github-script@v7
with:
script: |
const comments = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
})

const votes = new Map();
for(const comment of comments.data) {
const hasVotingRights = comment.author_association === 'MEMBER' || comment.author_association === 'OWNER'
const hasCastedVote = comment.body === '/force-merge'

if(hasVotingRights && hasCastedVote) {
votes.set(comment.user.login, comment.author_association);
}
}

// Display voters and role
console.table(votes)

return votes.size

- name: Set lables
if: ${{ steps.should-run.outputs.result == 'true' }}
uses: actions/github-script@v7
with:
script: |
const labels = await github.rest.issues.listLabelsOnIssue({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
})
const labelsToAdd = []
for(const label of labels.data) {
if(!label.name.startsWith('force-merge-votes-')) {
labelsToAdd.push(label.name)
}
}

const votes = ${{ steps.count-votes.outputs.result }}
if(votes >= 1 && votes < ${{env.quorum}}) {
labelsToAdd.push("force-merge-votes-" + votes)
}

console.log(labelsToAdd) // Debug
const result = github.rest.issues.setLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: labelsToAdd
})

- name: Perform merge
if: ${{ (steps.should-run.outputs.result == 'true') && (steps.count-votes.outputs.result >= env.quorum) }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.KURA_BOT_GITHUB_TOKEN }}
script: |
await github.rest.pulls.merge({
pull_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
merge_method: "squash"
});