Skip to content

Commit 91fc9df

Browse files
authored
Changelog Auto Releaser (#32)
* require-changelog-entry - add error_on_missing condition and error messaging * autoreleaser action WIP * gen READMEs * fix bash if condition * always run all steps * add changelog entry to require-changelog-entry * update README docs * autorelease action * fix minor issues in autoreleaser
1 parent a1ac802 commit 91fc9df

File tree

7 files changed

+237
-3
lines changed

7 files changed

+237
-3
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Auto Release require-changelog-entry
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- require-changelog-entry/docs/CHANGELOG.md
9+
10+
jobs:
11+
changelog-autorelease:
12+
name: Auto Release from CHANGELOG
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v3
18+
19+
- name: Auto Release from CHANGELOG
20+
id: changelog
21+
uses: ./autorelease
22+
with:
23+
token: ${{ secret.GITHUB_TOKEN }}
24+
changelog_path: require-changelog-entry/docs/CHANGELOG.md
25+
tag_prefix: require-changelog-entry@
26+
27+
- name: Print auto release Outputs
28+
if: always()
29+
run: echo "$OUTPUTS"
30+
env:
31+
OUTPUTS: ${{ toJSON(steps.changelog.outputs) }}

.github/workflows/test-require-changelog-entry.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@ jobs:
2222
token: ${{ secrets.GITHUB_TOKEN }}
2323
tag_prefix: require-changelog-entry@
2424
changelog_path: require-changelog-entry/docs/CHANGELOG.md
25+
error_on_missing: true
2526

2627
- name: Print CHANGELOG.md Outputs
28+
if: always()
2729
run: echo "$OUTPUTS"
2830
env:
2931
OUTPUTS: ${{ toJSON(steps.changelog.outputs) }}
3032

3133
- name: Run on no-changes-changelog.md
34+
if: always()
3235
id: no_changes_changelog
3336
uses: ./require-changelog-entry
3437
with:
@@ -37,6 +40,7 @@ jobs:
3740
changelog_path: require-changelog-entry/docs/no-changes-changelog.md
3841

3942
- name: Print no-changes-changelog.md Outputs
43+
if: always()
4044
run: echo "$OUTPUTS"
4145
env:
4246
OUTPUTS: ${{ toJSON(steps.no_changes_changelog.outputs) }}

autoreleaser/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<!-- action-docs-description -->
2+
## Description
3+
4+
Auto Release action based on new CHANGELOG entry version
5+
6+
7+
<!-- action-docs-description -->
8+
9+
## Example Usage
10+
11+
```yaml
12+
name: Auto Release from CHANGELOG
13+
on:
14+
push:
15+
branches:
16+
- main
17+
paths:
18+
- CHANGELOG.md
19+
20+
jobs:
21+
changelog-autorelease:
22+
name: Auto Release from CHANGELOG
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v3
28+
29+
- name: Auto Release from CHANGELOG
30+
id: changelog
31+
uses: lockerstock/github-actions/autorelease@main
32+
with:
33+
token: ${{ secret.GITHUB_TOKEN }}
34+
changelog_path: CHANGELOG.md
35+
```
36+
37+
<!-- action-docs-inputs -->
38+
## Inputs
39+
40+
| parameter | description | required | default |
41+
| - | - | - | - |
42+
| token | GITHUB_TOKEN to access the GitHub API if the repository is private | `true` | |
43+
| tag | Optional tag version to search for in the CHANGELOG. This can be used if prior steps determine which version needs released. If the provided input does not exist in the CHANGELOG, this action will fail. If this input is not provided, then the latest entry in the CHANGELOG will be retrieved. | `false` | |
44+
| tag_prefix | Optional prefix string to apply to tag during creation. | `false` | |
45+
| tag_suffix | Optional suffix string to apply to tag during creation. | `false` | |
46+
| changelog_path | Path to CHANGELOG file within repository | `false` | CHANGELOG.md |
47+
| artifacts | An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs). | `false` | |
48+
| replace_artifacts | Indicates if existing release artifacts should be replaced. | `false` | true |
49+
50+
51+
52+
<!-- action-docs-inputs -->
53+
54+
<!-- action-docs-outputs -->
55+
## Outputs
56+
57+
| parameter | description |
58+
| - | - |
59+
| changelog_version | Latest as-is CHANGELOG version entry or version matching inputted tag. |
60+
| prepared_version | Latest prefix/suffix prepared CHANGELOG version entry. |
61+
62+
63+
64+
<!-- action-docs-outputs -->
65+
66+
<!-- action-docs-runs -->
67+
## Runs
68+
69+
This action is a `composite` action.
70+
71+
72+
<!-- action-docs-runs -->

