9 Commits

Author SHA1 Message Date
Phil Jay
ae1ae190dc Merge pull request #31 from reecetech/feature/support-conventional-commits
Support conventional commits
2024-04-23 17:41:08 +10:00
Phil Jay
81805365e1 Update README.md for version bump 2024-04-23 17:37:34 +10:00
Phil Jay
c6ea11748a Update README.md for conventional commits 2024-04-23 17:34:47 +10:00
Phil Jay
73ade5516c Update version-increment.sh for old comment 2024-04-23 17:17:01 +10:00
Phil Jay
352a9961c8 Update action.yml for README 2024-04-23 17:13:22 +10:00
Daniel Atanasovski
a449b75848 test: add tests for new conventional_commits scheme 2024-03-20 15:41:30 +11:00
Daniel Atanasovski
0df84379a9 feat: add new scheme conventional_commits 2024-03-20 15:41:06 +11:00
Daniel Atanasovski
0c4ebd1e55 fix: strip leading 0 in date command for CI workflow 2024-03-20 15:39:13 +11:00
Daniel Atanasovski
b920b6b45e feat: shellcheck config for simplicity 2024-03-20 15:38:23 +11:00
8 changed files with 200 additions and 12 deletions

View File

@@ -65,7 +65,7 @@ jobs:
- name: Check increment result - name: Check increment result
shell: bash shell: bash
run: '[[ "$(date +%Y.%m)" == "$(echo "${{ steps.version-increment.outputs.VERSION }}" | cut -d "." -f 1-2)" ]]' run: '[[ "$(date +%Y.%-m)" == "$(echo "${{ steps.version-increment.outputs.VERSION }}" | cut -d "." -f 1-2)" ]]'
test-action-yml: # integration testing test-action-yml: # integration testing
needs: needs:

1
.shellcheckrc Normal file
View File

@@ -0,0 +1 @@
external-sources=true

View File

@@ -30,7 +30,7 @@ use the API mode:
```yaml ```yaml
- name: Get next version - name: Get next version
uses: reecetech/version-increment@2023.10.1 uses: reecetech/version-increment@2024.4.1
id: version id: version
with: with:
use_api: true use_api: true
@@ -70,6 +70,22 @@ If the current latest normal version is not the current year and month, then the
year and month digits will be year and month digits will be
set to the current year and month, and the release digit will be reset to 1. set to the current year and month, and the release digit will be reset to 1.
### Conventional Commits (semver with smarts) 💡
If you choose the conventional commits scheme, the action will parse the last commit message _(usually the merge commit)_ to determine
the increment type for a `semver` version.
The following increment types by keyword are supported:
- patch: build, chore, ci, docs, fix, perf, refactor, revert, style, test
- minor: feat
- major: any of the above keywords followed by a '!' character, or 'BREAKING CHANGE:' in commit body
If none of the keywords are detected, then the increment specified by the `increment` input will be used (defaults to patch).
> [!TIP]
> You might like to _enforce_ conventional commits in the title of your pull requests to ensure that the merge commit has the correct
> information. Something like this action might be handy: https://github.com/marketplace/actions/conventional-commit-in-pull-requests
### Default branch vs. any other branch 🎋 ### Default branch vs. any other branch 🎋
**Default branch** **Default branch**
@@ -107,7 +123,7 @@ Examples:
| name | description | required | default | | name | description | required | default |
| :--- | :--- | :--- | :--- | | :--- | :--- | :--- | :--- |
| scheme | The versioning scheme in-use, either `semver` or `calver` | No | `semver` | | scheme | The versioning scheme in-use, either `semver`, `calver` or `conventional_commits` | No | `semver` |
| pep440 | Set to `true` for PEP440 compatibility of _pre-release_ versions by making use of the build metadata segment of semver, which maps to local version identifier in PEP440 | No | `false` | | pep440 | Set to `true` for PEP440 compatibility of _pre-release_ versions by making use of the build metadata segment of semver, which maps to local version identifier in PEP440 | No | `false` |
| increment | The digit to increment, either `major`, `minor` or `patch`, ignored if `scheme` == `calver` | No | `patch` | | increment | The digit to increment, either `major`, `minor` or `patch`, ignored if `scheme` == `calver` | No | `patch` |
| release_branch | Specify a non-default branch to use for the release tag (the one without -pre) | No | | | release_branch | Specify a non-default branch to use for the release tag (the one without -pre) | No | |

