|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Script to create a new local tag in preparation for a release |
| 4 | +# This script is idempotent i.e. it always fetches remote tags to create the new tag. |
| 5 | +# E.g. If the current remote release tag is v1.0.0, |
| 6 | +## 1) running `create-local-tag-for-release -p` will create a new tag v1.0.1 |
| 7 | +## 2) immediately running `create-local-tag-for-release -m` will create a new tag v2.0.0 |
| 8 | + |
| 9 | +set -euo pipefail |
| 10 | + |
| 11 | +REPO_ROOT_PATH="$( cd "$(dirname "$0")"; cd ../; pwd -P )" |
| 12 | +MAKEFILE_PATH=$REPO_ROOT_PATH/Makefile |
| 13 | +TAG_REGEX="^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z]*)?$" |
| 14 | + |
| 15 | +HELP=$(cat << 'EOM' |
| 16 | + Create a new local tag in preparation for a release. This script is idempotent i.e. it always fetches remote tags to create the new tag. |
| 17 | +
|
| 18 | + Usage: create-local-tag-for-release [options] |
| 19 | +
|
| 20 | + Options: |
| 21 | + -v new tag / version number. The script relies on the user to specify a valid and accurately incremented tag. |
| 22 | + -m increment major version |
| 23 | + -i increment minor version |
| 24 | + -p increment patch version |
| 25 | + -h help |
| 26 | +
|
| 27 | + Examples: |
| 28 | + create-local-tag-for-release -v v1.0.0 Create local tag for new version v1.0.0 |
| 29 | + create-local-tag-for-release -i Create local tag for new version by incrementing minor version only (previous tag=v1.0.0, new tag=v1.1.0) |
| 30 | +EOM |
| 31 | +) |
| 32 | + |
| 33 | +MAJOR_INC=false |
| 34 | +MINOR_INC=false |
| 35 | +PATCH_INC=false |
| 36 | +NEW_TAG="" |
| 37 | +CURR_REMOTE_RELEASE_TAG="" |
| 38 | + |
| 39 | +process_args() { |
| 40 | + while getopts "hmipv:" opt; do |
| 41 | + case ${opt} in |
| 42 | + h ) |
| 43 | + echo -e "$HELP" 1>&2 |
| 44 | + exit 0 |
| 45 | + ;; |
| 46 | + m ) |
| 47 | + MAJOR_INC=true |
| 48 | + ;; |
| 49 | + i ) |
| 50 | + MINOR_INC=true |
| 51 | + ;; |
| 52 | + p ) |
| 53 | + PATCH_INC=true |
| 54 | + ;; |
| 55 | + v ) |
| 56 | + NEW_TAG="${OPTARG}" |
| 57 | + ;; |
| 58 | + \? ) |
| 59 | + echo "$HELP" 1>&2 |
| 60 | + exit 0 |
| 61 | + ;; |
| 62 | + esac |
| 63 | + done |
| 64 | +} |
| 65 | + |
| 66 | +validate_args() { |
| 67 | + if [[ ! -z $NEW_TAG ]]; then |
| 68 | + if ! [[ $NEW_TAG =~ $TAG_REGEX ]]; then |
| 69 | + echo "❌ Invalid new tag specified $NEW_TAG. Examples: v1.2.3, v1.2.3-dirty" |
| 70 | + exit 1 |
| 71 | + fi |
| 72 | + |
| 73 | + echo "🥑 Using the new tag specified with -v flag. All other flags, if specified, will be ignored." |
| 74 | + echo " NOTE:The script relies on the user to specify a valid and accurately incremented tag." |
| 75 | + return |
| 76 | + fi |
| 77 | + |
| 78 | + if ($MAJOR_INC && $MINOR_INC) || ($MAJOR_INC && $PATCH_INC) || ($MINOR_INC && $PATCH_INC); then |
| 79 | + echo "❌ Invalid arguments passed. Specify only one of 3 tag parts to increment for the new tag: -m (major) or -i (minor) or -p (patch)." |
| 80 | + exit 1 |
| 81 | + fi |
| 82 | + |
| 83 | + if $MAJOR_INC || $MINOR_INC || $PATCH_INC; then |
| 84 | + return |
| 85 | + fi |
| 86 | + |
| 87 | + echo -e "❌ Invalid arguments passed. Specify atleast one argument.\n$HELP" |
| 88 | + exit 1 |
| 89 | +} |
| 90 | + |
| 91 | +sync_local_tags_from_remote() { |
| 92 | + # setup remote upstream tracking to fetch tags |
| 93 | + git remote add the-real-upstream https://github.com/aws/aws-node-termination-handler.git &> /dev/null || true |
| 94 | + git fetch the-real-upstream |
| 95 | + |
| 96 | + # delete all local tags |
| 97 | + git tag -l | xargs git tag -d |
| 98 | + |
| 99 | + # fetch remote tags |
| 100 | + git fetch the-real-upstream --tags |
| 101 | + |
| 102 | + # record the latest release tag in remote, before creating a new tag |
| 103 | + CURR_REMOTE_RELEASE_TAG=$(get_latest_tag) |
| 104 | + |
| 105 | + # clean up tracking |
| 106 | + git remote remove the-real-upstream |
| 107 | +} |
| 108 | + |
| 109 | +create_tag() { |
| 110 | + git tag $NEW_TAG |
| 111 | + echo -e "\n✅ Created new tag $NEW_TAG (Current latest release tag in remote: v$CURR_REMOTE_RELEASE_TAG)\n" |
| 112 | + exit 0 |
| 113 | +} |
| 114 | + |
| 115 | +get_latest_tag() { |
| 116 | + make -s -f $MAKEFILE_PATH latest-release-tag | cut -b 2- |
| 117 | +} |
| 118 | + |
| 119 | +main() { |
| 120 | + process_args "$@" |
| 121 | + validate_args |
| 122 | + |
| 123 | + sync_local_tags_from_remote |
| 124 | + |
| 125 | + # if new tag is specified, create it |
| 126 | + if [[ ! -z $NEW_TAG ]]; then |
| 127 | + create_tag |
| 128 | + fi |
| 129 | + |
| 130 | + # increment version |
| 131 | + if $MAJOR_INC || $MINOR_INC || $PATCH_INC; then |
| 132 | + curr_major_v=$(echo $CURR_REMOTE_RELEASE_TAG | tr '.' '\n' | head -1) |
| 133 | + curr_minor_v=$(echo $CURR_REMOTE_RELEASE_TAG | tr '.' '\n' | head -2 | tail -1) |
| 134 | + curr_patch_v=$(echo $CURR_REMOTE_RELEASE_TAG | tr '.' '\n' | tail -1) |
| 135 | + |
| 136 | + if [[ $MAJOR_INC == true ]]; then |
| 137 | + new_major_v=$(echo $(($curr_major_v + 1))) |
| 138 | + NEW_TAG=$(echo v$new_major_v.0.0) |
| 139 | + elif [[ $MINOR_INC == true ]]; then |
| 140 | + new_minor_v=$(echo $(($curr_minor_v + 1))) |
| 141 | + NEW_TAG=$(echo v$curr_major_v.$new_minor_v.0) |
| 142 | + elif [[ $PATCH_INC == true ]]; then |
| 143 | + new_patch_v=$(echo $(($curr_patch_v + 1))) |
| 144 | + NEW_TAG=$(echo v$curr_major_v.$curr_minor_v.$new_patch_v) |
| 145 | + fi |
| 146 | + create_tag |
| 147 | + fi |
| 148 | +} |
| 149 | + |
| 150 | +main "$@" |
0 commit comments