A semantic release group of actions action for generating the next release version & changelog based on commit messages & notifying closed issues.
Still very much a v0.x beta.
- Assumptions
- Primary action
- Notify issues on release
- Plain old changelog generator
- Resolve the last released tag
- Resolve the next tag to release
- Check if the local branch is in sync with the remote
- Example workflows
- You have no diverging version trees. The version can only ever keep going up - if you release an update in v2.x you cannot use this action to release a for v1.x.
- You're following semantic versioning.
- You're using the following conventional commit message format:
type(scope?): Message
Extended message
Where the extended message can contain the following keywords:
Closes #1
,Closes #1, #2, #n
(case-insensitive) - mark this commit as closing the given issues.BREAKING CHANGE: description
(case-sensitive, configurable) - mark this commit as a breaking change.
- Parse commits since last release
- Determine next release version and whether we should make a release
- Generate changelog
- Output everything as action outputs
Key | Required | Default | Description |
---|---|---|---|
breaking-change-keywords |
✔️ | BREAKING CHANGE |
If the commit message extended body starts with one of these prefixes (one per line, case sensitive) then a breaking change release will be made |
minor-types |
❌ | Types that result in a minor version release. Format: type: Heading in the changelog (one per line). |
|
patch-types |
❌ | Types that result in a patch version release. Format: same as minor-types |
|
trivial-types |
❌ | Types that are included in the changelog, but don't result in a version bump. Format: same as minor-types |
|
stay-at-zero |
❌ | false |
If we're currently at version 0.x (or no version at all) then this can be set to true to stay at version 0.x with our releases. |
Types with identical headings will get merged under the same heading in the changelog regardless of whether they're all major/minor/patch or not.
Name | Description |
---|---|
changelog |
The generated changelog |
commit-count |
Total number of commits since the previous release |
relevant-commit-count |
commit-count with commits with mismatching message regex filtered out |
release-type |
The type of release that was generated: major , minor , patch |
next-version |
The next version we should release, based on commit messages |
next-version-major |
If next-version outputs v1.2.3 then this will output 1 |
next-version-minor |
If next-version outputs v1.2.3 then this will output 2 |
next-version-patch |
If next-version outputs v1.2.3 then this will output 3 |
last-tag |
The last tag we scanned from, if any |
in-sync |
Gets set to true if we're in sync with the remote repository, i.e. not behind or ahead of it in commits |
issues-closed |
A comma-separated list of issue numbers (without # ) closed by this release, if any |
should-release |
Gets set to true there were version bumping commits processed and we're in sync with the remote repository |
This action lives under /notify
.
- Take the
issues-closed
and, most likely,next-version
outputs of the primary action - Check if we're ahead of/behind the remote and terminate early if needed
- Apply a label to each issue and add a comment.
Key | Required | Default | Description |
---|---|---|---|
tag |
✔️ | The tag that just just released, e.g. the next-version output of the primary step |
|
issues |
✔️ | A comma-separated list of issues to notify, e.g. the issues-closed output of the primary step. Note that no duplicate verification happens in order to conserve API call quota, therefore calling this action repeatedly with the same issue(s) will result in multuple comments. |
|
labels |
✔️ | Released |
Labels to apply to released issues (1 per line) |
gh-token |
✔️ | ${{ github.token }} |
API token to use |
error-on-ratelimit |
❌ | false |
Error if the GitHub API token gits a rate limit (true) or just warn (false) |
error-on-out-of-sync |
❌ | false |
If we're behind/ahead of the remote, should the action skip notifications, but succeed (false) or fail with an error (true)? Overridden by allow-out-of-sync . |
allow-out-of-sync |
❌ | false |
Continue with notifications even if we're out of sync with the remote. Takes precedence over error-on-ratelimit . |
comment |
✔️ | This issue has been included in [{{tag}}]({{releaseUrl}}) :tada: |
The comment that'll be made on every issue. Accepts placeholders in the form of {{name}} - list included below. |
Comment placeholders:
- tag: The
tag
input - owner: The repo owner
- repo: The repo name
- baseUrl: Shorthand for
https://github.com/{{owner}}/{{repo}}
- releaseUrl: Shorthand for
{{baseUrl}}/releases/tag/{{tag}}
This action lives under /generate-changelog
.
Take a commit range in, spit a changelog out.
Same as primary action: breaking-change-keywords
, minor-types
, patch-types
, trivial-types
, stay-at-zero
.
Key | Required | Default | Description |
---|---|---|---|
from |
❌ | The beginning of all time | Commit/tag to start from. The lefthand side of a git log xx..yy command. |
last-tag |
❌ | The last tag that got released, if any | |
until |
❌ | HEAD |
Commit/tag to end at. The righthand side of a git log xx..yy command. |
Same as primary action: changelog
, release-type
, commit-count
, relevant-commit-count
, issues-closed
, in-sync
, should-release
, next-version
.
This action lives under /last-tag
. Same step as the primary action uses.
Key | Required | Default | Description |
---|---|---|---|
before |
❌ | If specified, the last tag must come before this tag sorted by semantic version. | |
after |
❌ | If specified, the last tag must come after this tag sorted by semantic version. |
last-tag
, if resolved.
Lives under /next-tag
. Generates the next tag based on the previous released version and a release type.
Key | Required | Default | Description |
---|---|---|---|
last-tag |
❌ | The last tag that got released | |
release-type |
✔️ | The type of release to make: major , minor , patch |
|
stay-at-zero |
❌ | false |
Same as primary action |
tag
with the full tag and major
, minor
, patch
with the broken down segments.
Lives under /sync-check
. No inputs, one output: in-sync
; gets set to true if we're still in sync.
Generate a release when the main branch gets major/minor/patch commits
name: Release
on:
push:
branches:
- master
- main
jobs:
release:
runs-on: ubuntu-latest
name: Release
permissions:
contents: write # Needed for the notify step unless a different GitHub token is provided
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # need to fetch the whole history
fetch-tags: true # needed to know what the previous release was
- uses: alorel-actions/semantic-release-lite@v0
id: parse-release
with:
minor-types: "feat: Features"
patch-types: |
fix: Bug Fixes
perf: Performance improvements
trivial-types: |
deps: Dependency Updates
ci: CI & Build
build: CI & Build
chore: Maintenance
- run: whatever you need to do for your release
if: ${{ steps.parse-release.outputs.should-release }}
- uses: alorel-actions/semantic-release-lite/notify@v0
if: ${{ steps.parse-release.outputs.should-release && steps.parse-release.outputs.issues-closed }}
with:
tag: ${{ steps.parse-release.outputs.next-version }}
issues: ${{ steps.parse-release.outputs.issues-closed }}
Generate a changelog for a specific commit range
name: Preliminary changelog
on: [pull_request]
jobs:
release:
runs-on: ubuntu-latest
name: Release
permissions:
contents: write # Needed for the notify step unless a different GitHub token is provided
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # need to fetch the whole history
fetch-tags: true # needed to know what the previous release was
- uses: alorel-actions/semantic-release-lite/generate-changelog@v0
id: changelog
with:
from: master
minor-types: "feat: Features"
patch-types: |
fix: Bug Fixes
perf: Performance improvements
trivial-types: |
deps: Dependency Updates
ci: CI & Build
build: CI & Build
chore: Maintenance
# Might want to e.g. post this as a PR comment
- run: 'echo -e "Changelog for this release: ${{ steps.parse-release.outputs.changelog }} "'