-
Notifications
You must be signed in to change notification settings - Fork 11
ci: Add PR review enforcement GitHub Action #473
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +0,0 @@ | ||
| * @rungalileo/product | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| name: Enforce Review Policy | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] | ||
| pull_request_review: | ||
| types: [submitted, dismissed] | ||
| workflow_run: | ||
| workflows: ["Test"] | ||
| types: [completed] | ||
|
|
||
| jobs: | ||
| enforce-review: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| pull-requests: write | ||
| steps: | ||
| - name: Enforce review policy | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const pr = context.payload.pull_request; | ||
| const event = context.eventName; | ||
| const isDependabot = pr.user?.login === 'dependabot[bot]'; | ||
|
|
||
| // Skip for Dependabot on all events | ||
| if (isDependabot) { | ||
| core.info('Dependabot PR detected - skipping review enforcement.'); | ||
| return; | ||
| } | ||
|
|
||
| // Only enforce review requirement on pull_request_review events | ||
| if (event === 'pull_request') { | ||
| core.info('PR opened/synchronized - waiting for review, not enforcing yet.'); | ||
| return; | ||
| } | ||
|
|
||
| // From here on, we know it's a pull_request_review event (submitted or dismissed): enforce rule | ||
| core.info('Review event detected - checking current approval status...'); | ||
|
|
||
| const reviews = await github.rest.pulls.listReviews({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| pull_number: pr.number | ||
| }); | ||
|
|
||
| const approvals = reviews.data.filter(r => r.state === 'APPROVED'); | ||
| const hasNonBazApproval = approvals.some( | ||
| r => r.user?.login && | ||
| r.user.login !== 'baz-reviewer' && | ||
| r.user.type === 'User' | ||
| ); | ||
|
|
||
| if (!hasNonBazApproval) { | ||
| core.setFailed('At least one approval from a non-baz-reviewer is required.'); | ||
| } | ||
|
Comment on lines
+41
to
+56
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Finding type: Prompt for AI Agents: |
||
|
|
||
| dependabot-ci-failure: | ||
| runs-on: ubuntu-latest | ||
| if: github.event.workflow_run.conclusion == 'failure' | ||
| permissions: | ||
| pull-requests: write | ||
| steps: | ||
| - name: Request review from random product team member on CI failure | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| github-token: ${{ secrets.GALILEO_AUTOMATION_GITHUB_TOKEN }} | ||
| script: | | ||
| // Get the PR associated with this workflow run | ||
| const workflowRun = context.payload.workflow_run; | ||
|
|
||
| if (!workflowRun.pull_requests || workflowRun.pull_requests.length === 0) { | ||
| core.info('No pull request associated with this workflow run.'); | ||
| return; | ||
| } | ||
|
|
||
| const prNumber = workflowRun.pull_requests[0].number; | ||
|
|
||
| // Get PR details | ||
| const { data: pr } = await github.rest.pulls.get({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| pull_number: prNumber | ||
| }); | ||
|
|
||
| const isDependabot = pr.user?.login === 'dependabot[bot]'; | ||
|
|
||
| if (!isDependabot) { | ||
| core.info('PR is not from Dependabot - skipping CI failure notification.'); | ||
| return; | ||
| } | ||
|
|
||
| core.info(`Dependabot PR #${prNumber} CI failed - requesting review from random product team member.`); | ||
|
|
||
| // Get members of the rungalileo/product team | ||
| let teamMembers; | ||
| try { | ||
| const { data: members } = await github.rest.teams.listMembersInOrg({ | ||
| org: 'rungalileo', | ||
| team_slug: 'product', | ||
| }); | ||
| teamMembers = members.map(m => m.login); | ||
| } catch (error) { | ||
| core.setFailed(`Failed to fetch team members: ${error.message}`); | ||
| return; | ||
| } | ||
|
|
||
| if (teamMembers.length === 0) { | ||
| core.setFailed('No members found in rungalileo/product team.'); | ||
| return; | ||
| } | ||
|
|
||
| // Select a random team member | ||
| const randomMember = teamMembers[Math.floor(Math.random() * teamMembers.length)]; | ||
| core.info(`Selected random reviewer: ${randomMember}`); | ||
|
|
||
| // Request review from the selected member | ||
| try { | ||
| await github.rest.pulls.requestReviewers({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| pull_number: prNumber, | ||
| reviewers: [randomMember] | ||
| }); | ||
| core.info(`Successfully requested review from ${randomMember} for PR #${prNumber}`); | ||
| } catch (error) { | ||
| core.setFailed(`Failed to request review: ${error.message}`); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
context.payload.pull_requestis undefined onworkflow_runevents, but the script immediately runsconst isDependabot = pr.user?.login === 'dependabot[bot]', which throws before the job can exit; can we guard forworkflow_run(or restrict the job topull_request*events) before accessingpr.user?Finding type:
Logical BugsPrompt for AI Agents: