From 3070fb0a7ccd1069b62747a6494456afc2c1e2af Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 09:27:20 +0200 Subject: [PATCH 01/15] - introduce test cases verifying ordering works --- __tests__/main.test.ts | 38 ++++++++++++++++++- .../configuration_all_placeholders.json | 0 configs_test/configuration_asc.json | 4 ++ configs_test/configuration_desc.json | 4 ++ 4 files changed, 45 insertions(+), 1 deletion(-) rename {configs => configs_test}/configuration_all_placeholders.json (100%) create mode 100644 configs_test/configuration_asc.json create mode 100644 configs_test/configuration_desc.json diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index d82074f..f44fd86 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -81,7 +81,7 @@ it('Should match generated changelog (unspecified fromTag)', async () => { it('Should match generated changelog (refs)', async () => { jest.setTimeout(180000) - const configuration = readConfiguration('configs/configuration_all_placeholders.json')!! + const configuration = readConfiguration('configs_test/configuration_all_placeholders.json')!! const releaseNotes = new ReleaseNotes({ owner: 'mikepenz', repo: 'release-changelog-builder-action', @@ -108,3 +108,39 @@ nhoelzl `) }) + +it('Should match ordered ASC', async () => { + jest.setTimeout(180000) + + const configuration = readConfiguration('configs_test/configuration_asc.json')!! + const releaseNotes = new ReleaseNotes({ + owner: 'mikepenz', + repo: 'release-changelog-builder-action', + fromTag: 'v0.3.0', + toTag: 'v0.5.0', + ignorePreReleases: false, + configuration: configuration + }) + + const changeLog = await releaseNotes.pull() + console.log(changeLog) + expect(changeLog).toStrictEqual(`## 🚀 Features\n\n22\n24\n25\n26\n28\n\n## 🐛 Fixes\n\n23\n\n`) +}) + +it('Should match ordered DESC', async () => { + jest.setTimeout(180000) + + const configuration = readConfiguration('configs_test/configuration_desc.json')!! + const releaseNotes = new ReleaseNotes({ + owner: 'mikepenz', + repo: 'release-changelog-builder-action', + fromTag: 'v0.3.0', + toTag: 'v0.5.0', + ignorePreReleases: false, + configuration: configuration + }) + + const changeLog = await releaseNotes.pull() + console.log(changeLog) + expect(changeLog).toStrictEqual(`## 🚀 Features\n\n28\n26\n25\n24\n22\n\n## 🐛 Fixes\n\n23\n\n`) +}) \ No newline at end of file diff --git a/configs/configuration_all_placeholders.json b/configs_test/configuration_all_placeholders.json similarity index 100% rename from configs/configuration_all_placeholders.json rename to configs_test/configuration_all_placeholders.json diff --git a/configs_test/configuration_asc.json b/configs_test/configuration_asc.json new file mode 100644 index 0000000..6e1fa39 --- /dev/null +++ b/configs_test/configuration_asc.json @@ -0,0 +1,4 @@ +{ + "sort": "ASC", + "pr_template": "${{NUMBER}}" +} \ No newline at end of file diff --git a/configs_test/configuration_desc.json b/configs_test/configuration_desc.json new file mode 100644 index 0000000..8d81997 --- /dev/null +++ b/configs_test/configuration_desc.json @@ -0,0 +1,4 @@ +{ + "sort": "DESC", + "pr_template": "${{NUMBER}}" +} \ No newline at end of file From 4a8c907e765e0ffe8d4278e31a87e35fa8d0eca3 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 09:39:18 +0200 Subject: [PATCH 02/15] - introduce new step, showcasing generation of changelog for an external configuration --- .github/workflows/ci.yml | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e7e3e55..4e714bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,10 +10,13 @@ jobs: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - run: | + - name: Checkout + uses: actions/checkout@v2 + - name: Install NPM + run: | npm install - - run: | + - name: Run NPM + run: | npm run all env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -22,10 +25,12 @@ jobs: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: + # the below actions use the local state of the action. please replace `./` with `mikepenz/release-changelog-builder-action@{latest-release}` + # Showcases how to use the action without a prior checkout # Won't support providing a configuration file, as no checkout was done - name: "Configuration without Checkout" id: without_checkout - uses: mikepenz/release-changelog-builder-action@develop + uses: ./ with: toTag: "v0.0.3" env: @@ -36,9 +41,8 @@ jobs: - name: Checkout uses: actions/checkout@v2 - with: - fetch-depth: 0 # Checkout full depth so tags can be discovered automatically if not specified + # Showcase the most minimal configuration possible - name: "Minimal Configuration" id: minimal_release uses: ./ @@ -48,6 +52,7 @@ jobs: - name: Echo Minimal Configuration Changelog run: echo "${{steps.minimal_release.outputs.changelog}}" + # Showcases a more complex configuration, providing a configuration, and specifically referencing owner, repo, from and to tag - name: "Complex Configuration" id: complex_release uses: ./ @@ -62,6 +67,21 @@ jobs: - name: Echo Complex Configuration Changelog run: echo "${{steps.complex_release.outputs.changelog}}" + # Showcases the capability to generate the changelog for an external repository provided + - name: "External Repo Configuration" + id: external_changelog + uses: ./ + with: + configuration: "configs/configuration_complex.json" + owner: "mikepenz" + repo: "MaterialDrawer" + fromTag: "v8.1.0" + toTag: "v8.1.6" + token: ${{ secrets.PERSONAL_TOKEN }} + + - name: Echo External Repo Configuration Changelog + run: echo "${{steps.external_changelog.outputs.changelog}}" + release: if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest From 13329e544c1784c5cd84a389136cf626ab2ff2ff Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 09:40:38 +0200 Subject: [PATCH 03/15] - can't use local action, as we didn't checkout :D --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e714bd..db68d94 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: # Won't support providing a configuration file, as no checkout was done - name: "Configuration without Checkout" id: without_checkout - uses: ./ + uses: mikepenz/release-changelog-builder-action@develop with: toTag: "v0.0.3" env: From 3f5c562f9202d4e82f5000662bab9371d2deb9bf Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 09:42:21 +0200 Subject: [PATCH 04/15] - return fetch depth to have capability to auto detect latest tag --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db68d94..c6d5cae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,8 @@ jobs: - name: Checkout uses: actions/checkout@v2 + with: + fetch-depth: 0 # Showcase the most minimal configuration possible - name: "Minimal Configuration" From ffce3af6792ca781e54f9543dd826a41f3074f84 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 10:04:10 +0200 Subject: [PATCH 05/15] - add support to prefer retrieving current `toTag` from `github.context.ref` if it starts with `refs/tags/` instead of git command --- src/main.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main.ts b/src/main.ts index 6968453..7716c1e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -48,11 +48,21 @@ async function run(): Promise { const ignorePreReleases = core.getInput('ignorePreReleases') if (!toTag) { - // if not specified try to retrieve tag from git - const gitHelper = await createCommandManager(repositoryPath) - const latestTag = await gitHelper.latestTag() - toTag = latestTag - core.debug(`toTag = '${latestTag}'`) + // if not specified try to retrieve tag from github.context.ref + if (github.context.ref.startsWith('refs/tags/')) { + toTag = github.context.ref.replace('refs/tags/', '') + core.info( + `🔖 Resolved current tag (${toTag}) from the 'github.context.ref'` + ) + } else { + // if not specified try to retrieve tag from git + const gitHelper = await createCommandManager(repositoryPath) + const latestTag = await gitHelper.latestTag() + toTag = latestTag + core.info( + `🔖 Resolved current tag (${toTag}) from 'git rev-list --tags --skip=0 --max-count=1'` + ) + } } if (!owner || !repo) { From ec2aabe545619f736fcb048520be9116937b0f81 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 10:22:47 +0200 Subject: [PATCH 06/15] - introduce more output values, and a more detailed description --- README.md | 13 +++++++++++-- src/main.ts | 3 +++ src/releaseNotes.ts | 7 +++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6e822b9..b391c45 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,6 @@ Specify the action as part of your GitHub actions workflow: ```yml - name: "Build Changelog" id: build_changelog - if: startsWith(github.ref, 'refs/tags/') uses: mikepenz/release-changelog-builder-action@{latest-release} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -61,13 +60,23 @@ By default the action will try to automatically retrieve the `tag` from the curr ### Action outputs -The action will succeed and return the `changelog` as a step output. Use it in any follow up step by referencing via its id. For example `build_changelog`. +After action execution it will return the `changelog` and additional information as step output. You can use it in any follow up step by referenceing the output by referencing it via the steps id. For example `build_changelog`. ```yml # ${{steps.{CHANGELOG_STEP_ID}.outputs.changelog}} ${{steps.build_changelog.outputs.changelog}} ``` +A full set list of possible output values for this action. + +| **Output** | **Description** | +|---------------------|-------------------------------------------------------------------------------------| +| `outputs.changelog` | The built release changelog built from the merged pull requests | +| `outputs.owner` | Specifies the owner of the repository processed | +| `outputs.repo` | Describes the repository name, which was processed | +| `outputs.fromTag` | Defines the `fromTag` which describes the lower bound to process pull requests for | +| `outputs.toTag` | Defines the `toTag` which describes the upper bound to process pull request for | + ## Customization đŸ–ī¸ ### Changelog Configuration diff --git a/src/main.ts b/src/main.ts index 7716c1e..88033e9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -89,6 +89,7 @@ async function run(): Promise { core.error(`đŸ’Ĩ Missing or couldn't resolve 'owner'`) return } else { + core.setOutput('owner', owner) core.debug(`Resolved 'owner' as ${owner}`) } @@ -96,6 +97,7 @@ async function run(): Promise { core.error(`đŸ’Ĩ Missing or couldn't resolve 'owner'`) return } else { + core.setOutput('repo', repo) core.debug(`Resolved 'repo' as ${repo}`) } @@ -103,6 +105,7 @@ async function run(): Promise { core.error(`đŸ’Ĩ Missing or couldn't resolve 'toTag'`) return } else { + core.setOutput('toTag', toTag) core.debug(`Resolved 'toTag' as ${toTag}`) } core.endGroup() diff --git a/src/releaseNotes.ts b/src/releaseNotes.ts index 003a21c..705978d 100755 --- a/src/releaseNotes.ts +++ b/src/releaseNotes.ts @@ -49,6 +49,13 @@ export class ReleaseNotes { core.endGroup() } + if (!this.options.fromTag) { + core.error(`đŸ’Ĩ Missing or couldn't resolve 'fromTag'`) + return configuration.empty_template ?? DefaultConfiguration.empty_template + } else { + core.setOutput('fromTag', this.options.fromTag) + } + core.startGroup(`🚀 Load pull requests`) const mergedPullRequests = await this.getMergedPullRequests(octokit) core.endGroup() From df528e71d1c5553879ac2a94ca771ba1575eaf6a Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 10:25:49 +0200 Subject: [PATCH 07/15] - simplify release build thanks to auto ref resolval --- .github/workflows/ci.yml | 6 ------ README.md | 7 ------- 2 files changed, 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6d5cae..16a52d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,17 +91,11 @@ jobs: - name: Checkout uses: actions/checkout@v2 - - name: Prepare Tag - if: startsWith(github.ref, 'refs/tags/') - id: tag_version - run: echo ::set-output name=VERSION::$(echo ${GITHUB_REF:10}) - - name: "Build Changelog" id: github_release uses: mikepenz/release-changelog-builder-action@main with: configuration: "configs/configuration_repo.json" - toTag: ${{ steps.tag_version.outputs.VERSION }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index b391c45..1a142fc 100644 --- a/README.md +++ b/README.md @@ -199,16 +199,9 @@ on: if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - - name: Retrieve tag - if: startsWith(github.ref, 'refs/tags/') - id: tag_version - run: echo ::set-output name=VERSION::$(echo ${GITHUB_REF:10}) - - name: Build Changelog id: github_release uses: mikepenz/release-changelog-builder-action@main - with: - toTag: ${{ steps.tag_version.outputs.VERSION }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 32d23197d5103f34c8e9f0c2aec223a383ed0dd0 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 10:35:37 +0200 Subject: [PATCH 08/15] - add better table to describe input configuration options --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a142fc..0ff4b92 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,18 @@ For advanced usecases additional settings can be provided to the action token: ${{ secrets.PAT }} ``` -💡 `ignorePreReleases` will be ignored, if `fromTag` is specified. `${{ secrets.GITHUB_TOKEN }}` only grants rights to the current repository, for other repos please use a PAT (Personal Access Token). +| **Input** | **Description** | +|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| configuration | Relative path, to the `configuration.json` file, providing additional configurations | +| owner | The owner of the repository to generate the changelog for | +| repo | Name of the repository we want to process | +| 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 | +| fromTag | Defines the 'start' from where the changelog will consider merged pull requests | +| toTag | Defines until which tag the changelog will consider merged pull requests | +| path | Allows to specify an alternative sub directory, to use as base | +| token | Alternative config to specify token. You should prefer `env.GITHUB_TOKEN` instead though | + +💡 `${{ secrets.GITHUB_TOKEN }}` only grants rights to the current repository, for other repos please use a PAT (Personal Access Token). ### PR Template placeholders From 3fd4677f8af771b636180f911670d0adb57582f7 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 11:06:02 +0200 Subject: [PATCH 09/15] - introduce new capability to enforce a build failure - introduce config to fail on error instead of just logging - simplify main logic, move functionality in other classes --- action.yml | 3 ++ src/main.ts | 92 +++++++++++++++++---------------------------- src/releaseNotes.ts | 42 +++++++++++++++------ src/utils.ts | 86 ++++++++++++++++++++++++++++++++++++++---- 4 files changed, 146 insertions(+), 77 deletions(-) diff --git a/action.yml b/action.yml index d875347..51c324e 100644 --- a/action.yml +++ b/action.yml @@ -20,6 +20,9 @@ inputs: ignorePreReleases: description: 'Defines if the action will only use full releases to compare against (Only used if fromTag is not defined). E.g. for 1.0.1... 1.0.0-rc02 <- ignore, 1.0.0 <- pick' default: "false" + failOnError: + description: 'Defines if the action should result in a build failure, if an error was discovered' + default: "false" token: description: 'Defines the token to use to execute the git API requests with, uses `env.GITHUB_TOKEN` by default' outputs: diff --git a/src/main.ts b/src/main.ts index 88033e9..7c3f514 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,52 +1,42 @@ import * as core from '@actions/core' -import {readConfiguration} from './utils' +import { + failOrError, + retrieveRepositoryPath, + resolveConfiguration +} from './utils' import {ReleaseNotes} from './releaseNotes' import {createCommandManager} from './gitHelper' import * as github from '@actions/github' -import * as path from 'path' import {DefaultConfiguration} from './configuration' async function run(): Promise { + core.setOutput('failed', false) // mark the action not failed by default + core.startGroup(`📘 Reading input values`) try { - let githubWorkspacePath = process.env['GITHUB_WORKSPACE'] - if (!githubWorkspacePath) { - throw new Error('GITHUB_WORKSPACE not defined') - } - githubWorkspacePath = path.resolve(githubWorkspacePath) - core.debug(`GITHUB_WORKSPACE = '${githubWorkspacePath}'`) - - let repositoryPath = core.getInput('path') || '.' - repositoryPath = path.resolve(githubWorkspacePath, repositoryPath) - core.debug(`repositoryPath = '${repositoryPath}'`) + // read in path specification, resolve github workspace, and repo path + const inputPath = core.getInput('path') + const repositoryPath = retrieveRepositoryPath(inputPath) + // read in configuration file if possible const configurationFile: string = core.getInput('configuration') - let configuration = DefaultConfiguration - if (configurationFile) { - const configurationPath = path.resolve( - githubWorkspacePath, - configurationFile - ) - core.debug(`configurationPath = '${configurationPath}'`) - const providedConfiguration = readConfiguration(configurationPath) - if (!providedConfiguration) { - core.info( - `âš ī¸ Configuration provided, but it couldn't be found, or failed to parse. Fallback to Defaults` - ) - } else { - configuration = providedConfiguration - } - } + const configuration = resolveConfiguration( + repositoryPath, + configurationFile + ) + // read in repository inputs const token = core.getInput('token') - let owner = core.getInput('owner') - let repo = core.getInput('repo') - + const owner = core.getInput('owner') ?? github.context.repo.owner + const repo = core.getInput('repo') ?? github.context.repo.repo + // read in from, to tag inputs const fromTag = core.getInput('fromTag') let toTag = core.getInput('toTag') + // read in flags + const ignorePreReleases = core.getInput('ignorePreReleases') === 'true' + const failOnError = core.getInput('failOnError') === 'true' - const ignorePreReleases = core.getInput('ignorePreReleases') - + // ensure to resolve the toTag if it was not provided if (!toTag) { // if not specified try to retrieve tag from github.context.ref if (github.context.ref.startsWith('refs/tags/')) { @@ -65,28 +55,8 @@ async function run(): Promise { } } - if (!owner || !repo) { - // Qualified repository - const qualifiedRepository = - core.getInput('repository') || - `${github.context.repo.owner}/${github.context.repo.repo}` - core.debug(`qualified repository = '${qualifiedRepository}'`) - const splitRepository = qualifiedRepository.split('/') - if ( - splitRepository.length !== 2 || - !splitRepository[0] || - !splitRepository[1] - ) { - throw new Error( - `Invalid repository '${qualifiedRepository}'. Expected format {owner}/{repo}.` - ) - } - owner = splitRepository[0] - repo = splitRepository[1] - } - if (!owner) { - core.error(`đŸ’Ĩ Missing or couldn't resolve 'owner'`) + failOrError(`đŸ’Ĩ Missing or couldn't resolve 'owner'`, failOnError) return } else { core.setOutput('owner', owner) @@ -94,7 +64,7 @@ async function run(): Promise { } if (!repo) { - core.error(`đŸ’Ĩ Missing or couldn't resolve 'owner'`) + failOrError(`đŸ’Ĩ Missing or couldn't resolve 'owner'`, failOnError) return } else { core.setOutput('repo', repo) @@ -102,7 +72,7 @@ async function run(): Promise { } if (!toTag) { - core.error(`đŸ’Ĩ Missing or couldn't resolve 'toTag'`) + failOrError(`đŸ’Ĩ Missing or couldn't resolve 'toTag'`, failOnError) return } else { core.setOutput('toTag', toTag) @@ -115,11 +85,17 @@ async function run(): Promise { repo, fromTag, toTag, - ignorePreReleases: ignorePreReleases === 'true', + ignorePreReleases, + failOnError, configuration }) - core.setOutput('changelog', await releaseNotes.pull(token)) + core.setOutput( + 'changelog', + (await releaseNotes.pull(token)) ?? + configuration.empty_template ?? + DefaultConfiguration.empty_template + ) } catch (error) { core.setFailed(error.message) } diff --git a/src/releaseNotes.ts b/src/releaseNotes.ts index 705978d..3d3989e 100755 --- a/src/releaseNotes.ts +++ b/src/releaseNotes.ts @@ -5,6 +5,7 @@ import {buildChangelog} from './transform' import * as core from '@actions/core' import {Tags} from './tags' import {Configuration, DefaultConfiguration} from './configuration' +import {failOrError} from './utils' export interface ReleaseNotesOptions { owner: string // the owner of the repository @@ -12,18 +13,26 @@ export interface ReleaseNotesOptions { fromTag: string | null // the tag/ref to start from toTag: string // the tag/ref up to ignorePreReleases: boolean // defines if we should ignore any pre-releases for matching, only relevant if fromTag is null + failOnError: boolean // defines if we should fail the action in case of an error configuration: Configuration // the configuration as defined in `configuration.ts` } export class ReleaseNotes { constructor(private options: ReleaseNotesOptions) {} - async pull(token?: string): Promise { + async pull(token?: string): Promise { const octokit = new Octokit({ auth: `token ${token || process.env.GITHUB_TOKEN}` }) - const {owner, repo, toTag, ignorePreReleases, configuration} = this.options + const { + owner, + repo, + toTag, + ignorePreReleases, + failOnError, + configuration + } = this.options if (!this.options.fromTag) { core.startGroup(`🔖 Resolve previous tag`) @@ -39,10 +48,11 @@ export class ReleaseNotes { DefaultConfiguration.max_tags_to_fetch ) if (previousTag == null) { - core.error(`đŸ’Ĩ Unable to retrieve previous tag given ${toTag}`) - return ( - configuration.empty_template ?? DefaultConfiguration.empty_template + failOrError( + `đŸ’Ĩ Unable to retrieve previous tag given ${toTag}`, + failOnError ) + return null } this.options.fromTag = previousTag.name core.debug(`fromTag resolved via previousTag as: ${previousTag.name}`) @@ -50,8 +60,8 @@ export class ReleaseNotes { } if (!this.options.fromTag) { - core.error(`đŸ’Ĩ Missing or couldn't resolve 'fromTag'`) - return configuration.empty_template ?? DefaultConfiguration.empty_template + failOrError(`đŸ’Ĩ Missing or couldn't resolve 'fromTag'`, failOnError) + return null } else { core.setOutput('fromTag', this.options.fromTag) } @@ -62,7 +72,7 @@ export class ReleaseNotes { if (mergedPullRequests.length === 0) { core.warning(`âš ī¸ No pull requests found`) - return configuration.empty_template ?? DefaultConfiguration.empty_template + return null } core.startGroup('đŸ“Ļ Build changelog') @@ -74,7 +84,14 @@ export class ReleaseNotes { private async getMergedPullRequests( octokit: Octokit ): Promise { - const {owner, repo, fromTag, toTag, configuration} = this.options + const { + owner, + repo, + fromTag, + toTag, + failOnError, + configuration + } = this.options core.info(`â„šī¸ Comparing ${owner}/${repo} - '${fromTag}...${toTag}'`) const commitsApi = new Commits(octokit) @@ -82,11 +99,14 @@ export class ReleaseNotes { try { commits = await commitsApi.getDiff(owner, repo, fromTag!!, toTag) } catch (error) { - core.error(`đŸ’Ĩ Failed to retrieve - Invalid tag? - Because of: ${error}`) + failOrError( + `đŸ’Ĩ Failed to retrieve - Invalid tag? - Because of: ${error}`, + failOnError + ) return [] } if (commits.length === 0) { - core.warning(`đŸ’Ĩ No commits found between - ${fromTag}...${toTag}`) + core.warning(`âš ī¸ No commits found between - ${fromTag}...${toTag}`) return [] } diff --git a/src/utils.ts b/src/utils.ts index a44fdc3..997409d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,71 @@ import * as fs from 'fs' -import {Configuration} from './configuration' +import {Configuration, DefaultConfiguration} from './configuration' +import * as core from '@actions/core' +import * as path from 'path' -export function readConfiguration(filename: string): Configuration | null { +/** + * Resolves the repository path, relatively to the GITHUB_WORKSPACE + */ +export function retrieveRepositoryPath(providedPath: string): string { + let githubWorkspacePath = process.env['GITHUB_WORKSPACE'] + if (!githubWorkspacePath) { + throw new Error('GITHUB_WORKSPACE not defined') + } + githubWorkspacePath = path.resolve(githubWorkspacePath) + core.debug(`GITHUB_WORKSPACE = '${githubWorkspacePath}'`) + + let repositoryPath = providedPath || '.' + repositoryPath = path.resolve(githubWorkspacePath, repositoryPath) + core.debug(`repositoryPath = '${repositoryPath}'`) + return repositoryPath +} + +/** + * 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( + message: string | Error, + failOnError: boolean +): void { + // if we report any failure, consider the action to have failed, may not make the build fail + core.setOutput('failed', true) + if (failOnError) { + core.setFailed(message) + } else { + core.error(message) + } +} + +/** + * Retrieves the configuration given the file path, if not found it will fallback to the `DefaultConfiguration` + */ +export function resolveConfiguration( + githubWorkspacePath: string, + configurationFile: string +): Configuration { + let configuration = DefaultConfiguration + if (configurationFile) { + const configurationPath = path.resolve( + githubWorkspacePath, + configurationFile + ) + core.debug(`configurationPath = '${configurationPath}'`) + const providedConfiguration = readConfiguration(configurationPath) + if (!providedConfiguration) { + core.info( + `âš ī¸ Configuration provided, but it couldn't be found, or failed to parse. Fallback to Defaults` + ) + } else { + configuration = providedConfiguration + } + } + return configuration +} + +/** + * Reads in the configuration from the JSON file + */ +function readConfiguration(filename: string): Configuration | null { try { const rawdata = fs.readFileSync(filename, 'utf8') const configurationJSON: Configuration = JSON.parse(rawdata) @@ -11,25 +75,31 @@ export function readConfiguration(filename: string): Configuration | null { } } -export function directoryExistsSync(path: string, required?: boolean): boolean { - if (!path) { +/** + * Checks if a given directory exists + */ +export function directoryExistsSync( + inputPath: string, + required?: boolean +): boolean { + if (!inputPath) { throw new Error("Arg 'path' must not be empty") } let stats: fs.Stats try { - stats = fs.statSync(path) + stats = fs.statSync(inputPath) } catch (error) { if (error.code === 'ENOENT') { if (!required) { return false } - throw new Error(`Directory '${path}' does not exist`) + throw new Error(`Directory '${inputPath}' does not exist`) } throw new Error( - `Encountered an error when checking whether path '${path}' exists: ${error.message}` + `Encountered an error when checking whether path '${inputPath}' exists: ${error.message}` ) } @@ -39,5 +109,5 @@ export function directoryExistsSync(path: string, required?: boolean): boolean { return false } - throw new Error(`Directory '${path}' does not exist`) + throw new Error(`Directory '${inputPath}' does not exist`) } From 883149d5f3901f2073c1435de3a162af28aaac66 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 11:11:36 +0200 Subject: [PATCH 10/15] - add new configuration ptions --- README.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0ff4b92..47a1d66 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,14 @@ ### What's included 🚀 - Super simple integration - - even on huge repositories with hundreds of tags + - ...even on huge repositories with hundreds of tags - Parallel releases support - Blazingly fast execution - Supports any git project - Highly flexible configuration - Lightweight - Supports any branch +- Rich build log output ------- @@ -69,13 +70,14 @@ ${{steps.build_changelog.outputs.changelog}} A full set list of possible output values for this action. -| **Output** | **Description** | -|---------------------|-------------------------------------------------------------------------------------| -| `outputs.changelog` | The built release changelog built from the merged pull requests | -| `outputs.owner` | Specifies the owner of the repository processed | -| `outputs.repo` | Describes the repository name, which was processed | -| `outputs.fromTag` | Defines the `fromTag` which describes the lower bound to process pull requests for | -| `outputs.toTag` | Defines the `toTag` which describes the upper bound to process pull request for | +| **Output** | **Description** | +|---------------------|---------------------------------------------------------------------------------------------------------------------------| +| `outputs.changelog` | The built release changelog built from the merged pull requests | +| `outputs.owner` | Specifies the owner of the repository processed | +| `outputs.repo` | Describes the repository name, which was processed | +| `outputs.fromTag` | Defines the `fromTag` which describes the lower bound to process pull requests for | +| `outputs.toTag` | Defines the `toTag` which describes the upper bound to process pull request for | +| `outputs.failed` | Defines if there was an issue with the action run, and the changelog may not have been generated correctly. [true, false] | ## Customization đŸ–ī¸ @@ -152,16 +154,19 @@ For advanced usecases additional settings can be provided to the action token: ${{ secrets.PAT }} ``` +💡 All input values are optional. It is only required to privde the `token` either via the input, or as `env` variable. + | **Input** | **Description** | |-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | configuration | Relative path, to the `configuration.json` file, providing additional configurations | | owner | The owner of the repository to generate the changelog for | | repo | Name of the repository we want to process | -| 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 | | fromTag | Defines the 'start' from where the changelog will consider merged pull requests | | toTag | Defines until which tag the changelog will consider merged pull requests | | path | Allows to specify an alternative sub directory, to use as base | | token | Alternative config to specify token. You should prefer `env.GITHUB_TOKEN` instead though | +| 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 | 💡 `${{ secrets.GITHUB_TOKEN }}` only grants rights to the current repository, for other repos please use a PAT (Personal Access Token). From 63430c1e77956c888cfc02e47a34dd9fa5875343 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 11:16:04 +0200 Subject: [PATCH 11/15] - adjust test cases and provide new flag --- __tests__/main.test.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index f44fd86..cfa86bd 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -1,5 +1,5 @@ import {ReleaseNotes} from '../src/releaseNotes' -import {readConfiguration} from '../src/utils' +import { resolveConfiguration } from '../src/utils'; // shows how the runner will run a javascript action with env / stdout protocol /* @@ -17,31 +17,33 @@ test('test runs', () => { it('Should have empty changelog (tags)', async () => { jest.setTimeout(180000) - const configuration = readConfiguration('configs/configuration.json')!! + const configuration = resolveConfiguration('', 'configs/configuration.json') const releaseNotes = new ReleaseNotes({ owner: 'mikepenz', repo: 'release-changelog-builder-action', fromTag: 'v0.0.1', toTag: 'v0.0.2', ignorePreReleases: false, + failOnError: false, configuration: configuration }) const changeLog = await releaseNotes.pull() console.log(changeLog) - expect(changeLog).toStrictEqual(`- no changes`) + expect(changeLog).toStrictEqual(null) }) it('Should match generated changelog (tags)', async () => { jest.setTimeout(180000) - const configuration = readConfiguration('configs/configuration.json')!! + const configuration = resolveConfiguration('', 'configs/configuration.json') const releaseNotes = new ReleaseNotes({ owner: 'mikepenz', repo: 'release-changelog-builder-action', fromTag: 'v0.0.1', toTag: 'v0.0.3', ignorePreReleases: false, + failOnError: false, configuration: configuration }) @@ -58,13 +60,14 @@ it('Should match generated changelog (tags)', async () => { it('Should match generated changelog (unspecified fromTag)', async () => { jest.setTimeout(180000) - const configuration = readConfiguration('configs/configuration.json')!! + const configuration = resolveConfiguration('', 'configs/configuration.json') const releaseNotes = new ReleaseNotes({ owner: 'mikepenz', repo: 'release-changelog-builder-action', fromTag: null, toTag: 'v0.0.3', ignorePreReleases: false, + failOnError: false, configuration: configuration }) @@ -81,13 +84,14 @@ it('Should match generated changelog (unspecified fromTag)', async () => { it('Should match generated changelog (refs)', async () => { jest.setTimeout(180000) - const configuration = readConfiguration('configs_test/configuration_all_placeholders.json')!! + const configuration = resolveConfiguration('', 'configs_test/configuration_all_placeholders.json') const releaseNotes = new ReleaseNotes({ owner: 'mikepenz', repo: 'release-changelog-builder-action', fromTag: '5ec7a2d86fe9f43fdd38d5e254a1117c8a51b4c3', toTag: 'fa3788c8c4b3373ef8424ce3eb008a5cd07cc5aa', ignorePreReleases: false, + failOnError: false, configuration: configuration }) @@ -112,13 +116,14 @@ nhoelzl it('Should match ordered ASC', async () => { jest.setTimeout(180000) - const configuration = readConfiguration('configs_test/configuration_asc.json')!! + const configuration = resolveConfiguration('', 'configs_test/configuration_asc.json') const releaseNotes = new ReleaseNotes({ owner: 'mikepenz', repo: 'release-changelog-builder-action', fromTag: 'v0.3.0', toTag: 'v0.5.0', ignorePreReleases: false, + failOnError: false, configuration: configuration }) @@ -130,13 +135,14 @@ it('Should match ordered ASC', async () => { it('Should match ordered DESC', async () => { jest.setTimeout(180000) - const configuration = readConfiguration('configs_test/configuration_desc.json')!! + const configuration = resolveConfiguration('', 'configs_test/configuration_desc.json') const releaseNotes = new ReleaseNotes({ owner: 'mikepenz', repo: 'release-changelog-builder-action', fromTag: 'v0.3.0', toTag: 'v0.5.0', ignorePreReleases: false, + failOnError: false, configuration: configuration }) From 78de09ed13a63d71f578cebb15f1bbf93a497fa2 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 11:39:20 +0200 Subject: [PATCH 12/15] - improve documentation by adding more in depth descriptions about configuration options --- README.md | 102 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 47a1d66..b8e4c71 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@

What's included 🚀Setup đŸ› ī¸ • + Full Sample đŸ–Ĩī¸Customization đŸ–ī¸Contribute đŸ§Ŧ • - Complete Sample đŸ–Ĩī¸License 📓

@@ -79,9 +79,45 @@ A full set list of possible output values for this action. | `outputs.toTag` | Defines the `toTag` which describes the upper bound to process pull request for | | `outputs.failed` | Defines if there was an issue with the action run, and the changelog may not have been generated correctly. [true, false] | + +## Full Sample đŸ–Ĩī¸ + +Below is a complete example showcasing how to define a build, which is executed when tagging the project. It consists of: +- Prepare tag, via the GITHUB_REF environment variable +- Build changelog, given the tag +- Create release on GitHub - specifying body with constructed changelog + +```yml +name: 'CI' +on: + push: + tags: + - '*' + + release: + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + steps: + - name: Build Changelog + id: github_release + uses: mikepenz/release-changelog-builder-action@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create Release + uses: actions/create-release@v1 + with: + tag_name: ${{ github.ref }} + release_name: ${{ github.ref }} + body: ${{steps.github_release.outputs.changelog}} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +``` + + ## Customization đŸ–ī¸ -### Changelog Configuration +### Configuration The action supports flexible configuration options to modify vast areas of its behavior. To do so, provide the configuration file to the workflow using the `configuration` setting. @@ -131,9 +167,9 @@ This configuration is a `.json` file in the following format. } ``` -Any section of the configruation can be ommited to have defaults apply. -Defaults for the configuraiton can be found in the [configuration.ts](https://github.com/mikepenz/release-changelog-builder-action/blob/develop/src/configuration.ts) - +Any section of the configuration can be ommited to have defaults apply. +Defaults for the configuration can be found in the [configuration.ts](https://github.com/mikepenz/release-changelog-builder-action/blob/develop/src/configuration.ts) +Please see the [Configuration Specification](https://github.com/mikepenz/release-changelog-builder-action#configuration-specification) for detailed descriptions on the offered configuration options. ### Advanced workflow specification @@ -149,12 +185,12 @@ For advanced usecases additional settings can be provided to the action owner: "mikepenz" repo: "release-changelog-builder-action" ignorePreReleases: "false" - fromTag: "0.0.2" - toTag: "0.0.3" + fromTag: "0.3.0" + toTag: "0.5.0" token: ${{ secrets.PAT }} ``` -💡 All input values are optional. It is only required to privde the `token` either via the input, or as `env` variable. +💡 All input values are optional. It is only required to provide the `token` either via the input, or as `env` variable. | **Input** | **Description** | |-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -196,40 +232,26 @@ Table of supported placeholders allowed to be used in the `pr_template` configur | `${{CHANGELOG}}` | The contents of the changelog, matching the labels as specified in the categories configuration | | `${{UNCATEGORIZED}}` | All pull requests not matching a specified label in categories | +### Configuration Specification -## Complete Sample đŸ–Ĩī¸ +Table of descriptions for the `configuration.json` options. -Below is a complete example showcasing how to define a build, which is executed when tagging the project. It consists of: -- Prepare tag, via the GITHUB_REF environment variable -- Build changelog, given the tag -- Create release on GitHub - specifying body with constructed changelog - -```yml -name: 'CI' -on: - push: - tags: - - '*' - - release: - if: startsWith(github.ref, 'refs/tags/') - runs-on: ubuntu-latest - steps: - - name: Build Changelog - id: github_release - uses: mikepenz/release-changelog-builder-action@main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create Release - uses: actions/create-release@v1 - with: - tag_name: ${{ github.ref }} - release_name: ${{ github.ref }} - body: ${{steps.github_release.outputs.changelog}} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -``` +| **Input** | **Description** | +|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| categories | An array of `category` specifications, offering a flexible way to group changes into categories | +| category.title | The display name of a category in the changelog | +| category.labels | An array of labels, to match pull request label against. If any PR label, matches any category label, the pull request will show up under this category | +| sort | The sort order of pull requests. [ASC, DESC] | +| template | Specifies the global template to pick for creating the changelog. See [Template placeholders](https://github.com/mikepenz/release-changelog-builder-action#template-placeholders) for possible values | +| pr_template | Defines the per pull request template. See [PR Template placeholders](https://github.com/mikepenz/release-changelog-builder-action#pr-template-placeholders) for possible values | +| empty_template | Template to pick if no changes are detected. Does not support placeholders | +| transformers | An array of `transform` specification, offering a flexible API to modify the text per pull request. This is applied on the change text created with `pr_template`. `transformers` are executed per change, in the order specified | +| transformer.pattern | A `regex` pattern, extracting values of the change message. | +| transformer.target | The result pattern, the regex groups will be filled into. Allows for full transformation of a pull request message. Including potentially specified texts | +| max_tags_to_fetch | The maximum amount of tags to load from the API to find the previous tag. Loaded paginated with 100 per page | +| max_pull_requests | The maximum amount of pull requests to load from the API. Loaded paginated with 30 per page | +| max_back_track_time_days | Defines the max amount of days to go back in time per changelog | +| exclude_merge_branches | An array of branches to be ignored from processing as merge commits | ## Contribute đŸ§Ŧ From e1cd50cb75cf81886d5ccb62fb311f60c976539a Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 11:42:31 +0200 Subject: [PATCH 13/15] - use shortened links --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b8e4c71..960224d 100644 --- a/README.md +++ b/README.md @@ -168,8 +168,10 @@ This configuration is a `.json` file in the following format. ``` Any section of the configuration can be ommited to have defaults apply. + Defaults for the configuration can be found in the [configuration.ts](https://github.com/mikepenz/release-changelog-builder-action/blob/develop/src/configuration.ts) -Please see the [Configuration Specification](https://github.com/mikepenz/release-changelog-builder-action#configuration-specification) for detailed descriptions on the offered configuration options. + +Please see the [Configuration Specification](#configuration-specification) for detailed descriptions on the offered configuration options. ### Advanced workflow specification @@ -242,8 +244,8 @@ Table of descriptions for the `configuration.json` options. | category.title | The display name of a category in the changelog | | category.labels | An array of labels, to match pull request label against. If any PR label, matches any category label, the pull request will show up under this category | | sort | The sort order of pull requests. [ASC, DESC] | -| template | Specifies the global template to pick for creating the changelog. See [Template placeholders](https://github.com/mikepenz/release-changelog-builder-action#template-placeholders) for possible values | -| pr_template | Defines the per pull request template. See [PR Template placeholders](https://github.com/mikepenz/release-changelog-builder-action#pr-template-placeholders) for possible values | +| template | Specifies the global template to pick for creating the changelog. See [Template placeholders](#template-placeholders) for possible values | +| pr_template | Defines the per pull request template. See [PR Template placeholders](#pr-template-placeholders) for possible values | | empty_template | Template to pick if no changes are detected. Does not support placeholders | | transformers | An array of `transform` specification, offering a flexible API to modify the text per pull request. This is applied on the change text created with `pr_template`. `transformers` are executed per change, in the order specified | | transformer.pattern | A `regex` pattern, extracting values of the change message. | From bc3df61db3352be6f0fa5f5dcdf1cad1e4c28f91 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 11:46:41 +0200 Subject: [PATCH 14/15] - slightly improve formatting --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 960224d..46204e8 100644 --- a/README.md +++ b/README.md @@ -290,7 +290,8 @@ Core parts of the PR fetching logic are based on [pull-release-notes](https://gi ## License - Copyright for portions of pr-release-notes are held by Nikolay Blagoev, 2019-2020 as part of project pull-release-notes. All other copyright for project pr-release-notes are held by Mike Penz, 2020. + Copyright for portions of pr-release-notes are held by Nikolay Blagoev, 2019-2020 as part of project pull-release-notes. + All other copyright for project pr-release-notes are held by Mike Penz, 2020. ## Fork License From a54776a7577be872fface462ce2fe84aafb442f2 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 18 Oct 2020 11:53:28 +0200 Subject: [PATCH 15/15] - fix a bunch of spelling mistakes --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 46204e8..d9a7ec6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

- ... a github action that builds your release notes fast, easy and exactly the way you want. + ... a GitHub action that builds your release notes fast, easy and exactly the way you want.

@@ -57,11 +57,11 @@ Specify the action as part of your GitHub actions workflow: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ``` -By default the action will try to automatically retrieve the `tag` from the current commit and automtacally resolve the `tag` before. Read more about this here. +By default the action will try to automatically retrieve the `tag` from the current commit and automatically resolve the `tag` before. Read more about this here. ### Action outputs -After action execution it will return the `changelog` and additional information as step output. You can use it in any follow up step by referenceing the output by referencing it via the steps id. For example `build_changelog`. +After action execution it will return the `changelog` and additional information as step output. You can use it in any follow-up step by referencing the output by referencing it via the id of the step. For example `build_changelog`. ```yml # ${{steps.{CHANGELOG_STEP_ID}.outputs.changelog}} @@ -167,7 +167,7 @@ This configuration is a `.json` file in the following format. } ``` -Any section of the configuration can be ommited to have defaults apply. +Any section of the configuration can be omitted to have defaults apply. Defaults for the configuration can be found in the [configuration.ts](https://github.com/mikepenz/release-changelog-builder-action/blob/develop/src/configuration.ts) @@ -175,7 +175,7 @@ Please see the [Configuration Specification](#configuration-specification) for d ### Advanced workflow specification -For advanced usecases additional settings can be provided to the action +For advanced use cases additional settings can be provided to the action ```yml - name: "Complex Configuration" @@ -194,19 +194,19 @@ For advanced usecases additional settings can be provided to the action 💡 All input values are optional. It is only required to provide the `token` either via the input, or as `env` variable. -| **Input** | **Description** | -|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| configuration | Relative path, to the `configuration.json` file, providing additional configurations | -| owner | The owner of the repository to generate the changelog for | -| repo | Name of the repository we want to process | -| fromTag | Defines the 'start' from where the changelog will consider merged pull requests | -| toTag | Defines until which tag the changelog will consider merged pull requests | -| path | Allows to specify an alternative sub directory, to use as base | -| token | Alternative config to specify token. You should prefer `env.GITHUB_TOKEN` instead though | -| 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 | +| **Input** | **Description** | +|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `configuration` | Relative path, to the `configuration.json` file, providing additional configurations | +| `owner` | The owner of the repository to generate the changelog for | +| `repo` | Name of the repository we want to process | +| `fromTag` | Defines the 'start' from where the changelog will consider merged pull requests | +| `toTag` | Defines until which tag the changelog will consider merged pull requests | +| `path` | Allows to specify an alternative sub directory, to use as base | +| `token` | Alternative config to specify token. You should prefer `env.GITHUB_TOKEN` instead though | +| `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 | -💡 `${{ secrets.GITHUB_TOKEN }}` only grants rights to the current repository, for other repos please use a PAT (Personal Access Token). +💡 `${{ secrets.GITHUB_TOKEN }}` only grants rights to the current repository, for other repositories please use a PAT (Personal Access Token). ### PR Template placeholders @@ -242,12 +242,12 @@ Table of descriptions for the `configuration.json` options. |--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | categories | An array of `category` specifications, offering a flexible way to group changes into categories | | category.title | The display name of a category in the changelog | -| category.labels | An array of labels, to match pull request label against. If any PR label, matches any category label, the pull request will show up under this category | +| category.labels | An array of labels, to match pull request labels against. If any PR label, matches any category label, the pull request will show up under this category | | sort | The sort order of pull requests. [ASC, DESC] | | template | Specifies the global template to pick for creating the changelog. See [Template placeholders](#template-placeholders) for possible values | | pr_template | Defines the per pull request template. See [PR Template placeholders](#pr-template-placeholders) for possible values | | empty_template | Template to pick if no changes are detected. Does not support placeholders | -| transformers | An array of `transform` specification, offering a flexible API to modify the text per pull request. This is applied on the change text created with `pr_template`. `transformers` are executed per change, in the order specified | +| transformers | An array of `transform` specifications, offering a flexible API to modify the text per pull request. This is applied on the change text created with `pr_template`. `transformers` are executed per change, in the order specified | | transformer.pattern | A `regex` pattern, extracting values of the change message. | | transformer.target | The result pattern, the regex groups will be filled into. Allows for full transformation of a pull request message. Including potentially specified texts | | max_tags_to_fetch | The maximum amount of tags to load from the API to find the previous tag. Loaded paginated with 100 per page | @@ -271,7 +271,7 @@ $ npm test $ npm run lint -- --fix ``` -It's suggested to export the token to your path before running the tests, so that API calls can be done to github. +It's suggested to export the token to your path before running the tests so that API calls can be done to GitHub. ```bash export GITHUB_TOKEN=your_personal_github_pat