... a GitHub action that builds your release notes / changelog fast, easy and exactly the way you want.
What's included ๐ • Setup ๐ ๏ธ • Sample ๐ฅ๏ธ • Customization ๐๏ธ • Contribute ๐งฌ • Local Testing ๐งช • License ๐
------- ### What's included ๐ - Super simple integration - ...even on huge repositories with hundreds of tags - Parallel releases support - Rich changelogs based on PRs - Alternative commit based mode - Blazingly fast execution - Supports any git project - Highly flexible configuration - Lightweight - Supports any branch - Rich build log output ------- ## Setup ### Configure the workflow Specify the action as part of your GitHub actions workflow: ```yml - name: "Build Changelog" id: build_changelog uses: mikepenz/release-changelog-builder-action@{latest-release} ``` ### 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 referencing the output by referencing it via the id of the step. 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 | | `outputs.failed` | Defines if there was an issue with the action run, and the changelog may not have been generated correctly. [true, false] | | `outputs.pull_requests` | Defines a `,` joined array with all PR IDs associated with the generated changelog. | | `outputs.categorized_prs` | Count of PRs which were successfully categorized as part of the action. | | `outputs.open_prs` | Count of open PRs. Only fetched if `includeOpen` is enabled. | | `outputs.uncategorized_prs` | Count of PRs which were not categorized as part of the action. | | `outputs.changed_files` | Count of changed files in this release. | | `outputs.additions` | Count of code additions in this release (lines). | | `outputs.deletions` | Count of code deletions in this release (lines). | | `outputs.changes` | Total count of changes in this release (lines). | | `outputs.commits` | Count of commits which have been added in this release. | | `outputs.categorized` | The categorized pull requests used to build the changelog as serialized JSON. | | `outputs.cache` | The file pointing to the cache for the current fetched data. Can be provided to another action step. | ## 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 > [!NOTE] > Pre v4 PRs will only show up in the changelog if assigned one of the default label categories "feature", "fix" or "test". Starting with v4 these PRs will be in the `Uncategorized` section.```yml name: 'CI' on: push: tags: - '*' jobs: release: if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - name: Build Changelog id: github_release uses: mikepenz/release-changelog-builder-action@v3 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create Release uses: mikepenz/action-gh-release@v0.2.0-a03 #softprops/action-gh-release with: body: ${{steps.github_release.outputs.changelog}} ```
```yml
jobs:
release:
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- name: Build Changelog
uses: mikepenz/release-changelog-builder-action@v3
with:
configurationJson: |
{
"template": "#{{CHANGELOG}}\n\nUncategorized
\n\n#{{UNCATEGORIZED}}\n
Table of special array placeholders allowed to be used in the `pr_template` configuration. Array placeholders follow the following format: `(KEY)[(*/index)]` for example: `ASSIGNEES[*]` or `ASSIGNEES[0]`. When using `*` values are joined by `,`. | **Placeholder** | **Description** | |---------------------|-------------------------------------------------------------------------------------| | `#{{ASSIGNEES[*]}}` | Login names of assigned GitHub users. | | `#{{REVIEWERS[*]}}` | GitHub Login names of specified reviewers. Requires `fetchReviewers` to be enabled. | | `#{{APPROVERS[*]}}` | GitHub Login names of users who approved the PR. | Additionally there are special array placeholders like `REVIEWS` which allows access to it's properties via `(KEY)[(*/index)].(property)`. For example: `REVIEWS[*].author` or `REVIEWS[*].body` | **Placeholder** | **Description** | |-------------------------------|--------------------------------------------| | `#{{REVIEWS[*].author}}` | GitHub Login names of specified reviewers. | | `#{{REVIEWS[*].body}}` | The body of the review. | | `#{{REVIEWS[*].htmlURL}}` | The URL to the given review. | | `#{{REVIEWS[*].submittedAt}}` | The date whent he review was submitted. | | `#{{REVIEWS[*].state}}` | The state of the given review. | Similar to `REVIEWS`, `REFERENCED` PRs also offer special placeholders. | **Placeholder** | **Description** | |-------------------------------|---------------------------------------------------------------------------| | `#{{REFERENCED[*].number}}` | The PR number of the referenced PR. | | `#{{REFERENCED[*].title}}` | The title of the referenced PR. | | `#{{REFERENCED[*]."..."}}` | Allows to use most other PR properties as placeholder. |
Custom placeholders can be defined via the `configuration.json` as `custom_placeholders`. See the below example json:
```json
{
"template": "**Epics**\n#{{EPIC[*]}}\n\n#{{CHANGELOG}}",
"pr_template": "- #{{TITLE}} - #{{URL}} #{{EPIC}}",
"custom_placeholders": [
{
"name": "EPIC",
"source": "BODY",
"transformer": {
"pattern": "[\\S\\s]*?(https:\\/\\/corp\\.atlassian\\.net\\/browse\\/EPIC-.{2,4})[\\S\\s]*",
"target": "- $1"
}
}
]
}
```
This example will look for JIRA tickets in the EPIC project, and extract all of these tickets. The exciting part for that case is, that the ticket is PR bound, but can be used in the global TEMPLATE, but equally also in the PR template. This is unique for CUSTOM PLACEHOLDERS as standard palceholders do not offer this functionality.
| **Input** | **Description** |
|-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
| custom_placeholders | An array of `Placeholder` specifications, offering a flexible API to extract custom placeholders from existing placeholders. |
| custom_placeholders.name | The name of the custom placeholder. Will be used within the template. |
| custom_placeholders.source | The source PLACEHOLDER, requires to be one of the existing Template or PR Template placeholders. |
| custom_placeholders.transformer.
```typescript import {mergeConfiguration, resolveConfiguration} from '../src/utils' import {ReleaseNotesBuilder} from '../src/releaseNotesBuilder' jest.setTimeout(180000) it('Test custom changelog builder', async () => { const configuration = mergeConfiguration(undefined, resolveConfiguration( '', 'configs_test/configuration_approvers.json' )) const releaseNotesBuilder = new ReleaseNotesBuilder( null, // baseUrl null, // token '.', // repoPath 'mikepenz', // user 'release-changelog-builder-action-playground', // repo '1.5.0', // fromTag '2.0.0', // toTag false, // includeOpen false, // failOnError false, // ignorePrePrelease false, // enable to fetch via commits false, // enable to fetch reviewers false, // enable to fetch release information false, // enable to fetch reviews false, // enable commitMode false, // enable exportCache false, // enable exportOnly null, // path to the cache configuration // configuration ) const changeLog = await releaseNotesBuilder.build() console.log(changeLog) }) ```