2 Commits

Author SHA1 Message Date
Phil Jay
3d5d532814 Avoid version 2020 warning
e.g.

```
🛑 The major version number is greater than 2020, but the scheme is not set to 'calver'
```
2023-10-19 00:25:49 +11:00
Phil Jay
b78a17540f Test use_api branch 2023-10-19 00:20:53 +11:00
9 changed files with 99 additions and 497 deletions

View File

@@ -9,134 +9,12 @@ on:
- '**' - '**'
jobs: jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@2.0.0
with:
check_together: 'yes'
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Get next version
uses: actions/checkout@v4 uses: reecetech/version-increment@use_api
id: version
- name: Setup bats
uses: bats-core/bats-action@2.0.0
with: with:
bats-version: 1.11.0
- name: Test
run: bats tests/*.bats
test-api-mode: # requires github API, didn't want to mock it
runs-on: ubuntu-latest
env:
github_token: ${{ github.token }}
steps:
- name: Checkout code # have to checkout to have the source code available
uses: actions/checkout@v4
- name: Remove .git directory # remove the git directory to make the testing valid
run: rm -rf .git/
- name: Test lookup version (with API)
id: version-lookup
env:
use_api: 'true'
run: ./version-lookup.sh
- name: Check lookup result
shell: bash
run: '[[ -n "${{ steps.version-lookup.outputs.CURRENT_VERSION }}" ]]'
- name: Test increment version (with API)
id: version-increment
run: ./version-increment.sh
env:
current_version: ${{ steps.version-lookup.outputs.CURRENT_VERSION }}
scheme: calver scheme: calver
use_api: 'true'
- name: Check increment result
shell: bash
run: '[[ "$(date +%Y.%-m)" == "$(echo "${{ steps.version-increment.outputs.VERSION }}" | cut -d "." -f 1-2)" ]]'
test-action-yml: # integration testing
needs:
- lint
- test
- test-api-mode
strategy:
matrix:
os:
- macos-latest
- ubuntu-latest
- windows-latest
fail-fast: true
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code # have to checkout to have the source code available
uses: actions/checkout@v4
- name: Remove .git directory # remove the git directory to make the testing valid
shell: bash
run: rm -rf .git/
- name: Get next version via API
uses: ./
id: version-via-api
with:
scheme: 'calver'
use_api: true use_api: true
- name: Checkout code
uses: actions/checkout@v4
- name: Get next version via Git
uses: ./
id: version-via-git
with:
scheme: 'calver'
use_api: false
- name: Check results agree
shell: bash
run: |
[[ "${{ steps.version-via-api.outputs.current-version }}" == "${{ steps.version-via-git.outputs.current-version }}" ]]
[[ "${{ steps.version-via-api.outputs.major-version }}" == "${{ steps.version-via-git.outputs.major-version }}" ]]
[[ "${{ steps.version-via-api.outputs.minor-version }}" == "${{ steps.version-via-git.outputs.minor-version }}" ]]
[[ "${{ steps.version-via-api.outputs.patch-version }}" == "${{ steps.version-via-git.outputs.patch-version }}" ]]
# Don't test the full version or pre-version, since the number of digits is likely to be different (9 via api vs. 7 via git)
release:
needs:
- test-action-yml
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Lookup version
id: version-lookup
run: ./version-lookup.sh
- name: Increment version
id: version-increment
run: ./version-increment.sh
env:
current_version: ${{ steps.version-lookup.outputs.CURRENT_VERSION }}
scheme: calver
- name: Release version
uses: softprops/action-gh-release@v1
if: ${{ github.ref_name == github.event.repository.default_branch }}
with:
draft: false
prerelease: false
tag_name: "${{ steps.version-increment.outputs.VERSION }}"

View File

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

View File

@@ -1,19 +1,15 @@
# Version Increment # Version Increment
## Use 📄 ## 📄 Use
> [!NOTE] ### ⌨️ Example
> This action is confirmed to work on all three of GitHub's hosted runners -
> `ubuntu-latest`, `macos-latest` and `windows-latest` - at the point in time of the release of the action
### Example ⌨️
```yaml ```yaml
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Get next version - name: Get next version
uses: reecetech/version-increment@2024.4.3 uses: reecetech/version-increment@2023.9.3
id: version id: version
with: with:
scheme: semver scheme: semver
@@ -27,20 +23,7 @@
context: . context: .
``` ```
#### API mode 🔗 ### 🔖 semver
Maybe you don't want to checkout your code in the job that calculates the version number. That's okay, you can
use the API mode:
```yaml
- name: Get next version
uses: reecetech/version-increment@2024.4.3
id: version
with:
use_api: true
```
### semver 🔖
This action will detect the current latest _normal_ semantic version (semver) from the tags in This action will detect the current latest _normal_ semantic version (semver) from the tags in
a git repository. It will increment the version as directed (by default: +1 to a git repository. It will increment the version as directed (by default: +1 to
@@ -54,7 +37,7 @@ e.g. `1.2.7`
See: https://semver.org/spec/v2.0.0.html See: https://semver.org/spec/v2.0.0.html
### calver (semver compliant) 📅 ### 📅 calver (semver compliant)
Optionally, this action can provide semver compliant calendar versions (calver). Optionally, this action can provide semver compliant calendar versions (calver).
In this calver scheme, the semver major, minor and patch digits map to year, In this calver scheme, the semver major, minor and patch digits map to year,
@@ -74,23 +57,7 @@ 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) 💡 ### 🎋 Default branch vs. any other branch
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** **Default branch**
@@ -101,17 +68,6 @@ Examples:
* `1.2.7` * `1.2.7`
* `2021.6.2` * `2021.6.2`
You may override the branch to consider the release branch if it is not the default branch, by providing a specific
release branch name as an input. For example:
```yaml
- name: Get next version
uses: reecetech/version-increment@2023.10.1
id: version
with:
release_branch: publish
```
**Any other branch** **Any other branch**
The action will return a _pre-release_ version if any other branch is detected The action will return a _pre-release_ version if any other branch is detected
@@ -123,17 +79,16 @@ Examples:
* `1.2.7-pre.41218aa78` * `1.2.7-pre.41218aa78`
* `2021.6.2-pre.32fd19841` * `2021.6.2-pre.32fd19841`
### Inputs 📥 ### 📥 Inputs
| name | description | required | default | | name | description | required | default |
| :--- | :--- | :--- | :--- | | :--- | :--- | :--- | :--- |
| scheme | The versioning scheme in-use, either `semver`, `calver` or `conventional_commits` | No | `semver` | | scheme | The versioning scheme in-use, either `semver` or `calver` | 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 | |
| use_api | Use the GitHub API to discover current tags, which avoids the need for a git checkout, but requires `curl` and `jq` | No | `false` |
### Outputs 📤 ### 📤 Outputs
| name | description | | name | description |
| :--- | :--- | | :--- | :--- |
@@ -149,7 +104,7 @@ Examples:
| minor-v-version | Minor number of the incremented version, prefixed with a `v` character | | minor-v-version | Minor number of the incremented version, prefixed with a `v` character |
| patch-v-version | Patch number of the incremented version, prefixed with a `v` character | | patch-v-version | Patch number of the incremented version, prefixed with a `v` character |
## Contributing 💕 ## 💕 Contributing
Please raise a pull request, but note the testing tools below Please raise a pull request, but note the testing tools below

View File

@@ -8,14 +8,7 @@ branding:
inputs: inputs:
scheme: scheme:
description: | description: 'Versioning scheme - semver, or, calver (defaults to semver)'
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:
@@ -26,9 +19,6 @@ 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,24 +26,20 @@ inputs:
description: 'Specify a non-default branch to use for the release tag (the one without -pre)' description: 'Specify a non-default branch to use for the release tag (the one without -pre)'
required: false required: false
type: string type: string
use_api:
description: 'Use the GitHub API to discover current tags, which avoids the need for a git checkout, but requires `curl` and `jq`'
required: false
default: false
outputs: outputs:
current-version: current-version:
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` character' description: 'Current normal version detected, prefixed with a `v` charatcter'
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 }}
@@ -80,21 +66,17 @@ runs:
using: "composite" using: "composite"
steps: steps:
- id: version-lookup - id: version-lookup
run: "${GITHUB_ACTION_PATH}/version-lookup.sh" run: ${{ github.action_path }}/version-lookup.sh
shell: bash shell: bash
env: env:
github_token: ${{ github.token }}
scheme: ${{ inputs.scheme }} scheme: ${{ inputs.scheme }}
use_api: ${{ inputs.use_api }}
- id: version-increment - id: version-increment
run: "${GITHUB_ACTION_PATH}/version-increment.sh" run: ${{ github.action_path }}/version-increment.sh
shell: bash shell: bash
env: env:
current_version: ${{ steps.version-lookup.outputs.CURRENT_VERSION }} current_version: ${{ steps.version-lookup.outputs.CURRENT_VERSION }}
increment: ${{ inputs.increment }} increment: ${{ inputs.increment }}
github_token: ${{ github.token }}
pep440: ${{ inputs.pep440 }} pep440: ${{ inputs.pep440 }}
scheme: ${{ inputs.scheme }} scheme: ${{ inputs.scheme }}
release_branch: ${{ inputs.release_branch }} release_branch: ${{ inputs.release_branch }}
use_api: ${{ inputs.use_api }}

View File

@@ -2,9 +2,6 @@
# shellcheck disable=SC2034 # shellcheck disable=SC2034
set -euo pipefail set -euo pipefail
# Force UTF-8 for all commands, for Git-Bash on Windows compatibility
export LC_ALL=C.UTF-8
##==---------------------------------------------------------------------------- ##==----------------------------------------------------------------------------
## SemVer regexes ## SemVer regexes
## see: https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string ## see: https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
@@ -14,21 +11,13 @@ 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' && "${scheme}" != 'conventional_commits' ]] ; then if [[ "${scheme}" != 'semver' && "${scheme}" != 'calver' ]] ; then
echo "🛑 Value of 'scheme' is not valid, choose from 'semver', 'calver' or 'conventional_commits" 1>&2 echo "🛑 Value of 'scheme' is not valid, choose from 'semver' or 'calver'" 1>&2
input_errors='true' input_errors='true'
fi fi
@@ -38,49 +27,18 @@ if [[ "${pep440}" != 'false' && "${pep440}" != 'true' ]] ; then
input_errors='true' input_errors='true'
fi fi
use_api="${use_api:-false}"
if [[ "${use_api}" != 'false' && "${use_api}" != 'true' ]] ; then
echo "🛑 Value of 'use_api' is not valid, choose from 'false' or 'true'" 1>&2
input_errors='true'
fi
if [[ "${use_api}" == 'true' ]] ; then
if [[ -z "${github_token:-}" ]] ; then
echo "🛑 'use_api' is true, but environment variable 'github_token' is not set" 1>&2
input_errors='true'
fi
fi
##==---------------------------------------------------------------------------- ##==----------------------------------------------------------------------------
## MacOS compatibility ## MacOS compatibility - for local testing
export use_perl="false" export grep="grep"
export use_gnugrep="false" if [[ "$(uname)" == "Darwin" ]] ; then
if [[ "${GITHUB_ACTIONS:-}" == 'true' && "$(uname)" == 'Darwin' ]] ; then export grep="ggrep"
export use_perl="true" if ! grep --version 1>/dev/null ; then
elif [[ "$(uname)" == 'Darwin' ]] ; then
if perl --version 1>/dev/null ; then
export use_perl="true"
elif ! ggrep --version 1>/dev/null ; then
echo "🛑 GNU grep not installed, try brew install coreutils" 1>&2 echo "🛑 GNU grep not installed, try brew install coreutils" 1>&2
exit 9 exit 9
else
export use_gnugrep="true"
fi fi
fi fi
function grep_p() {
if [[ "${use_perl}" == 'true' ]] ; then
perl -ne "print if /${1}/"
elif [[ "${use_gnugrep}" == 'true' ]] ; then
# shellcheck disable=SC2086
ggrep -P "${1}"
else
# shellcheck disable=SC2086
command grep -P "${1}"
fi
}
##==---------------------------------------------------------------------------- ##==----------------------------------------------------------------------------
## Non GitHub compatibility - for testing both locally and in BATS ## Non GitHub compatibility - for testing both locally and in BATS

View File

@@ -1,15 +1,6 @@
#!/usr/bin/env bats #!/usr/bin/env bats
# vim: set ft=sh sw=4 : # vim: set ft=sh sw=4 :
setup() {
# get the containing directory of this file
# use $BATS_TEST_FILENAME instead of ${BASH_SOURCE[0]} or $0,
# as those will point to the bats executable's location or the preprocessed file respectively
DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )"
# make executables in src/ visible to PATH
PATH="$DIR/../:$PATH"
}
load helper_print-info load helper_print-info
export repo=".tmp_testing/repo" export repo=".tmp_testing/repo"
@@ -31,7 +22,7 @@ function init_repo {
@test "fails if no current_version given" { @test "fails if no current_version given" {
init_repo init_repo
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 8 ] && [ "$status" -eq 8 ] &&
@@ -43,7 +34,7 @@ function init_repo {
export current_version=1.3.5-prerelease export current_version=1.3.5-prerelease
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 8 ] && [ "$status" -eq 8 ] &&
@@ -55,7 +46,7 @@ function init_repo {
export scheme="foover" export scheme="foover"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 8 ] && [ "$status" -eq 8 ] &&
@@ -67,7 +58,7 @@ function init_repo {
export pep440="yes" export pep440="yes"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 8 ] && [ "$status" -eq 8 ] &&
@@ -79,7 +70,7 @@ function init_repo {
export increment="critical" export increment="critical"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 8 ] && [ "$status" -eq 8 ] &&
@@ -99,7 +90,7 @@ function init_repo {
export current_version=1.2.3 export current_version=1.2.3
export increment="patch" export increment="patch"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -115,7 +106,7 @@ function init_repo {
export current_version=1.2.3 export current_version=1.2.3
export increment="minor" export increment="minor"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -132,7 +123,7 @@ function init_repo {
export pep404="false" export pep404="false"
export increment="minor" export increment="minor"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -148,7 +139,7 @@ function init_repo {
export current_version=1.2.3 export current_version=1.2.3
export increment="major" export increment="major"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -165,7 +156,7 @@ function init_repo {
export pep404="true" export pep404="true"
export increment="major" export increment="major"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -181,7 +172,7 @@ function init_repo {
export current_version=1.2.3 export current_version=1.2.3
export increment="major" export increment="major"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -198,7 +189,7 @@ function init_repo {
export current_version=2020.6.4 export current_version=2020.6.4
export scheme="calver" export scheme="calver"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -211,7 +202,7 @@ function init_repo {
export current_version="$(date +%Y.%-m.123)" export current_version="$(date +%Y.%-m.123)"
export scheme="calver" export scheme="calver"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -225,7 +216,7 @@ function init_repo {
export GITHUB_REF="refs/heads/super-awesome-feature" export GITHUB_REF="refs/heads/super-awesome-feature"
export short_ref="$(git rev-parse --short HEAD | sed 's/0*//')" export short_ref="$(git rev-parse --short HEAD | sed 's/0*//')"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -240,7 +231,7 @@ function init_repo {
export GITHUB_REF="refs/heads/releases" export GITHUB_REF="refs/heads/releases"
export release_branch="releases" export release_branch="releases"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -257,7 +248,7 @@ function init_repo {
export GITHUB_REF="refs/heads/super-awesome-python" export GITHUB_REF="refs/heads/super-awesome-python"
export short_ref="$(git rev-parse --short HEAD | sed 's/0*//')" export short_ref="$(git rev-parse --short HEAD | sed 's/0*//')"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -274,138 +265,10 @@ function init_repo {
export GITHUB_REF="refs/heads/super-awesome-python" export GITHUB_REF="refs/heads/super-awesome-python"
export short_ref="$(git rev-parse --short HEAD | sed 's/0*//')" export short_ref="$(git rev-parse --short HEAD | sed 's/0*//')"
run version-increment.sh run ../../version-increment.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
[[ "$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

@@ -5,15 +5,6 @@ load helper_print-info
export repo=".tmp_testing/repo" export repo=".tmp_testing/repo"
setup() {
# get the containing directory of this file
# use $BATS_TEST_FILENAME instead of ${BASH_SOURCE[0]} or $0,
# as those will point to the bats executable's location or the preprocessed file respectively
DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )"
# make executables in src/ visible to PATH
PATH="$DIR/../:$PATH"
}
function init_repo { function init_repo {
rm -rf "${repo}" && rm -rf "${repo}" &&
mkdir -p "${repo}" && mkdir -p "${repo}" &&
@@ -31,7 +22,7 @@ function init_repo {
export scheme="foover" export scheme="foover"
run version-lookup.sh run ../../version-lookup.sh
print_run_info print_run_info
[ "$status" -eq 8 ] && [ "$status" -eq 8 ] &&
@@ -52,7 +43,7 @@ function init_repo {
git tag 0.1.1 git tag 0.1.1
git tag 0.1.2 git tag 0.1.2
run version-lookup.sh run ../../version-lookup.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -64,7 +55,7 @@ function init_repo {
git tag 0.1.2 git tag 0.1.2
run version-lookup.sh run ../../version-lookup.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -78,7 +69,7 @@ function init_repo {
git tag 1.2.300 git tag 1.2.300
git tag 1.2.301-dev.234 git tag 1.2.301-dev.234
run version-lookup.sh run ../../version-lookup.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -88,7 +79,7 @@ function init_repo {
@test "returns 0.0.0 if no normal version detected" { @test "returns 0.0.0 if no normal version detected" {
init_repo init_repo
run version-lookup.sh run ../../version-lookup.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -100,7 +91,7 @@ function init_repo {
git tag 0.0.1-dev.999 git tag 0.0.1-dev.999
run version-lookup.sh run ../../version-lookup.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
@@ -112,19 +103,31 @@ function init_repo {
export scheme="calver" export scheme="calver"
run version-lookup.sh run ../../version-lookup.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&
[[ "$output" = *"CURRENT_VERSION=$(date '+%Y.%-m.0')"* ]] [[ "$output" = *"CURRENT_VERSION=$(date '+%Y.%-m.0')"* ]]
} }
@test "converts from older calver scheme automatically" {
init_repo
git tag 2020-09-R2
run ../../version-lookup.sh
print_run_info
[ "$status" -eq 0 ] &&
[[ "$output" = *"CURRENT_VERSION=2020.9.2"* ]]
}
@test "strips v from the version" { @test "strips v from the version" {
init_repo init_repo
git tag v3.4.5 git tag v3.4.5
run version-lookup.sh run ../../version-lookup.sh
print_run_info print_run_info
[ "$status" -eq 0 ] && [ "$status" -eq 0 ] &&

View File

@@ -15,7 +15,7 @@ fi
if [[ -z "${current_version:-}" ]] ; then if [[ -z "${current_version:-}" ]] ; then
echo "🛑 Environment variable 'current_version' is unset or empty" 1>&2 echo "🛑 Environment variable 'current_version' is unset or empty" 1>&2
input_errors='true' input_errors='true'
elif [[ -z "$(echo "${current_version}" | grep_p "${pcre_master_ver}")" ]] ; then elif [[ -z "$(echo "${current_version}" | ${grep} -P "${pcre_master_ver}")" ]] ; then
echo "🛑 Environment variable 'current_version' is not a valid normal version (M.m.p)" 1>&2 echo "🛑 Environment variable 'current_version' is not a valid normal version (M.m.p)" 1>&2
input_errors='true' input_errors='true'
fi fi
@@ -28,60 +28,20 @@ fi
## Git info - branch names, commit short ref ## Git info - branch names, commit short ref
default_branch='main' default_branch='main'
# if we're _not_ testing, then _actually_ check the origin
if [[ -z "${BATS_VERSION:-}" ]] ; then
default_branch="$(git remote show origin | ${grep} 'HEAD branch' | cut -d ' ' -f 5)"
fi
# 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
# if we're _not_ testing, then _actually_ check the origin
if [[ "${use_api:-}" == 'true' ]] ; then
default_branch="$(
curl -fsSL \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${github_token}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}" \
| jq -r '.default_branch'
)"
else
default_branch="$(git remote show origin | grep 'HEAD branch' | cut -d ' ' -f 5)"
fi
fi fi
current_ref="${GITHUB_REF:-}" current_ref="${GITHUB_REF:-}"
git_commit_sha=${GITHUB_SHA:-} git_commit="$(git rev-parse --short HEAD | sed 's/0*//')" # trim leading zeros, because semver doesn't allow that in
# the 'pre-release version' part, but we can't use the + char
if [[ "${use_api:-}" == 'true' ]] ; then # to make it 'build metadata' as that's not supported in K8s
# because we cannot use `rev-parse` with the API, we'll take a punt that 9 characters is enough for uniqueness # labels
# shellcheck disable=SC2001
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
git_commit="$(git rev-parse --short HEAD | sed 's/0*//')" # to make it 'build metadata' as that's not supported in K8s
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
@@ -128,7 +88,7 @@ if [[ "${current_ref}" != "refs/heads/${default_branch}" ]] ; then
echo "PRE_RELEASE_LABEL=${pre_release}" >> "${GITHUB_OUTPUT}" echo "PRE_RELEASE_LABEL=${pre_release}" >> "${GITHUB_OUTPUT}"
fi fi
if [[ -z "$(echo "${new_version}" | grep_p "${pcre_semver}")" ]] ; then if [[ -z "$(echo "${new_version}" | ${grep} -P "${pcre_semver}")" ]] ; then
echo "🛑 Version incrementing has failed to produce a semver compliant version" 1>&2 echo "🛑 Version incrementing has failed to produce a semver compliant version" 1>&2
echo " See: https://semver.org/spec/v2.0.0.html" 1>&2 echo " See: https://semver.org/spec/v2.0.0.html" 1>&2
echo " Failed version string: '${new_version}'" 1>&2 echo " Failed version string: '${new_version}'" 1>&2

View File

@@ -10,35 +10,39 @@ if [[ "${input_errors}" == 'true' ]] ; then
exit 8 exit 8
fi fi
##==----------------------------------------------------------------------------
## MacOS compatibility - for local testing
export grep="grep"
if [[ "$(uname)" == "Darwin" ]] ; then
export grep="ggrep"
if ! grep --version 1>/dev/null ; then
echo "🛑 GNU grep not installed, try brew install coreutils" 1>&2
exit 9
fi
fi
##==---------------------------------------------------------------------------- ##==----------------------------------------------------------------------------
## Get tags from GitHub repo ## Get tags from GitHub repo
# Skip if testing, or if use_api is true, otherwise pull tags # Skip if testing, otherwise pull tags
if [[ -z "${BATS_VERSION:-}" ]] ; then if [[ -z "${BATS_VERSION:-}" ]] ; then
if [[ "${use_api:-}" != 'true' ]] ; then git fetch --quiet --force origin 'refs/tags/*:refs/tags/*'
git fetch --quiet --force origin 'refs/tags/*:refs/tags/*'
fi
fi fi
##==---------------------------------------------------------------------------- ##==----------------------------------------------------------------------------
## Version parsing ## Version parsing
# detect current version - removing "v" from start of tag if it exists # detect current version - removing "v" from start of tag if it exists
if [[ "${use_api:-}" == 'true' ]] ; then current_version="$(git tag -l | { ${grep} -P "${pcre_allow_vprefix}" || true; } | sed 's/^v//g' | sort -V | tail -n 1)"
current_version="$(
curl -fsSL \ # support transition from an old reecetech calver style (yyyy-mm-Rr, where R is the literal `R`, and r is the nth release for the month)
-H "Accept: application/vnd.github+json" \ if [[ -z "${current_version:-}" ]] ; then
-H "Authorization: Bearer ${github_token}" \ current_version="$(git tag -l | { ${grep} -P "${pcre_old_calver}" || true; } | sort -V | tail -n 1)"
-H "X-GitHub-Api-Version: 2022-11-28" \ if [[ -n "${current_version:-}" ]] ; then
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/git/matching-refs/tags/" \ # convert - to . and drop leading zeros & the R
| jq -r '.[].ref' | sed 's|refs/tags/||g' \ current_version="$(echo "${current_version}" | sed -r 's/^([0-9]+)-0{0,1}([0-9]+)-R0{0,1}([0-9]+)$/\1.\2.\3/')"
| { grep_p "${pcre_allow_vprefix}" || true; } | sed 's/^v//g' | sort -V | tail -n 1 fi
)"
else
current_version="$(
git tag -l \
| { grep_p "${pcre_allow_vprefix}" || true; } | sed 's/^v//g' | sort -V | tail -n 1
)"
fi fi
# handle no version detected - start versioning! # handle no version detected - start versioning!
@@ -46,7 +50,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 | conventional_commits) semver)
current_version="0.0.0" current_version="0.0.0"
;; ;;
calver) calver)