Skip to content

Commit

Permalink
feat(workflows) improve prev_tag script
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleksiivanov committed Jan 15, 2024
1 parent f44a8f6 commit 883121e
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 65 deletions.
65 changes: 64 additions & 1 deletion .github/workflows/scripts/prev_tag-test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash

# tests only for local running, to verify that prev_tag.sh works as expected
# Function to create a mock git repository
setup_mock_repo() {
mkdir temp_repo
Expand All @@ -11,6 +11,11 @@ setup_mock_repo() {
git commit -m "Initial commit"

# Add mock tags to simulate different scenarios
git tag 0.5.1
git tag 0.7.3
git tag 0.11.0
git tag 0.23.2
git tag 7.4.0
git tag 8.2.0
git tag 8.2.1
git tag 8.3.0-alpha1
Expand All @@ -20,6 +25,8 @@ setup_mock_repo() {
git tag 8.3.1
git tag 8.3.2-rc1
git tag 8.3.2-rc2
git tag 8.3.2-rc5
git tag 8.3.2-rc11
git tag 8.3.2
git tag 8.3.3
git tag 8.4.0-alpha1
Expand All @@ -30,6 +37,7 @@ setup_mock_repo() {
git tag 8.4.0-rc1
git tag 8.4.0-rc2
git tag 8.4.0-rc3
git tag 8.4.0-rc23
git tag 8.4.0
git tag 8.4.1-alpha1
git tag 8.4.2
Expand All @@ -43,6 +51,30 @@ setup_mock_repo() {
git tag 9.1.0
git tag 9.2.0-alpha2
git tag 9.2.0-rc2
git tag 11.2.0
git tag 12.0.0
git tag 12.2.0
git tag 15.0.0-rc1
git tag 15.0.0
git tag 16.0.0-rc2
git tag 16.0.0-alpha2
git tag 19.0.0-alpha3
git tag 19.0.3-alpha3
git tag 19.0.3-rc3
git tag 19.0.3
git tag 19.0.4-alpha2
git tag 19.0.4-alpha6
git tag 20.3.0
git tag 20.3.1-alpha2
git tag 20.3.1-alpha5
git tag 20.3.1-alpha11
git tag 20.3.1-alpha23
git tag 20.4.1-alpha1-rc11
git tag 20.4.1-alpha1-rc3
git tag 20.4.1-alpha1-rc20
git tag 20.4.1-alpha11
git tag 20.4.1-alpha30-rc1
git tag 20.4.1-alpha2-rc1
}

# Function to clean up the mock repository
Expand All @@ -54,6 +86,8 @@ cleanup() {
# Initialize a variable to store test results
passed_tests_results=""
fail_test_results=""
test_passed_count=0
test_fail_count=0

# Function to run a single test case
run_test() {
Expand All @@ -63,8 +97,10 @@ run_test() {
output=$(bash ../prev_tag.sh $input_tag)
if [[ $output == *"$expected_output"* ]]; then
passed_tests_results+="Test passed for input $input_tag: Expected and got $expected_output\n"
((test_passed_count++))
else
fail_test_results+="Test failed for input $input_tag: Expected $expected_output, got $output\n"
((test_fail_count++))
fi
}

Expand All @@ -91,16 +127,41 @@ run_test "8.4.2-alpha1" "8.4.1" # First alpha of a new alpha version

run_test "8.3.2-rc1" "8.3.1" # RC for normal release, next lower normal tag
run_test "8.3.2-rc2" "8.3.2-rc1" # Next RC in series
run_test "8.3.2-rc5" "8.3.2-rc2" # Next RC in series

run_test "8.4.0-rc1" "8.3.0" # RC for normal release, next lower normal tag
run_test "8.4.0-rc2" "8.4.0-rc1" # Next RC in series
run_test "8.4.0-rc3" "8.4.0-rc2" # Next RC in series

run_test "8.4.0-alpha2" "8.4.0-alpha1" # Next alpha in series

run_test "9.0.0" "8.4.0" # First release in a new major version
run_test "9.1.0" "9.0.0" # First release in a new minor version after a major version

#additional test cases
run_test "9.2.0-alpha2" "9.1.0" # Missed alpha1
run_test "9.2.0-rc2" "9.1.0" # Missed rc1
run_test "8.2.0" "7.4.0"
run_test "7.4.0" "0.23.2"
run_test "0.23.2" "0.11.0"
run_test "0.11.0" "0.7.3"
run_test "0.7.3" "0.5.1"
run_test "12.0.0" "11.2.0"
run_test "15.0.0" "12.2.0"
run_test "15.0.0-rc1" "12.2.0"
run_test "15.0.3-rc2" "5.0.0"
run_test "16.0.0-rc2" "15.0.0"
run_test "19.0.0-alpha3" "15.0.0"
run_test "19.0.3-alpha3" "15.0.0"
run_test "19.0.3-rc3" "15.0.0"
run_test "19.0.4-alpha11" "19.0.4-alpha6"
run_test "20.3.1-alpha5" "20.3.1-alpha2"
run_test "20.3.1-alpha23" "20.3.1-alpha11"
run_test "20.4.1-alpha1-rc20" "20.4.1-alpha1-rc11"
run_test "20.4.1-alpha1-rc11" "20.4.1-alpha1-rc3"
run_test "20.4.1-alpha1-rc3" "20.3.0"
run_test "20.4.1-alpha30-rc1" "20.4.1-alpha11"
run_test "20.4.1-alpha2-rc1" "20.3.0"

# Invalid Tag Format
run_test "invalid-tag" "Release tag is invalid" # Invalid tag format
Expand All @@ -112,3 +173,5 @@ cleanup
# Output all test results at the end
echo -e "$passed_tests_results"
echo -e "$fail_test_results"
echo "Total tests passed: $test_passed_count"
echo "Total tests fail: $test_fail_count"
161 changes: 97 additions & 64 deletions .github/workflows/scripts/prev_tag.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,79 +22,113 @@
# Release Candidates (RC) for Major Versions:
# - For RC releases of a major version (e.g., 9.0.0-rc1), the previous tag is the base (x.0) tag of the highest minor version from the last major series (e.g., 8.9.0).

# Function to determine the previous tag using 'NORMAL' logic
determine_normal_prev_tag() {
local candidate=""
local candidateWithPatch0=""
for tag in "${prev_tags[@]}"; do
echo "$tag"
IFS='.' read -r tag_major tag_minor tag_patch <<< "$tag"
IFS='.' read -r curr_major curr_minor curr_patch <<< "$current_tag"

if ((tag_major < curr_major)); then
candidate="$tag"
elif ((tag_major == curr_major)); then
if ((tag_minor < curr_minor)); then
candidate="$tag"
elif ((tag_minor == curr_minor)); then
if ((tag_patch <= curr_patch)); then
candidate="$tag"
fi
fi
fi

if ((tag_patch == 0)) && ((tag_major <= curr_major)) && ((tag_minor <= curr_minor)); then
if [[ -n "$candidateWithPatch0" ]]; then
IFS='.' read -r candidate_major candidate_minor _ <<< "$candidateWithPatch0"
if ((candidate_major < tag_major)) || ((candidate_minor < tag_minor)); then
candidateWithPatch0="$tag"
fi
else
candidateWithPatch0="$tag"
fi
fi
done

if [[ "$curr_patch" == "0" ]]; then
if [[ -n "$candidateWithPatch0" ]]; then
prev_tag="$candidateWithPatch0"
else
prev_tag="$candidate"
fi
else
prev_tag="$candidate"
fi
}

# Function to determine the previous tag based on the type and version
determine_prev_tag() {
local current_tag=$1
local type=$2
local major_minor=$(echo "$current_tag" | cut -d '.' -f 1,2)
local patch_version=$(echo "$current_tag" | cut -d '.' -f 3 | grep -oE "^[0-9]+")
local prev_major_minor=$(echo "$major_minor" | awk -F. '{$NF = $NF - 1;} 1' | sed 's/ /./g')

local prev_tag=""
local prev_tags=$(git --no-pager tag --sort=-v:refname)

case $type in
NORMAL)
# For a normal release, find the highest tag that is lower than the current tag in the same minor version series
prev_tag=$(echo "$prev_tags" | grep -E "^$major_minor\.[0-9]+$" | awk -v curTag="$current_tag" '$0 < curTag' | head -1)

# If no previous tag is found within the same minor version, default to the .0 tag of the previous minor version
[[ -z $prev_tag ]] && prev_tag="$prev_major_minor.0"
;;

RC)
# Remove the RC part from the current tag to find the base version
local base_version=$(echo "$current_tag" | sed 's/-rc[0-9]*$//')
# For regular RC releases, find the highest RC tag that is lower than the current tag in the same minor version series
prev_tag=$(echo "$prev_tags" | grep -E "^$major_minor\.[0-9]+-rc[0-9]+$" | awk -v curTag="$current_tag" '$0 < curTag' | head -1)
# If no previous RC is found within the same minor version, default to the .0 tag of the previous minor version
[[ -z $prev_tag ]] && prev_tag="$prev_major_minor.0"
;;

local type=$2
local major_minor=$(echo "$current_tag" | cut -d '.' -f 1,2)
local patch_version=$(echo "$current_tag" | cut -d '.' -f 3 | grep -oE "^[0-9]+")
local prev_major_minor=$(echo "$major_minor" | awk -F. '{$NF = $NF - 1;} 1' | sed 's/ /./g')
IFS='.' read -r current_major current_minor current_patch <<< "$current_tag"
local prev_tag=""
local prev_tags=$(git --no-pager tag --sort=-v:refname)

case $type in
NORMAL)
determine_normal_prev_tag
;;
RC)
# Remove the RC part from the current tag to find the base version
local base_version=$(echo "$current_tag" | sed 's/-rc[0-9]*$//')
# Extract the RC number from the current tag
local rc_number=$(echo "$current_tag" | sed 's/.*-rc\([0-9]*\)$/\1/')

# Check if there's a previous RC within the same minor version and with a lower RC number
local prev_rc_tag=$(echo "$prev_tags" | grep -E "^$major_minor\.[0-9]+-rc[0-9]+$" | awk -v curTag="$current_tag" -v curRc="$rc_number" '$0 < curTag && $0 ~ "-rc[0-9]+$" {split($0, a, "-rc"); if (a[2] + 0 < curRc + 0) print}' | sort -n | tail -1)

if [[ -n $prev_rc_tag ]]; then
prev_tag="$prev_rc_tag"
fi
# Fallback to 'NORMAL' logic if no previous tag found
if [[ -z $prev_tag ]]; then
determine_normal_prev_tag
fi
echo "$prev_tag"
;;
ALPHA)
if [[ $current_tag =~ -alpha[0-9]+-rc[0-9]+$ ]]; then
local alpha_version=$(echo "$current_tag" | sed 's/-rc[0-9]*$//')
local base_alpha=$(echo "$alpha_version" | sed 's/-alpha[0-9]*$//')
local alpha_base=$(echo "$current_tag" | sed 's/-alpha[0-9]*$//')

# Get the list of all RCs for the current alpha version
local rc_tags=$(echo "$prev_tags" | grep -E "^$alpha_version-rc[0-9]+$" | sort -rV)
if [[ $current_tag =~ -alpha[0-9]+-rc[0-9]+$ ]]; then
local alpha_version=$(echo "$current_tag" | sed 's/-rc[0-9]*$//')

if [[ -z $rc_tags ]]; then
# If no RCs found for the current alpha version, set the previous tag to the highest alpha version before the current alpha
prev_tag=$(echo "$prev_tags" | grep -E "^$base_alpha-alpha[0-9]+$" | sort -rV | awk -v curAlpha="$alpha_version" '$0 < curAlpha' | head -1)
else
# Find the immediate preceding RC for the current tag
prev_tag=$(echo "$rc_tags" | awk -v curTag="$current_tag" '$0 < curTag' | head -1)
if [[ -z $prev_tag ]]; then
# If no preceding RC found, it means the current tag is the first RC of the alpha version
# So, set the previous tag to the highest alpha version before the current alpha
prev_tag=$(echo "$prev_tags" | grep -E "^$base_alpha-alpha[0-9]+$" | sort -rV | awk -v curAlpha="$alpha_version" '$0 < curAlpha' | head -1)
fi
fi
elif [[ $current_tag =~ -alpha[0-9]+$ ]]; then
local alpha_base=$(echo "$current_tag" | sed 's/-alpha[0-9]*$//')
# Extract the RC number from the current tag
local rc_number=$(echo "$current_tag" | sed 's/.*-rc\([0-9]*\)$/\1/')

# Find the previous tag within the same major.minor version for alpha releases
prev_tag=$(echo "$prev_tags" | grep -E "^$major_minor\.[0-9]+-alpha[0-9]+$" | awk -v curTag="$current_tag" '$0 < curTag' | sort -rV | head -1)
# Check if there's a previous RC within the same alpha version and with a lower RC number
local prev_rc_tag=$(echo "$prev_tags" | grep -E "^$alpha_version-rc[0-9]+$" | awk -v curTag="$current_tag" -v curRc="$rc_number" '$0 < curTag && $0 ~ "-rc[0-9]+$" {split($0, a, "-rc"); if (a[2] + 0 < curRc + 0) print}' | sort -n | tail -1)

if [[ -z $prev_tag ]]; then
# For the first alpha release of a new minor version, set the previous tag to the base tag of the preceding minor version
if [[ $patch_version == 0 ]]; then
prev_tag="$prev_major_minor.0"
else
# For subsequent alpha releases, find the last alpha release before the current tag
prev_tag="$major_minor.$((patch_version - 1))"
fi
fi
if [[ -z $prev_rc_tag ]]; then
# If no previous RC found for the same alpha version, find the highest alpha version before the current alpha
prev_tag=$(echo "$prev_tags" | grep -E "^$base_alpha-alpha[0-9]+$" | sort -rV | awk -v curAlpha="$alpha_version" '$0 < curAlpha' | head -1)
else
prev_tag=$prev_rc_tag
fi
elif [[ $current_tag =~ -alpha[0-9]+$ ]]; then
local alpha_number=$(echo "$current_tag" | grep -oE "alpha[0-9]+$" | sed 's/alpha//')
prev_tag=$(echo "$prev_tags" | grep -E "^$alpha_base-alpha[0-9]+$" | awk -v curAlpha="$alpha_number" 'BEGIN{FS="-alpha"} $2+0 < curAlpha+0' | sort -rV | head -1)
fi
;;
MAJOR)
local major=$(echo "$current_tag" | cut -d '.' -f 1)
local prev_major=$((major - 1))
prev_tag=$(echo "$prev_tags" | grep -E "^$prev_major\.[0-9]+\.0$" | head -1)
;;
esac

# Fallback to 'NORMAL' logic if no previous tag found
if [[ -z $prev_tag ]]; then
determine_normal_prev_tag
fi
;;

esac
echo "$prev_tag"
}

Expand All @@ -108,7 +142,6 @@ fi
TYPE=""
if [[ $1 =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
TYPE="NORMAL"
[[ $1 =~ ^[0-9]+\.0\.0$ ]] && TYPE="MAJOR"
elif [[ $1 =~ -alpha[0-9]+(-rc[0-9]+)?$ ]]; then
TYPE="ALPHA"
elif [[ $1 =~ -rc[0-9]+$ ]]; then
Expand Down

0 comments on commit 883121e

Please sign in to comment.