autoreleaser/action.yaml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Changelog Auto Releaser
2+
description: Auto Release action based on new CHANGELOG entry version
3+
4+
inputs:
5+
token:
6+
description: GITHUB_TOKEN to access the GitHub API if the repository is private
7+
required: true
8+
9+
tag:
10+
description: Optional tag version to search for in the CHANGELOG. This can be used if prior steps determine which version needs released. If the provided input does not exist in the CHANGELOG, this action will fail. If this input is not provided, then the latest entry in the CHANGELOG will be retrieved.
11+
required: false
12+
default: ''
13+
14+
tag_prefix:
15+
description: Optional prefix string to apply to tag during creation.
16+
required: false
17+
default: ''
18+
19+
tag_suffix:
20+
description: Optional suffix string to apply to tag during creation.
21+
required: false
22+
default: ''
23+
24+
changelog_path:
25+
description: Path to CHANGELOG file within repository
26+
required: false
27+
default: 'CHANGELOG.md'
28+
29+
artifacts:
30+
description: An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
31+
required: false
32+
33+
replace_artifacts:
34+
description: Indicates if existing release artifacts should be replaced.
35+
required: false
36+
default: 'true'
37+
38+
outputs:
39+
changelog_version:
40+
description: 'Latest as-is CHANGELOG version entry or version matching inputted tag.'
41+
value: ${{ steps.changelog_reader.outputs.version }}
42+
43+
prepared_version:
44+
description: 'Latest prefix/suffix prepared CHANGELOG version entry.'
45+
value: ${{ steps.prepared.outputs.version }}
46+
47+
runs:
48+
using: composite
49+
steps:
50+
- name: Get Changelog Entry
51+
id: changelog_reader
52+
uses: mindsers/changelog-reader-action@v2
53+
with:
54+
validation_level: none
55+
path: ${{ inputs.changelog_path }}
56+
version: ${{ inputs.tag }}
57+
58+
- name: Prepare Tag
59+
id: prepared
60+
run: echo "version=${{ inputs.tag_prefix }}${{ steps.changelog_reader.outputs.version }}${{ inputs.tag_suffix }}" >> $GITHUB_OUTPUT
61+
shell: bash
62+
63+
- name: Check if tag already exists
64+
uses: lockerstock/github-actions/git-tag-exists@main
65+
id: tag
66+
with:
67+
token: ${{ inputs.token }}
68+
tag: ${{ steps.prepared.outputs.version }}
69+
70+
- name: Create Tag
71+
id: tag_version
72+
if: steps.tag.outputs.exists == 'false'
73+
uses: mathieudutour/github-tag-action@v6.1
74+
with:
75+
github_token: ${{ inputs.token }}
76+
custom_tag: ${{ steps.prepared.outputs.version }}
77+
release_branches: ${{ github.event.repository.name }}
78+
tag_prefix: ''
79+
80+
- name: Create a GitHub release
81+
if: steps.tag.outputs.exists == 'false'
82+
uses: ncipollo/release-action@v1
83+
with:
84+
token: ${{ inputs.token }}
85+
tag: ${{ steps.prepared.outputs.version }}
86+
name: ${{ steps.prepared.outputs.version }}
87+
body: ${{ steps.changelog_reader.outputs.changes }}
88+
artifacts: ${{ inputs.artifacts }}
89+
replacesArtifacts: ${{ inputs.replace_artifacts }}
90+
prerelease: ${{ steps.changelog_reader.outputs.status == 'prereleased' }}
91+
draft: false

