Skip to content

ci: add a github bot to support advanced PR review workflows #21

ci: add a github bot to support advanced PR review workflows

ci: add a github bot to support advanced PR review workflows #21

Workflow file for this run

name: GitHub Bot
on:
# Watch for changes on PR state, assignees, labels, head branch and draft/ready status
pull_request:
types:
- assigned
- unassigned
- labeled
- unlabeled
- opened
- reopened
- synchronize # PR head updated
- converted_to_draft
- ready_for_review
# Watch for changes on PR comment
issue_comment:
types: [created, edited, deleted]
# Manual run from GitHub Actions interface
workflow_dispatch:
inputs:
pull-request-list:
description: "PR(s) to process: specify 'all' or a comma separated list of PR numbers, e.g. '42,1337,7890'"
required: true
default: all
type: string
jobs:
# This job creates a matrix of PR numbers based on the inputs from the various
# events that can trigger this workflow so that the process-pr job below can
# handle the parallel processing of the pull-requests
define-prs-matrix:
name: Define PRs matrix
# Prevent bot from retriggering itself
if: ${{ github.actor != vars.GH_BOT_LOGIN }}
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
pr-numbers: ${{ steps.pr-numbers.outputs.pr-numbers }}
steps:
- name: Parse event inputs
id: pr-numbers
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Triggered by a workflow dispatch event
if [ '${{ github.event_name }}' = 'workflow_dispatch' ]; then
# If the input is 'all', create a matrix with every open PRs
if [ '${{ inputs.pull-request-list }}' = 'all' ]; then
pr_list=`gh pr list --state 'open' --repo '${{ github.repository }}' --json 'number' --template '{{$first := true}}{{range .}}{{if $first}}{{$first = false}}{{else}}, {{end}}{{"\""}}{{.number}}{{"\""}}{{end}}'`
[ -z "$pr_list" ] && echo 'Error: no opened PR found' >&2 && exit 1
echo "pr-numbers=[$pr_list]" >> "$GITHUB_OUTPUT"
# If the input is not 'all', test for each number in the comma separated
# list if the associated PR is opened, then add it to the matrix
else
pr_list_raw='${{ inputs.pull-request-list }}'
pr_list=''
IFS=','
for number in $pr_list; do
trimed=`echo "$number" | xargs`
pr_state=`gh pr view "$trimed" --repo '${{ github.repository }}' --json 'state' --template '{{.state}}' 2> /dev/null`
[ "$pr_state" != 'OPEN' ] && echo "Error: PR with number <$trimed> is not opened" >&2 && exit 1
done
echo "pr-numbers=[$pr_list]" >> "$GITHUB_OUTPUT"
fi
# Triggered by comment event, just add the associated PR number to the matrix
elif [ '${{ github.event_name }}' = 'issue_comment' ]; then
echo 'pr-numbers=["${{ github.event.issue.number }}"]' >> "$GITHUB_OUTPUT"
# Triggered by pull request event, just add the associated PR number to the matrix
elif [ '${{ github.event_name }}' = 'pull_request' ]; then
echo 'pr-numbers=["${{ github.event.pull_request.number }}"]' >> "$GITHUB_OUTPUT"
# Should never happen
else
echo 'Error: unknown event ${{ github.event_name }}' >&2 && exit 1
fi
# This job processes each pull request in the matrix individually while ensuring
# that a same PR cannot be processed concurrently by mutliple runners
process-pr:
name: Process PR
needs: define-prs-matrix
runs-on: ubuntu-latest
strategy:
matrix:
# Run one job for each PR to process
pr-number: ${{ fromJSON(needs.define-prs-matrix.outputs.pr-numbers) }}
concurrency:
# Prevent running concurrent jobs for a given PR number
group: ${{ matrix.pr-number }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Run GitHub Bot
working-directory: contribs/github-bot
env:
GITHUB_TOKEN: ${{ secrets.GH_BOT_PAT }}
run: go run . -pr-numbers '${{ matrix.pr-number }}' -verbose