Skip to content

Commit

Permalink
Add support for pull_request_review event.
Browse files Browse the repository at this point in the history
  • Loading branch information
reitermarkus committed Mar 18, 2023
1 parent ea1ff8e commit f482a8c
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 20 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/automerge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: automerge
on:
schedule:
- cron: 0 * * * *
pull_request_review:
types:
- submitted
pull_request_target:
types:
- opened
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Ensure the following is set up in your repository settings before enabling this
| `required-labels` | no | Comma-separated list of labels that are required to be applied to a pull request for it to be merged automatically. |
| `pull-request` | no | Try merging the specified pull request automatically. For example, you can pass an input from a `workflow_dispatch` event. |
| `pull-request-author-associations` | no | Comma-separated list of required [author associations](https://docs.github.com/en/graphql/reference/enums#commentauthorassociation) for the pull request author. (By default, pull requests by any author are allowed.) |
| `review-author-associations` | no | Comma-separated list of required [author associations](https://docs.github.com/en/graphql/reference/enums#commentauthorassociation) for the review author. (By default, pull requests reviewd by `OWNER`s, `MEMBER`s and `COLLABORATOR`s are allowed.) |
| `dry-run` | no | If set to `true`, will not actually merge pull requests but still perform all other checks. |

## Example Workflow
Expand All @@ -50,6 +51,12 @@ on:
schedule:
- cron: 0 * * * *

# Try enabling auto-merge when a pull request is approved. Note that this event skips the check
# for the pull request author association and instead checks the review author association.
pull_request_review:
types:
- submitted

# Try enabling auto-merge for a pull request when a draft is marked as “ready for review”, when
# a required label is applied or when a “do not merge” label is removed, or when a pull request
# is updated in any way (opened, synchronized, reopened, edited).
Expand Down
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ inputs:
description: >
Comma-separated list of required author associations for the pull request author.
(By default, pull requests by any author are allowed.)
review-author-associations:
required: false
default: OWNER,MEMBER,COLLABORATOR
description: >
Comma-separated list of required author associations for the review author.
(By default, pull requests reviewed by `OWNER`s, `MEMBER`s and `COLLABORATOR`s are allowed.)
dry-run:
required: true
description: >
Expand Down
53 changes: 45 additions & 8 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

65 changes: 54 additions & 11 deletions src/automerge-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
requiredStatusChecksForBranch,
squashCommit,
} from './helpers'
import { MergeMethod, Octokit, PullRequest } from './types'
import { MergeMethod, Octokit, PullRequest, Review } from './types'

export class AutomergeAction {
octokit: Octokit
Expand Down Expand Up @@ -117,7 +117,7 @@ export class AutomergeAction {
}
}

async autoMergePullRequest(number: number): Promise<void> {
async autoMergePullRequest(number: number, review?: Review): Promise<void> {
core.info(`Evaluating mergeability for pull request ${number}:`)

const pullRequest = (
Expand Down Expand Up @@ -146,14 +146,38 @@ export class AutomergeAction {
return
}

const authorAssociations = this.input.pullRequestAuthorAssociations
if (authorAssociations.length > 0 && !isAuthorAllowed(pullRequest, authorAssociations)) {
core.info(
`Author of pull request ${number} is ${pullRequest.author_association} but must be one of the following: ` +
`${authorAssociations.join(', ')}`
)
await this.disableAutoMerge(pullRequest)
return
if (review) {
const authorAssociations = this.input.reviewAuthorAssociations

if (authorAssociations.length > 0 && !isAuthorAllowed(review, authorAssociations)) {
core.info(
`Reviewer of pull request ${number} is ${review.author_association} but must be one of the following: ` +
`${authorAssociations.join(', ')}`
)
return
}

if (review.state !== 'approved') {
core.info(`Pull request ${number} is not mergable because the review is not an approval.`)
return
}

if (pullRequest.head.sha !== review.commit_id) {
core.info(
`Pull request ${number} is not mergable because current commit ${pullRequest.head.sha} does not match reviewed commit ${review.commit_id}.`
)
return
}
} else {
const authorAssociations = this.input.pullRequestAuthorAssociations
if (authorAssociations.length > 0 && !isAuthorAllowed(pullRequest, authorAssociations)) {
core.info(
`Author of pull request ${number} is ${pullRequest.author_association} but must be one of the following: ` +
`${authorAssociations.join(', ')}`
)
await this.disableAutoMerge(pullRequest)
return
}
}

const baseBranch = pullRequest.base.ref
Expand Down Expand Up @@ -247,7 +271,7 @@ export class AutomergeAction {
async handlePullRequestTarget(): Promise<void> {
core.debug('handlePullRequestTarget()')

const { action, label, pull_request: pullRequest } = github.context.payload
const { action, pull_request: pullRequest } = github.context.payload

if (!action || !pullRequest) {
return
Expand All @@ -256,6 +280,25 @@ export class AutomergeAction {
await this.autoMergePullRequest(pullRequest.number)
}

async handlePullRequestReview(): Promise<void> {
core.debug('handlePullRequestReview()')

const { action, pull_request: pullRequest, review } = github.context.payload

if (!action || !pullRequest || !review) {
return
}

if (action !== 'submitted') {
core.warning(
`This action does not support the '${action}' action for the '${github.context.eventName}' event.`
)
return
}

await this.autoMergePullRequest(pullRequest.number, review)
}

async handleSchedule(): Promise<void> {
core.debug('handleSchedule()')

Expand Down
3 changes: 3 additions & 0 deletions src/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class Input {
requiredLabels: string[]
pullRequest: number | null
pullRequestAuthorAssociations: string[]
reviewAuthorAssociations: string[]
dryRun: boolean

constructor() {
Expand Down Expand Up @@ -72,6 +73,8 @@ export class Input {
this.pullRequest = getNumber('pull-request')
this.pullRequestAuthorAssociations = getArray('pull-request-author-associations')

this.reviewAuthorAssociations = getArray('review-author-associations')

this.dryRun = core.getInput('dry-run') === 'true'
}

Expand Down
4 changes: 4 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ async function run(): Promise<void> {

const eventName = github.context.eventName
switch (eventName) {
case 'pull_request_review': {
await action.handlePullRequestReview()
break
}
case 'pull_request_target': {
await action.handlePullRequestTarget()
break
Expand Down

0 comments on commit f482a8c

Please sign in to comment.