feat: revise handling of team reviewers

This commit is contained in:
Peter Evans 2023-04-03 11:31:13 +09:00
parent 91b6c0aa50
commit 1c9f3a221f
5 changed files with 53 additions and 20 deletions

View file

@ -68,7 +68,7 @@ All inputs are **optional**. If not set, sensible defaults will be used.
| `labels` | A comma or newline-separated list of labels. | | | `labels` | A comma or newline-separated list of labels. | |
| `assignees` | A comma or newline-separated list of assignees (GitHub usernames). | | | `assignees` | A comma or newline-separated list of assignees (GitHub usernames). | |
| `reviewers` | A comma or newline-separated list of reviewers (GitHub usernames) to request a review from. | | | `reviewers` | A comma or newline-separated list of reviewers (GitHub usernames) to request a review from. | |
| `team-reviewers` | A comma or newline-separated list of GitHub teams to request a review from. Note that a `repo` scoped [PAT](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) may be required. See [this issue](https://github.com/peter-evans/create-pull-request/issues/155). If using a GitHub App, refer to [Authenticating with GitHub App generated tokens](docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens) for the proper permissions. | | | `team-reviewers` | A comma or newline-separated list of GitHub teams to request a review from. Note that a `repo` scoped [PAT](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token), or equivalent [GitHub App permissions](docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens), are required. | |
| `milestone` | The number of the milestone to associate this pull request with. | | | `milestone` | The number of the milestone to associate this pull request with. | |
| `draft` | Create a [draft pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests). It is not possible to change draft status after creation except through the web interface. | `false` | | `draft` | Create a [draft pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests). It is not possible to change draft status after creation except through the web interface. | `false` |
@ -252,8 +252,8 @@ jobs:
assignees: peter-evans assignees: peter-evans
reviewers: peter-evans reviewers: peter-evans
team-reviewers: | team-reviewers: |
owners developers
maintainers qa-team
milestone: 1 milestone: 1
draft: false draft: false
``` ```

View file

@ -25,6 +25,18 @@ describe('utils tests', () => {
expect(array2.length).toEqual(0) expect(array2.length).toEqual(0)
}) })
test('stripOrgPrefixFromTeams strips org prefixes correctly', async () => {
const array = utils.stripOrgPrefixFromTeams([
'org/team1',
'org/team2',
'team3'
])
expect(array.length).toEqual(3)
expect(array[0]).toEqual('team1')
expect(array[1]).toEqual('team2')
expect(array[2]).toEqual('team3')
})
test('getRepoPath successfully returns the path to the repository', async () => { test('getRepoPath successfully returns the path to the repository', async () => {
expect(utils.getRepoPath()).toEqual(process.env['GITHUB_WORKSPACE']) expect(utils.getRepoPath()).toEqual(process.env['GITHUB_WORKSPACE'])
expect(utils.getRepoPath('foo')).toEqual( expect(utils.getRepoPath('foo')).toEqual(

27
dist/index.js vendored
View file

@ -1034,7 +1034,7 @@ exports.GitHubHelper = void 0;
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const octokit_client_1 = __nccwpck_require__(5040); const octokit_client_1 = __nccwpck_require__(5040);
const utils = __importStar(__nccwpck_require__(918)); const utils = __importStar(__nccwpck_require__(918));
const ERROR_PR_REVIEW_FROM_AUTHOR = 'Review cannot be requested from pull request author'; const ERROR_PR_REVIEW_TOKEN_SCOPE = 'Validation Failed: "Could not resolve to a node with the global id of';
class GitHubHelper { class GitHubHelper {
constructor(token) { constructor(token) {
const options = {}; const options = {};
@ -1123,20 +1123,19 @@ class GitHubHelper {
core.info(`Requesting reviewers '${inputs.reviewers}'`); core.info(`Requesting reviewers '${inputs.reviewers}'`);
} }
if (inputs.teamReviewers.length > 0) { if (inputs.teamReviewers.length > 0) {
requestReviewersParams['team_reviewers'] = inputs.teamReviewers; const teams = utils.stripOrgPrefixFromTeams(inputs.teamReviewers);
core.info(`Requesting team reviewers '${inputs.teamReviewers}'`); requestReviewersParams['team_reviewers'] = teams;
core.info(`Requesting team reviewers '${teams}'`);
} }
if (Object.keys(requestReviewersParams).length > 0) { if (Object.keys(requestReviewersParams).length > 0) {
try { try {
yield this.octokit.rest.pulls.requestReviewers(Object.assign(Object.assign(Object.assign({}, this.parseRepository(baseRepository)), { pull_number: pull.number }), requestReviewersParams)); yield this.octokit.rest.pulls.requestReviewers(Object.assign(Object.assign(Object.assign({}, this.parseRepository(baseRepository)), { pull_number: pull.number }), requestReviewersParams));
} }
catch (e) { catch (e) {
if (utils.getErrorMessage(e).includes(ERROR_PR_REVIEW_FROM_AUTHOR)) { if (utils.getErrorMessage(e).includes(ERROR_PR_REVIEW_TOKEN_SCOPE)) {
core.warning(ERROR_PR_REVIEW_FROM_AUTHOR); core.error(`Unable to request reviewers. If requesting team reviewers a 'repo' scoped PAT is required.`);
}
else {
throw e;
} }
throw e;
} }
} }
return pull; return pull;
@ -1283,7 +1282,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result; return result;
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getErrorMessage = exports.fileExistsSync = exports.parseDisplayNameEmail = exports.randomString = exports.secondsSinceEpoch = exports.getRemoteUrl = exports.getRemoteDetail = exports.getRepoPath = exports.getStringAsArray = exports.getInputAsArray = void 0; exports.getErrorMessage = exports.fileExistsSync = exports.parseDisplayNameEmail = exports.randomString = exports.secondsSinceEpoch = exports.getRemoteUrl = exports.getRemoteDetail = exports.getRepoPath = exports.stripOrgPrefixFromTeams = exports.getStringAsArray = exports.getInputAsArray = void 0;
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const fs = __importStar(__nccwpck_require__(7147)); const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017)); const path = __importStar(__nccwpck_require__(1017));
@ -1298,6 +1297,16 @@ function getStringAsArray(str) {
.filter(x => x !== ''); .filter(x => x !== '');
} }
exports.getStringAsArray = getStringAsArray; exports.getStringAsArray = getStringAsArray;
function stripOrgPrefixFromTeams(teams) {
return teams.map(team => {
const slashIndex = team.lastIndexOf('/');
if (slashIndex > 0) {
return team.substring(slashIndex + 1);
}
return team;
});
}
exports.stripOrgPrefixFromTeams = stripOrgPrefixFromTeams;
function getRepoPath(relativePath) { function getRepoPath(relativePath) {
let githubWorkspacePath = process.env['GITHUB_WORKSPACE']; let githubWorkspacePath = process.env['GITHUB_WORKSPACE'];
if (!githubWorkspacePath) { if (!githubWorkspacePath) {

View file

@ -3,8 +3,8 @@ import {Inputs} from './create-pull-request'
import {Octokit, OctokitOptions} from './octokit-client' import {Octokit, OctokitOptions} from './octokit-client'
import * as utils from './utils' import * as utils from './utils'
const ERROR_PR_REVIEW_FROM_AUTHOR = const ERROR_PR_REVIEW_TOKEN_SCOPE =
'Review cannot be requested from pull request author' 'Validation Failed: "Could not resolve to a node with the global id of'
interface Repository { interface Repository {
owner: string owner: string
@ -159,8 +159,9 @@ export class GitHubHelper {
core.info(`Requesting reviewers '${inputs.reviewers}'`) core.info(`Requesting reviewers '${inputs.reviewers}'`)
} }
if (inputs.teamReviewers.length > 0) { if (inputs.teamReviewers.length > 0) {
requestReviewersParams['team_reviewers'] = inputs.teamReviewers const teams = utils.stripOrgPrefixFromTeams(inputs.teamReviewers)
core.info(`Requesting team reviewers '${inputs.teamReviewers}'`) requestReviewersParams['team_reviewers'] = teams
core.info(`Requesting team reviewers '${teams}'`)
} }
if (Object.keys(requestReviewersParams).length > 0) { if (Object.keys(requestReviewersParams).length > 0) {
try { try {
@ -170,11 +171,12 @@ export class GitHubHelper {
...requestReviewersParams ...requestReviewersParams
}) })
} catch (e) { } catch (e) {
if (utils.getErrorMessage(e).includes(ERROR_PR_REVIEW_FROM_AUTHOR)) { if (utils.getErrorMessage(e).includes(ERROR_PR_REVIEW_TOKEN_SCOPE)) {
core.warning(ERROR_PR_REVIEW_FROM_AUTHOR) core.error(
} else { `Unable to request reviewers. If requesting team reviewers a 'repo' scoped PAT is required.`
throw e )
} }
throw e
} }
} }

View file

@ -16,6 +16,16 @@ export function getStringAsArray(str: string): string[] {
.filter(x => x !== '') .filter(x => x !== '')
} }
export function stripOrgPrefixFromTeams(teams: string[]): string[] {
return teams.map(team => {
const slashIndex = team.lastIndexOf('/')
if (slashIndex > 0) {
return team.substring(slashIndex + 1)
}
return team
})
}
export function getRepoPath(relativePath?: string): string { export function getRepoPath(relativePath?: string): string {
let githubWorkspacePath = process.env['GITHUB_WORKSPACE'] let githubWorkspacePath = process.env['GITHUB_WORKSPACE']
if (!githubWorkspacePath) { if (!githubWorkspacePath) {