Skip to content

Commit

Permalink
ci: enable Automatic Merge of Approved Pull Requests (#306)
Browse files Browse the repository at this point in the history
Add automation that will merge approved PRs with passed CI checks automatically.

It uses following GitHub Actions:

* https://github.com/redhat-plumbers-in-action/gather-pull-request-metadata - to gather important data about PRs (used in following actions)
* https://github.com/redhat-plumbers-in-action/pull-request-validator - to check if PR is approved and has passed CI checks, and more
* https://github.com/redhat-plumbers-in-action/auto-merge - to merge approved PRs
* https://github.com/redhat-plumbers-in-action/issue-commentator - to comment on PR with status of PR and merge status
  • Loading branch information
jamacku authored Jun 27, 2024
1 parent f3d5723 commit 994e37c
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/auto-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target-branch': ['master']
95 changes: 95 additions & 0 deletions .github/workflows/auto-merge-on-demand.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Auto Merge On Demand
on:
schedule:
# Workflow runs every 45 minutes
- cron: '*/45 * * * *'
workflow_dispatch:
inputs:
pr-number:
description: 'Pull Request number/s ; when not provided, the workflow will run for all open PRs'
required: true
default: '0'

permissions:
contents: read

jobs:
# Get all open PRs
gather-pull-requests:
if: github.repository_owner == 'sclorg'
runs-on: ubuntu-latest

outputs:
pr-numbers: ${{ steps.get-pr-numbers.outputs.result }}
pr-numbers-manual: ${{ steps.parse-manual-input.outputs.result }}

steps:
- id: get-pr-numbers
if: inputs.pr-number == '0'
name: Get all open PRs
uses: actions/github-script@v6
with:
# !FIXME: this is not working if there is more than 100 PRs opened
script: |
const { data: pullRequests } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
per_page: 100
});
return pullRequests.map(pr => pr.number);
- id: parse-manual-input
if: inputs.pr-number != '0'
name: Parse manual input
run: |
# shellcheck disable=SC2086
echo "result="[ ${{ inputs.pr-number }} ]"" >> $GITHUB_OUTPUT
shell: bash

validate-pr:
name: 'Validation of Pull Request #${{ matrix.pr-number }}'
needs: [ gather-pull-requests ]
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
pr-number: ${{ inputs.pr-number == 0 && fromJSON(needs.gather-pull-requests.outputs.pr-numbers) || fromJSON(needs.gather-pull-requests.outputs.pr-numbers-manual) }}

permissions:
# required for merging PRs
contents: write
# required for PR comments and setting labels
pull-requests: write

steps:
- id: metadata
name: Gather Pull Request Metadata
uses: redhat-plumbers-in-action/gather-pull-request-metadata@v1
with:
pr-number: ${{ matrix.pr-number }}

- id: pull-request-validator
name: Pull Request Validator
uses: redhat-plumbers-in-action/pull-request-validator@v2
with:
pr-metadata: ${{ steps.metadata.outputs.metadata }}
token: ${{ secrets.GITHUB_TOKEN }}

- id: auto-merge
name: Auto Merge
uses: redhat-plumbers-in-action/auto-merge@v2
with:
pr-metadata: ${{ steps.metadata.outputs.metadata }}
token: ${{ secrets.GITHUB_TOKEN }}

- if: ${{ !cancelled() }}
name: Show results in PR comment
uses: redhat-plumbers-in-action/issue-commentator@v1
with:
issue: ${{ fromJSON(steps.metadata.outputs.metadata).number }}
message: |
${{ steps.pull-request-validator.outputs.status && steps.pull-request-validator.outputs.status || '' }}
${{ steps.auto-merge.outputs.status && steps.auto-merge.outputs.status || '' }}
token: ${{ secrets.GITHUB_TOKEN }}
61 changes: 61 additions & 0 deletions .github/workflows/auto-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Auto Merge
on:
workflow_run:
workflows: [ Gather Pull Request Metadata ]
types:
- completed

permissions:
contents: read

jobs:
download-metadata:
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest

outputs:
pr-metadata: ${{ steps.Artifact.outputs.pr-metadata-json }}

steps:
- id: Artifact
name: Download Artifact
uses: redhat-plumbers-in-action/download-artifact@v1
with:
name: pr-metadata

auto-merge:
needs: [ download-metadata ]
runs-on: ubuntu-latest

permissions:
# required for ability to merge Pull Request
contents: write
# required for setting labels
pull-requests: write

steps:
- id: pull-request-validator
name: Pull Request Validator
uses: redhat-plumbers-in-action/pull-request-validator@v2
with:
pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
token: ${{ secrets.GITHUB_TOKEN }}

- id: auto-merge
name: Auto Merge
uses: redhat-plumbers-in-action/auto-merge@v2
with:
pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
token: ${{ secrets.GITHUB_TOKEN }}

- if: ${{ !cancelled() }}
name: Show results in PR comment
uses: redhat-plumbers-in-action/issue-commentator@v1
with:
issue: ${{ fromJSON(needs.download-metadata.outputs.pr-metadata).number }}
message: |
${{ steps.pull-request-validator.outputs.status && steps.pull-request-validator.outputs.status || '' }}
${{ steps.auto-merge.outputs.status && steps.auto-merge.outputs.status || '' }}
token: ${{ secrets.GITHUB_TOKEN }}
27 changes: 27 additions & 0 deletions .github/workflows/pr-metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Gather Pull Request Metadata
on:
pull_request:
types: [ opened, reopened, synchronize ]
branches: [ master ]

permissions:
contents: read

jobs:
gather-metadata:
if: github.repository_owner == 'sclorg'
runs-on: ubuntu-latest

steps:
- name: Repository checkout
uses: actions/checkout@v4

- id: Metadata
name: Gather Pull Request Metadata
uses: redhat-plumbers-in-action/gather-pull-request-metadata@v1

- name: Upload artifact with gathered metadata
uses: actions/upload-artifact@v4
with:
name: pr-metadata
path: ${{ steps.Metadata.outputs.metadata-file }}

0 comments on commit 994e37c

Please sign in to comment.