- introduce new configuration fetchViaCommits which is best suited for environments with shorter diffs and/or squash merging (1 api request per commit)
This commit is contained in:
@@ -333,6 +333,7 @@ For advanced use cases additional settings can be provided to the action
|
||||
| `includeOpen` | Enables to also fetch currently open PRs. Default: false |
|
||||
| `ignorePreReleases` | Allows to ignore pre-releases for changelog generation (E.g. for 1.0.1... 1.0.0-rc02 <- ignore, 1.0.0 <- pick). Only used if `fromTag` was not specified. Default: false |
|
||||
| `failOnError` | Defines if the action will result in a build failure if problems occurred. Default: false |
|
||||
| `fetchViaCommits` | Enables PRs to get fetched via the commits identified between from->to tag. This will do 1 API request per commit -> Best for scenarios with squash merges | Or shorter from->to diffs (< 10 commits) | Also effective for shorters diffs for very old PRs. Default: false |
|
||||
| `fetchReviewers` | Will enable fetching the users/reviewers who approved the PR. Default: false |
|
||||
| `fetchReleaseInformation` | Will enable fetching additional release information from tags. Default: false |
|
||||
| `fetchReviews` | Will enable fetching the reviews on of the PR. Default: false |
|
||||
|
||||
@@ -28,6 +28,9 @@ inputs:
|
||||
failOnError:
|
||||
description: 'Defines if the action should result in a build failure, if an error was discovered'
|
||||
default: "false"
|
||||
fetchViaCommits:
|
||||
description: 'Defines if PRs are fetched via the commits identified. This will do 1 API request per commit -> Best for scenarios with squash merges | Or shorter from-to diffs (< 10 commits) | Also effective for shorters diffs for very old PRs'
|
||||
default: "false"
|
||||
fetchReviewers:
|
||||
description: 'Will enable fetching the users/reviewers who approved the PR'
|
||||
default: "false"
|
||||
|
||||
+92
-34
@@ -141,12 +141,13 @@ function run() {
|
||||
const includeOpen = core.getInput('includeOpen') === 'true';
|
||||
const ignorePreReleases = core.getInput('ignorePreReleases') === 'true';
|
||||
const failOnError = core.getInput('failOnError') === 'true';
|
||||
const fetchViaCommits = core.getInput('fetchViaCommits') === 'true';
|
||||
const fetchReviewers = core.getInput('fetchReviewers') === 'true';
|
||||
const fetchReleaseInformation = core.getInput('fetchReleaseInformation') === 'true';
|
||||
const fetchReviews = core.getInput('fetchReviews') === 'true';
|
||||
const commitMode = core.getInput('commitMode') === 'true';
|
||||
const exportOnly = core.getInput('exportOnly') === 'true';
|
||||
const result = yield new releaseNotesBuilder_1.ReleaseNotesBuilder(baseUrl, token, repositoryPath, owner, repo, fromTag, toTag, includeOpen, failOnError, ignorePreReleases, fetchReviewers, fetchReleaseInformation, fetchReviews, commitMode, exportOnly, configuration).build();
|
||||
const result = yield new releaseNotesBuilder_1.ReleaseNotesBuilder(baseUrl, token, repositoryPath, owner, repo, fromTag, toTag, includeOpen, failOnError, ignorePreReleases, fetchViaCommits, fetchReviewers, fetchReleaseInformation, fetchReviews, commitMode, exportOnly, configuration).build();
|
||||
core.setOutput('changelog', result);
|
||||
// write the result in changelog to file if possible
|
||||
const outputFile = core.getInput('outputFile');
|
||||
@@ -282,7 +283,7 @@ const transform_1 = __nccwpck_require__(1644);
|
||||
const github_pr_collector_1 = __nccwpck_require__(3196);
|
||||
const utils_2 = __nccwpck_require__(853);
|
||||
class ReleaseNotesBuilder {
|
||||
constructor(baseUrl, token, repositoryPath, owner, repo, fromTag, toTag, includeOpen = false, failOnError, ignorePreReleases, fetchReviewers = false, fetchReleaseInformation = false, fetchReviews = false, commitMode = false, exportOnly = false, configuration) {
|
||||
constructor(baseUrl, token, repositoryPath, owner, repo, fromTag, toTag, includeOpen = false, failOnError, ignorePreReleases, fetchViaCommits = false, fetchReviewers = false, fetchReleaseInformation = false, fetchReviews = false, commitMode = false, exportOnly = false, configuration) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.token = token;
|
||||
this.repositoryPath = repositoryPath;
|
||||
@@ -293,6 +294,7 @@ class ReleaseNotesBuilder {
|
||||
this.includeOpen = includeOpen;
|
||||
this.failOnError = failOnError;
|
||||
this.ignorePreReleases = ignorePreReleases;
|
||||
this.fetchViaCommits = fetchViaCommits;
|
||||
this.fetchReviewers = fetchReviewers;
|
||||
this.fetchReleaseInformation = fetchReleaseInformation;
|
||||
this.fetchReviews = fetchReviews;
|
||||
@@ -319,7 +321,7 @@ class ReleaseNotesBuilder {
|
||||
core.debug(`Resolved 'repo' as ${this.repo}`);
|
||||
}
|
||||
core.endGroup();
|
||||
const prData = yield new github_pr_collector_1.PullRequestCollector(this.baseUrl, this.token, this.repositoryPath, this.owner, this.repo, this.fromTag, this.toTag, this.includeOpen, this.failOnError, this.ignorePreReleases, this.fetchReviewers, this.fetchReleaseInformation, this.fetchReviews, this.commitMode, this.configuration).build();
|
||||
const prData = yield new github_pr_collector_1.PullRequestCollector(this.baseUrl, this.token, this.repositoryPath, this.owner, this.repo, this.fromTag, this.toTag, this.includeOpen, this.failOnError, this.ignorePreReleases, this.fetchViaCommits, this.fetchReviewers, this.fetchReleaseInformation, this.fetchReviews, this.commitMode, this.configuration).build();
|
||||
if (prData == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -26557,7 +26559,7 @@ const https_proxy_agent_1 = __nccwpck_require__(7219);
|
||||
const pullRequests_1 = __nccwpck_require__(1948);
|
||||
const commits_1 = __nccwpck_require__(5789);
|
||||
class PullRequestCollector {
|
||||
constructor(baseUrl, token, repositoryPath, owner, repo, fromTag, toTag, includeOpen = false, failOnError, ignorePreReleases, fetchReviewers = false, fetchReleaseInformation = false, fetchReviews = false, commitMode = false, configuration) {
|
||||
constructor(baseUrl, token, repositoryPath, owner, repo, fromTag, toTag, includeOpen = false, failOnError, ignorePreReleases, fetchViaCommits = false, fetchReviewers = false, fetchReleaseInformation = false, fetchReviews = false, commitMode = false, configuration) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.token = token;
|
||||
this.repositoryPath = repositoryPath;
|
||||
@@ -26568,6 +26570,7 @@ class PullRequestCollector {
|
||||
this.includeOpen = includeOpen;
|
||||
this.failOnError = failOnError;
|
||||
this.ignorePreReleases = ignorePreReleases;
|
||||
this.fetchViaCommits = fetchViaCommits;
|
||||
this.fetchReviewers = fetchReviewers;
|
||||
this.fetchReleaseInformation = fetchReleaseInformation;
|
||||
this.fetchReviews = fetchReviews;
|
||||
@@ -26632,6 +26635,7 @@ class PullRequestCollector {
|
||||
toTag: thisTag,
|
||||
includeOpen: this.includeOpen,
|
||||
failOnError: this.failOnError,
|
||||
fetchViaCommits: this.fetchViaCommits,
|
||||
fetchReviewers: this.fetchReviewers,
|
||||
fetchReleaseInformation: this.fetchReleaseInformation,
|
||||
fetchReviews: this.fetchReviews,
|
||||
@@ -26774,15 +26778,47 @@ class PullRequests {
|
||||
}
|
||||
});
|
||||
}
|
||||
getBetweenDates(owner, repo, fromDate, toDate, maxPullRequests) {
|
||||
getForCommitHash(owner, repo, commit_sha, maxPullRequests) {
|
||||
var _a, e_1, _b, _c;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const mergedPRs = [];
|
||||
const options = this.octokit.repos.listPullRequestsAssociatedWithCommit.endpoint.merge({
|
||||
owner,
|
||||
repo,
|
||||
commit_sha,
|
||||
per_page: `${Math.min(10, maxPullRequests)}`,
|
||||
direction: 'desc'
|
||||
});
|
||||
try {
|
||||
for (var _d = true, _e = __asyncValues(this.octokit.paginate.iterator(options)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
|
||||
_c = _f.value;
|
||||
_d = false;
|
||||
const response = _c;
|
||||
const prs = response.data;
|
||||
for (const pr of prs) {
|
||||
mergedPRs.push(mapPullRequest(pr, !!pr.merged_at ? 'merged' : 'open'));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
}
|
||||
return sortPrs(mergedPRs);
|
||||
});
|
||||
}
|
||||
getBetweenDates(owner, repo, fromDate, toDate, maxPullRequests) {
|
||||
var _a, e_2, _b, _c;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const mergedPRs = [];
|
||||
const options = this.octokit.pulls.list.endpoint.merge({
|
||||
owner,
|
||||
repo,
|
||||
state: 'closed',
|
||||
sort: 'updated',
|
||||
sort: 'merged',
|
||||
per_page: `${Math.min(100, maxPullRequests)}`,
|
||||
direction: 'desc'
|
||||
});
|
||||
@@ -26803,22 +26839,22 @@ class PullRequests {
|
||||
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests}`);
|
||||
}
|
||||
// bail out early to not keep iterating on PRs super old
|
||||
return sortPrs(mergedPRs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
finally { if (e_2) throw e_2.error; }
|
||||
}
|
||||
return sortPrs(mergedPRs);
|
||||
});
|
||||
}
|
||||
getOpen(owner, repo, maxPullRequests) {
|
||||
var _a, e_2, _b, _c;
|
||||
var _a, e_3, _b, _c;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const openPrs = [];
|
||||
const options = this.octokit.pulls.list.endpoint.merge({
|
||||
@@ -26844,22 +26880,22 @@ class PullRequests {
|
||||
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests}`);
|
||||
}
|
||||
// bail out early to not keep iterating on PRs super old
|
||||
return sortPrs(openPrs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
||||
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
||||
}
|
||||
finally { if (e_2) throw e_2.error; }
|
||||
finally { if (e_3) throw e_3.error; }
|
||||
}
|
||||
return sortPrs(openPrs);
|
||||
});
|
||||
}
|
||||
getReviews(owner, repo, pr) {
|
||||
var _a, e_3, _b, _c;
|
||||
var _a, e_4, _b, _c;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const options = this.octokit.pulls.listReviews.endpoint.merge({
|
||||
owner,
|
||||
@@ -26880,12 +26916,12 @@ class PullRequests {
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
||||
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
||||
}
|
||||
finally { if (e_3) throw e_3.error; }
|
||||
finally { if (e_4) throw e_4.error; }
|
||||
}
|
||||
pr.reviews = prReviews;
|
||||
});
|
||||
@@ -26909,27 +26945,49 @@ class PullRequests {
|
||||
fromDate = maxFromDate;
|
||||
}
|
||||
core.info(`ℹ️ Fetching PRs between dates ${fromDate.toISOString()} to ${toDate.toISOString()} for ${owner}/${repo}`);
|
||||
const pullRequests = yield this.getBetweenDates(owner, repo, fromDate, toDate, configuration.max_pull_requests);
|
||||
core.info(`ℹ️ Retrieved ${pullRequests.length} PRs for ${owner}/${repo} in date range from API`);
|
||||
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches);
|
||||
core.info(`ℹ️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`);
|
||||
// create array of commits for this release
|
||||
const releaseCommitHashes = prCommits.map(commmit => {
|
||||
return commmit.sha;
|
||||
const releaseCommitHashes = prCommits.map(commit => {
|
||||
return commit.sha;
|
||||
});
|
||||
// filter out pull requests not associated with this release
|
||||
const mergedPullRequests = pullRequests.filter(pr => {
|
||||
return releaseCommitHashes.includes(pr.mergeCommitSha);
|
||||
});
|
||||
core.info(`ℹ️ Retrieved ${mergedPullRequests.length} merged PRs for ${owner}/${repo}`);
|
||||
let allPullRequests = mergedPullRequests;
|
||||
if (includeOpen) {
|
||||
// retrieve all open pull requests
|
||||
const openPullRequests = yield this.getOpen(owner, repo, configuration.max_pull_requests);
|
||||
core.info(`ℹ️ Retrieved ${openPullRequests.length} open PRs for ${owner}/${repo}`);
|
||||
// all pull requests
|
||||
allPullRequests = allPullRequests.concat(openPullRequests);
|
||||
core.info(`ℹ️ Retrieved ${allPullRequests.length} total PRs for ${owner}/${repo}`);
|
||||
let pullRequests;
|
||||
if (options.fetchViaCommits) {
|
||||
// fetch PRs based on commits instead (will get associated PRs per commit found)
|
||||
const prsForReleaseCommits = new Map();
|
||||
for (const commit of prCommits) {
|
||||
const result = yield this.getForCommitHash(owner, repo, commit.sha, configuration.max_pull_requests);
|
||||
result.forEach(pr => prsForReleaseCommits.set(pr.number, pr));
|
||||
}
|
||||
const dedupedPrsForReleaseCommits = Array.from(prsForReleaseCommits.values());
|
||||
if (!includeOpen) {
|
||||
pullRequests = dedupedPrsForReleaseCommits.filter(pr => pr.status !== 'open');
|
||||
core.info(`ℹ️ Retrieved ${pullRequests.length} PRs for ${owner}/${repo} based on the release commit hashes`);
|
||||
}
|
||||
else {
|
||||
pullRequests = dedupedPrsForReleaseCommits;
|
||||
core.info(`ℹ️ Retrieved ${pullRequests.length} PRs for ${owner}/${repo} based on the release commit hashes (including open)`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// fetch PRs based on the date range identified
|
||||
const pullRequestsBetweenDate = yield this.getBetweenDates(owner, repo, fromDate, toDate, configuration.max_pull_requests);
|
||||
core.info(`ℹ️ Retrieved ${pullRequestsBetweenDate.length} PRs for ${owner}/${repo} in date range from API`);
|
||||
// filter out pull requests not associated with this release
|
||||
const mergedPullRequests = pullRequestsBetweenDate.filter(pr => {
|
||||
return releaseCommitHashes.includes(pr.mergeCommitSha);
|
||||
});
|
||||
core.info(`ℹ️ Retrieved ${mergedPullRequests.length} merged PRs for ${owner}/${repo}`);
|
||||
let allPullRequests = mergedPullRequests;
|
||||
if (includeOpen) {
|
||||
// retrieve all open pull requests
|
||||
const openPullRequests = yield this.getOpen(owner, repo, configuration.max_pull_requests);
|
||||
core.info(`ℹ️ Retrieved ${openPullRequests.length} open PRs for ${owner}/${repo}`);
|
||||
// all pull requests
|
||||
allPullRequests = allPullRequests.concat(openPullRequests);
|
||||
core.info(`ℹ️ Retrieved ${allPullRequests.length} total PRs for ${owner}/${repo}`);
|
||||
}
|
||||
pullRequests = allPullRequests;
|
||||
}
|
||||
// retrieve base branches we allow
|
||||
const baseBranches = configuration.base_branches;
|
||||
@@ -26937,7 +26995,7 @@ class PullRequests {
|
||||
return new RegExp(baseBranch.replace('\\\\', '\\'), 'gu');
|
||||
});
|
||||
// return only prs if the baseBranch is matching the configuration
|
||||
const finalPrs = allPullRequests.filter(pr => {
|
||||
const finalPrs = pullRequests.filter(pr => {
|
||||
if (baseBranches.length !== 0) {
|
||||
return baseBranchPatterns.some(pattern => {
|
||||
return pr.baseBranch.match(pattern) !== null;
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -238,7 +238,7 @@ export class PullRequests {
|
||||
})
|
||||
|
||||
let pullRequests: PullRequestInfo[]
|
||||
if (releaseCommitHashes.length < 10) {
|
||||
if (options.fetchViaCommits) {
|
||||
// fetch PRs based on commits instead (will get associated PRs per commit found)
|
||||
const prsForReleaseCommits: Map<number, PullRequestInfo> = new Map()
|
||||
for (const commit of prCommits) {
|
||||
@@ -264,7 +264,7 @@ export class PullRequests {
|
||||
})
|
||||
|
||||
core.info(`ℹ️ Retrieved ${mergedPullRequests.length} merged PRs for ${owner}/${repo}`)
|
||||
|
||||
|
||||
let allPullRequests = mergedPullRequests
|
||||
if (includeOpen) {
|
||||
// retrieve all open pull requests
|
||||
|
||||
@@ -50,6 +50,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 fetchViaCommits = core.getInput('fetchViaCommits') === 'true'
|
||||
const fetchReviewers = core.getInput('fetchReviewers') === 'true'
|
||||
const fetchReleaseInformation = core.getInput('fetchReleaseInformation') === 'true'
|
||||
const fetchReviews = core.getInput('fetchReviews') === 'true'
|
||||
@@ -67,6 +68,7 @@ async function run(): Promise<void> {
|
||||
includeOpen,
|
||||
failOnError,
|
||||
ignorePreReleases,
|
||||
fetchViaCommits,
|
||||
fetchReviewers,
|
||||
fetchReleaseInformation,
|
||||
fetchReviews,
|
||||
|
||||
@@ -40,6 +40,7 @@ export class ReleaseNotesBuilder {
|
||||
private includeOpen: boolean = false,
|
||||
private failOnError: boolean,
|
||||
private ignorePreReleases: boolean,
|
||||
private fetchViaCommits: boolean = false,
|
||||
private fetchReviewers: boolean = false,
|
||||
private fetchReleaseInformation: boolean = false,
|
||||
private fetchReviews: boolean = false,
|
||||
@@ -77,6 +78,7 @@ export class ReleaseNotesBuilder {
|
||||
this.includeOpen,
|
||||
this.failOnError,
|
||||
this.ignorePreReleases,
|
||||
this.fetchViaCommits,
|
||||
this.fetchReviewers,
|
||||
this.fetchReleaseInformation,
|
||||
this.fetchReviews,
|
||||
|
||||
Reference in New Issue
Block a user