diff --git a/dist/index.js b/dist/index.js index 0310109..f762810 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1074,10 +1074,10 @@ class GitHubHelper { requestReviewersParams['reviewers'] = inputs.reviewers; core.info(`Requesting reviewers '${inputs.reviewers}'`); } - if (inputs.teamReviewers.length > 0) { - requestReviewersParams['team_reviewers'] = inputs.teamReviewers; - core.info(`Requesting team reviewers '${inputs.teamReviewers}'`); - } + // if (inputs.teamReviewers.length > 0) { + // requestReviewersParams['team_reviewers'] = inputs.teamReviewers + // core.info(`Requesting team reviewers '${inputs.teamReviewers}'`) + // } if (Object.keys(requestReviewersParams).length > 0) { try { yield this.octokit.rest.pulls.requestReviewers(Object.assign(Object.assign(Object.assign({}, this.parseRepository(baseRepository)), { pull_number: pull.number }), requestReviewersParams)); @@ -1091,9 +1091,104 @@ class GitHubHelper { } } } + const orgs = inputs.teamReviewers.map(team => { + if (!team.includes('/')) { + throw new Error(`Team ${team} is not in the correct format. It should be in the format org/team`); + } + return team.split('/')[0]; + }); + const distinctOrgs = [...new Set(orgs)]; + core.debug(`distinctOrgs: ${distinctOrgs}`); + const orgTeams = yield Promise.all(distinctOrgs.map(org => this.getOrgTeams(org))); + const teamIds = inputs.teamReviewers.map(team => { + var _a; + const [org, teamName] = team.split('/'); + const orgTeam = orgTeams.find(orgTeam => orgTeam.organization.login === org); + if (!orgTeam) { + throw new Error(`Org ${org} not found`); + } + const teamId = (_a = orgTeam.organization.teams.edges.find(team => team.node.slug === teamName)) === null || _a === void 0 ? void 0 : _a.node.id; + if (!teamId) { + throw new Error(`Team ${teamName} not found in ${org}`); + } + return teamId; + }); + core.debug(`teamIds: ${teamIds}`); + if (teamIds.length > 0) { + const repository = this.parseRepository(baseRepository); + const pullNodeId = yield this.getPullNodeId(repository.owner, repository.repo, pull.number); + core.debug(`pullNodeId: ${pullNodeId}`); + yield this.requestReviewers(pullNodeId, teamIds); + } return pull; }); } + getOrgTeams(orgName) { + return __awaiter(this, void 0, void 0, function* () { + const query = ` + query($orgName: String!, $teamCount: Int!) { + organization(login: $orgName) { + login + teams(first: $teamCount) { + edges { + node { + id + slug + } + } + } + } + } + `; + const teamCount = 100; + return this.octokit.graphql(query, { + orgName, + teamCount + }); + }); + } + getPullNodeId(owner, repo, pullNumber) { + return __awaiter(this, void 0, void 0, function* () { + const query = ` + query($owner: String!, $repo: String!) { + repository(owner: $owner, name: $repo) { + pullRequest(number: ${pullNumber}) { + id + } + } + } + `; + return (yield this.octokit.graphql(query, { + owner, + repo + })).repository.pullRequest.id; + }); + } + requestReviewers(pullRequestId, teamIds) { + return __awaiter(this, void 0, void 0, function* () { + const mutation = ` + mutation($input: RequestReviewsInput!) { + requestReviews(input: $input) { + clientMutationId + } + } + `; + yield this.octokit + .graphql(mutation, { + input: { + pullRequestId, + teamIds: teamIds, + union: true + } + }) + .then(response => { + core.info('Reviews requested successfully'); + }) + .catch(error => { + core.error(error); + }); + }); + } } exports.GitHubHelper = GitHubHelper; diff --git a/src/github-helper.ts b/src/github-helper.ts index 7e0cfee..4d409f6 100644 --- a/src/github-helper.ts +++ b/src/github-helper.ts @@ -158,10 +158,10 @@ export class GitHubHelper { requestReviewersParams['reviewers'] = inputs.reviewers core.info(`Requesting reviewers '${inputs.reviewers}'`) } - if (inputs.teamReviewers.length > 0) { - requestReviewersParams['team_reviewers'] = inputs.teamReviewers - core.info(`Requesting team reviewers '${inputs.teamReviewers}'`) - } + // if (inputs.teamReviewers.length > 0) { + // requestReviewersParams['team_reviewers'] = inputs.teamReviewers + // core.info(`Requesting team reviewers '${inputs.teamReviewers}'`) + // } if (Object.keys(requestReviewersParams).length > 0) { try { await this.octokit.rest.pulls.requestReviewers({ @@ -178,6 +178,147 @@ export class GitHubHelper { } } + const orgs = inputs.teamReviewers.map(team => { + if (!team.includes('/')) { + throw new Error( + `Team ${team} is not in the correct format. It should be in the format org/team` + ) + } + return team.split('/')[0] + }) + const distinctOrgs = [...new Set(orgs)] + core.debug(`distinctOrgs: ${distinctOrgs}`) + + const orgTeams = await Promise.all( + distinctOrgs.map(org => this.getOrgTeams(org)) + ) + + const teamIds = inputs.teamReviewers.map(team => { + const [org, teamName] = team.split('/') + const orgTeam = orgTeams.find( + orgTeam => orgTeam.organization.login === org + ) + if (!orgTeam) { + throw new Error(`Org ${org} not found`) + } + const teamId = orgTeam.organization.teams.edges.find( + team => team.node.slug === teamName + )?.node.id + if (!teamId) { + throw new Error(`Team ${teamName} not found in ${org}`) + } + return teamId + }) + core.debug(`teamIds: ${teamIds}`) + + if (teamIds.length > 0) { + const repository = this.parseRepository(baseRepository) + const pullNodeId = await this.getPullNodeId( + repository.owner, + repository.repo, + pull.number + ) + core.debug(`pullNodeId: ${pullNodeId}`) + + await this.requestReviewers(pullNodeId, teamIds) + } + return pull } + + async getOrgTeams(orgName: string): Promise { + const query = ` + query($orgName: String!, $teamCount: Int!) { + organization(login: $orgName) { + login + teams(first: $teamCount) { + edges { + node { + id + slug + } + } + } + } + } + ` + const teamCount = 100 + return this.octokit.graphql(query, { + orgName, + teamCount + }) + } + + async getPullNodeId( + owner: string, + repo: string, + pullNumber: number + ): Promise { + const query = ` + query($owner: String!, $repo: String!) { + repository(owner: $owner, name: $repo) { + pullRequest(number: ${pullNumber}) { + id + } + } + } + ` + + return ( + await this.octokit.graphql(query, { + owner, + repo + }) + ).repository.pullRequest.id + } + + async requestReviewers( + pullRequestId: string, + teamIds: string[] + ): Promise { + const mutation = ` + mutation($input: RequestReviewsInput!) { + requestReviews(input: $input) { + clientMutationId + } + } + ` + + await this.octokit + .graphql(mutation, { + input: { + pullRequestId, + teamIds: teamIds, + union: true + } + }) + .then(response => { + core.info('Reviews requested successfully') + }) + .catch(error => { + core.error(error) + }) + } +} + +interface OrgTeams { + organization: { + login: string + teams: { + edges: { + node: { + id: string + slug: string + } + }[] + } + } +} + +interface PullRequestResponse { + repository: { + pullRequest: { + id: string + } + } }