View File

@@ -8,7 +8,14 @@ branding:
inputs: inputs:
scheme: scheme:
description: 'Versioning scheme - semver, or, calver (defaults to semver)' description: |
Versioning scheme - semver, calver or conventional_commits (defaults to semver).
`conventional_commits` Will parse the last commit message (e.g. the merge commit) to
determine the increment type, and supports the following increment types by keyword:
- patch (build, chore, ci, docs, fix, perf, refactor, revert, style, test)
- minor (feat)
- major (any of the above keywords followed by a '!' character, or 'BREAKING CHANGE:' in commit body)
required: false required: false
default: 'semver' default: 'semver'
pep440: pep440:
@@ -19,6 +26,9 @@ inputs:
description: | description: |
Field to increment - major, minor, or, patch (defaults to patch) Field to increment - major, minor, or, patch (defaults to patch)
If using the `conventional_commits` scheme, this is the default increment if the parsing of the merge commit fails to
find conventional commits information
Not applicable to `calver` scheme Not applicable to `calver` scheme
required: false required: false
default: 'patch' default: 'patch'
@@ -36,14 +46,14 @@ outputs:
description: 'Current normal version detected' description: 'Current normal version detected'
value: ${{ steps.version-lookup.outputs.CURRENT_VERSION }} value: ${{ steps.version-lookup.outputs.CURRENT_VERSION }}
current-v-version: current-v-version:
description: 'Current normal version detected, prefixed with a `v` charatcter' description: 'Current normal version detected, prefixed with a `v` character'
value: ${{ steps.version-lookup.outputs.CURRENT_V_VERSION }} value: ${{ steps.version-lookup.outputs.CURRENT_V_VERSION }}
version: version:
description: 'Incremented version calculated' description: 'Incremented version calculated'
value: ${{ steps.version-increment.outputs.VERSION }} value: ${{ steps.version-increment.outputs.VERSION }}
v-version: v-version:
description: 'Incremented version calculated, prefixed with a `v` charatcter' description: 'Incremented version calculated, prefixed with a `v` charatcter'
value: ${{ steps.version-increment.outputs.V_VERSION }} value: ${{ steps.version-increment.outputs.V_VERSION }}
major-version: major-version:
description: 'Major number of the incremented version' description: 'Major number of the incremented version'
value: ${{ steps.version-increment.outputs.MAJOR_VERSION }} value: ${{ steps.version-increment.outputs.MAJOR_VERSION }}

View File

@@ -11,13 +11,21 @@ pcre_master_ver='^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9
pcre_allow_vprefix="^v{0,1}${pcre_master_ver:1}" pcre_allow_vprefix="^v{0,1}${pcre_master_ver:1}"
pcre_old_calver='^(?P<major>0|[1-9]\d*)-0{0,1}(?P<minor>0|[0-9]\d*)-R(?P<patch>0|[1-9]\d*)$' pcre_old_calver='^(?P<major>0|[1-9]\d*)-0{0,1}(?P<minor>0|[0-9]\d*)-R(?P<patch>0|[1-9]\d*)$'
##==----------------------------------------------------------------------------
## Conventional commit regexes
## see: https://www.conventionalcommits.org/en/v1.0.0/
pcre_conventional_commit_patch='^(build|chore|ci|docs|fix|perf|refactor|revert|style|test)(\([a-zA-Z0-9-]+\))?:\s.*'
pcre_conventional_commit_minor='^(feat)(\([a-zA-Z0-9-]+\))?:\s.*'
pcre_conventional_commit_breaking='^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-zA-Z0-9-]+\))?!:.*|BREAKING CHANGE:'
##==---------------------------------------------------------------------------- ##==----------------------------------------------------------------------------
## Input validation ## Input validation
input_errors='false' input_errors='false'
scheme="${scheme:-semver}" scheme="${scheme:-semver}"
if [[ "${scheme}" != 'semver' && "${scheme}" != 'calver' ]] ; then if [[ "${scheme}" != 'semver' && "${scheme}" != 'calver' && "${scheme}" != 'conventional_commits' ]] ; then
echo "🛑 Value of 'scheme' is not valid, choose from 'semver' or 'calver'" 1>&2 echo "🛑 Value of 'scheme' is not valid, choose from 'semver', 'calver' or 'conventional_commits" 1>&2
input_errors='true' input_errors='true'
fi fi
@@ -40,7 +48,6 @@ if [[ "${use_api}" == 'true' ]] ; then
fi fi
fi fi
##==---------------------------------------------------------------------------- ##==----------------------------------------------------------------------------
## MacOS compatibility - for local testing ## MacOS compatibility - for local testing

