- introduce new flag allowing to fetch reviewers who approved PRs
- add new testcase which verifies approvers being included - adjust config for some test cases to verify reviewers not being pulled if disabled
This commit is contained in:
@@ -35,6 +35,7 @@ async function run(): Promise<void> {
|
||||
const includeOpen = core.getInput('includeOpen') === 'true'
|
||||
const ignorePreReleases = core.getInput('ignorePreReleases') === 'true'
|
||||
const failOnError = core.getInput('failOnError') === 'true'
|
||||
const fetchReviewers = core.getInput('fetchReviewers') === 'true'
|
||||
const commitMode = core.getInput('commitMode') === 'true'
|
||||
|
||||
const result = await new ReleaseNotesBuilder(
|
||||
@@ -48,6 +49,7 @@ async function run(): Promise<void> {
|
||||
includeOpen,
|
||||
failOnError,
|
||||
ignorePreReleases,
|
||||
fetchReviewers,
|
||||
commitMode,
|
||||
configuration
|
||||
).build()
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface PullRequestInfo {
|
||||
body: string
|
||||
assignees: string[]
|
||||
requestedReviewers: string[]
|
||||
approvedReviewers: string[]
|
||||
status: 'open' | 'merged'
|
||||
}
|
||||
|
||||
@@ -26,6 +27,9 @@ type PullData = RestEndpointMethodTypes['pulls']['get']['response']['data']
|
||||
type PullsListData =
|
||||
RestEndpointMethodTypes['pulls']['list']['response']['data']
|
||||
|
||||
type PullReviewData =
|
||||
RestEndpointMethodTypes['pulls']['listReviews']['response']['data']
|
||||
|
||||
export class PullRequests {
|
||||
constructor(private octokit: Octokit) {}
|
||||
|
||||
@@ -127,6 +131,28 @@ export class PullRequests {
|
||||
|
||||
return sortPullRequests(openPrs, true)
|
||||
}
|
||||
|
||||
async getReviewers(
|
||||
owner: string,
|
||||
repo: string,
|
||||
pr: PullRequestInfo
|
||||
): Promise<PullReviewData[]> {
|
||||
const options = this.octokit.pulls.listReviews.endpoint.merge({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pr.number
|
||||
})
|
||||
|
||||
for await (const response of this.octokit.paginate.iterator(options)) {
|
||||
const reviews: PullReviewData = response.data as PullReviewData
|
||||
pr.approvedReviewers = reviews
|
||||
.filter(r => r.state === 'APPROVED')
|
||||
.map(r => r.user?.login)
|
||||
.filter(r => !!r) as string[]
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export function sortPullRequests(
|
||||
@@ -192,5 +218,6 @@ const mapPullRequest = (
|
||||
assignees: pr.assignees?.map(asignee => asignee?.login || '') || [],
|
||||
requestedReviewers:
|
||||
pr.requested_reviewers?.map(reviewer => reviewer?.login || '') || [],
|
||||
approvedReviewers: [],
|
||||
status
|
||||
})
|
||||
|
||||
+20
-2
@@ -13,6 +13,7 @@ export interface ReleaseNotesOptions {
|
||||
toTag: string // the tag/ref up to
|
||||
includeOpen: boolean // defines if we should also fetch open pull requests
|
||||
failOnError: boolean // defines if we should fail the action in case of an error
|
||||
fetchReviewers: boolean // defines if the action should fetch the reviewers for PRs - approved reviewers are not included in the default PR listing
|
||||
commitMode: boolean // defines if we use the alternative commit based mode. note: this is only partially supported
|
||||
configuration: Configuration // the configuration as defined in `configuration.ts`
|
||||
}
|
||||
@@ -81,7 +82,8 @@ export class ReleaseNotes {
|
||||
private async getMergedPullRequests(
|
||||
octokit: Octokit
|
||||
): Promise<PullRequestInfo[]> {
|
||||
const {owner, repo, includeOpen, configuration} = this.options
|
||||
const {owner, repo, includeOpen, fetchReviewers, configuration} =
|
||||
this.options
|
||||
|
||||
const commits = await this.getCommitHistory(octokit)
|
||||
if (commits.length === 0) {
|
||||
@@ -169,7 +171,7 @@ export class ReleaseNotes {
|
||||
})
|
||||
|
||||
// return only prs if the baseBranch is matching the configuration
|
||||
return allPullRequests.filter(pr => {
|
||||
const finalPrs = allPullRequests.filter(pr => {
|
||||
if (baseBranches.length !== 0) {
|
||||
return baseBranchPatterns.some(pattern => {
|
||||
return pr.baseBranch.match(pattern) !== null
|
||||
@@ -177,6 +179,21 @@ export class ReleaseNotes {
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if (fetchReviewers) {
|
||||
core.info(`ℹ️ Fetching reviewers was enabled`)
|
||||
// update PR information with reviewers who approved
|
||||
for (const pr of finalPrs) {
|
||||
await pullRequestsApi.getReviewers(owner, repo, pr)
|
||||
if (pr.approvedReviewers.length > 0) {
|
||||
core.info(
|
||||
`ℹ️ Retrieved ${pr.approvedReviewers.length} reviewer(s) for PR ${owner}/${repo}/#${pr.number}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return finalPrs
|
||||
}
|
||||
|
||||
private async generateCommitPRs(
|
||||
@@ -213,6 +230,7 @@ export class ReleaseNotes {
|
||||
body: commit.message || '',
|
||||
assignees: [],
|
||||
requestedReviewers: [],
|
||||
approvedReviewers: [],
|
||||
status: 'merged'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -15,9 +15,10 @@ export class ReleaseNotesBuilder {
|
||||
private repo: string | null,
|
||||
private fromTag: string | null,
|
||||
private toTag: string | null,
|
||||
private includeOpen: boolean,
|
||||
private includeOpen: boolean = false,
|
||||
private failOnError: boolean,
|
||||
private ignorePreReleases: boolean,
|
||||
private fetchReviewers: boolean = false,
|
||||
private commitMode: boolean,
|
||||
private configuration: Configuration
|
||||
) {}
|
||||
@@ -91,6 +92,7 @@ export class ReleaseNotesBuilder {
|
||||
toTag: this.toTag,
|
||||
includeOpen: this.includeOpen,
|
||||
failOnError: this.failOnError,
|
||||
fetchReviewers: this.fetchReviewers,
|
||||
commitMode: this.commitMode,
|
||||
configuration: this.configuration
|
||||
}
|
||||
|
||||
@@ -335,6 +335,10 @@ function fillTemplate(pr: PullRequestInfo, template: string): string {
|
||||
/\${{REVIEWERS}}/g,
|
||||
pr.requestedReviewers?.join(', ') || ''
|
||||
)
|
||||
transformed = transformed.replace(
|
||||
/\${{APPROVERS}}/g,
|
||||
pr.approvedReviewers?.join(', ') || ''
|
||||
)
|
||||
return transformed
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user