require-changelog-entry/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ jobs:
3838
3939
| parameter | description | required | default |
4040
| - | - | - | - |
41-
| token | GITHUB_TOKEN to access the GitHub API if the repository is private | `false` | |
41+
| token | GITHUB_TOKEN to access the GitHub API if the repository is private | `true` | |
4242
| default_branch | Default branch to compare the "Unreleased" section of the CHANGELOG to. | `false` | ${{ github.event.repository.default_branch }} |
4343
| tag_prefix | Optional prefix string to apply to tag search | `false` | |
4444
| tag_suffix | Optional suffix string to apply to tag search | `false` | |
4545
| changelog_path | Path to CHANGELOG file within repository | `false` | CHANGELOG.md |
46+
| error_on_missing | Boolean flag to have this action terminate with error when a new version and new Unreleased entry are not found. | `false` | false |
47+
| error_message | Error message to print when a new version and new Unreleased entry are not found. Will be applied as an error to the given CHANGELOG path. | `false` | It is required via GitHub Action workflow that this CHANGELOG has a new version or new Unreleased entry. |
4648

4749

4850

require-changelog-entry/action.yaml

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: 'Checks the CHANGELOG for either new version entry or an updated en
44
inputs:
55
token:
66
description: GITHUB_TOKEN to access the GitHub API if the repository is private
7-
required: false
7+
required: true
88

99
default_branch:
1010
description: Default branch to compare the "Unreleased" section of the CHANGELOG to.
@@ -26,14 +26,24 @@ inputs:
2626
required: false
2727
default: 'CHANGELOG.md'
2828

29+
error_on_missing:
30+
description: Boolean flag to have this action terminate with error when a new version and new Unreleased entry are not found.
31+
required: false
32+
default: 'false'
33+
34+
error_message:
35+
description: Error message to print when a new version and new Unreleased entry are not found. Will be applied as an error to the given CHANGELOG path.
36+
required: false
37+
default: 'It is required via GitHub Action workflow that this CHANGELOG has a new version or new Unreleased entry.'
38+
2939
outputs:
3040
has_changed:
3141
description: 'Boolean output indicating whether the CHANGELOG file has changed'
3242
value: ${{ steps.changes.outputs.changelog }}
3343

3444
has_new_version:
3545
description: 'Boolean output indicating whether a new, untagged version was found in the CHANGELOG'
36-
value: ${{ steps.tag.outputs.exists == 'false' }}
46+
value: ${{ steps.new_version.outputs.has_new_version }}
3747

3848
changelog_version_exists:
3949
description: 'Boolean flag indicating whether the latest CHANGELOG version exists as a git tag.'
@@ -140,3 +150,20 @@ runs:
140150
echo "changed=true" >> $GITHUB_OUTPUT
141151
fi
142152
shell: bash
153+
154+
- name: Check for new version
155+
id: new_version
156+
run: echo "has_new_version=${{ steps.tag.outputs.exists == 'false' }}" >> $GITHUB_OUTPUT
157+
shell: bash
158+
159+
###### Error on missing new entries ######
160+
161+
- name: Error on Missing New entries
162+
if: steps.new_version.outputs.has_new_version == 'false' && steps.unreleased.outputs.changed == 'false'
163+
run: |
164+
echo "::error file=${{ inputs.changelog_path }}::${{ inputs.error_message }}"
165+
166+
if [ "${{ inputs.error_on_missing }}" = true ]; then
167+
exit 1
168+
fi
169+
shell: bash

require-changelog-entry/docs/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
### Removed
1717

18+
## [v0.2.0]
19+
20+
### Added
21+
22+
- Optional exit with error state on no new CHANGELOG entries
23+
- Append customizable error message to CHANGELOG file when no new entries
24+
1825
## [v0.1.0]
1926

2027
### Added

0 commit comments

Comments
 (0)