diff --git a/.github/workflows/test-and-release.yml b/.github/workflows/test-and-release.yml index f46778e..647ca3f 100644 --- a/.github/workflows/test-and-release.yml +++ b/.github/workflows/test-and-release.yml @@ -114,6 +114,21 @@ jobs: [[ "${{ 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) + - name: Get next version via Git with tag-prefix + uses: ./ + id: version-prefix + with: + scheme: 'semver' + use_api: false + tag_prefix: 'foo/bar@' + + - name: Check that it starts from 0.0.1 (since prefix doesn't exist) + shell: bash + run: | + [[ "${{ steps.version-prefix.outputs.current-version }}" == "0.0.0" ]] + [[ "${{ steps.version-prefix.outputs.version }}" == "0.0.1" ]] + [[ "${{ steps.version-prefix.outputs.prefixed-version }}" == "foo/bar@0.0.1" ]] + release: needs: - test-action-yml diff --git a/README.md b/README.md index 9eeadb7..f434371 100644 --- a/README.md +++ b/README.md @@ -132,22 +132,25 @@ Examples: | 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 | | | 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` | +| tag_prefix | Prefix the tag with a string (defaults to empty string). e.g. if set to `@org/product/` the action will filter by this prefix and return `@org/product/1.2.3` in `prefixed-version` output | No | | ### Outputs 📤 -| name | description | -| :--- | :--- | -| current-version | The current latest version detected from the git repositories tags | -| current-v-version | The current latest version detected from the git repositories tags, prefixed with a `v` character | -| version | The incremented version number (e.g. the next version) | -| v-version | The incremented version number (e.g. the next version), prefixed with a `v` character | -| major-version | Major number of the incremented version | -| minor-version | Minor number of the incremented version | -| patch-version | Patch number of the incremented version | -| pre-release-label | Pre-release label of the incremented version | -| major-v-version | Major 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 | +| name | description | +| :--- | :--- | +| current-version | The current latest version detected from the git repositories tags | +| current-v-version | The current latest version detected from the git repositories tags, prefixed with a `v` character | +| version | The incremented version number (e.g. the next version) | +| v-version | The incremented version number (e.g. the next version), prefixed with a `v` character | +| major-version | Major number of the incremented version | +| minor-version | Minor number of the incremented version | +| patch-version | Patch number of the incremented version | +| pre-release-label | Pre-release label of the incremented version | +| major-v-version | Major 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 | +| prefixed-version | Incremented version calculated, including a `tag_prefix` if specified | +| prefixed-v-version | Incremented version calculated, prefixed with a `v` charatcter, and also including a `tag_prefix` if specified | ## Contributing 💕 diff --git a/action.yml b/action.yml index 5975dde..994c024 100644 --- a/action.yml +++ b/action.yml @@ -40,6 +40,11 @@ inputs: 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 + tag_prefix: + description: | + Prefix the tag with a string (defaults to empty string). e.g. if set to `@org/product/` the action will filter by this prefix and return `@org/product/1.2.3` in `prefixed-version` output + required: false + default: false outputs: current-version: @@ -75,6 +80,12 @@ outputs: patch-v-version: description: 'Patch number of the incremented version, prefixed with a `v` charatcter' value: ${{ steps.version-increment.outputs.PATCH_V_VERSION }} + prefixed-version: + description: 'Incremented version calculated, including a `tag_prefix` if specified' + value: ${{ inputs.tag_prefix}}${{ steps.version-increment.outputs.VERSION }} + prefixed-v-version: + description: 'Incremented version calculated, prefixed with a `v` charatcter, and also including a `tag_prefix` if specified' + value: ${{ inputs.tag_prefix}}${{ steps.version-increment.outputs.V_VERSION }} runs: using: "composite" @@ -86,6 +97,7 @@ runs: github_token: ${{ github.token }} scheme: ${{ inputs.scheme }} use_api: ${{ inputs.use_api }} + tag_prefix: ${{ inputs.tag_prefix }} - id: version-increment run: "${GITHUB_ACTION_PATH}/version-increment.sh" diff --git a/shared.sh b/shared.sh index 8fe79cc..d1b605a 100644 --- a/shared.sh +++ b/shared.sh @@ -14,6 +14,27 @@ pcre_master_ver='^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9 pcre_allow_vprefix="^v{0,1}${pcre_master_ver:1}" pcre_old_calver='^(?P0|[1-9]\d*)-0{0,1}(?P0|[0-9]\d*)-R(?P0|[1-9]\d*)$' +##==---------------------------------------------------------------------------- +## Utility function for removing tag_prefix if present + +remove_prefix() { + local tag="$1" + if [[ -n "${tag_prefix:-}" ]]; then + # Escape special characters in tag_prefix + local escaped_prefix + escaped_prefix=$(printf '%s\n' "$tag_prefix" | sed 's/[][\/.^$*]/\\&/g') + + if [[ -z "$(echo "${tag}" | grep "^${tag_prefix}")" ]] ; then + echo "" + return + fi + # Use | as the delimiter to avoid conflicts with / + echo "${tag}" | sed "s|^${escaped_prefix}||" + else + echo "${tag}" + fi +} + ##==---------------------------------------------------------------------------- ## Conventional commit regexes ## see: https://www.conventionalcommits.org/en/v1.0.0/ @@ -51,6 +72,9 @@ if [[ "${use_api}" == 'true' ]] ; then fi fi +# Check if the tag_prefix is set, and if not, set it to an empty string +tag_prefix="${tag_prefix:-}" + ##==---------------------------------------------------------------------------- ## MacOS compatibility diff --git a/tests/test_version-increment.bats b/tests/test_version-increment.bats index 1638a7d..2aa5704 100644 --- a/tests/test_version-increment.bats +++ b/tests/test_version-increment.bats @@ -409,3 +409,24 @@ function init_repo { [[ "$output" = *"VERSION=1.2.4"* ]] [[ "$output" = *"No conventional commit found"* ]] } + + +@test "increments the patch version by default if no conventional commits found and enabled (conventional commits) (with tag_prefix)" { + init_repo + + export tag_prefix="@org/product@" + 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" = *"V_VERSION=v1.2.4"* ]] + [[ "$output" = *"No conventional commit found"* ]] +} diff --git a/tests/test_version-lookup.bats b/tests/test_version-lookup.bats index 7373e37..ebb03f1 100644 --- a/tests/test_version-lookup.bats +++ b/tests/test_version-lookup.bats @@ -72,6 +72,37 @@ function init_repo { [[ "$output" = *"CURRENT_V_VERSION=v0.1.2"* ]] } +@test "finds the current normal version with tag_prefix enabled" { + init_repo + + export tag_prefix="@org/product@" + + git tag @org/product@0.0.1 + git tag @org/product@0.1.1 + git tag @org/product@0.1.2 + + run version-lookup.sh + + print_run_info + [ "$status" -eq 0 ] && + [[ "$output" = *"CURRENT_VERSION=0.1.2"* ]] +} + +@test "tag_prefix enabled prefixes with a v" { + init_repo + + export tag_prefix="@org/product/" + + git tag @org/product/0.1.2 + + run version-lookup.sh + + print_run_info + [ "$status" -eq 0 ] && + [[ "$output" = *"CURRENT_VERSION=0.1.2"* ]] && + [[ "$output" = *"CURRENT_V_VERSION=v0.1.2"* ]] +} + @test "finds the current normal version even if there's a newer pre-release version" { init_repo @@ -85,6 +116,24 @@ function init_repo { [[ "$output" = *"CURRENT_VERSION=1.2.300"* ]] } +@test "finds only prefixed tags when tag_prefix set" { + init_repo + + export tag_prefix="my_product-" + + git tag my_product-0.1.2 + git tag my_product-0.1.3-dev.123 + git tag 2.4.5 + git tag 2.4.6-dev.456 + + run version-lookup.sh + + print_run_info + [ "$status" -eq 0 ] && + [[ "$output" = *"CURRENT_VERSION=0.1.2"* ]] && + [[ "$output" = *"CURRENT_V_VERSION=v0.1.2"* ]] +} + @test "returns 0.0.0 if no normal version detected" { init_repo @@ -107,6 +156,20 @@ function init_repo { [[ "$output" = *"CURRENT_VERSION=0.0.0"* ]] } +@test "returns 0.0.0 if no prefix version detected even if there's a non-prefix release version" { + init_repo + + export tag_prefix="code/" + + git tag 0.1.0 + + run version-lookup.sh + + print_run_info + [ "$status" -eq 0 ] && + [[ "$output" = *"CURRENT_VERSION=0.0.0"* ]] +} + @test "returns a calver if no normal version detected and calver scheme specified" { init_repo diff --git a/version-lookup.sh b/version-lookup.sh index 1780cc9..3d9120b 100755 --- a/version-lookup.sh +++ b/version-lookup.sh @@ -32,12 +32,18 @@ if [[ "${use_api:-}" == 'true' ]] ; then -H "X-GitHub-Api-Version: 2022-11-28" \ "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/git/matching-refs/tags/" \ | jq -r '.[].ref' | sed 's|refs/tags/||g' \ - | { grep_p "${pcre_allow_vprefix}" || true; } | sed 's/^v//g' | sort -V | tail -n 1 + | while read -r tag; do remove_prefix "$tag"; done \ + | { grep_p "${pcre_allow_vprefix}" || true; } \ + | sed 's/^v//g' \ + | sort -V | tail -n 1 )" else current_version="$( git tag -l \ - | { grep_p "${pcre_allow_vprefix}" || true; } | sed 's/^v//g' | sort -V | tail -n 1 + | while read -r tag; do remove_prefix "$tag"; done \ + | { grep_p "${pcre_allow_vprefix}" || true; } \ + | sed 's/^v//g' \ + | sort -V | tail -n 1 )" fi