Skip to content

Commit

Permalink
fix(github-bot): handle review event on PR from fork
Browse files Browse the repository at this point in the history
  • Loading branch information
aeddi committed Dec 10, 2024
1 parent c33cf67 commit c09bcd4
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/bot-proxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: GitHub Bot Proxy

on:
# Watch for any completed run on bot.yml workflow
workflow_run:
workflows: [GitHub Bot]
types: [completed]

jobs:
# This workflow monitors any run completed on the GitHub Bot workflow and
# checks if the event that triggered it is limited to read-only permissions
# (e.g 'pull_request_review' on a pull request opened from a fork).
# In this case, it reruns the GitHub Bot workflow using a 'workflow_dispatch'
# event, thereby allowing it to run with write permissions.
#
# Complete flow:
# 'pull_request_review' from fork on bot.yml (read-only) -> 'workflow_run' on bot-proxy.yml (write) -> 'workflow_dispatch' on bot.yml (write)
rerun-with-write-perm:
name: Rerun Bot with write permission
# Skip this workflow if the original event is not 'pull_request_review'
if: github.event.workflow_run.event == 'pull_request_review'
runs-on: ubuntu-latest
permissions:
actions: write

steps:
- name: Download artifact from previous run
uses: actions/download-artifact@v4
with:
name: pr-number
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
# Even if the artifact doesn't exist, do not mark the workflow as failed
# Useful if the 'pull_request_review' event was emitted by a PR opened
# from a branch on the main repo, so it has already been processed by
# the bot workflow, and no artifact has been uploaded.
continue-on-error: true
id: download

- name: Send workflow_dispatch event to Github Bot
# Run only if an artifact was downloaded
if: steps.download.outcome == 'success'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.event.workflow_run.repository.full_name }}
run: |
gh workflow run bot.yml -R "$REPO" -f "pull-request-list=$(cat pr-number)"
36 changes: 33 additions & 3 deletions .github/workflows/bot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,14 @@ jobs:
# handle the parallel processing of the pull-requests
define-prs-matrix:
name: Define PRs matrix
# Prevent bot from retriggering itself and ignore event emitted by codecov
if: ${{ github.actor != vars.GH_BOT_LOGIN && github.actor != 'codecov[bot]' }}
# Skip this workflow if:
# - the bot is retriggering itself
# - the event is emitted by codecov
# - the event is a review on a pull request from a fork (see save-pr-number job below)
if: |
github.actor != vars.GH_BOT_LOGIN &&
github.actor != 'codecov[bot]' &&
(github.event_name != 'pull_request_review' || github.event.pull_request.base.repo.full_name == github.event.pull_request.head.repo.full_name)
runs-on: ubuntu-latest
permissions:
pull-requests: read
Expand All @@ -61,13 +67,37 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: go run . matrix -matrix-key 'pr-numbers' -verbose

# This job is executed if an event with read-only permission has triggered this
# workflow (e.g 'pull_request_review' on a pull request opened from a fork).
# In this case, this job persists the PR number in an artifact so that the
# proxy workflow can use it to rerun the current workflow with write permission.
# See bot-proxy.yml for more info.
save-pr-number:
name: Persist PR number for proxy
# Run this job if the event is a review on a pull request opened from a fork
if: github.event_name == 'pull_request_review' && github.event.pull_request.base.repo.full_name != github.event.pull_request.head.repo.full_name
runs-on: ubuntu-latest

steps:
- name: Write PR number to a file
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
echo $PR_NUMBER > pr-number
- name: Upload it as an artifact
uses: actions/upload-artifact@v4
with:
name: pr-number
path: pr-number

# 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
# Just skip this job if PR numbers matrix is empty (prevent failed state)
if: ${{ needs.define-prs-matrix.outputs.pr-numbers != '[]' && needs.define-prs-matrix.outputs.pr-numbers != '' }}
if: needs.define-prs-matrix.outputs.pr-numbers != '[]' && needs.define-prs-matrix.outputs.pr-numbers != ''
runs-on: ubuntu-latest
strategy:
matrix:
Expand Down

0 comments on commit c09bcd4

Please sign in to comment.