Skip to content

Commit

Permalink
Approve all workflow runs for a specific contributor PR (#3876)
Browse files Browse the repository at this point in the history
### What

This PR adds the ability to approve workflow runs on forks on any
current and subsequent changes automatically. This is a step above the
"don't approve any workflow runs on forks automatically" that we have
set up right now.

The approval is triggered by commenting on a PR issue (`issue_comment`),
or the usual PR activity (`pull_request_target`). It then looks through
all comments on the PR, searching for the substring `@rerun-bot
approve`. If it finds at least one, then it checks if the user that sent
that comment is any of:

- A repository owner
- A member of the repository's organization
- A repository collaborator

If that is the case, then it approves all workflow runs on that pull
request.

PRs cannot modify this workflow or the script it uses to change how it
works. The changes must first be merged into the default branch before
having any effect, so this is safe for contributor PRs.

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested [demo.rerun.io](https://demo.rerun.io/pr/3876) (if
applicable)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG

- [PR Build Summary](https://build.rerun.io/pr/3876)
- [Docs
preview](https://rerun.io/preview/5b5366f30d2c75c24fc85a437fb6c976807beb57/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/5b5366f30d2c75c24fc85a437fb6c976807beb57/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://ref.rerun.io/dev/bench/)
- [Wasm size tracking](https://ref.rerun.io/dev/sizes/)
  • Loading branch information
jprochazk authored Oct 17, 2023
1 parent 3c912be commit 1e4d053
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/auto_approve.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: "Approve Workflow Runs"

on:
pull_request_target:
issue_comment:
types: [created, edited]

permissions:
actions: "write"

jobs:
approve-workflow-runs:
name: "Check for approval"
runs-on: ubuntu-latest
if: ${{ github.event_name == 'pull_request' || github.event.issue.pull_request }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v4

- name: Install dependencies
run: |
pip install PyGithub==1.59.0 requests>=2.31,<3
- name: Wait a few seconds
run: |
# Give GitHub a bit of time to synchronize everything
sleep 10s
- name: Approve workflow runs
run: |
python3 scripts/ci/approve_workflow_runs.py \
--github-token "${{ secrets.GITHUB_TOKEN }}" \
--github-repository "rerun-io/rerun"
--pr-number "${{ github.event.pull_request.number || github.event.issue.number }}"
70 changes: 70 additions & 0 deletions scripts/ci/approve_workflow_runs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3

"""
Script to auto-approve workflow runs if certain criteria are met.
Checks for a `@rerun-bot approve` comment made by an official Rerun team member,
and approves any workflow runs with pending approval.
This is expected to be run by the `auto_approve.yml` GitHub workflow.
Requires the following packages:
pip install PyGithub==1.59.0 requests>=2.31,<3
"""
from __future__ import annotations

import argparse

import requests
from github import Github
from github.WorkflowRun import WorkflowRun

APPROVAL = "@rerun-bot approve"


def approve(github_token: str, workflow_run: WorkflowRun) -> None:
print(f"approving {workflow_run.id}")
requests.post(
f"https://api.github.com/repos/rerun-io/rerun/actions/runs/{workflow_run.id}/approve",
headers={
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {github_token}",
"X-GitHub-Api-Version": "2022-11-28",
},
).raise_for_status()


def main() -> None:
parser = argparse.ArgumentParser(description="Generate a PR summary page")
parser.add_argument("--github-token", required=True, help="GitHub token")
parser.add_argument("--github-repository", required=True, help="GitHub repository")
parser.add_argument("--pr-number", required=True, type=int, help="PR number")
args = parser.parse_args()

gh = Github(args.github_token)
repo = gh.get_repo(args.github_repository)
pr = repo.get_pull(args.pr_number)

for comment in pr.get_issue_comments():
if APPROVAL not in comment.body:
continue

can_user_approve_workflows = (
repo.owner.login == comment.user.login
or repo.organization.has_in_members(comment.user)
or repo.has_in_collaborators(comment.user)
)
if not can_user_approve_workflows:
continue

print(f"found valid approval by {comment.user.login}")
for workflow_run in repo.get_workflow_runs(branch=pr.head.ref):
if workflow_run.status == "action_required" or workflow_run.conclusion == "action_required":
approve(args.github_token, workflow_run)

# We only need one approval
return


if __name__ == "__main__":
main()

0 comments on commit 1e4d053

Please sign in to comment.