diff --git a/action.yml b/action.yml index 5975dde..4f64fd7 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: | + Field to prefix the tag with a string (defaults to empty string). This is useful for projects that use a prefix in their tags. E.g. if set to `@org/product` the action will return `@org/product/1.2.3` as version. + required: false + default: false outputs: current-version: @@ -86,6 +91,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..4f64f5b 100644 --- a/shared.sh +++ b/shared.sh @@ -11,7 +11,11 @@ export LC_ALL=C.UTF-8 pcre_semver='^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' pcre_master_ver='^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)$' -pcre_allow_vprefix="^v{0,1}${pcre_master_ver:1}" + +# Extended regex to allow arbitrary prefixes before the semver +pcre_allow_prefix='^.*(?P'"${pcre_master_ver:1}"')$' + +pcre_allow_vprefix="^v{0,1}${pcre_allow_prefix:1}" pcre_old_calver='^(?P0|[1-9]\d*)-0{0,1}(?P0|[0-9]\d*)-R(?P0|[1-9]\d*)$' ##==---------------------------------------------------------------------------- @@ -51,6 +55,15 @@ 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:-}" + +# Add a trailing @ to tag_prefix if it doesn't already end with one +if [[ -n "$tag_prefix" && "${tag_prefix: -1}" != "@" ]]; then + tag_prefix="${tag_prefix}@" +fi + + ##==---------------------------------------------------------------------------- ## MacOS compatibility diff --git a/tests/test_version-increment.bats b/tests/test_version-increment.bats index 1638a7d..68db626 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="@org/product@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=@org/product@1.2.4"* ]] + [[ "$output" = *"V_VERSION=@org/product@v1.2.4"* ]] + [[ "$output" = *"No conventional commit found"* ]] +} diff --git a/tests/test_version-lookup.bats b/tests/test_version-lookup.bats index 7373e37..57c2932 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 diff --git a/version-increment.sh b/version-increment.sh index 9fef875..a754abe 100755 --- a/version-increment.sh +++ b/version-increment.sh @@ -15,8 +15,8 @@ fi if [[ -z "${current_version:-}" ]] ; then echo "🛑 Environment variable 'current_version' is unset or empty" 1>&2 input_errors='true' -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 +elif [[ -z "$(echo "${current_version}" | grep_p "${pcre_allow_prefix}")" ]] ; then + echo "🛑 Environment variable 'current_version' is not a valid normal version (M.m.p) or (prefix@M.m.p)" 1>&2 input_errors='true' fi @@ -108,7 +108,8 @@ elif [[ "${increment}" == 'major' ]] ; then version_array[2]='0' fi -new_version="${version_array[0]}.${version_array[1]}.${version_array[2]}" +new_version="${tag_prefix}${version_array[0]}.${version_array[1]}.${version_array[2]}" +new_v_version="${tag_prefix}v${version_array[0]}.${version_array[1]}.${version_array[2]}" # check we haven't accidentally forgotten to set scheme to calver # TODO: provide an override "I know my version numbers are > 2020, but it's semver!" option @@ -139,7 +140,7 @@ echo "â„šī¸ The new version is ${new_version}" # shellcheck disable=SC2129 echo "VERSION=${new_version}" >> "${GITHUB_OUTPUT}" -echo "V_VERSION=v${new_version}" >> "${GITHUB_OUTPUT}" +echo "V_VERSION=${new_v_version}" >> "${GITHUB_OUTPUT}" echo "MAJOR_VERSION=${version_array[0]}" >> "${GITHUB_OUTPUT}" echo "MINOR_VERSION=${version_array[1]}" >> "${GITHUB_OUTPUT}" echo "PATCH_VERSION=${version_array[2]}" >> "${GITHUB_OUTPUT}" diff --git a/version-lookup.sh b/version-lookup.sh index 1780cc9..a06cd6c 100755 --- a/version-lookup.sh +++ b/version-lookup.sh @@ -23,6 +23,21 @@ fi ##==---------------------------------------------------------------------------- ## Version parsing +# Function to extract the semver part from the tag +extract_semver() { + 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') + + # Use | as the delimiter to avoid conflicts with / + echo "${tag}" | sed "s|^${escaped_prefix}||" + else + echo "${tag}" + fi +} + # detect current version - removing "v" from start of tag if it exists if [[ "${use_api:-}" == 'true' ]] ; then current_version="$( @@ -32,12 +47,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 + | { grep_p "${pcre_allow_vprefix}" || true; } \ + | sed 's/^v//g' \ + | while read -r tag; do extract_semver "$tag"; done \ + | 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 + | { grep_p "${pcre_allow_vprefix}" || true; } \ + | sed 's/^v//g' \ + | while read -r tag; do extract_semver "$tag"; done \ + | sort -V | tail -n 1 )" fi