Skip to content

Commit

Permalink
feat: releasetagcheck with version output (#158)
Browse files Browse the repository at this point in the history
* feat: releasetagcheck with version output

* fix: rename to VERSION_PREFIX

* docs: fix readme
  • Loading branch information
erikburt committed Mar 5, 2024
1 parent fbeadc1 commit 2031e56
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 17 deletions.
52 changes: 52 additions & 0 deletions release/release-tag-check/README.md
Original file line number Diff line number Diff line change
@@ -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/<tag name>`)
- 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/<tag name>`)
- 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
6 changes: 6 additions & 0 deletions release/release-tag-check/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
43 changes: 26 additions & 17 deletions release/release-tag-check/scripts/releasetagcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,46 @@

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
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"
101 changes: 101 additions & 0 deletions release/release-tag-check/scripts/releasetagcheck.test.sh
Original file line number Diff line number Diff line change
@@ -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"

0 comments on commit 2031e56

Please sign in to comment.