View File

@@ -272,3 +272,131 @@ function init_repo {
[[ "$output" = *"PRE_RELEASE_LABEL=pre.${short_ref}"* ]] && [[ "$output" = *"PRE_RELEASE_LABEL=pre.${short_ref}"* ]] &&
[[ "$output" = *"VERSION=$(date +%Y.%-m.1)+pre.${short_ref}"* ]] [[ "$output" = *"VERSION=$(date +%Y.%-m.1)+pre.${short_ref}"* ]]
} }
@test "increments the patch version after a fix commit (conventional commits)" {
init_repo
export current_version=1.2.3
export scheme="conventional_commits"
echo "fix: something" > fix.txt
git add fix.txt
git commit -m "fix: something"
run ../../version-increment.sh
print_run_info
[ "$status" -eq 0 ] &&
[[ "$output" = *"VERSION=1.2.4"* ]]
[[ "$output" != *"No conventional commit found"* ]]
}
@test "increments the patch version after a scoped fix commit (conventional commits)" {
init_repo
export current_version=1.2.3
export scheme="conventional_commits"
echo "fix: something" > fix.txt
git add fix.txt
git commit -m "fix(api): something"
run ../../version-increment.sh
print_run_info
[ "$status" -eq 0 ] &&
[[ "$output" = *"VERSION=1.2.4"* ]]
[[ "$output" != *"No conventional commit found"* ]]
}
@test "increments the major version after a breaking fix commit (conventional commits)" {
init_repo
export current_version=1.2.3
export scheme="conventional_commits"
echo "fix: breaking something" > fix.txt
git add fix.txt
git commit -m "fix!: something"
run ../../version-increment.sh
print_run_info
[ "$status" -eq 0 ] &&
[[ "$output" = *"VERSION=2.0.0"* ]]
[[ "$output" != *"No conventional commit found"* ]]
}
@test "increments the minor version after a feat commit (conventional commits)" {
init_repo
export current_version=1.2.3
export scheme="conventional_commits"
echo "new feature" > feat.txt
git add feat.txt
git commit -m "feat: something"
run ../../version-increment.sh
print_run_info
[ "$status" -eq 0 ] &&
[[ "$output" = *"VERSION=1.3.0"* ]]
[[ "$output" != *"No conventional commit found"* ]]
}
@test "increments the major version after a breaking feat commit (conventional commits)" {
init_repo
export current_version=1.2.3
export scheme="conventional_commits"
echo "breaking new feature" > feat.txt
git add feat.txt
git commit -m "feat!: something"
run ../../version-increment.sh
print_run_info
[ "$status" -eq 0 ] &&
[[ "$output" = *"VERSION=2.0.0"* ]]
[[ "$output" != *"No conventional commit found"* ]]
}
@test "increments the major version after a breaking change in the commit body (conventional commits)" {
init_repo
export current_version=1.2.3
export scheme="conventional_commits"
echo "breaking new fix" > feat.txt
git add feat.txt
git commit -m "Fix: something
BREAKING CHANGE: really important"
run ../../version-increment.sh
print_run_info
[ "$status" -eq 0 ] &&
[[ "$output" = *"VERSION=2.0.0"* ]]
[[ "$output" != *"No conventional commit found"* ]]
}
@test "increments the patch version by default if no conventional commits found and enabled (conventional commits)" {
init_repo
export current_version=1.2.3
export scheme="conventional_commits"
echo "some new change" > feat.txt
git add feat.txt
git commit -m "new change"
run ../../version-increment.sh
print_run_info
[ "$status" -eq 0 ] &&
[[ "$output" = *"VERSION=1.2.4"* ]]
[[ "$output" = *"No conventional commit found"* ]]
}

