- reformat source - lineLength 120
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"printWidth": 80,
|
"printWidth": 120,
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
"semi": false,
|
"semi": false,
|
||||||
|
|||||||
+10
-34
@@ -282,38 +282,20 @@ class GitCommandManager {
|
|||||||
}
|
}
|
||||||
latestTag() {
|
latestTag() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const revListOutput = yield this.execGit([
|
const revListOutput = yield this.execGit(['rev-list', '--tags', '--skip=0', '--max-count=1']);
|
||||||
'rev-list',
|
const output = yield this.execGit(['describe', '--abbrev=0', '--tags', revListOutput.stdout.trim()]);
|
||||||
'--tags',
|
|
||||||
'--skip=0',
|
|
||||||
'--max-count=1'
|
|
||||||
]);
|
|
||||||
const output = yield this.execGit([
|
|
||||||
'describe',
|
|
||||||
'--abbrev=0',
|
|
||||||
'--tags',
|
|
||||||
revListOutput.stdout.trim()
|
|
||||||
]);
|
|
||||||
return output.stdout.trim();
|
return output.stdout.trim();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initialCommit() {
|
initialCommit() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const revListOutput = yield this.execGit([
|
const revListOutput = yield this.execGit(['rev-list', '--max-parents=0', 'HEAD']);
|
||||||
'rev-list',
|
|
||||||
'--max-parents=0',
|
|
||||||
'HEAD'
|
|
||||||
]);
|
|
||||||
return revListOutput.stdout.trim();
|
return revListOutput.stdout.trim();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
tagCreation(tagName) {
|
tagCreation(tagName) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const creationDate = yield this.execGit([
|
const creationDate = yield this.execGit(['for-each-ref', '--format="%(creatordate:rfc)"', `refs/tags/${tagName}`]);
|
||||||
'for-each-ref',
|
|
||||||
'--format="%(creatordate:rfc)"',
|
|
||||||
`refs/tags/${tagName}`
|
|
||||||
]);
|
|
||||||
return creationDate.stdout.trim().replace(/"/g, '');
|
return creationDate.stdout.trim().replace(/"/g, '');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -800,8 +782,7 @@ class ReleaseNotes {
|
|||||||
core.setOutput('commits', diffInfo.commits);
|
core.setOutput('commits', diffInfo.commits);
|
||||||
if (mergedPullRequests.length === 0) {
|
if (mergedPullRequests.length === 0) {
|
||||||
core.warning(`⚠️ No pull requests found`);
|
core.warning(`⚠️ No pull requests found`);
|
||||||
return (0, transform_1.fillAdditionalPlaceholders)(this.options.configuration.empty_template ||
|
return (0, transform_1.fillAdditionalPlaceholders)(this.options.configuration.empty_template || configuration_1.DefaultConfiguration.empty_template, this.options);
|
||||||
configuration_1.DefaultConfiguration.empty_template, this.options);
|
|
||||||
}
|
}
|
||||||
core.startGroup('📦 Build changelog');
|
core.startGroup('📦 Build changelog');
|
||||||
const resultChangelog = (0, transform_1.buildChangelog)(diffInfo, mergedPullRequests, this.options);
|
const resultChangelog = (0, transform_1.buildChangelog)(diffInfo, mergedPullRequests, this.options);
|
||||||
@@ -841,8 +822,7 @@ class ReleaseNotes {
|
|||||||
const lastCommit = commits[commits.length - 1];
|
const lastCommit = commits[commits.length - 1];
|
||||||
let fromDate = firstCommit.date;
|
let fromDate = firstCommit.date;
|
||||||
const toDate = lastCommit.date;
|
const toDate = lastCommit.date;
|
||||||
const maxDays = configuration.max_back_track_time_days ||
|
const maxDays = configuration.max_back_track_time_days || configuration_1.DefaultConfiguration.max_back_track_time_days;
|
||||||
configuration_1.DefaultConfiguration.max_back_track_time_days;
|
|
||||||
const maxFromDate = toDate.clone().subtract(maxDays, 'days');
|
const maxFromDate = toDate.clone().subtract(maxDays, 'days');
|
||||||
if (maxFromDate.isAfter(fromDate)) {
|
if (maxFromDate.isAfter(fromDate)) {
|
||||||
core.info(`⚠️ Adjusted 'fromDate' to go max ${maxDays} back`);
|
core.info(`⚠️ Adjusted 'fromDate' to go max ${maxDays} back`);
|
||||||
@@ -852,8 +832,7 @@ class ReleaseNotes {
|
|||||||
const pullRequestsApi = new pullRequests_1.PullRequests(octokit);
|
const pullRequestsApi = new pullRequests_1.PullRequests(octokit);
|
||||||
const pullRequests = yield pullRequestsApi.getBetweenDates(owner, repo, fromDate, toDate, configuration.max_pull_requests || configuration_1.DefaultConfiguration.max_pull_requests);
|
const pullRequests = yield pullRequestsApi.getBetweenDates(owner, repo, fromDate, toDate, configuration.max_pull_requests || configuration_1.DefaultConfiguration.max_pull_requests);
|
||||||
core.info(`ℹ️ Retrieved ${pullRequests.length} merged PRs for ${owner}/${repo}`);
|
core.info(`ℹ️ Retrieved ${pullRequests.length} merged PRs for ${owner}/${repo}`);
|
||||||
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches ||
|
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches || configuration_1.DefaultConfiguration.exclude_merge_branches);
|
||||||
configuration_1.DefaultConfiguration.exclude_merge_branches);
|
|
||||||
core.info(`ℹ️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`);
|
core.info(`ℹ️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`);
|
||||||
// create array of commits for this release
|
// create array of commits for this release
|
||||||
const releaseCommitHashes = prCommits.map(commmit => {
|
const releaseCommitHashes = prCommits.map(commmit => {
|
||||||
@@ -866,8 +845,7 @@ class ReleaseNotes {
|
|||||||
let allPullRequests = mergedPullRequests;
|
let allPullRequests = mergedPullRequests;
|
||||||
if (includeOpen) {
|
if (includeOpen) {
|
||||||
// retrieve all open pull requests
|
// retrieve all open pull requests
|
||||||
const openPullRequests = yield pullRequestsApi.getOpen(owner, repo, configuration.max_pull_requests ||
|
const openPullRequests = yield pullRequestsApi.getOpen(owner, repo, configuration.max_pull_requests || configuration_1.DefaultConfiguration.max_pull_requests);
|
||||||
configuration_1.DefaultConfiguration.max_pull_requests);
|
|
||||||
core.info(`ℹ️ Retrieved ${openPullRequests.length} open PRs for ${owner}/${repo}`);
|
core.info(`ℹ️ Retrieved ${openPullRequests.length} open PRs for ${owner}/${repo}`);
|
||||||
// all pull requests
|
// all pull requests
|
||||||
allPullRequests = allPullRequests.concat(openPullRequests);
|
allPullRequests = allPullRequests.concat(openPullRequests);
|
||||||
@@ -911,8 +889,7 @@ class ReleaseNotes {
|
|||||||
if (commits.length === 0) {
|
if (commits.length === 0) {
|
||||||
return [diffInfo, []];
|
return [diffInfo, []];
|
||||||
}
|
}
|
||||||
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches ||
|
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches || configuration_1.DefaultConfiguration.exclude_merge_branches);
|
||||||
configuration_1.DefaultConfiguration.exclude_merge_branches);
|
|
||||||
core.info(`ℹ️ Retrieved ${prCommits.length} commits for ${owner}/${repo}`);
|
core.info(`ℹ️ Retrieved ${prCommits.length} commits for ${owner}/${repo}`);
|
||||||
const prs = prCommits.map(function (commit) {
|
const prs = prCommits.map(function (commit) {
|
||||||
return {
|
return {
|
||||||
@@ -1032,8 +1009,7 @@ class ReleaseNotesBuilder {
|
|||||||
// ensure proper from <-> to tag range
|
// ensure proper from <-> to tag range
|
||||||
core.startGroup(`🔖 Resolve tags`);
|
core.startGroup(`🔖 Resolve tags`);
|
||||||
const tagsApi = new tags_1.Tags(octokit);
|
const tagsApi = new tags_1.Tags(octokit);
|
||||||
const tagRange = yield tagsApi.retrieveRange(this.repositoryPath, this.owner, this.repo, this.fromTag, this.toTag, this.ignorePreReleases, this.configuration.max_tags_to_fetch ||
|
const tagRange = yield tagsApi.retrieveRange(this.repositoryPath, this.owner, this.repo, this.fromTag, this.toTag, this.ignorePreReleases, this.configuration.max_tags_to_fetch || configuration_1.DefaultConfiguration.max_tags_to_fetch, this.configuration.tag_resolver || configuration_1.DefaultConfiguration.tag_resolver);
|
||||||
configuration_1.DefaultConfiguration.max_tags_to_fetch, this.configuration.tag_resolver || configuration_1.DefaultConfiguration.tag_resolver);
|
|
||||||
let thisTag = tagRange.to;
|
let thisTag = tagRange.to;
|
||||||
if (!thisTag) {
|
if (!thisTag) {
|
||||||
(0, utils_1.failOrError)(`💥 Missing or couldn't resolve 'toTag'`, this.failOnError);
|
(0, utils_1.failOrError)(`💥 Missing or couldn't resolve 'toTag'`, this.failOnError);
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+5
-21
@@ -31,23 +31,13 @@ export interface CommitInfo {
|
|||||||
export class Commits {
|
export class Commits {
|
||||||
constructor(private octokit: Octokit) {}
|
constructor(private octokit: Octokit) {}
|
||||||
|
|
||||||
async getDiff(
|
async getDiff(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
base: string,
|
|
||||||
head: string
|
|
||||||
): Promise<DiffInfo> {
|
|
||||||
const diff: DiffInfo = await this.getDiffRemote(owner, repo, base, head)
|
const diff: DiffInfo = await this.getDiffRemote(owner, repo, base, head)
|
||||||
diff.commitInfo = this.sortCommits(diff.commitInfo)
|
diff.commitInfo = this.sortCommits(diff.commitInfo)
|
||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getDiffRemote(
|
private async getDiffRemote(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
base: string,
|
|
||||||
head: string
|
|
||||||
): Promise<DiffInfo> {
|
|
||||||
let changedFilesCount = 0
|
let changedFilesCount = 0
|
||||||
let additionCount = 0
|
let additionCount = 0
|
||||||
let deletionCount = 0
|
let deletionCount = 0
|
||||||
@@ -56,8 +46,7 @@ export class Commits {
|
|||||||
|
|
||||||
// Fetch comparisons recursively until we don't find any commits
|
// Fetch comparisons recursively until we don't find any commits
|
||||||
// This is because the GitHub API limits the number of commits returned in a single response.
|
// This is because the GitHub API limits the number of commits returned in a single response.
|
||||||
let commits: RestEndpointMethodTypes['repos']['compareCommits']['response']['data']['commits'] =
|
let commits: RestEndpointMethodTypes['repos']['compareCommits']['response']['data']['commits'] = []
|
||||||
[]
|
|
||||||
let compareHead = head
|
let compareHead = head
|
||||||
// eslint-disable-next-line no-constant-condition
|
// eslint-disable-next-line no-constant-condition
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -84,9 +73,7 @@ export class Commits {
|
|||||||
compareHead = `${commits[0].sha}^`
|
compareHead = `${commits[0].sha}^`
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info(
|
core.info(`ℹ️ Found ${commits.length} commits from the GitHub API for ${owner}/${repo}`)
|
||||||
`ℹ️ Found ${commits.length} commits from the GitHub API for ${owner}/${repo}`
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
changedFiles: changedFilesCount,
|
changedFiles: changedFilesCount,
|
||||||
@@ -135,10 +122,7 @@ export class Commits {
|
|||||||
/**
|
/**
|
||||||
* Filters out all commits which match the exclude pattern
|
* Filters out all commits which match the exclude pattern
|
||||||
*/
|
*/
|
||||||
export function filterCommits(
|
export function filterCommits(commits: CommitInfo[], excludeMergeBranches: string[]): CommitInfo[] {
|
||||||
commits: CommitInfo[],
|
|
||||||
excludeMergeBranches: string[]
|
|
||||||
): CommitInfo[] {
|
|
||||||
const filteredCommits = []
|
const filteredCommits = []
|
||||||
|
|
||||||
for (const commit of commits) {
|
for (const commit of commits) {
|
||||||
|
|||||||
+8
-36
@@ -2,9 +2,7 @@ import * as exec from '@actions/exec'
|
|||||||
import * as io from '@actions/io'
|
import * as io from '@actions/io'
|
||||||
import {directoryExistsSync} from './utils'
|
import {directoryExistsSync} from './utils'
|
||||||
|
|
||||||
export async function createCommandManager(
|
export async function createCommandManager(workingDirectory: string): Promise<GitCommandManager> {
|
||||||
workingDirectory: string
|
|
||||||
): Promise<GitCommandManager> {
|
|
||||||
return await GitCommandManager.createCommandManager(workingDirectory)
|
return await GitCommandManager.createCommandManager(workingDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,52 +18,28 @@ class GitCommandManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async latestTag(): Promise<string> {
|
async latestTag(): Promise<string> {
|
||||||
const revListOutput = await this.execGit([
|
const revListOutput = await this.execGit(['rev-list', '--tags', '--skip=0', '--max-count=1'])
|
||||||
'rev-list',
|
const output = await this.execGit(['describe', '--abbrev=0', '--tags', revListOutput.stdout.trim()])
|
||||||
'--tags',
|
|
||||||
'--skip=0',
|
|
||||||
'--max-count=1'
|
|
||||||
])
|
|
||||||
const output = await this.execGit([
|
|
||||||
'describe',
|
|
||||||
'--abbrev=0',
|
|
||||||
'--tags',
|
|
||||||
revListOutput.stdout.trim()
|
|
||||||
])
|
|
||||||
return output.stdout.trim()
|
return output.stdout.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialCommit(): Promise<string> {
|
async initialCommit(): Promise<string> {
|
||||||
const revListOutput = await this.execGit([
|
const revListOutput = await this.execGit(['rev-list', '--max-parents=0', 'HEAD'])
|
||||||
'rev-list',
|
|
||||||
'--max-parents=0',
|
|
||||||
'HEAD'
|
|
||||||
])
|
|
||||||
return revListOutput.stdout.trim()
|
return revListOutput.stdout.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
async tagCreation(tagName: string): Promise<string> {
|
async tagCreation(tagName: string): Promise<string> {
|
||||||
const creationDate = await this.execGit([
|
const creationDate = await this.execGit(['for-each-ref', '--format="%(creatordate:rfc)"', `refs/tags/${tagName}`])
|
||||||
'for-each-ref',
|
|
||||||
'--format="%(creatordate:rfc)"',
|
|
||||||
`refs/tags/${tagName}`
|
|
||||||
])
|
|
||||||
return creationDate.stdout.trim().replace(/"/g, '')
|
return creationDate.stdout.trim().replace(/"/g, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
static async createCommandManager(
|
static async createCommandManager(workingDirectory: string): Promise<GitCommandManager> {
|
||||||
workingDirectory: string
|
|
||||||
): Promise<GitCommandManager> {
|
|
||||||
const result = new GitCommandManager()
|
const result = new GitCommandManager()
|
||||||
await result.initializeCommandManager(workingDirectory)
|
await result.initializeCommandManager(workingDirectory)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private async execGit(
|
private async execGit(args: string[], allowAllExitCodes = false, silent = false): Promise<GitOutput> {
|
||||||
args: string[],
|
|
||||||
allowAllExitCodes = false,
|
|
||||||
silent = false
|
|
||||||
): Promise<GitOutput> {
|
|
||||||
directoryExistsSync(this.workingDirectory, true)
|
directoryExistsSync(this.workingDirectory, true)
|
||||||
|
|
||||||
const result = new GitOutput()
|
const result = new GitOutput()
|
||||||
@@ -88,9 +62,7 @@ class GitCommandManager {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initializeCommandManager(
|
private async initializeCommandManager(workingDirectory: string): Promise<void> {
|
||||||
workingDirectory: string
|
|
||||||
): Promise<void> {
|
|
||||||
this.workingDirectory = workingDirectory
|
this.workingDirectory = workingDirectory
|
||||||
this.gitPath = await io.which('git', true)
|
this.gitPath = await io.which('git', true)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-8
@@ -1,11 +1,6 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import {
|
import {parseConfiguration, resolveConfiguration, retrieveRepositoryPath, writeOutput} from './utils'
|
||||||
parseConfiguration,
|
|
||||||
resolveConfiguration,
|
|
||||||
retrieveRepositoryPath,
|
|
||||||
writeOutput
|
|
||||||
} from './utils'
|
|
||||||
import {ReleaseNotesBuilder} from './releaseNotesBuilder'
|
import {ReleaseNotesBuilder} from './releaseNotesBuilder'
|
||||||
import {Configuration} from './configuration'
|
import {Configuration} from './configuration'
|
||||||
|
|
||||||
@@ -44,8 +39,7 @@ async function run(): Promise<void> {
|
|||||||
const ignorePreReleases = core.getInput('ignorePreReleases') === 'true'
|
const ignorePreReleases = core.getInput('ignorePreReleases') === 'true'
|
||||||
const failOnError = core.getInput('failOnError') === 'true'
|
const failOnError = core.getInput('failOnError') === 'true'
|
||||||
const fetchReviewers = core.getInput('fetchReviewers') === 'true'
|
const fetchReviewers = core.getInput('fetchReviewers') === 'true'
|
||||||
const fetchReleaseInformation =
|
const fetchReleaseInformation = core.getInput('fetchReleaseInformation') === 'true'
|
||||||
core.getInput('fetchReleaseInformation') === 'true'
|
|
||||||
const commitMode = core.getInput('commitMode') === 'true'
|
const commitMode = core.getInput('commitMode') === 'true'
|
||||||
|
|
||||||
const result = await new ReleaseNotesBuilder(
|
const result = await new ReleaseNotesBuilder(
|
||||||
|
|||||||
+11
-43
@@ -26,20 +26,14 @@ export interface PullRequestInfo {
|
|||||||
|
|
||||||
type PullData = RestEndpointMethodTypes['pulls']['get']['response']['data']
|
type PullData = RestEndpointMethodTypes['pulls']['get']['response']['data']
|
||||||
|
|
||||||
type PullsListData =
|
type PullsListData = RestEndpointMethodTypes['pulls']['list']['response']['data']
|
||||||
RestEndpointMethodTypes['pulls']['list']['response']['data']
|
|
||||||
|
|
||||||
type PullReviewData =
|
type PullReviewData = RestEndpointMethodTypes['pulls']['listReviews']['response']['data']
|
||||||
RestEndpointMethodTypes['pulls']['listReviews']['response']['data']
|
|
||||||
|
|
||||||
export class PullRequests {
|
export class PullRequests {
|
||||||
constructor(private octokit: Octokit) {}
|
constructor(private octokit: Octokit) {}
|
||||||
|
|
||||||
async getSingle(
|
async getSingle(owner: string, repo: string, prNumber: number): Promise<PullRequestInfo | null> {
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
prNumber: number
|
|
||||||
): Promise<PullRequestInfo | null> {
|
|
||||||
try {
|
try {
|
||||||
const {data} = await this.octokit.pulls.get({
|
const {data} = await this.octokit.pulls.get({
|
||||||
owner,
|
owner,
|
||||||
@@ -49,9 +43,7 @@ export class PullRequests {
|
|||||||
|
|
||||||
return mapPullRequest(data)
|
return mapPullRequest(data)
|
||||||
} catch (e: any /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
} catch (e: any /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
core.warning(
|
core.warning(`⚠️ Cannot find PR ${owner}/${repo}#${prNumber} - ${e.message}`)
|
||||||
`⚠️ Cannot find PR ${owner}/${repo}#${prNumber} - ${e.message}`
|
|
||||||
)
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,11 +90,7 @@ export class PullRequests {
|
|||||||
return sortPrs(mergedPRs)
|
return sortPrs(mergedPRs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOpen(
|
async getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
maxPullRequests: number
|
|
||||||
): Promise<PullRequestInfo[]> {
|
|
||||||
const openPrs: PullRequestInfo[] = []
|
const openPrs: PullRequestInfo[] = []
|
||||||
const options = this.octokit.pulls.list.endpoint.merge({
|
const options = this.octokit.pulls.list.endpoint.merge({
|
||||||
owner,
|
owner,
|
||||||
@@ -134,11 +122,7 @@ export class PullRequests {
|
|||||||
return sortPrs(openPrs)
|
return sortPrs(openPrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getReviewers(
|
async getReviewers(owner: string, repo: string, pr: PullRequestInfo): Promise<PullReviewData[]> {
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
pr: PullRequestInfo
|
|
||||||
): Promise<PullReviewData[]> {
|
|
||||||
const options = this.octokit.pulls.listReviews.endpoint.merge({
|
const options = this.octokit.pulls.listReviews.endpoint.merge({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
@@ -164,10 +148,7 @@ function sortPrs(pullRequests: PullRequestInfo[]): PullRequestInfo[] {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sortPullRequests(
|
export function sortPullRequests(pullRequests: PullRequestInfo[], sort: Sort | string): PullRequestInfo[] {
|
||||||
pullRequests: PullRequestInfo[],
|
|
||||||
sort: Sort | string
|
|
||||||
): PullRequestInfo[] {
|
|
||||||
let sortConfig: Sort
|
let sortConfig: Sort
|
||||||
|
|
||||||
// legacy handling to support string sort config
|
// legacy handling to support string sort config
|
||||||
@@ -191,11 +172,7 @@ export function sortPullRequests(
|
|||||||
return pullRequests
|
return pullRequests
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compare(
|
export function compare(a: PullRequestInfo, b: PullRequestInfo, sort: Sort): number {
|
||||||
a: PullRequestInfo,
|
|
||||||
b: PullRequestInfo,
|
|
||||||
sort: Sort
|
|
||||||
): number {
|
|
||||||
if (sort.on_property === 'mergedAt') {
|
if (sort.on_property === 'mergedAt') {
|
||||||
const aa = a.mergedAt || a.createdAt
|
const aa = a.mergedAt || a.createdAt
|
||||||
const bb = b.mergedAt || b.createdAt
|
const bb = b.mergedAt || b.createdAt
|
||||||
@@ -212,10 +189,7 @@ export function compare(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// helper function to add a special open label to prs not merged.
|
// helper function to add a special open label to prs not merged.
|
||||||
function attachSpeciaLabels(
|
function attachSpeciaLabels(status: 'open' | 'merged', labels: Set<string>): Set<string> {
|
||||||
status: 'open' | 'merged',
|
|
||||||
labels: Set<string>
|
|
||||||
): Set<string> {
|
|
||||||
labels.add(`--rcba-${status}`)
|
labels.add(`--rcba-${status}`)
|
||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
@@ -234,17 +208,11 @@ const mapPullRequest = (
|
|||||||
mergeCommitSha: pr.merge_commit_sha || '',
|
mergeCommitSha: pr.merge_commit_sha || '',
|
||||||
author: pr.user?.login || '',
|
author: pr.user?.login || '',
|
||||||
repoName: pr.base.repo.full_name,
|
repoName: pr.base.repo.full_name,
|
||||||
labels: attachSpeciaLabels(
|
labels: attachSpeciaLabels(status, new Set(pr.labels?.map(lbl => lbl.name?.toLocaleLowerCase('en') || '') || [])),
|
||||||
status,
|
|
||||||
new Set(
|
|
||||||
pr.labels?.map(lbl => lbl.name?.toLocaleLowerCase('en') || '') || []
|
|
||||||
)
|
|
||||||
),
|
|
||||||
milestone: pr.milestone?.title || '',
|
milestone: pr.milestone?.title || '',
|
||||||
body: pr.body || '',
|
body: pr.body || '',
|
||||||
assignees: pr.assignees?.map(asignee => asignee?.login || '') || [],
|
assignees: pr.assignees?.map(asignee => asignee?.login || '') || [],
|
||||||
requestedReviewers:
|
requestedReviewers: pr.requested_reviewers?.map(reviewer => reviewer?.login || '') || [],
|
||||||
pr.requested_reviewers?.map(reviewer => reviewer?.login || '') || [],
|
|
||||||
approvedReviewers: [],
|
approvedReviewers: [],
|
||||||
status
|
status
|
||||||
})
|
})
|
||||||
|
|||||||
+19
-54
@@ -62,54 +62,39 @@ export class ReleaseNotes {
|
|||||||
if (mergedPullRequests.length === 0) {
|
if (mergedPullRequests.length === 0) {
|
||||||
core.warning(`⚠️ No pull requests found`)
|
core.warning(`⚠️ No pull requests found`)
|
||||||
return fillAdditionalPlaceholders(
|
return fillAdditionalPlaceholders(
|
||||||
this.options.configuration.empty_template ||
|
this.options.configuration.empty_template || DefaultConfiguration.empty_template,
|
||||||
DefaultConfiguration.empty_template,
|
|
||||||
this.options
|
this.options
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
core.startGroup('📦 Build changelog')
|
core.startGroup('📦 Build changelog')
|
||||||
const resultChangelog = buildChangelog(
|
const resultChangelog = buildChangelog(diffInfo, mergedPullRequests, this.options)
|
||||||
diffInfo,
|
|
||||||
mergedPullRequests,
|
|
||||||
this.options
|
|
||||||
)
|
|
||||||
core.endGroup()
|
core.endGroup()
|
||||||
return resultChangelog
|
return resultChangelog
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getCommitHistory(octokit: Octokit): Promise<DiffInfo> {
|
private async getCommitHistory(octokit: Octokit): Promise<DiffInfo> {
|
||||||
const {owner, repo, fromTag, toTag, failOnError} = this.options
|
const {owner, repo, fromTag, toTag, failOnError} = this.options
|
||||||
core.info(
|
core.info(`ℹ️ Comparing ${owner}/${repo} - '${fromTag.name}...${toTag.name}'`)
|
||||||
`ℹ️ Comparing ${owner}/${repo} - '${fromTag.name}...${toTag.name}'`
|
|
||||||
)
|
|
||||||
|
|
||||||
const commitsApi = new Commits(octokit)
|
const commitsApi = new Commits(octokit)
|
||||||
let diffInfo: DiffInfo
|
let diffInfo: DiffInfo
|
||||||
try {
|
try {
|
||||||
diffInfo = await commitsApi.getDiff(owner, repo, fromTag.name, toTag.name)
|
diffInfo = await commitsApi.getDiff(owner, repo, fromTag.name, toTag.name)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
failOrError(
|
failOrError(`💥 Failed to retrieve - Invalid tag? - Because of: ${error}`, failOnError)
|
||||||
`💥 Failed to retrieve - Invalid tag? - Because of: ${error}`,
|
|
||||||
failOnError
|
|
||||||
)
|
|
||||||
return DefaultDiffInfo
|
return DefaultDiffInfo
|
||||||
}
|
}
|
||||||
if (diffInfo.commitInfo.length === 0) {
|
if (diffInfo.commitInfo.length === 0) {
|
||||||
core.warning(
|
core.warning(`⚠️ No commits found between - ${fromTag.name}...${toTag.name}`)
|
||||||
`⚠️ No commits found between - ${fromTag.name}...${toTag.name}`
|
|
||||||
)
|
|
||||||
return DefaultDiffInfo
|
return DefaultDiffInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
return diffInfo
|
return diffInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getMergedPullRequests(
|
private async getMergedPullRequests(octokit: Octokit): Promise<[DiffInfo, PullRequestInfo[]]> {
|
||||||
octokit: Octokit
|
const {owner, repo, includeOpen, fetchReviewers, configuration} = this.options
|
||||||
): Promise<[DiffInfo, PullRequestInfo[]]> {
|
|
||||||
const {owner, repo, includeOpen, fetchReviewers, configuration} =
|
|
||||||
this.options
|
|
||||||
|
|
||||||
const diffInfo = await this.getCommitHistory(octokit)
|
const diffInfo = await this.getCommitHistory(octokit)
|
||||||
const commits = diffInfo.commitInfo
|
const commits = diffInfo.commitInfo
|
||||||
@@ -122,18 +107,14 @@ export class ReleaseNotes {
|
|||||||
let fromDate = firstCommit.date
|
let fromDate = firstCommit.date
|
||||||
const toDate = lastCommit.date
|
const toDate = lastCommit.date
|
||||||
|
|
||||||
const maxDays =
|
const maxDays = configuration.max_back_track_time_days || DefaultConfiguration.max_back_track_time_days
|
||||||
configuration.max_back_track_time_days ||
|
|
||||||
DefaultConfiguration.max_back_track_time_days
|
|
||||||
const maxFromDate = toDate.clone().subtract(maxDays, 'days')
|
const maxFromDate = toDate.clone().subtract(maxDays, 'days')
|
||||||
if (maxFromDate.isAfter(fromDate)) {
|
if (maxFromDate.isAfter(fromDate)) {
|
||||||
core.info(`⚠️ Adjusted 'fromDate' to go max ${maxDays} back`)
|
core.info(`⚠️ Adjusted 'fromDate' to go max ${maxDays} back`)
|
||||||
fromDate = maxFromDate
|
fromDate = maxFromDate
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info(
|
core.info(`ℹ️ Fetching PRs between dates ${fromDate.toISOString()} to ${toDate.toISOString()} for ${owner}/${repo}`)
|
||||||
`ℹ️ Fetching PRs between dates ${fromDate.toISOString()} to ${toDate.toISOString()} for ${owner}/${repo}`
|
|
||||||
)
|
|
||||||
|
|
||||||
const pullRequestsApi = new PullRequests(octokit)
|
const pullRequestsApi = new PullRequests(octokit)
|
||||||
const pullRequests = await pullRequestsApi.getBetweenDates(
|
const pullRequests = await pullRequestsApi.getBetweenDates(
|
||||||
@@ -144,19 +125,14 @@ export class ReleaseNotes {
|
|||||||
configuration.max_pull_requests || DefaultConfiguration.max_pull_requests
|
configuration.max_pull_requests || DefaultConfiguration.max_pull_requests
|
||||||
)
|
)
|
||||||
|
|
||||||
core.info(
|
core.info(`ℹ️ Retrieved ${pullRequests.length} merged PRs for ${owner}/${repo}`)
|
||||||
`ℹ️ Retrieved ${pullRequests.length} merged PRs for ${owner}/${repo}`
|
|
||||||
)
|
|
||||||
|
|
||||||
const prCommits = filterCommits(
|
const prCommits = filterCommits(
|
||||||
commits,
|
commits,
|
||||||
configuration.exclude_merge_branches ||
|
configuration.exclude_merge_branches || DefaultConfiguration.exclude_merge_branches
|
||||||
DefaultConfiguration.exclude_merge_branches
|
|
||||||
)
|
)
|
||||||
|
|
||||||
core.info(
|
core.info(`ℹ️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`)
|
||||||
`ℹ️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`
|
|
||||||
)
|
|
||||||
|
|
||||||
// create array of commits for this release
|
// create array of commits for this release
|
||||||
const releaseCommitHashes = prCommits.map(commmit => {
|
const releaseCommitHashes = prCommits.map(commmit => {
|
||||||
@@ -174,25 +150,19 @@ export class ReleaseNotes {
|
|||||||
const openPullRequests = await pullRequestsApi.getOpen(
|
const openPullRequests = await pullRequestsApi.getOpen(
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
configuration.max_pull_requests ||
|
configuration.max_pull_requests || DefaultConfiguration.max_pull_requests
|
||||||
DefaultConfiguration.max_pull_requests
|
|
||||||
)
|
)
|
||||||
|
|
||||||
core.info(
|
core.info(`ℹ️ Retrieved ${openPullRequests.length} open PRs for ${owner}/${repo}`)
|
||||||
`ℹ️ Retrieved ${openPullRequests.length} open PRs for ${owner}/${repo}`
|
|
||||||
)
|
|
||||||
|
|
||||||
// all pull requests
|
// all pull requests
|
||||||
allPullRequests = allPullRequests.concat(openPullRequests)
|
allPullRequests = allPullRequests.concat(openPullRequests)
|
||||||
|
|
||||||
core.info(
|
core.info(`ℹ️ Retrieved ${allPullRequests.length} total PRs for ${owner}/${repo}`)
|
||||||
`ℹ️ Retrieved ${allPullRequests.length} total PRs for ${owner}/${repo}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieve base branches we allow
|
// retrieve base branches we allow
|
||||||
const baseBranches =
|
const baseBranches = configuration.base_branches || DefaultConfiguration.base_branches
|
||||||
configuration.base_branches || DefaultConfiguration.base_branches
|
|
||||||
const baseBranchPatterns = baseBranches.map(baseBranch => {
|
const baseBranchPatterns = baseBranches.map(baseBranch => {
|
||||||
return new RegExp(baseBranch.replace('\\\\', '\\'), 'gu')
|
return new RegExp(baseBranch.replace('\\\\', '\\'), 'gu')
|
||||||
})
|
})
|
||||||
@@ -213,9 +183,7 @@ export class ReleaseNotes {
|
|||||||
for (const pr of finalPrs) {
|
for (const pr of finalPrs) {
|
||||||
await pullRequestsApi.getReviewers(owner, repo, pr)
|
await pullRequestsApi.getReviewers(owner, repo, pr)
|
||||||
if (pr.approvedReviewers.length > 0) {
|
if (pr.approvedReviewers.length > 0) {
|
||||||
core.info(
|
core.info(`ℹ️ Retrieved ${pr.approvedReviewers.length} reviewer(s) for PR ${owner}/${repo}/#${pr.number}`)
|
||||||
`ℹ️ Retrieved ${pr.approvedReviewers.length} reviewer(s) for PR ${owner}/${repo}/#${pr.number}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -225,9 +193,7 @@ export class ReleaseNotes {
|
|||||||
return [diffInfo, finalPrs]
|
return [diffInfo, finalPrs]
|
||||||
}
|
}
|
||||||
|
|
||||||
private async generateCommitPRs(
|
private async generateCommitPRs(octokit: Octokit): Promise<[DiffInfo, PullRequestInfo[]]> {
|
||||||
octokit: Octokit
|
|
||||||
): Promise<[DiffInfo, PullRequestInfo[]]> {
|
|
||||||
const {owner, repo, configuration} = this.options
|
const {owner, repo, configuration} = this.options
|
||||||
|
|
||||||
const diffInfo = await this.getCommitHistory(octokit)
|
const diffInfo = await this.getCommitHistory(octokit)
|
||||||
@@ -238,8 +204,7 @@ export class ReleaseNotes {
|
|||||||
|
|
||||||
const prCommits = filterCommits(
|
const prCommits = filterCommits(
|
||||||
commits,
|
commits,
|
||||||
configuration.exclude_merge_branches ||
|
configuration.exclude_merge_branches || DefaultConfiguration.exclude_merge_branches
|
||||||
DefaultConfiguration.exclude_merge_branches
|
|
||||||
)
|
)
|
||||||
|
|
||||||
core.info(`ℹ️ Retrieved ${prCommits.length} commits for ${owner}/${repo}`)
|
core.info(`ℹ️ Retrieved ${prCommits.length} commits for ${owner}/${repo}`)
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ export class ReleaseNotesBuilder {
|
|||||||
this.fromTag,
|
this.fromTag,
|
||||||
this.toTag,
|
this.toTag,
|
||||||
this.ignorePreReleases,
|
this.ignorePreReleases,
|
||||||
this.configuration.max_tags_to_fetch ||
|
this.configuration.max_tags_to_fetch || DefaultConfiguration.max_tags_to_fetch,
|
||||||
DefaultConfiguration.max_tags_to_fetch,
|
|
||||||
this.configuration.tag_resolver || DefaultConfiguration.tag_resolver
|
this.configuration.tag_resolver || DefaultConfiguration.tag_resolver
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -73,10 +72,7 @@ export class ReleaseNotesBuilder {
|
|||||||
|
|
||||||
let previousTag = tagRange.from
|
let previousTag = tagRange.from
|
||||||
if (previousTag == null) {
|
if (previousTag == null) {
|
||||||
failOrError(
|
failOrError(`💥 Unable to retrieve previous tag given ${this.toTag}`, this.failOnError)
|
||||||
`💥 Unable to retrieve previous tag given ${this.toTag}`,
|
|
||||||
this.failOnError
|
|
||||||
)
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
core.setOutput('fromTag', previousTag.name)
|
core.setOutput('fromTag', previousTag.name)
|
||||||
@@ -85,18 +81,8 @@ export class ReleaseNotesBuilder {
|
|||||||
if (this.fetchReleaseInformation) {
|
if (this.fetchReleaseInformation) {
|
||||||
// load release information from the GitHub API
|
// load release information from the GitHub API
|
||||||
core.info(`ℹ️ Fetching release information was enabled`)
|
core.info(`ℹ️ Fetching release information was enabled`)
|
||||||
thisTag = await tagsApi.fillTagInformation(
|
thisTag = await tagsApi.fillTagInformation(this.repositoryPath, this.owner, this.repo, thisTag)
|
||||||
this.repositoryPath,
|
previousTag = await tagsApi.fillTagInformation(this.repositoryPath, this.owner, this.repo, previousTag)
|
||||||
this.owner,
|
|
||||||
this.repo,
|
|
||||||
thisTag
|
|
||||||
)
|
|
||||||
previousTag = await tagsApi.fillTagInformation(
|
|
||||||
this.repositoryPath,
|
|
||||||
this.owner,
|
|
||||||
this.repo,
|
|
||||||
previousTag
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
core.debug(`ℹ️ Fetching release information was disabled`)
|
core.debug(`ℹ️ Fetching release information was disabled`)
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-70
@@ -26,11 +26,7 @@ export interface SortableTagInfo extends TagInfo {
|
|||||||
export class Tags {
|
export class Tags {
|
||||||
constructor(private octokit: Octokit) {}
|
constructor(private octokit: Octokit) {}
|
||||||
|
|
||||||
async getTags(
|
async getTags(owner: string, repo: string, maxTagsToFetch: number): Promise<TagInfo[]> {
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
maxTagsToFetch: number
|
|
||||||
): Promise<TagInfo[]> {
|
|
||||||
const tagsInfo: TagInfo[] = []
|
const tagsInfo: TagInfo[] = []
|
||||||
const options = this.octokit.repos.listTags.endpoint.merge({
|
const options = this.octokit.repos.listTags.endpoint.merge({
|
||||||
owner,
|
owner,
|
||||||
@@ -40,8 +36,7 @@ export class Tags {
|
|||||||
})
|
})
|
||||||
|
|
||||||
for await (const response of this.octokit.paginate.iterator(options)) {
|
for await (const response of this.octokit.paginate.iterator(options)) {
|
||||||
type TagsListData =
|
type TagsListData = RestEndpointMethodTypes['repos']['listTags']['response']['data']
|
||||||
RestEndpointMethodTypes['repos']['listTags']['response']['data']
|
|
||||||
const tags: TagsListData = response.data as TagsListData
|
const tags: TagsListData = response.data as TagsListData
|
||||||
|
|
||||||
for (const tag of tags) {
|
for (const tag of tags) {
|
||||||
@@ -63,12 +58,7 @@ export class Tags {
|
|||||||
return tagsInfo
|
return tagsInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
async fillTagInformation(
|
async fillTagInformation(repositoryPath: string, owner: string, repo: string, tagInfo: TagInfo): Promise<TagInfo> {
|
||||||
repositoryPath: string,
|
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
tagInfo: TagInfo
|
|
||||||
): Promise<TagInfo> {
|
|
||||||
const options = this.octokit.repos.getReleaseByTag.endpoint.merge({
|
const options = this.octokit.repos.getReleaseByTag.endpoint.merge({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
@@ -77,14 +67,11 @@ export class Tags {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.octokit.request(options)
|
const response = await this.octokit.request(options)
|
||||||
type ReleaseInformation =
|
type ReleaseInformation = RestEndpointMethodTypes['repos']['getReleaseByTag']['response']['data']
|
||||||
RestEndpointMethodTypes['repos']['getReleaseByTag']['response']['data']
|
|
||||||
|
|
||||||
const release: ReleaseInformation = response.data as ReleaseInformation
|
const release: ReleaseInformation = response.data as ReleaseInformation
|
||||||
tagInfo.date = moment(release.created_at)
|
tagInfo.date = moment(release.created_at)
|
||||||
core.info(
|
core.info(`ℹ️ Retrieved information about the release associated with ${tagInfo.name} from the GitHub API`)
|
||||||
`ℹ️ Retrieved information about the release associated with ${tagInfo.name} from the GitHub API`
|
|
||||||
)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.info(
|
core.info(
|
||||||
`⚠️ No release information found for ${tagInfo.name}, trying to retrieve tag creation time as fallback.`
|
`⚠️ No release information found for ${tagInfo.name}, trying to retrieve tag creation time as fallback.`
|
||||||
@@ -117,13 +104,9 @@ export class Tags {
|
|||||||
const length = tags.length
|
const length = tags.length
|
||||||
if (tags.length > 1) {
|
if (tags.length > 1) {
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
if (
|
if (tags[i].name.toLocaleLowerCase('en') === tag.toLocaleLowerCase('en')) {
|
||||||
tags[i].name.toLocaleLowerCase('en') === tag.toLocaleLowerCase('en')
|
|
||||||
) {
|
|
||||||
if (ignorePreReleases) {
|
if (ignorePreReleases) {
|
||||||
core.info(
|
core.info(`ℹ️ Enabled 'ignorePreReleases', searching for the closest release`)
|
||||||
`ℹ️ Enabled 'ignorePreReleases', searching for the closest release`
|
|
||||||
)
|
|
||||||
for (let ii = i + 1; ii < length; ii++) {
|
for (let ii = i + 1; ii < length; ii++) {
|
||||||
if (!tags[ii].name.includes('-')) {
|
if (!tags[ii].name.includes('-')) {
|
||||||
return tags[ii]
|
return tags[ii]
|
||||||
@@ -134,15 +117,11 @@ export class Tags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
core.info(
|
core.info(`ℹ️ Only one tag found for the given repository. Usually this is the case for the initial release.`)
|
||||||
`ℹ️ Only one tag found for the given repository. Usually this is the case for the initial release.`
|
|
||||||
)
|
|
||||||
// if not specified try to retrieve tag from git
|
// if not specified try to retrieve tag from git
|
||||||
const gitHelper = await createCommandManager(repositoryPath)
|
const gitHelper = await createCommandManager(repositoryPath)
|
||||||
const initialCommit = await gitHelper.initialCommit()
|
const initialCommit = await gitHelper.initialCommit()
|
||||||
core.info(
|
core.info(`🔖 Resolved initial commit (${initialCommit}) from 'git rev-list --max-parents=0 HEAD'`)
|
||||||
`🔖 Resolved initial commit (${initialCommit}) from 'git rev-list --max-parents=0 HEAD'`
|
|
||||||
)
|
|
||||||
return {name: initialCommit, commit: initialCommit}
|
return {name: initialCommit, commit: initialCommit}
|
||||||
}
|
}
|
||||||
return tags[0]
|
return tags[0]
|
||||||
@@ -203,25 +182,19 @@ export class Tags {
|
|||||||
// if not specified try to retrieve tag from github.context.ref
|
// if not specified try to retrieve tag from github.context.ref
|
||||||
if (github.context.ref?.startsWith('refs/tags/') === true) {
|
if (github.context.ref?.startsWith('refs/tags/') === true) {
|
||||||
toTag = github.context.ref.replace('refs/tags/', '')
|
toTag = github.context.ref.replace('refs/tags/', '')
|
||||||
core.info(
|
core.info(`🔖 Resolved current tag (${toTag}) from the 'github.context.ref'`)
|
||||||
`🔖 Resolved current tag (${toTag}) from the 'github.context.ref'`
|
|
||||||
)
|
|
||||||
resultToTag = {
|
resultToTag = {
|
||||||
name: toTag,
|
name: toTag,
|
||||||
commit: toTag
|
commit: toTag
|
||||||
}
|
}
|
||||||
} else if (tags.length > 1) {
|
} else if (tags.length > 1) {
|
||||||
resultToTag = tags[0]
|
resultToTag = tags[0]
|
||||||
core.info(
|
core.info(`🔖 Resolved current tag (${resultToTag.name}) from the tags git API`)
|
||||||
`🔖 Resolved current tag (${resultToTag.name}) from the tags git API`
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
// if not specified try to retrieve tag from git
|
// if not specified try to retrieve tag from git
|
||||||
const gitHelper = await createCommandManager(repositoryPath)
|
const gitHelper = await createCommandManager(repositoryPath)
|
||||||
const latestTag = await gitHelper.latestTag()
|
const latestTag = await gitHelper.latestTag()
|
||||||
core.info(
|
core.info(`🔖 Resolved current tag (${latestTag}) from 'git rev-list --tags --skip=0 --max-count=1'`)
|
||||||
`🔖 Resolved current tag (${latestTag}) from 'git rev-list --tags --skip=0 --max-count=1'`
|
|
||||||
)
|
|
||||||
resultToTag = {
|
resultToTag = {
|
||||||
name: latestTag,
|
name: latestTag,
|
||||||
commit: latestTag
|
commit: latestTag
|
||||||
@@ -241,17 +214,10 @@ export class Tags {
|
|||||||
if (!fromTag) {
|
if (!fromTag) {
|
||||||
core.debug(`fromTag undefined, trying to resolve via API`)
|
core.debug(`fromTag undefined, trying to resolve via API`)
|
||||||
|
|
||||||
resultFromTag = await this.findPredecessorTag(
|
resultFromTag = await this.findPredecessorTag(tags, repositoryPath, toTag, ignorePreReleases)
|
||||||
tags,
|
|
||||||
repositoryPath,
|
|
||||||
toTag,
|
|
||||||
ignorePreReleases
|
|
||||||
)
|
|
||||||
|
|
||||||
if (resultFromTag != null) {
|
if (resultFromTag != null) {
|
||||||
core.info(
|
core.info(`🔖 Resolved previous tag (${resultFromTag.name}) from the tags git API`)
|
||||||
`🔖 Resolved previous tag (${resultFromTag.name}) from the tags git API`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resultFromTag = {
|
resultFromTag = {
|
||||||
@@ -271,20 +237,12 @@ export class Tags {
|
|||||||
* Uses the provided filter (if available) to filter out any tags not currently relevant.
|
* Uses the provided filter (if available) to filter out any tags not currently relevant.
|
||||||
* https://github.com/mikepenz/release-changelog-builder-action/issues/566
|
* https://github.com/mikepenz/release-changelog-builder-action/issues/566
|
||||||
*/
|
*/
|
||||||
export function filterTags(
|
export function filterTags(tags: TagInfo[], tagResolver: TagResolver): TagInfo[] {
|
||||||
tags: TagInfo[],
|
|
||||||
tagResolver: TagResolver
|
|
||||||
): TagInfo[] {
|
|
||||||
const filter = tagResolver.filter
|
const filter = tagResolver.filter
|
||||||
if (filter !== undefined) {
|
if (filter !== undefined) {
|
||||||
const regex = new RegExp(
|
const regex = new RegExp(filter.pattern.replace('\\\\', '\\'), filter.flags ?? 'gu')
|
||||||
filter.pattern.replace('\\\\', '\\'),
|
|
||||||
filter.flags ?? 'gu'
|
|
||||||
)
|
|
||||||
const filteredTags = tags.filter(tag => tag.name.match(regex) !== null)
|
const filteredTags = tags.filter(tag => tag.name.match(regex) !== null)
|
||||||
core.debug(
|
core.debug(`ℹ️ Filtered tags count: ${filteredTags.length}, original count: ${tags.length}`)
|
||||||
`ℹ️ Filtered tags count: ${filteredTags.length}, original count: ${tags.length}`
|
|
||||||
)
|
|
||||||
return filteredTags
|
return filteredTags
|
||||||
} else {
|
} else {
|
||||||
return tags
|
return tags
|
||||||
@@ -294,16 +252,10 @@ export function filterTags(
|
|||||||
/**
|
/**
|
||||||
* Helper function to transform the tag name given the transformer
|
* Helper function to transform the tag name given the transformer
|
||||||
*/
|
*/
|
||||||
function transformTags(
|
function transformTags(tags: TagInfo[], transformer: RegexTransformer): TagInfo[] {
|
||||||
tags: TagInfo[],
|
|
||||||
transformer: RegexTransformer
|
|
||||||
): TagInfo[] {
|
|
||||||
return tags.map(function (tag) {
|
return tags.map(function (tag) {
|
||||||
if (transformer.pattern) {
|
if (transformer.pattern) {
|
||||||
const transformedName = tag.name.replace(
|
const transformedName = tag.name.replace(transformer.pattern, transformer.target)
|
||||||
transformer.pattern,
|
|
||||||
transformer.target
|
|
||||||
)
|
|
||||||
core.debug(`ℹ️ Transformed ${tag.name} to ${transformedName}`)
|
core.debug(`ℹ️ Transformed ${tag.name} to ${transformedName}`)
|
||||||
return {
|
return {
|
||||||
tmp: tag.name, // remember the original name
|
tmp: tag.name, // remember the original name
|
||||||
@@ -347,9 +299,7 @@ function semVerSorting(tags: TagInfo[]): TagInfo[] {
|
|||||||
loose: true
|
loose: true
|
||||||
}) !== null
|
}) !== null
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
core.debug(
|
core.debug(`⚠️ dropped tag ${tag.name} because it is not a valid semver tag`)
|
||||||
`⚠️ dropped tag ${tag.name} because it is not a valid semver tag`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return isValid
|
return isValid
|
||||||
})
|
})
|
||||||
|
|||||||
+40
-159
@@ -1,19 +1,10 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {
|
import {Category, DefaultConfiguration, Extractor, Transformer} from './configuration'
|
||||||
Category,
|
|
||||||
DefaultConfiguration,
|
|
||||||
Extractor,
|
|
||||||
Transformer
|
|
||||||
} from './configuration'
|
|
||||||
import {PullRequestInfo, sortPullRequests} from './pullRequests'
|
import {PullRequestInfo, sortPullRequests} from './pullRequests'
|
||||||
import {ReleaseNotesOptions} from './releaseNotes'
|
import {ReleaseNotesOptions} from './releaseNotes'
|
||||||
import {DiffInfo} from './commits'
|
import {DiffInfo} from './commits'
|
||||||
|
|
||||||
export function buildChangelog(
|
export function buildChangelog(diffInfo: DiffInfo, prs: PullRequestInfo[], options: ReleaseNotesOptions): string {
|
||||||
diffInfo: DiffInfo,
|
|
||||||
prs: PullRequestInfo[],
|
|
||||||
options: ReleaseNotesOptions
|
|
||||||
): string {
|
|
||||||
// sort to target order
|
// sort to target order
|
||||||
const config = options.configuration
|
const config = options.configuration
|
||||||
const sort = config.sort || DefaultConfiguration.sort
|
const sort = config.sort || DefaultConfiguration.sort
|
||||||
@@ -33,18 +24,14 @@ export function buildChangelog(
|
|||||||
if (extracted !== null && extracted.length > 0) {
|
if (extracted !== null && extracted.length > 0) {
|
||||||
deduplicatedMap.set(extracted[0], pr)
|
deduplicatedMap.set(extracted[0], pr)
|
||||||
} else {
|
} else {
|
||||||
core.info(
|
core.info(` PR (${pr.number}) did not resolve an ID using the \`duplicate_filter\``)
|
||||||
` PR (${pr.number}) did not resolve an ID using the \`duplicate_filter\``
|
|
||||||
)
|
|
||||||
unmatched.push(pr)
|
unmatched.push(pr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const deduplicatedPRs = Array.from(deduplicatedMap.values())
|
const deduplicatedPRs = Array.from(deduplicatedMap.values())
|
||||||
deduplicatedPRs.push(...unmatched) // add all unmatched PRs to map
|
deduplicatedPRs.push(...unmatched) // add all unmatched PRs to map
|
||||||
const removedElements = prs.length - deduplicatedPRs.length
|
const removedElements = prs.length - deduplicatedPRs.length
|
||||||
core.info(
|
core.info(`ℹ️ Removed ${removedElements} pull requests during deduplication`)
|
||||||
`ℹ️ Removed ${removedElements} pull requests during deduplication`
|
|
||||||
)
|
|
||||||
prs = sortPullRequests(deduplicatedPRs, sort) // resort deduplicatedPRs
|
prs = sortPullRequests(deduplicatedPRs, sort) // resort deduplicatedPRs
|
||||||
} else {
|
} else {
|
||||||
core.warning(`⚠️ Configured \`duplicate_filter\` invalid.`)
|
core.warning(`⚠️ Configured \`duplicate_filter\` invalid.`)
|
||||||
@@ -70,25 +57,16 @@ export function buildChangelog(
|
|||||||
for (const pr of prs) {
|
for (const pr of prs) {
|
||||||
transformedMap.set(
|
transformedMap.set(
|
||||||
pr,
|
pr,
|
||||||
transform(
|
transform(fillTemplate(pr, config.pr_template || DefaultConfiguration.pr_template), validatedTransformers)
|
||||||
fillTemplate(
|
|
||||||
pr,
|
|
||||||
config.pr_template || DefaultConfiguration.pr_template
|
|
||||||
),
|
|
||||||
validatedTransformers
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
core.info(
|
core.info(`ℹ️ Used ${validatedTransformers.length} transformers to adjust message`)
|
||||||
`ℹ️ Used ${validatedTransformers.length} transformers to adjust message`
|
|
||||||
)
|
|
||||||
core.info(`✒️ Wrote messages for ${prs.length} pull requests`)
|
core.info(`✒️ Wrote messages for ${prs.length} pull requests`)
|
||||||
|
|
||||||
// bring PRs into the order of categories
|
// bring PRs into the order of categories
|
||||||
const categorized = new Map<Category, string[]>()
|
const categorized = new Map<Category, string[]>()
|
||||||
const categories = config.categories || DefaultConfiguration.categories
|
const categories = config.categories || DefaultConfiguration.categories
|
||||||
const ignoredLabels =
|
const ignoredLabels = config.ignore_labels || DefaultConfiguration.ignore_labels
|
||||||
config.ignore_labels || DefaultConfiguration.ignore_labels
|
|
||||||
|
|
||||||
for (const category of categories) {
|
for (const category of categories) {
|
||||||
categorized.set(category, [])
|
categorized.set(category, [])
|
||||||
@@ -203,9 +181,7 @@ export function buildChangelog(
|
|||||||
for (const pr of uncategorizedPrs) {
|
for (const pr of uncategorizedPrs) {
|
||||||
changelogUncategorized = `${changelogUncategorized + pr}\n`
|
changelogUncategorized = `${changelogUncategorized + pr}\n`
|
||||||
}
|
}
|
||||||
core.info(
|
core.info(`✒️ Wrote ${uncategorizedPrs.length} non categorized pull requests down`)
|
||||||
`✒️ Wrote ${uncategorizedPrs.length} non categorized pull requests down`
|
|
||||||
)
|
|
||||||
if (core.isDebug()) {
|
if (core.isDebug()) {
|
||||||
for (const pr of uncategorizedPrs) {
|
for (const pr of uncategorizedPrs) {
|
||||||
core.debug(` ${pr}`)
|
core.debug(` ${pr}`)
|
||||||
@@ -240,95 +216,41 @@ export function buildChangelog(
|
|||||||
|
|
||||||
// fill template
|
// fill template
|
||||||
let transformedChangelog = config.template || DefaultConfiguration.template
|
let transformedChangelog = config.template || DefaultConfiguration.template
|
||||||
transformedChangelog = transformedChangelog.replace(
|
transformedChangelog = transformedChangelog.replace(/\${{CHANGELOG}}/g, changelog)
|
||||||
/\${{CHANGELOG}}/g,
|
transformedChangelog = transformedChangelog.replace(/\${{UNCATEGORIZED}}/g, changelogUncategorized)
|
||||||
changelog
|
transformedChangelog = transformedChangelog.replace(/\${{OPEN}}/g, changelogOpen)
|
||||||
)
|
transformedChangelog = transformedChangelog.replace(/\${{IGNORED}}/g, changelogIgnored)
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{UNCATEGORIZED}}/g,
|
|
||||||
changelogUncategorized
|
|
||||||
)
|
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{OPEN}}/g,
|
|
||||||
changelogOpen
|
|
||||||
)
|
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{IGNORED}}/g,
|
|
||||||
changelogIgnored
|
|
||||||
)
|
|
||||||
|
|
||||||
// fill other placeholders
|
// fill other placeholders
|
||||||
transformedChangelog = transformedChangelog.replace(
|
transformedChangelog = transformedChangelog.replace(/\${{CATEGORIZED_COUNT}}/g, categorizedPrs.length.toString())
|
||||||
/\${{CATEGORIZED_COUNT}}/g,
|
transformedChangelog = transformedChangelog.replace(/\${{UNCATEGORIZED_COUNT}}/g, uncategorizedPrs.length.toString())
|
||||||
categorizedPrs.length.toString()
|
transformedChangelog = transformedChangelog.replace(/\${{OPEN_COUNT}}/g, openPrs.length.toString())
|
||||||
)
|
transformedChangelog = transformedChangelog.replace(/\${{IGNORED_COUNT}}/g, ignoredPrs.length.toString())
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{UNCATEGORIZED_COUNT}}/g,
|
|
||||||
uncategorizedPrs.length.toString()
|
|
||||||
)
|
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{OPEN_COUNT}}/g,
|
|
||||||
openPrs.length.toString()
|
|
||||||
)
|
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{IGNORED_COUNT}}/g,
|
|
||||||
ignoredPrs.length.toString()
|
|
||||||
)
|
|
||||||
// code change placeholders
|
// code change placeholders
|
||||||
transformedChangelog = transformedChangelog.replace(
|
transformedChangelog = transformedChangelog.replace(/\${{CHANGED_FILES}}/g, diffInfo.changedFiles.toString())
|
||||||
/\${{CHANGED_FILES}}/g,
|
transformedChangelog = transformedChangelog.replace(/\${{ADDITIONS}}/g, diffInfo.additions.toString())
|
||||||
diffInfo.changedFiles.toString()
|
transformedChangelog = transformedChangelog.replace(/\${{DELETIONS}}/g, diffInfo.deletions.toString())
|
||||||
)
|
transformedChangelog = transformedChangelog.replace(/\${{CHANGES}}/g, diffInfo.changes.toString())
|
||||||
transformedChangelog = transformedChangelog.replace(
|
transformedChangelog = transformedChangelog.replace(/\${{COMMITS}}/g, diffInfo.commits.toString())
|
||||||
/\${{ADDITIONS}}/g,
|
transformedChangelog = fillAdditionalPlaceholders(transformedChangelog, options)
|
||||||
diffInfo.additions.toString()
|
|
||||||
)
|
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{DELETIONS}}/g,
|
|
||||||
diffInfo.deletions.toString()
|
|
||||||
)
|
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{CHANGES}}/g,
|
|
||||||
diffInfo.changes.toString()
|
|
||||||
)
|
|
||||||
transformedChangelog = transformedChangelog.replace(
|
|
||||||
/\${{COMMITS}}/g,
|
|
||||||
diffInfo.commits.toString()
|
|
||||||
)
|
|
||||||
transformedChangelog = fillAdditionalPlaceholders(
|
|
||||||
transformedChangelog,
|
|
||||||
options
|
|
||||||
)
|
|
||||||
|
|
||||||
core.info(`ℹ️ Filled template`)
|
core.info(`ℹ️ Filled template`)
|
||||||
return transformedChangelog
|
return transformedChangelog
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fillAdditionalPlaceholders(
|
export function fillAdditionalPlaceholders(text: string, options: ReleaseNotesOptions): string {
|
||||||
text: string,
|
|
||||||
options: ReleaseNotesOptions
|
|
||||||
): string {
|
|
||||||
let transformed = text
|
let transformed = text
|
||||||
// repository placeholders
|
// repository placeholders
|
||||||
transformed = transformed.replace(/\${{OWNER}}/g, options.owner)
|
transformed = transformed.replace(/\${{OWNER}}/g, options.owner)
|
||||||
transformed = transformed.replace(/\${{REPO}}/g, options.repo)
|
transformed = transformed.replace(/\${{REPO}}/g, options.repo)
|
||||||
transformed = transformed.replace(/\${{FROM_TAG}}/g, options.fromTag.name)
|
transformed = transformed.replace(/\${{FROM_TAG}}/g, options.fromTag.name)
|
||||||
transformed = transformed.replace(
|
transformed = transformed.replace(/\${{FROM_TAG_DATE}}/g, options.fromTag.date?.toISOString() || '')
|
||||||
/\${{FROM_TAG_DATE}}/g,
|
|
||||||
options.fromTag.date?.toISOString() || ''
|
|
||||||
)
|
|
||||||
transformed = transformed.replace(/\${{TO_TAG}}/g, options.toTag.name)
|
transformed = transformed.replace(/\${{TO_TAG}}/g, options.toTag.name)
|
||||||
transformed = transformed.replace(
|
transformed = transformed.replace(/\${{TO_TAG_DATE}}/g, options.toTag.date?.toISOString() || '')
|
||||||
/\${{TO_TAG_DATE}}/g,
|
|
||||||
options.toTag.date?.toISOString() || ''
|
|
||||||
)
|
|
||||||
const fromDate = options.fromTag.date
|
const fromDate = options.fromTag.date
|
||||||
const toDate = options.toTag.date
|
const toDate = options.toTag.date
|
||||||
if (fromDate !== undefined && toDate !== undefined) {
|
if (fromDate !== undefined && toDate !== undefined) {
|
||||||
transformed = transformed.replace(
|
transformed = transformed.replace(/\${{DAYS_SINCE}}/g, toDate.diff(fromDate, 'days').toString() || '')
|
||||||
/\${{DAYS_SINCE}}/g,
|
|
||||||
toDate.diff(fromDate, 'days').toString() || ''
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
transformed = transformed.replace(/\${{DAYS_SINCE}}/g, '')
|
transformed = transformed.replace(/\${{DAYS_SINCE}}/g, '')
|
||||||
}
|
}
|
||||||
@@ -353,14 +275,8 @@ function fillTemplate(pr: PullRequestInfo, template: string): string {
|
|||||||
transformed = transformed.replace(/\${{TITLE}}/g, pr.title)
|
transformed = transformed.replace(/\${{TITLE}}/g, pr.title)
|
||||||
transformed = transformed.replace(/\${{URL}}/g, pr.htmlURL)
|
transformed = transformed.replace(/\${{URL}}/g, pr.htmlURL)
|
||||||
transformed = transformed.replace(/\${{STATUS}}/g, pr.status)
|
transformed = transformed.replace(/\${{STATUS}}/g, pr.status)
|
||||||
transformed = transformed.replace(
|
transformed = transformed.replace(/\${{CREATED_AT}}/g, pr.createdAt.toISOString())
|
||||||
/\${{CREATED_AT}}/g,
|
transformed = transformed.replace(/\${{MERGED_AT}}/g, pr.mergedAt?.toISOString() || '')
|
||||||
pr.createdAt.toISOString()
|
|
||||||
)
|
|
||||||
transformed = transformed.replace(
|
|
||||||
/\${{MERGED_AT}}/g,
|
|
||||||
pr.mergedAt?.toISOString() || ''
|
|
||||||
)
|
|
||||||
transformed = transformed.replace(/\${{MERGE_SHA}}/g, pr.mergeCommitSha)
|
transformed = transformed.replace(/\${{MERGE_SHA}}/g, pr.mergeCommitSha)
|
||||||
transformed = transformed.replace(/\${{AUTHOR}}/g, pr.author)
|
transformed = transformed.replace(/\${{AUTHOR}}/g, pr.author)
|
||||||
transformed = transformed.replace(
|
transformed = transformed.replace(
|
||||||
@@ -369,18 +285,9 @@ function fillTemplate(pr: PullRequestInfo, template: string): string {
|
|||||||
)
|
)
|
||||||
transformed = transformed.replace(/\${{MILESTONE}}/g, pr.milestone || '')
|
transformed = transformed.replace(/\${{MILESTONE}}/g, pr.milestone || '')
|
||||||
transformed = transformed.replace(/\${{BODY}}/g, pr.body)
|
transformed = transformed.replace(/\${{BODY}}/g, pr.body)
|
||||||
transformed = transformed.replace(
|
transformed = transformed.replace(/\${{ASSIGNEES}}/g, pr.assignees?.join(', ') || '')
|
||||||
/\${{ASSIGNEES}}/g,
|
transformed = transformed.replace(/\${{REVIEWERS}}/g, pr.requestedReviewers?.join(', ') || '')
|
||||||
pr.assignees?.join(', ') || ''
|
transformed = transformed.replace(/\${{APPROVERS}}/g, pr.approvedReviewers?.join(', ') || '')
|
||||||
)
|
|
||||||
transformed = transformed.replace(
|
|
||||||
/\${{REVIEWERS}}/g,
|
|
||||||
pr.requestedReviewers?.join(', ') || ''
|
|
||||||
)
|
|
||||||
transformed = transformed.replace(
|
|
||||||
/\${{APPROVERS}}/g,
|
|
||||||
pr.approvedReviewers?.join(', ') || ''
|
|
||||||
)
|
|
||||||
return transformed
|
return transformed
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,11 +304,8 @@ function transform(filled: string, transformers: RegexTransformer[]): string {
|
|||||||
return transformed
|
return transformed
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateTransformers(
|
function validateTransformers(specifiedTransformers: Transformer[]): RegexTransformer[] {
|
||||||
specifiedTransformers: Transformer[]
|
const transformers = specifiedTransformers || DefaultConfiguration.transformers
|
||||||
): RegexTransformer[] {
|
|
||||||
const transformers =
|
|
||||||
specifiedTransformers || DefaultConfiguration.transformers
|
|
||||||
return transformers
|
return transformers
|
||||||
.map(transformer => {
|
.map(transformer => {
|
||||||
return validateTransformer(transformer)
|
return validateTransformer(transformer)
|
||||||
@@ -412,9 +316,7 @@ function validateTransformers(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateTransformer(
|
export function validateTransformer(transformer?: Transformer): RegexTransformer | null {
|
||||||
transformer?: Transformer
|
|
||||||
): RegexTransformer | null {
|
|
||||||
if (transformer === undefined) {
|
if (transformer === undefined) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -436,10 +338,7 @@ export function validateTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pattern: new RegExp(
|
pattern: new RegExp(transformer.pattern.replace('\\\\', '\\'), transformer.flags ?? 'gu'),
|
||||||
transformer.pattern.replace('\\\\', '\\'),
|
|
||||||
transformer.flags ?? 'gu'
|
|
||||||
),
|
|
||||||
target: transformer.target || '',
|
target: transformer.target || '',
|
||||||
onProperty,
|
onProperty,
|
||||||
method,
|
method,
|
||||||
@@ -451,33 +350,20 @@ export function validateTransformer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractValues(
|
function extractValues(pr: PullRequestInfo, extractor: RegexTransformer, extractor_usecase: string): string[] | null {
|
||||||
pr: PullRequestInfo,
|
|
||||||
extractor: RegexTransformer,
|
|
||||||
extractor_usecase: string
|
|
||||||
): string[] | null {
|
|
||||||
if (extractor.pattern == null) {
|
if (extractor.pattern == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extractor.onProperty !== undefined) {
|
if (extractor.onProperty !== undefined) {
|
||||||
let results: string[] = []
|
let results: string[] = []
|
||||||
const list: (
|
const list: ('title' | 'author' | 'milestone' | 'body' | 'status' | 'branch')[] = extractor.onProperty
|
||||||
| 'title'
|
|
||||||
| 'author'
|
|
||||||
| 'milestone'
|
|
||||||
| 'body'
|
|
||||||
| 'status'
|
|
||||||
| 'branch'
|
|
||||||
)[] = extractor.onProperty
|
|
||||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
||||||
for (let i = 0; i < list.length; i++) {
|
for (let i = 0; i < list.length; i++) {
|
||||||
const prop = list[i]
|
const prop = list[i]
|
||||||
let value: string | undefined = pr[prop]
|
let value: string | undefined = pr[prop]
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
core.warning(
|
core.warning(`⚠️ the provided property '${extractor.onProperty}' for \`${extractor_usecase}\` is not valid`)
|
||||||
`⚠️ the provided property '${extractor.onProperty}' for \`${extractor_usecase}\` is not valid`
|
|
||||||
)
|
|
||||||
value = pr['body']
|
value = pr['body']
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,10 +378,7 @@ function extractValues(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractValuesFromString(
|
function extractValuesFromString(value: string, extractor: RegexTransformer): string[] | null {
|
||||||
value: string,
|
|
||||||
extractor: RegexTransformer
|
|
||||||
): string[] | null {
|
|
||||||
if (extractor.pattern == null) {
|
if (extractor.pattern == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -520,9 +403,7 @@ function extractValuesFromString(
|
|||||||
export interface RegexTransformer {
|
export interface RegexTransformer {
|
||||||
pattern: RegExp | null
|
pattern: RegExp | null
|
||||||
target: string
|
target: string
|
||||||
onProperty?:
|
onProperty?: ('title' | 'author' | 'milestone' | 'body' | 'status' | 'branch')[] | undefined
|
||||||
| ('title' | 'author' | 'milestone' | 'body' | 'status' | 'branch')[]
|
|
||||||
| undefined
|
|
||||||
method?: 'replace' | 'match' | undefined
|
method?: 'replace' | 'match' | undefined
|
||||||
onEmpty?: string | undefined
|
onEmpty?: string | undefined
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-33
@@ -23,10 +23,7 @@ export function retrieveRepositoryPath(providedPath: string): string {
|
|||||||
/**
|
/**
|
||||||
* Will automatically either report the message to the log, or mark the action as failed. Additionally defining the output failed, allowing it to be read in by other actions
|
* Will automatically either report the message to the log, or mark the action as failed. Additionally defining the output failed, allowing it to be read in by other actions
|
||||||
*/
|
*/
|
||||||
export function failOrError(
|
export function failOrError(message: string | Error, failOnError: boolean): void {
|
||||||
message: string | Error,
|
|
||||||
failOnError: boolean
|
|
||||||
): void {
|
|
||||||
// if we report any failure, consider the action to have failed, may not make the build fail
|
// if we report any failure, consider the action to have failed, may not make the build fail
|
||||||
core.setOutput('failed', true)
|
core.setOutput('failed', true)
|
||||||
if (failOnError) {
|
if (failOnError) {
|
||||||
@@ -39,16 +36,10 @@ export function failOrError(
|
|||||||
/**
|
/**
|
||||||
* Retrieves the configuration given the file path, if not found it will fallback to the `DefaultConfiguration`
|
* Retrieves the configuration given the file path, if not found it will fallback to the `DefaultConfiguration`
|
||||||
*/
|
*/
|
||||||
export function resolveConfiguration(
|
export function resolveConfiguration(githubWorkspacePath: string, configurationFile: string): Configuration {
|
||||||
githubWorkspacePath: string,
|
|
||||||
configurationFile: string
|
|
||||||
): Configuration {
|
|
||||||
let configuration = DefaultConfiguration
|
let configuration = DefaultConfiguration
|
||||||
if (configurationFile) {
|
if (configurationFile) {
|
||||||
const configurationPath = path.resolve(
|
const configurationPath = path.resolve(githubWorkspacePath, configurationFile)
|
||||||
githubWorkspacePath,
|
|
||||||
configurationFile
|
|
||||||
)
|
|
||||||
core.debug(`configurationPath = '${configurationPath}'`)
|
core.debug(`configurationPath = '${configurationPath}'`)
|
||||||
const providedConfiguration = readConfiguration(configurationPath)
|
const providedConfiguration = readConfiguration(configurationPath)
|
||||||
if (providedConfiguration) {
|
if (providedConfiguration) {
|
||||||
@@ -76,9 +67,7 @@ function readConfiguration(filename: string): Configuration | undefined {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.debug(`Failed to load configuration due to: ${error}`)
|
core.debug(`Failed to load configuration due to: ${error}`)
|
||||||
}
|
}
|
||||||
core.info(
|
core.info(`⚠️ Configuration provided, but it couldn't be found. Fallback to Defaults.`)
|
||||||
`⚠️ Configuration provided, but it couldn't be found. Fallback to Defaults.`
|
|
||||||
)
|
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -87,14 +76,10 @@ function readConfiguration(filename: string): Configuration | undefined {
|
|||||||
export function parseConfiguration(config: string): Configuration | undefined {
|
export function parseConfiguration(config: string): Configuration | undefined {
|
||||||
try {
|
try {
|
||||||
// for compatiblity with the `yml` file we require to use `#{{}}` instead of `${{}}` - replace it here.
|
// for compatiblity with the `yml` file we require to use `#{{}}` instead of `${{}}` - replace it here.
|
||||||
const configurationJSON: Configuration = JSON.parse(
|
const configurationJSON: Configuration = JSON.parse(config.replace(/#{{/g, '${{'))
|
||||||
config.replace(/#{{/g, '${{')
|
|
||||||
)
|
|
||||||
return configurationJSON
|
return configurationJSON
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.info(
|
core.info(`⚠️ Configuration provided, but it couldn't be parsed. Fallback to Defaults.`)
|
||||||
`⚠️ Configuration provided, but it couldn't be parsed. Fallback to Defaults.`
|
|
||||||
)
|
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,10 +87,7 @@ export function parseConfiguration(config: string): Configuration | undefined {
|
|||||||
/**
|
/**
|
||||||
* Checks if a given directory exists
|
* Checks if a given directory exists
|
||||||
*/
|
*/
|
||||||
export function directoryExistsSync(
|
export function directoryExistsSync(inputPath: string, required?: boolean): boolean {
|
||||||
inputPath: string,
|
|
||||||
required?: boolean
|
|
||||||
): boolean {
|
|
||||||
if (!inputPath) {
|
if (!inputPath) {
|
||||||
throw new Error("Arg 'path' must not be empty")
|
throw new Error("Arg 'path' must not be empty")
|
||||||
}
|
}
|
||||||
@@ -122,9 +104,7 @@ export function directoryExistsSync(
|
|||||||
throw new Error(`Directory '${inputPath}' does not exist`)
|
throw new Error(`Directory '${inputPath}' does not exist`)
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(`Encountered an error when checking whether path '${inputPath}' exists: ${error.message}`)
|
||||||
`Encountered an error when checking whether path '${inputPath}' exists: ${error.message}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
@@ -139,11 +119,7 @@ export function directoryExistsSync(
|
|||||||
/**
|
/**
|
||||||
* Writes the changelog to the given the file
|
* Writes the changelog to the given the file
|
||||||
*/
|
*/
|
||||||
export function writeOutput(
|
export function writeOutput(githubWorkspacePath: string, outputFile: string, changelog: string | null): void {
|
||||||
githubWorkspacePath: string,
|
|
||||||
outputFile: string,
|
|
||||||
changelog: string | null
|
|
||||||
): void {
|
|
||||||
if (outputFile && changelog) {
|
if (outputFile && changelog) {
|
||||||
const outputPath = path.resolve(githubWorkspacePath, outputFile)
|
const outputPath = path.resolve(githubWorkspacePath, outputFile)
|
||||||
core.debug(`outputPath = '${outputPath}'`)
|
core.debug(`outputPath = '${outputPath}'`)
|
||||||
|
|||||||
Reference in New Issue
Block a user