-
Notifications
You must be signed in to change notification settings - Fork 78
/
Copy pathtag-and-release.sh
executable file
·133 lines (106 loc) · 3.05 KB
/
tag-and-release.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/bash
# This script generates a tag in the format, <YYYY>.<MM>.<DD>-0, and pushes the tag to origin in
# order to trigger the deploy-prod workflow.
# Note: This script is called from the makefile target 'tag-and-release'
#
# Usage:
# Tag HEAD and push tag to remote: './tag-and-release.sh'
# Tag a particular commit and push tag to remote: './tag-and-release.sh --commit-id=<GITHUB_SHA>'
# Ignore dirty git tree: './tag-and-release.sh --commit-id=<GITHUB_SHA> --outdated'
# Create a tag on non main branch: './tag-and-release.sh --commit-id=<GITHUB_SHA> --no-main'
set -euo pipefail
function log() {
echo "$1" 1>&2
}
function bail() {
log "$1"
exit 1
}
function parse_flags() {
for i in "$@"; do
case ${1} in
--no-main)
no_main="1"
shift
;;
--outdated)
outdated="1"
shift
;;
--commit-id=*)
commit_id="${1#*=}"
shift
;;
*)
bail "Unknown flag $1"
;;
esac
done
}
function require_branch_main() {
local branch=
branch="$(git rev-parse --abbrev-ref HEAD)"
if [ "$branch" != "main" ]; then
bail "Must be on branch main"
fi
}
function require_branch_up_to_date() {
if ! git status -uno | grep -q "Your branch is up to date with" ; then
bail "Branch must be up to date"
fi
}
function require_commits() {
local previous_tag=$1
local commits=
commits="$(git rev-list --count "$previous_tag"..HEAD)"
if [ -z "$commits" ] || [ "$commits" -le 0 ]; then
bail "Must be at least one commit"
fi
}
function find_previous_tag() {
local previous_tag=
previous_tag="$(git describe --tags "$(git rev-list --tags --max-count=1)")"
if [ -z "$previous_tag" ]; then
bail "Failed to find previous tag"
fi
echo "$previous_tag"
}
function find_next_tag() {
local previous_tag=$1
local today=
today="$(date -u +%Y.%m.%d)"
local i=0
if echo "$previous_tag" | grep -qF "$today" ; then
i="$(echo "$previous_tag" | awk -F'-' '{print $2}')"
i=$((i+1))
fi
echo "v$today-$i"
}
function main() {
local no_main=0
local outdated=0
local commit_id=
commit_id=$(git rev-parse --short HEAD)
parse_flags "$@"
git fetch -q
if [ "$no_main" != "1" ]; then
require_branch_main
fi
if [ "$outdated" != "1" ]; then
require_branch_up_to_date
fi
local previous_tag=
previous_tag="$(find_previous_tag)"
require_commits "$previous_tag"
local tag=
tag="$(find_next_tag "$previous_tag")"
echo "Tagging and releasing version $tag (${commit_id}) with commits:"
echo ""
git log --pretty=oneline "$previous_tag"..."${commit_id}"
echo ""
local confirm=
echo -n "Are you sure? [yes/N] " && read -r confirm && [ "${confirm:-N}" = "yes" ]
echo ""
(set -x; git tag -a -m "Release $tag" "$tag" "${commit_id}" && git push origin "$tag")
}
main "$@"