diff --git a/README.md b/README.md index f5924eb..0fa02e5 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ This is accomplished by counting the merges of branches matching the [naming sch ## Recent Changes +- 1.0.0: (non-breaking) Addition of support for mono-repos. IE: Discretely version specific directories. + - NOTE: Github, Jira, etc., were designed to host one product per repo/project. DO NOT create new mono-repo projects unless you're specifically tooling out to support them well. - 0.3.1: Update the checkout action version to v4. - 0.3.0: Bring back the unshallowing, which ensures the full git log is available. - TODO: Adjust scripts to use `git log --remotes` to avoid unshallowing large repos. @@ -56,6 +58,28 @@ git push --set-upstream origin fix/not-a-feature # THEN: Click the link to create a PR & merge it +### Inputs + +Note: Only required for setting up mono-repo versioning. + +
+
mono-repo-product-name: [string]
+
Enables mono-repo mode. The product name to match against.
+ Eg: 'bob', would match the tags like 'bob_1.2.3'.
+ Required: if mono-repo-mode: true
+ Default: ''
+
mono-repo-product-path: [string]
+
The path to the product.
+ Eg: path/to/bob
+ Required: if mono-repo-mode: true
+ Default: ''
+
force-patch-increment: [bool]
+
Forces a PATCH increment if no other increment detected.
+ (Intended for development purposes only.)
+ Required: false
+ Default: false
+
+ ### Outputs
@@ -84,7 +108,7 @@ Below is a valid workflow utilizing this action. If you wanted to extend it to d - uses: actions/checkout@v3 - name: Run GitOps Automatic Versioning Action id: gitops-autover - uses: AlexAtkinson/github-action-gitops-autover@0.3.0 + uses: AlexAtkinson/github-action-gitops-autover@0.3.1 - name: Verify Outputs run: | NEW_VERSION=${{ steps.gitops-autover.outputs.new-version }} @@ -92,6 +116,14 @@ Below is a valid workflow utilizing this action. If you wanted to extend it to d PREVIOUS_VERSION=${{ steps.gitops-autover.outputs.previous-version }} echo "previous-version: $PREVIOUS_VERSION" +To make use of the mono-repo support, simply add a block for the director you wish to version. + + - name: Run GitOps Automatic Versioning Action + id: gitops-autover + uses: AlexAtkinson/github-action-gitops-autover@0.3.1 + with: + mono-repo-product-name: bob + This results in outputs like: _major:_ @@ -151,7 +183,7 @@ Additionally, this repo uses its own action for versioning, so feel free to inve echo "PRODUCT_NAME_LOWER=$PRODUCT_NAME_LOWER" >> $GITHUB_OUTPUT - name: GitOps Automatic Versioning id: gitops-autover - uses: AlexAtkinson/github-action-gitops-autover@0.3.0 + uses: AlexAtkinson/github-action-gitops-autover@0.3.1 build: name: "Build" runs-on: ubuntu-latest @@ -265,5 +297,5 @@ For those interested, here's some pseudo code: PRs are welcome. - input(s): iteration-branches (map) - inform MINOR and PATCH incrementing branch name patterns. -- input(s): mono-mode (bool) - version subdirs discretely -- ~~CAN'T DO~~: DONE: unshallow from last version tag to latest commit to... Seems a limitation of (git at first glance). See the [Checkout From Tag](https://github.com/marketplace/actions/checkout-from-tag) action. +- DONE: input(s): mono-mode (bool) - version subdirs discretely +- UNDONE-CAN'T DO: ~~CAN'T DO~~: ~~DONE:~~ unshallow from last version tag to latest commit to... Seems a limitation of (git at first glance). See the [Checkout From Tag](https://github.com/marketplace/actions/checkout-from-tag) action. diff --git a/action.yml b/action.yml index 94c425b..84795df 100644 --- a/action.yml +++ b/action.yml @@ -13,6 +13,14 @@ inputs: description: "Forces a PATCH increment if no other increment detected. NOTE: This is intended for development purposes only." required: false default: 'false' + mono-repo-product-name: + description: "Enables mono-repo mode. The product name to match against. EG: 'bob', match the tags like 'bob_1.2.3'." + required: false + default: '' + mono-repo-product-path: + description: "The path to the product. IE: 'path/to/bob'. Required if 'mono-repo-mode' is enabled." + required: false + default: '' outputs: new-version: description: "New Version" @@ -41,8 +49,13 @@ runs: run: | cd $GITHUB_WORKSPACE opt='' - [[ "${{ inputs.force-re-evaluate }}" == 'true' ]] && opt='-f' - [[ "${{ inputs.force-patch-increment }}" == 'true' ]] && opt='-p' + [[ "${{ inputs.force-re-evaluate }}" == 'true' ]] && opt='$opt -f' + [[ "${{ inputs.force-patch-increment }}" == 'true' ]] && opt='$opt -p' + if [[ -z ${{ inputs.mono-repo-product-name }} ]]; then + echo -e "ERROR: 571 - mono-repo-product-name must be set and NOT null!" + exit 1 || true + fi + [[ -n "${{ inputs.mono-repo-product-name }}" ]] && opt='$opt -n ${{ inputs.mono-repo-product-name }}' new_version="$(${{ github.action_path }}/scripts/detectNewVersion.sh $opt)" || true echo "new-version=$new_version" | tee $GITHUB_OUTPUT if [[ "$new_version" =~ "520" ]]; then diff --git a/scripts/detectNewVersion.sh b/scripts/detectNewVersion.sh index 41ddfba..7e28f9a 100755 --- a/scripts/detectNewVersion.sh +++ b/scripts/detectNewVersion.sh @@ -29,7 +29,7 @@ NAME ${0##*/} SYNOPSIS - ${0##*/} [-hv] + ${0##*/} [-hefpnd] DESCRIPTION Detects the new version for the repository by analyzing the gitflow branch history since the @@ -47,6 +47,12 @@ DESCRIPTION -p Increments PATCH version on _every_ run. WARN: This is intended development use only. + -n Enables mono-repo mode allowing the product name to match against tags. + EG: 'bob' would match tags like 'bob_1.2.3'. + TIP: dir names and product names should match. This arg exists in case they do not. + + -d The directory of the product to version. EG: 'path/to/bob'. + EXAMPLES The following detects the new version for the repo. @@ -75,7 +81,7 @@ fi # -------------------------------------------------------------------------------------------------- OPTIND=1 -while getopts "he:vfp" opt; do +while getopts "he:vfpn:d:" opt; do case $opt in h) printHelp @@ -95,6 +101,17 @@ while getopts "he:vfp" opt; do p) arg_p='set' ;; + n) + arg_n='set' + arg_n_val="$OPTARG" + arg_opts="$arg_opts -n $OPTARG" + ;; + d) + arg_d='set' + arg_d_val="$OPTARG" + arg_d_opt="--full-history" + arg_opts="$arg_opts -d $OPTARG" + ;; *) echo -e "\e[01;31mERROR\e[00m: 570 - Invalid argument!" printHelp @@ -118,13 +135,13 @@ tsCmd='date --utc +%FT%T.%3NZ' relative_path="$(dirname "${BASH_SOURCE[0]}")" dir="$(realpath "${relative_path}")" -lastVersion=$(/usr/bin/env bash -c "${dir}/detectPreviousVersion.sh") -lastVersionMajor=$(/usr/bin/env bash -c "${dir}/validateSemver.sh -p major $lastVersion") -lastVersionMinor=$(/usr/bin/env bash -c "${dir}/validateSemver.sh -p minor $lastVersion") -lastVersionPatch=$(/usr/bin/env bash -c "${dir}/validateSemver.sh -p patch $lastVersion") -lastVersionCommitHash=$(/usr/bin/env bash -c "${dir}/detectPreviousVersion.sh -c") +lastVersion=$(/usr/bin/env bash -c "${dir}/detectPreviousVersion.sh -9 $arg_opts") +lastVersionMajor=$(/usr/bin/env bash -c "${dir}/validateSemver.sh -p major $lastVersion $arg_opts") +lastVersionMinor=$(/usr/bin/env bash -c "${dir}/validateSemver.sh -p minor $lastVersion $arg_opts") +lastVersionPatch=$(/usr/bin/env bash -c "${dir}/validateSemver.sh -p patch $lastVersion $arg_opts") +lastVersionCommitHash=$(/usr/bin/env bash -c "${dir}/detectPreviousVersion.sh -9 -c $arg_opts") lastCommitHash=$(git rev-parse HEAD) -firstCommitHash=$(git rev-list --max-parents=0 HEAD) +firstCommitHash=$(git rev-list --max-parents=0 HEAD | tail -n 1) ci_name=$("${dir}/detect-ci.sh") origin=$(git config --get remote.origin.url) @@ -169,12 +186,12 @@ if [[ -n $arg_e ]]; then fi fi -git log --pretty=oneline "$lastVersionCommitHash".."$lastCommitHash" | grep '+semver' | grep -q 'major\|breaking' && incrementMajor='true' +git log $arg_d_opt --pretty=oneline "$lastVersionCommitHash".."$lastCommitHash" $arg_d_val | grep '+semver' | grep -q 'major\|breaking' && incrementMajor='true' if [[ $incrementMajor != 'true' ]]; then IFS=$'\r\n' if [[ -n $arg_f ]]; then - for i in $(git log --pretty=oneline "${firstCommitHash}".."${lastCommitHash}" | awk -v s="$merge_string" -v c="$column" '$0 ~ s {print $c}' | awk -v f="$field" -F'/' '{print $f}' | tr -d "'" | grep -i '^enhancement$\|^feature$\|^fix$\|^hotfix$\|^bugfix$\|^ops$' | awk -F '\r' '{print $1}' | sort | uniq -c | sort -nr) ; do + for i in $(git log $arg_d_opt --pretty=oneline "${firstCommitHash}".."${lastCommitHash}" $arg_d_val | awk -v s="$merge_string" -v c="$column" '$0 ~ s {print $c}' | awk -v f="$field" -F'/' '{print $f}' | tr -d "'" | grep -i '^enhancement$\|^feature$\|^fix$\|^hotfix$\|^bugfix$\|^ops$' | awk -F '\r' '{print $1}' | sort | uniq -c | sort -nr) ; do varname=$(echo "$i" | awk '{print $2}') varname=${varname,,} value=$(echo "$i" | awk '{print $1}') @@ -182,7 +199,7 @@ if [[ $incrementMajor != 'true' ]]; then declare count_"$varname"="$value" done else - for i in $(git log --pretty=oneline "${lastVersionCommitHash}".."${lastCommitHash}" | awk -v s="$merge_string" -v c="$column" '$0 ~ s {print $c}' | awk -v f="$field" -F'/' '{print $f}' | tr -d "'" | grep -i '^enhancement$\|^feature$\|^fix$\|^hotfix$\|^bugfix$\|^ops$' | awk -F '\r' '{print $1}' | sort | uniq -c | sort -nr) ; do + for i in $(git log $arg_d_opt --pretty=oneline "${lastVersionCommitHash}".."${lastCommitHash}" $arg_d_val | awk -v s="$merge_string" -v c="$column" '$0 ~ s {print $c}' | awk -v f="$field" -F'/' '{print $f}' | tr -d "'" | grep -i '^enhancement$\|^feature$\|^fix$\|^hotfix$\|^bugfix$\|^ops$' | awk -F '\r' '{print $1}' | sort | uniq -c | sort -nr) ; do varname=$(echo "$i" | awk '{print $2}') varname=${varname,,} value=$(echo "$i" | awk '{print $1}') @@ -236,7 +253,8 @@ elif [[ -n $arg_p ]]; then newVersionPatch=$((lastVersionPatch + 1)) fi -newVersion=$(/usr/bin/env bash -c "${dir}/validateSemver.sh -9p full $newVersionMajor.$newVersionMinor.$newVersionPatch") +newVersion=$(/usr/bin/env bash -c "${dir}/validateSemver.sh -9p full $newVersionMajor.$newVersionMinor.$newVersionPatch $arg_opts") +[[ -n $arg_n ]] && newVersion="${arg_n_val}_${newVersion}" if [[ -n $arg_e ]]; then export_var="$arg_e_val" @@ -244,4 +262,4 @@ if [[ -n $arg_e ]]; then export export_var else echo "$newVersion" -fi \ No newline at end of file +fi diff --git a/scripts/detectPreviousVersion.sh b/scripts/detectPreviousVersion.sh index 4d72153..7884b5f 100755 --- a/scripts/detectPreviousVersion.sh +++ b/scripts/detectPreviousVersion.sh @@ -15,7 +15,7 @@ NAME detectPreviousVersion.sh SYNOPSIS - ${0##*/} [-hvc] + ${0##*/} [-hvcnd] DESCRIPTION Detects most recent version tag of the repository. @@ -30,6 +30,12 @@ DESCRIPTION -c Prints the commit hash instead of the detected version to stdout. + -n Enables mono-repo mode allowing the product name to match against tags. + EG: 'bob' would match tags like 'bob_1.2.3'. + TIP: dir names and product names should match. This arg exists in case they do not. + + -d The directory of the product to version. EG: 'path/to/bob'. + EXAMPLES Detects previous version, printing additional information if available. @@ -59,7 +65,7 @@ fi # -------------------------------------------------------------------------------------------------- OPTIND=1 -while getopts "hvc" opt; do +while getopts "hv9cn:d:" opt; do case $opt in h) printHelp @@ -71,6 +77,20 @@ while getopts "hvc" opt; do c) arg_c='set' ;; + 9) + arg_9='set' + ;; + n) + arg_n='set' + arg_n_val="$OPTARG" + arg_opts="$arg_opts -n $OPTARG" + ;; + d) + arg_d='set' + arg_d_val="$OPTARG" + arg_d_opt="--full-history" + arg_opts="$arg_opts -d $OPTARG" + ;; *) echo -e "\e[01;31mERROR\e[00m: Invalid argument!" printHelp @@ -85,31 +105,43 @@ shift $((OPTIND-1)) # -------------------------------------------------------------------------------------------------- tsCmd='date --utc +%FT%T.%3NZ' -semverRegex="^[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-([0-9A-Za-z]+))?(\\+((([1-9])|([1-9][0-9]+))))?$" + +if [[ -n $arg_9 ]]; then + semverRegex="^[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" + [[ -n $arg_d ]] && semverRegex="([0-9A-Za-z]+)?[_-]?[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" +else + semverRegex="^[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-([0-9A-Za-z]+))?(\\+((([1-9])|([1-9][0-9]+))))?$" + [[ -n $arg_d ]] && semverRegex="^([0-9A-Za-z]+)?[_-]?[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-([0-9A-Za-z]+))?(\\+((([1-9])|([1-9][0-9]+))))?$" +fi relative_path="$(dirname "${BASH_SOURCE[0]}")" dir="$(realpath "${relative_path}")" lastVersion=$(git for-each-ref --sort=creatordate --format '%(refname:lstrip=2)' refs/tags | grep -E "$semverRegex" | tail -n 1) +# Support mono-repos where a product name is specified. +[[ -n $arg_n ]] && lastVersion=$(git for-each-ref --sort=creatordate --format '%(refname:lstrip=2)' refs/tags | grep "$arg_n_val" | grep -E "$semverRegex" | tail -n 1) # -------------------------------------------------------------------------------------------------- # Sanity (2/2) # -------------------------------------------------------------------------------------------------- if [[ "$lastVersion" == '' ]]; then - [[ -n $arg_v ]] && echo -e "[$(${tsCmd})] INFO: No previous version detected. Initializing at '0.0.0'.\n" + [[ -n $arg_v && -z $arg_n ]] && echo -e "[$(${tsCmd})] INFO: No previous version detected. Initializing at '0.0.0'.\n" + [[ -n $arg_v && -n $arg_n ]] && echo -e "[$(${tsCmd})] INFO: No previous version detected. Initializing at '${arg_n_val}_0.0.0'.\n" lastVersion='0.0.0' lastVersionCommitHash=$(git rev-list --max-parents=0 HEAD) else - if ! bash -c "${dir}/validateSemver.sh -v9 $lastVersion"; then + if ! bash -c "${dir}/validateSemver.sh -v9 $arg_opts $lastVersion"; then exit 1 else lastVersionCommitHash=$(git rev-list -n 1 "$lastVersion") # Ensure lastVersion does not include a leading [vV] - lastVersion=$(bash -c "${dir}/validateSemver.sh -v9p full $lastVersion") + lastVersion=$(bash -c "${dir}/validateSemver.sh -v9p full $arg_opts $lastVersion") fi fi +[[ -n $arg_n ]] && lastVersion="${arg_n_val}_${lastVersion}" + # -------------------------------------------------------------------------------------------------- # Main Operations # -------------------------------------------------------------------------------------------------- diff --git a/scripts/tests.sh b/scripts/tests.sh new file mode 100755 index 0000000..8aafcb2 --- /dev/null +++ b/scripts/tests.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env bash +# test.sh + +TEST="test_$(date --utc +"%s")" +trap 'rm -rf $TEST; \ + git reset --hard $STARTING_COMMIT;' EXIT + #git reset HEAD~$TEST_COMMIT_COUNT;' EXIT + +STARTING_COMMIT=$(git rev-parse HEAD) + +TEST_COMMIT_COUNT=0 + +function printHeading () { + txt="$@"; + printf "\n\e[01;39m${txt}\e[0m "; + printf '\n%*s' "$((${COLUMNS}-$((${COLUMNS}-$(wc -c<<<$txt)+1))))" | tr ' ' -; + printf '\n' +} + +function add_history() { + if [[ $# -ne 3 ]] && [[ $# -ne 4 ]]; then echo "ERROR: Exactly 3 or 4 arguments required!"; return 1; fi + DIR="$1" + COUNT="$2" + BRANCH_TYPE="$3" + MAJOR="$4" + cd "$DIR" + for i in $(seq 1 $COUNT); do + TEST_FILE="${i}_$(date +"%s%6N")" + touch $TEST_FILE + git add "$TEST_FILE" >/dev/null 2>&1 + [[ -n $MAJOR ]] && git commit -m "+semver major $TEST" >/dev/null 2>&1 + git commit -m "Merge pull request #9999 from AlexAtkinson/$BRANCH_TYPE/${TEST}_$i" >/dev/null 2>&1 + done + cd - >/dev/null 2>&1 +} + +function test_previous() { + if [[ $# -lt 3 ]]; then echo "ERROR: At least 3 arguments required!"; return 1; fi + TEST_TYPE="${1:-Repository}" # Repository, Directory + DIRECTORY="${2:-./}" + ASSERTION="$3" + COMMENT="${@:4}"; [[ -z $COMMENT ]] && COMMENT="No Comment" + if [[ "$TEST_TYPE" == "Repository" ]]; then + echo -e "\e[01;39m$TEST_TYPE: Previous Version ($COMMENT)\e[0m" + TEST_OUTPUT=$(scripts/detectPreviousVersion.sh) + if grep -q "$ASSERTION" <<<$TEST_OUTPUT; then RESULT="\e[01;32mOK\e[0m"; else RESULT="\e[01;31mFAIL\e[0m"; FAILURE="TRUE"; fi + echo -e " $RESULT - $TEST_OUTPUT" + fi + if [[ "$TEST_TYPE" == "Directory" ]]; then + echo -e "\e[01;39m$TEST_TYPE - $DIRECTORY: Previous Version ($COMMENT)\e[0m" + TEST_OUTPUT=$(scripts/detectPreviousVersion.sh -d "$DIRECTORY" -n "${DIRECTORY##*/}") + if grep -q "$ASSERTION" <<<$TEST_OUTPUT; then RESULT="\e[01;32mOK\e[0m"; else RESULT="\e[01;31mFAIL\e[0m"; FAILURE="TRUE"; fi + echo -e " $RESULT - $TEST_OUTPUT" + fi +} + +function test_new() { + if [[ $# -lt 3 ]]; then echo "ERROR: At least 3 arguments required!"; return 1; fi + TEST_TYPE="${1:-Repository}" # Repository, Directory + DIRECTORY="${2:-./}" + ASSERTION="$3" + COMMENT="${@:4}"; [[ -z $COMMENT ]] && COMMENT="No Comment" + if [[ "$TEST_TYPE" == "Repository" ]]; then + echo -e "\e[01;39m$TEST_TYPE: New Version ($COMMENT)\e[0m" + TEST_OUTPUT=$(scripts/detectNewVersion.sh) + if grep -q "$ASSERTION" <<<$TEST_OUTPUT; then RESULT="\e[01;32mOK\e[0m"; else RESULT="\e[01;31mFAIL\e[0m"; FAILURE="TRUE"; fi + echo -e " $RESULT - $TEST_OUTPUT" + fi + if [[ "$TEST_TYPE" == "Directory" ]]; then + echo -e "\e[01;39m$TEST_TYPE - $DIRECTORY: New Version ($COMMENT)\e[0m" + TEST_OUTPUT=$(scripts/detectNewVersion.sh -d "$DIRECTORY" -n "${DIRECTORY##*/}") + if grep -q "$ASSERTION" <<<$TEST_OUTPUT; then RESULT="\e[01;32mOK\e[0m"; else RESULT="\e[01;31mFAIL\e[0m"; FAILURE="TRUE"; fi + echo -e " $RESULT - $TEST_OUTPUT" + fi +} + +relative_path="$(dirname "${BASH_SOURCE[0]}")" +dir="$(realpath "${relative_path}")" + +ci_name=$("${dir}/detect-ci.sh") +origin=$(git config --get remote.origin.url) + +#origin=${ci_name:-origin} +# Executes in ANY CI so long as repo origin is one of the following. +# Uncomment origin override to restrict this. +[[ "$origin" =~ "git@github.com"* || "$ci_name" == "github" ]] && origin_host=github +[[ "$origin" =~ "git@gitlab.com"* || "$ci_name" == "gitlab" ]] && origin_host=gitlab +[[ "$origin" =~ "git@bitbucket.com"* || "$ci_name" == "bitbucket" ]] && origin_host=bitbucket + +case "$origin_host" in + github) + merge_string="Merge pull request #" + column=7 + field=2 + ;; + gitlab) + merge_string="Merge branch" + column=4 + field=1 + ;; + bitbucket) + merge_string="Merged in" + column=4 + field=1 + ;; + *) + echo -e "\e[01;31mERROR\e[0m: 591 - Unsupported origin host." + exit 1 + ;; +esac + + +# TEST: Repo Versioning + +## Activities + +# Tests: +# - Repo Versioning +# - Diectory Versioning +# - x Minor Increments +# - x Patch Increments + +printHeading Running Test: $TEST + +echo NOTE: These tests are not committed. + +mkdir -p $TEST/{A..C} + +# Directory Test: A +# ASSERTIONS: +# - Previous version is: A_0.0.0 +# - New Version is: ERROR: 599 +test_previous "Repository" "./" "$(scripts/detectPreviousVersion.sh)" +test_new "Repository" "./" " 599" + +test_previous "Directory" "$TEST/A" "A_0.0.0" +test_new "Directory" "$TEST/A" " 599" + +test_previous "Directory" "$TEST/B" "B_0.0.0" +add_history "$TEST/B" 3 ops +test_new "Directory" "$TEST/B" "B_0.0.3" patches +3 +git tag -a "B_0.0.3" -m "TAG" +test_previous "Directory" "$TEST/B" "B_0.0.3" previous version tagged +add_history "$TEST/B" 17 ops +test_new "Directory" "$TEST/B" "B_0.0.20" patches +17 +git tag -d "B_0.0.3" >/dev/null 2>&1 + +test_previous "Directory" "$TEST/C" "C_0.0.0" +add_history "$TEST/C" 9 ops +test_new "Directory" "$TEST/C" "C_0.0.9" patches +9 +git tag -a "C_0.0.9" -m "TAG" +test_previous "Directory" "$TEST/C" "C_0.0.9" previous version tagged +test_new "Directory" "$TEST/C" " 599" + +add_history "$TEST/C" 5 feature +test_new "Directory" "$TEST/C" "C_0.5.0" features +5 +git tag -a "C_0.5.0" -m "TAG" +add_history "$TEST/C" 19 ops +test_new "Directory" "$TEST/C" "C_0.5.19" patches +19 +add_history "$TEST/C" 1 features major +test_new "Directory" "$TEST/C" "C_1.0.0" features +1 BREAKING +git tag -d "C_0.0.9" >/dev/null 2>&1 +git tag -d "C_0.5.0" >/dev/null 2>&1 + diff --git a/scripts/validateSemver.sh b/scripts/validateSemver.sh index e3ba25c..6bd23dd 100755 --- a/scripts/validateSemver.sh +++ b/scripts/validateSemver.sh @@ -15,7 +15,7 @@ NAME validateSemver.sh SYNOPSIS - ${0##*/} [-hpv9] + ${0##*/} [-hpv9nd] DESCRIPTION Validates the schema of a provided version string against the semantic versioning standard. @@ -48,6 +48,12 @@ DESCRIPTION (v)[Major].[Minor].[Patch] + -n Enables mono-repo mode allowing the product name to match against tags. + EG: 'bob' would match tags like 'bob_1.2.3'. + TIP: dir names and product names should match. This arg exists in case they do not. + + -d The directory of the product to version. EG: 'path/to/bob'. + EXAMPLES The following returns an exit code of 0, as the supplied version is Agile CICD compliant. @@ -80,7 +86,7 @@ fi # -------------------------------------------------------------------------------------------------- OPTIND=1 -while getopts "hp:v9" opt; do +while getopts "hp:v9n:d:" opt; do case $opt in h) printHelp @@ -96,6 +102,17 @@ while getopts "hp:v9" opt; do 9) arg_9='set' ;; + n) + arg_n='set' + arg_n_val="$OPTARG" + arg_opts="$arg_opts -n $OPTARG" + ;; + d) + arg_d='set' + arg_d_val="$OPTARG" + arg_d_opt="--full-history" + arg_opts="$arg_opts -d $OPTARG" + ;; *) echo -e "\e[01;31mERROR\e[00m: Invalid argument!" printHelp @@ -113,8 +130,10 @@ tsCmd='date --utc +%FT%T.%3NZ' if [[ -n $arg_9 ]]; then semverRegex="^[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" + [[ -n $arg_d ]] && semverRegex="([0-9A-Za-z]+)?[_-]?[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" else semverRegex="^[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-([0-9A-Za-z]+))?(\\+((([1-9])|([1-9][0-9]+))))?$" + [[ -n $arg_d ]] && semverRegex="^([0-9A-Za-z]+)?[_-]?[v]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-([0-9A-Za-z]+))?(\\+((([1-9])|([1-9][0-9]+))))?$" fi # -------------------------------------------------------------------------------------------------- @@ -123,6 +142,8 @@ fi function validateSemver { local version=$1 + version=${version##*_} + version=${version##*-} [[ "$version" =~ ^[vV]* ]] && version=${version//^[vV]/""/} if [[ "$version" =~ $semverRegex ]]; then local major=${BASH_REMATCH[1]} @@ -149,6 +170,7 @@ function validateSemver { else [[ -z $arg_9 && -n $arg_v ]] && echo -e "[$(${tsCmd})] \e[01;31mFATAL\e[00m: '$version' does not match the semver schema: '(v)[Major].[Minor].[Patch](-PRERELEASE)(+BUILD)'!\n" [[ -n $arg_9 && -n $arg_v ]] && echo -e "[$(${tsCmd})] \e[01;31mFATAL\e[00m: '$version' does not match the semver schema: '(v)[Major].[Minor].[Patch]'!\n" + [[ -n $arg_9 && -n $arg_v && -n $arg_d ]] && echo -e "[$(${tsCmd})] \e[01;31mFATAL\e[00m: '$version' does not match the semver schema: '[product_name][-_](v)[Major].[Minor].[Patch]'!\n" exit 1 fi }