From 2031e56eb4edb8115ce8ba07cbbfb457149d865d Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Tue, 5 Mar 2024 11:18:02 -0800 Subject: [PATCH] feat: releasetagcheck with version output (#158) * feat: releasetagcheck with version output * fix: rename to VERSION_PREFIX * docs: fix readme --- release/release-tag-check/README.md | 52 +++++++++ release/release-tag-check/action.yml | 6 ++ .../scripts/releasetagcheck.sh | 43 +++++--- .../scripts/releasetagcheck.test.sh | 101 ++++++++++++++++++ 4 files changed, 185 insertions(+), 17 deletions(-) create mode 100644 release/release-tag-check/README.md create mode 100755 release/release-tag-check/scripts/releasetagcheck.test.sh diff --git a/release/release-tag-check/README.md b/release/release-tag-check/README.md new file mode 100644 index 0000000..cacfa64 --- /dev/null +++ b/release/release-tag-check/README.md @@ -0,0 +1,52 @@ +# Release Tag Check + +Checks if git tag is a release or pre-release, and tells you the version. + +## Inputs + +These are passed by setting environment variables. + +- GITHUB_REF + - Automatically available in a Github workflow. Will only work with `tag` pushes, otherwise the extracted ref will have an extra `/` + - If a tag is the git ref, the prefix will be `refs/tags/`, if a branch is the git ref, the prefix will be `refs/heads/` (10 characters vs 11 characters). +- RELEASE_REGEX + - Used to determine if the tag pushed is the expected format of a release + - Defaults to: `^v[0-9]+\.[0-9]+\.[0-9]+$` +- PRE_RELEASE_REGEX + - Used to determine if the tag pushed is the expected format of a pre-release + - Defaults to: `^v[0-9]+\.[0-9]+\.[0-9]+-(.+)$` +- VERSION_PREFIX + - Used for determining the `release-version` and `pre-release-version` outputs only. This will not affect how the release/pre-release regexes determine the output. + - Defaults to: `v` + + +## Outputs + +- `is-release` - whether the tag name conformed to the release regex (`refs/tag/`) + - If yes, `release-version` should be set to the version. Without the `$VERSION_PREFIX` on the tag name +- `is-pre-release` whether the tag name conformed to the pre-release regex (`refs/tag/`) + - If yes, `pre-release-version` should be set to the version. Without the `$VERSION_PREFIX` on the tag name + + +## Examples + +1. Ref: refs/tag/v1.2.3-beta.0 + - is-pre-release: true + - is-release: false + - pre-release-version: 1.2.3-beta.0 + - release-version: null +2. Ref: refs/tag/v1.2.3 + - is-pre-release: false + - is-release: true + - pre-release-version: null + - release-version: 1.2.3 +3. Ref: refs/tag/release-v1.2.3 (must override release_regex, and VERSION_PREFIX) + - is-pre-release: false + - is-release: true + - pre-release-version: null + - release-version: 1.2.3 +4. Ref: refs/head/v1.2.3 + - is-pre-release: false + - is-release: false + - pre-release-version: null + - release-version: false diff --git a/release/release-tag-check/action.yml b/release/release-tag-check/action.yml index ed7eeab..de9ec27 100644 --- a/release/release-tag-check/action.yml +++ b/release/release-tag-check/action.yml @@ -7,6 +7,12 @@ outputs: is-release: description: '`true if the release is final' value: ${{ steps.check.outputs.is-release }} + release-version: + description: 'The version of the release' + value: ${{ steps.check.outputs.release-version }} + pre-release-version: + description: 'The version of the pre-release' + value: ${{ steps.check.outputs.pre-release-version }} runs: using: composite steps: diff --git a/release/release-tag-check/scripts/releasetagcheck.sh b/release/release-tag-check/scripts/releasetagcheck.sh index fa5df11..484e92f 100755 --- a/release/release-tag-check/scripts/releasetagcheck.sh +++ b/release/release-tag-check/scripts/releasetagcheck.sh @@ -2,22 +2,13 @@ set -euo pipefail -## -# Check if git tag is a release or pre-release. -# -# Examples: -# 1. v1.2.3-beta.0 -> pre-release -# 2. v1.2.3 -> release -# -# Override default regex by setting these env vars: -# - RELEASE_REGEX -# - PRE_RELEASE_REGEX -## - # Configurable regex patterns with defaults RELEASE_REGEX=${RELEASE_REGEX:-"^v[0-9]+\.[0-9]+\.[0-9]+$"} PRE_RELEASE_REGEX=${PRE_RELEASE_REGEX:-"^v[0-9]+\.[0-9]+\.[0-9]+-(.+)$"} +# Configurable prefix removal with default +VERSION_PREFIX=${VERSION_PREFIX:-"v"} + if [[ -z "${GITHUB_REF:-}" ]]; then echo "ERROR: GITHUB_REF environment variable is required" exit 1 @@ -25,14 +16,32 @@ fi TAG_REF="${GITHUB_REF}" TAG_NAME=${TAG_REF:10} # remove "refs/tags/" prefix -echo "The tag name is $TAG_NAME". + +# Remove specified prefix from the version tag +VERSION_TAG=${TAG_NAME#"${VERSION_PREFIX}"} + +echo "Tag: $TAG_NAME" echo "Checking if $TAG_NAME is a release or pre-release tag..." + IS_RELEASE=false IS_PRE_RELEASE=false +RELEASE_VERSION="null" +PRE_RELEASE_VERSION="null" + if [[ $TAG_NAME =~ $RELEASE_REGEX ]]; then - IS_RELEASE="true" + echo "Release tag detected. Tag: $TAG_NAME - Version: $VERSION_TAG" + IS_RELEASE=true + RELEASE_VERSION=$VERSION_TAG elif [[ $TAG_NAME =~ $PRE_RELEASE_REGEX ]]; then - IS_PRE_RELEASE="true" + echo "Pre-release tag detected. Tag: $TAG_NAME - Version: $VERSION_TAG" + IS_PRE_RELEASE=true + PRE_RELEASE_VERSION=$VERSION_TAG +else + echo "No release or pre-release tag detected. Tag: $TAG_NAME" fi -echo "is-release=${IS_RELEASE}" | tee -a "$GITHUB_OUTPUT" -echo "is-pre-release=${IS_PRE_RELEASE}" | tee -a "$GITHUB_OUTPUT" + +echo "is-release=$IS_RELEASE" | tee -a "$GITHUB_OUTPUT" +echo "release-version=$RELEASE_VERSION" | tee -a "$GITHUB_OUTPUT" + +echo "is-pre-release=$IS_PRE_RELEASE" | tee -a "$GITHUB_OUTPUT" +echo "pre-release-version=$PRE_RELEASE_VERSION" | tee -a "$GITHUB_OUTPUT" diff --git a/release/release-tag-check/scripts/releasetagcheck.test.sh b/release/release-tag-check/scripts/releasetagcheck.test.sh new file mode 100755 index 0000000..c28fbb5 --- /dev/null +++ b/release/release-tag-check/scripts/releasetagcheck.test.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash + +run_test_case() { + echo -e "====================================================================" + GITHUB_REF="$1" + expected_release="$2" + expected_pre_release="$3" + expected_release_version="$4" + expected_pre_release_version="$5" + release_regex="${6:-}" # Optional, use default if not provided + pre_release_regex="${7:-}" # Optional, use default if not provided + + # Create a temporary file for GITHUB_OUTPUT + GITHUB_OUTPUT=$(mktemp) + + # Set environment variables for the test case, including optional regex overrides + env_vars=( + "GITHUB_REF=$GITHUB_REF" + "GITHUB_OUTPUT=$GITHUB_OUTPUT" + "VERSION_PREFIX=${VERSION_PREFIX:-v}" + ) + + # Add regex overrides to environment variables if provided + [[ -n "$release_regex" ]] && env_vars+=("RELEASE_REGEX=$release_regex") + [[ -n "$pre_release_regex" ]] && env_vars+=("PRE_RELEASE_REGEX=$pre_release_regex") + + # Run the script with the environment variables set for this test case + output=$(env "${env_vars[@]}" ./releasetagcheck.sh) + + # Read outputs from GITHUB_OUTPUT file and trim potential trailing newlines + is_release=$(grep "^is-release" "$GITHUB_OUTPUT" | cut -d= -f2 | tr -d '\n') + is_pre_release=$(grep "^is-pre-release" "$GITHUB_OUTPUT" | cut -d= -f2 | tr -d '\n') + release_version=$(grep "^release-version" "$GITHUB_OUTPUT" | cut -d= -f2 | tr -d '\n') + pre_release_version=$(grep "^pre-release-version" "$GITHUB_OUTPUT" | cut -d= -f2 | tr -d '\n') + + # Verify the outputs + if [[ "$is_release" == "$expected_release" && \ + "$is_pre_release" == "$expected_pre_release" && \ + "$release_version" == "$expected_release_version" && \ + "$pre_release_version" == "$expected_pre_release_version" ]]; then + echo "Test case $GITHUB_REF passed." + else + echo "Test case $GITHUB_REF failed." + echo "Expected: is-release=$expected_release, is-pre-release=$expected_pre_release, release-version=$expected_release_version, pre-release-version=$expected_pre_release_version" + echo "Got: is-release=$is_release, is-pre-release=$is_pre_release, release-version=$release_version, pre-release-version=$pre_release_version" + fi + + # Clean up the temporary GITHUB_OUTPUT file + rm -f "$GITHUB_OUTPUT" + + echo -e "====================================================================\n" +} + +# Test cases +run_test_case "refs/tags/v1.2.3" "true" "false" "1.2.3" "null" +run_test_case "refs/tags/v1.2.3-beta.1" "false" "true" "null" "1.2.3-beta.1" +run_test_case "refs/tags/v1.2.3.4" "false" "false" "null" "null" # Invalid tag +run_test_case "refs/tags/release-1.2.3" "false" "false" "null" "null" # Custom tag not matching default regex + +# Standard release version +run_test_case "refs/tags/v1.2.4" "true" "false" "1.2.4" "null" + +# Pre-release with multiple identifiers +run_test_case "refs/tags/v1.2.5-alpha.1.beta" "false" "true" "null" "1.2.5-alpha.1.beta" + +# Release version without 'v' prefix (requires changing VERSION_PREFIX) +VERSION_PREFIX="" +run_test_case "refs/tags/1.2.6" "true" "false" "1.2.6" "null" "^[0-9]+\.[0-9]+\.[0-9]+$" +VERSION_PREFIX="v" + +# Tag with a non-standard prefix "release-v" +VERSION_PREFIX="release-v" +run_test_case "refs/tags/release-v1.3.0" "true" "false" "1.3.0" "null" "^release-v[0-9]+\.[0-9]+\.[0-9]+$" +VERSION_PREFIX="v" + +# Tag with a non-standard prefix "release-" (no 'v') +VERSION_PREFIX="release-" +run_test_case "refs/tags/release-1.3.0" "true" "false" "1.3.0" "null" "^release-[0-9]+\.[0-9]+\.[0-9]+$" +VERSION_PREFIX="v" + +# Tag with a non-standard prefix "release-v" (prerelease) +VERSION_PREFIX="release-v" +run_test_case "refs/tags/release-v1.3.0-beta.5" "false" "true" "null" "1.3.0-beta.5" "^release-v[0-9]+\.[0-9]+\.[0-9]+$" "^release-v[0-9]+\.[0-9]+\.[0-9]+-(.+)$" +VERSION_PREFIX="v" + +# Tag with a non-standard prefix "release-" (no 'v') (prereslease) +VERSION_PREFIX="release-" +run_test_case "refs/tags/release-1.3.0-beta.0" "false" "true" "null" "1.3.0-beta.0" "^release-[0-9]+\.[0-9]+\.[0-9]+$" "^release-[0-9]+\.[0-9]+\.[0-9]+-(.+)$" +VERSION_PREFIX="v" + +# Tag with complex pre-release and build metadata +run_test_case "refs/tags/v1.3.1-rc.1+build.123" "false" "true" "null" "1.3.1-rc.1+build.123" + +# Edge case: version with leading zeros +run_test_case "refs/tags/v0.0.9" "true" "false" "0.0.9" "null" + +# Edge case: version with extended numeric identifiers +run_test_case "refs/tags/v1.2.3.4" "false" "false" "null" "null" + +# Invalid tag not following semantic versioning +run_test_case "refs/tags/v1.2" "false" "false" "null" "null"