74 lines
2.3 KiB
Python
Executable File
74 lines
2.3 KiB
Python
Executable File
#!/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.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
from typing import TYPE_CHECKING
|
|
|
|
import requests
|
|
from github import Github
|
|
from github.NamedUser import NamedUser
|
|
|
|
if TYPE_CHECKING:
|
|
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
|
|
|
|
user = comment.user
|
|
assert isinstance(user, NamedUser), f"Expected NamedUser, got {type(user)}"
|
|
|
|
can_user_approve_workflows = (
|
|
repo.owner.login == user.login or repo.organization.has_in_members(user) or repo.has_in_collaborators(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(head_sha=pr.head.sha):
|
|
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()
|