View File

@@ -30,7 +30,7 @@ fi
default_branch='main' default_branch='main'
# use release_branch if not empty # use release_branch if not empty
if [[ -n "${release_branch:-}" ]] ; then if [[ -n "${release_branch:-}" ]] ; then
default_branch="${release_branch}" default_branch="${release_branch}"
elif [[ -z "${BATS_VERSION:-}" ]] ; then elif [[ -z "${BATS_VERSION:-}" ]] ; then
# if we're _not_ testing, then _actually_ check the origin # if we're _not_ testing, then _actually_ check the origin
if [[ "${use_api:-}" == 'true' ]] ; then if [[ "${use_api:-}" == 'true' ]] ; then
@@ -48,6 +48,7 @@ elif [[ -z "${BATS_VERSION:-}" ]] ; then
fi fi
current_ref="${GITHUB_REF:-}" current_ref="${GITHUB_REF:-}"
git_commit_sha=${GITHUB_SHA:-}
if [[ "${use_api:-}" == 'true' ]] ; then if [[ "${use_api:-}" == 'true' ]] ; then
# because we cannot use `rev-parse` with the API, we'll take a punt that 9 characters is enough for uniqueness # because we cannot use `rev-parse` with the API, we'll take a punt that 9 characters is enough for uniqueness
@@ -55,7 +56,32 @@ if [[ "${use_api:-}" == 'true' ]] ; then
git_commit="$(echo "${GITHUB_SHA:0:9}" | sed 's/0*//')" # Also, trim leading zeros, because semver doesn't allow that in git_commit="$(echo "${GITHUB_SHA:0:9}" | sed 's/0*//')" # Also, trim leading zeros, because semver doesn't allow that in
else # the 'pre-release version' part, but we can't use the + char else # the 'pre-release version' part, but we can't use the + char
git_commit="$(git rev-parse --short HEAD | sed 's/0*//')" # to make it 'build metadata' as that's not supported in K8s git_commit="$(git rev-parse --short HEAD | sed 's/0*//')" # to make it 'build metadata' as that's not supported in K8s
fi # labels git_commit_sha="$(git rev-parse --short HEAD)" # labels
fi
##==----------------------------------------------------------------------------
## Conventional commits
if [[ "${scheme}" == 'conventional_commits' ]] ; then
# Get message from given commit
commit_message=$(git log -1 --pretty=format:%B "${git_commit_sha}")
# Check commit message header
found_match='false'
if [[ -n "$(echo "${commit_message}" | ${grep} -P "${pcre_conventional_commit_breaking}")" ]] ; then
increment='major'
found_match='true'
elif [[ -n "$(echo "${commit_message}" | ${grep} -P "${pcre_conventional_commit_minor}")" ]] ; then
increment='minor'
found_match='true'
elif [[ -n "$(echo "${commit_message}" | ${grep} -P "${pcre_conventional_commit_patch}")" ]] ; then
increment='patch'
found_match='true'
fi
if [[ "${found_match}" == 'false' ]] ; then
echo "⚠️ No conventional commit found, defaulting to ${increment} increment" 1>&2
fi
fi
##==---------------------------------------------------------------------------- ##==----------------------------------------------------------------------------
## Version increment ## Version increment

View File

@@ -46,7 +46,7 @@ if [[ -z "${current_version:-}" ]] ; then
echo "⚠️ No previous release version identified in git tags" echo "⚠️ No previous release version identified in git tags"
# brand new repo! (probably) # brand new repo! (probably)
case "${scheme}" in case "${scheme}" in
semver) semver | conventional_commits)
current_version="0.0.0" current_version="0.0.0"
;; ;;
calver) calver)