-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(github): add workflow and action for automating review labels (#…
…5649) * chore(github): add workflow and action for automating review labels * feat(cli): add support for multiple package roots * chore(actions): run sync command for package files * Update actions/add-review-labels/index.js * Update actions/add-review-labels/index.js * Update actions/add-review-labels/index.js * fix(actions): update logic for adding ready label * chore(project): update eslint to check in actions folder
- Loading branch information
Showing
24 changed files
with
387 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name: Add Review Labels | ||
on: pull_request_review | ||
jobs: | ||
reviewer: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@master | ||
- uses: ./actions/add-review-labels | ||
with: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
AUTO_LABEL_USERS: 'asudoh,emyarod,tw15egan' |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
**/__mocks__/** | ||
**/__tests__/** | ||
**/examples/** | ||
**/tasks/** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
FROM node:slim | ||
|
||
WORKDIR /usr/src/action | ||
COPY . . | ||
RUN yarn install --production | ||
ENTRYPOINT ["node", "/usr/src/action/index.js"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
name: Add review labels | ||
description: A custom action that adds review labels to a Pull Request | ||
inputs: | ||
GITHUB_TOKEN: | ||
description: A GitHub token to execute GitHub tasks | ||
required: true | ||
AUTO_LABEL_USERS: | ||
description: | ||
Opt-in users who want the ready to merge label automatically applied | ||
runs: | ||
using: 'docker' | ||
image: 'Dockerfile' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
/** | ||
* Copyright IBM Corp. 2020, 2020 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const github = require('@actions/github'); | ||
const core = require('@actions/core'); | ||
|
||
async function run() { | ||
const { context } = github; | ||
const token = core.getInput('GITHUB_TOKEN', { | ||
required: true, | ||
}); | ||
const autoLabelUsers = core.getInput('AUTO_LABEL_USERS').split(','); | ||
const octokit = new github.GitHub(token); | ||
const { pull_request: pullRequest, repository, review } = context.payload; | ||
const { state, draft } = pullRequest; | ||
|
||
// We only want to work with Pull Requests that are marked as open | ||
if (state !== 'open') { | ||
return; | ||
} | ||
|
||
// We only want to work with Pull Requests that are not draft PRs | ||
if (draft) { | ||
return; | ||
} | ||
|
||
const { | ||
data: permissionLevel, | ||
} = await octokit.repos.getCollaboratorPermissionLevel({ | ||
owner: repository.owner.login, | ||
repo: repository.name, | ||
username: review.user.login, | ||
}); | ||
|
||
// If the reviewer doesn't have one of the following permission levels | ||
// then ignore the event | ||
const acceptedPermissionLevels = new Set(['admin', 'write']); | ||
if (!acceptedPermissionLevels.has(permissionLevel.permission)) { | ||
return; | ||
} | ||
|
||
// If the review was not an approval then we'll ignore the event | ||
if (review.state !== 'approved') { | ||
return; | ||
} | ||
|
||
const { data: allReviews } = await octokit.pulls.listReviews({ | ||
owner: repository.owner.login, | ||
repo: repository.name, | ||
pull_number: pullRequest.number, | ||
per_page: 100, | ||
}); | ||
|
||
// The `listReviews` endpoint will return all of the reviews for the pull | ||
// request. We only care about the most recent reviews so we'll go through the | ||
// list and get the most recent review for each reviewer | ||
const reviewers = {}; | ||
const reviews = []; | ||
|
||
// Process reviews in reverse order since they are listed from oldest to newest | ||
for (const review of allReviews.reverse()) { | ||
const { author_association: association, user } = review; | ||
// If we've already saved a review for this user we already have the most | ||
// recent review | ||
if (reviewers[user.login]) { | ||
continue; | ||
} | ||
|
||
// If the author of the review is not a collaborator we ignore it | ||
if (association !== 'COLLABORATOR') { | ||
continue; | ||
} | ||
|
||
reviewers[user.login] = true; | ||
reviews.push(review); | ||
} | ||
|
||
const approved = reviews.filter(review => { | ||
return review.state === 'APPROVED'; | ||
}); | ||
|
||
const additionalReviewLabel = 'status: one more review 👀'; | ||
const readyForReviewLabel = 'status: ready for review 👀'; | ||
const readyToMergeLabel = 'status: ready to merge 🎉'; | ||
const visualReviewLabel = 'status: visual review 🔍'; | ||
const contentReviewLabel = 'status: content review ✍️'; | ||
const needsReviewLabels = new Set([visualReviewLabel, contentReviewLabel]); | ||
|
||
if (approved.length > 0) { | ||
const hasReadyLabel = pullRequest.labels.find(label => { | ||
return label.name === readyForReviewLabel; | ||
}); | ||
if (hasReadyLabel) { | ||
await octokit.issues.removeLabel({ | ||
owner: repository.owner.login, | ||
repo: repository.name, | ||
issue_number: pullRequest.number, | ||
name: readyForReviewLabel, | ||
}); | ||
} | ||
} | ||
|
||
if (approved.length === 1) { | ||
const hasAdditionalReviewLabel = pullRequest.labels.find(label => { | ||
return label.name === additionalReviewLabel; | ||
}); | ||
if (!hasAdditionalReviewLabel) { | ||
await octokit.issues.addLabels({ | ||
owner: repository.owner.login, | ||
repo: repository.name, | ||
issue_number: pullRequest.number, | ||
labels: [additionalReviewLabel], | ||
}); | ||
} | ||
return; | ||
} | ||
|
||
if (approved.length >= 2) { | ||
const hasAdditionalReviewLabel = pullRequest.labels.find(label => { | ||
return label.name === additionalReviewLabel; | ||
}); | ||
if (hasAdditionalReviewLabel) { | ||
await octokit.issues.removeLabel({ | ||
owner: repository.owner.login, | ||
repo: repository.name, | ||
issue_number: pullRequest.number, | ||
name: additionalReviewLabel, | ||
}); | ||
} | ||
|
||
const allNeedsReviewLabels = pullRequest.labels.filter(label => { | ||
return needsReviewLabels.has(label.name); | ||
}); | ||
if (allNeedsReviewLabels.length > 0) { | ||
return; | ||
} | ||
|
||
const shouldAutoLabel = autoLabelUsers.find(user => { | ||
return user === pullRequest.user.login; | ||
}); | ||
if (shouldAutoLabel) { | ||
await octokit.issues.addLabels({ | ||
owner: repository.owner.login, | ||
repo: repository.name, | ||
issue_number: pullRequest.number, | ||
labels: [readyToMergeLabel], | ||
}); | ||
} | ||
return; | ||
} | ||
} | ||
|
||
run().catch(error => { | ||
console.log(error); | ||
process.exit(1); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"name": "@carbon/actions-add-review-labels", | ||
"private": true, | ||
"version": "0.0.0", | ||
"license": "Apache-2.0", | ||
"main": "index.js", | ||
"repository": "https://github.com/carbon-design-system/carbon/tree/master/actions/add-review-labels", | ||
"bugs": "https://github.com/carbon-design-system/carbon/issues", | ||
"keywords": [ | ||
"ibm", | ||
"carbon", | ||
"carbon-design-system", | ||
"components", | ||
"react" | ||
], | ||
"dependencies": { | ||
"@actions/core": "^1.2.3", | ||
"@actions/github": "^2.1.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.