Skip to content

Commit

Permalink
feat(pr-label-by-review): allow checking rulesets instead of branch p…
Browse files Browse the repository at this point in the history
…rotections (#60)
  • Loading branch information
Cysword committed Sep 8, 2023
1 parent 8f73717 commit 8afb162
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@ Label a pull request based on the review state. For use with the `pull_request_r
label-approved: 'yay' # The label to add when the PR is approved.
label-changes-requested: 'nay' # The label to add when changes are requested.
required-approvals: 2 # The number of reviews required to merge the PR. Should be passed only if you don't have an access token or app with the read settings permission.
branch-protections: 'rulesets' # Whether to use branch protection or rulesets to determine the number of required reviews.
```

##### Inputs
Expand All @@ -739,6 +740,7 @@ Label a pull request based on the review state. For use with the `pull_request_r
| false | `required-approvals` | The number of reviews required to merge the PR. Can be passed if you don't have an access token or app with the read settings permission. | `2` ||
| false | `label-approved` | The label to add when the PR is approved. | `ready to merge` | `approved` |
| false | `label-changes-requested` | The label to add when changes are requested. | `needs work` | `changes requested` |
| false | `branch-protection` | Whether to use branch protection or rulesets to determine the number of required reviews. | `rulesets` | `branch-protection` |

#### pr-validate-title-conventional

Expand Down
40 changes: 38 additions & 2 deletions pr-label-by-review/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ inputs:
description: 'Label to add when PR status is changes requested.'
default: 'changes requested'

protection-type:
description: 'Type of protection to check for. Can be either "branch-protection" or "rulesets".'
default: 'branch-protection'

runs:
using: composite
steps:
Expand All @@ -36,7 +40,7 @@ runs:

- name: 'Get required approvals from branch protection'
id: branch-protection
if: inputs.required-approvals == ''
if: inputs.required-approvals == '' && inputs.protectionType == 'branch-protection'
uses: actions/github-script@v6
with:
github-token: ${{ steps.token.outputs.token }}
Expand All @@ -51,6 +55,38 @@ runs:
core.setOutput('required-approvals', requiredApprovals);
- name: 'Get required approvals from rule sets'
id: rulesets
if: inputs.required-approvals == '' && inputs.protectionType == 'rulesets'
uses: actions/github-script@v6
with:
github-token: ${{ steps.token.outputs.token }}
script: |
// Get all rules for the branch
// we can use it directly from octokit since the endpoint is not yet supported by github-script
// https://octokit.github.io/rest.js/v20#repos-get-branch-rules
// When this issue is resolved, we can use `github.rest.repos.getBranchRules` to get the rules
// https://github.com/actions/github-script/issues/345
const rulesets = await github.request('/repos/{owner}/{repo}/rules/branches/{branch}', {
owner: context.repo.owner,
repo: context.repo.repo,
branch: context.payload.pull_request.base.ref,
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
});
// Filter out rules that are not for pull requests, Since we get all rules for the branch
const pullRequestRules = rules.data.filter(rule => rule.type === 'pull_request');
const highestAmountOfApprovals = pullRequestRules.reduce((highest, rule) => {
const approvals = rule.parameters.required_approving_review_count ?? 0;
return approvals > highest ? approvals : highest;
}, 0);
const requiredApprovals = highestAmountOfApprovals ?? 0;
core.setOutput('required-approvals', requiredApprovals);
- name: 'Collect pull request reviews'
id: check
uses: actions/github-script@v6
Expand Down Expand Up @@ -81,7 +117,7 @@ runs:
const changesRequested = userReviewsArray.some(review => review.state === 'CHANGES_REQUESTED');
const approvals = userReviewsArray.filter(review => review.state === 'APPROVED');
const requiredApprovals = Number(${{ inputs.required-approvals || steps.branch-protection.outputs.required-approvals }});
const requiredApprovals = Number(${{ inputs.required-approvals || steps.branch-protection.outputs.required-approvals || steps.rulesets.outputs.required-approvals }});
const isApproved = !changesRequested && approvals.length >= requiredApprovals;
core.setOutput('approved', isApproved ? 'true' : 'false');
Expand Down

0 comments on commit 8afb162

Please sign in to comment.