-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit-release
executable file
·135 lines (106 loc) · 3.21 KB
/
git-release
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
134
135
#!/bin/bash
# release
# Prepare a release by bumping the version number and committing the
# CHANGELOG file for the upcoming release.
set -euo pipefail
shopt -s nullglob failglob extglob
[[ ${1-} == -x ]] && set -xv
DEBUG=0; [[ ${1-} == -d ]] && DEBUG=1
if [[ ${1-} == -h ]]; then
cat <<EOF
[git checkout release/v1.0 &&] ${0##*/} [<version>|point|minor|major]
EOF
exit
fi
changelog=( CHANGELOG.* @(CHANGELOG|changelog)* )
if [[ -z $changelog ]]; then
changelog='CHANGELOG.md'
fi
cur_branch=$(git rev-parse --abbrev-ref HEAD)
prev_tag=$(git describe --abbrev=0 --tags 2>/dev/null || true)
new_tag=
under_gitflow=0
git config --get gitflow.branch.master &>/dev/null && under_gitflow=1
if [[ ${1-} == v* ]]; then
new_tag="${1-}"
elif [[ ${1-} == @(bugfix|hotfix|major|minor|patch|point) ]]; then
_prev_tag="${prev_tag%%-*}" # Drop any trailing identifiers
if [[ $1 == @(bugfix|hotfix|patch|point) ]]; then
# take v1.0.1 -> v1.0.2
o="${_prev_tag##*.}"
n=$(( o + 1 ))
new_tag="${_prev_tag%%$o}$n"
elif [[ $1 == minor ]]; then
# take v1.0.1 -> v1.1.0
t="${_prev_tag%.*}"
o="${t##*.}"
n=$(( o + 1 ))
new_tag="${t%%$o}$n.0"
elif [[ $1 == major ]]; then
# take v1.0.1 -> v2.0.0
t="${_prev_tag%%.*}"
o="${t##[!0-9]}"
n=$(( o + 1 ))
new_tag="${t%%$o}$n.0.0"
fi
elif [[ $cur_branch == @(bugfix|hotfix|release)@(-|/)* ]]; then
new_tag="${cur_branch##@(bugfix|hotfix|release)@(-|/)}"
elif [[ $prev_tag ]]; then
# no args were passed but if current branch has a tag (a la trunk-based-dev,
# git(hub|lab)flow, etc), let's assume we're making a point release
exec "$0" point
fi
if (( under_gitflow == 1 )) && [[ $cur_branch != release@(-|/)* ]]; then
echo "Last identified tag was '$prev_tag', Creating 'release/$new_tag'"
git flow release start "$new_tag"
fi
if [[ -z $new_tag ]]; then
echo >&2 "Target tag for release is not specified and could not be determined"
echo >&2 "Assuming release is the first and so setting tag to v0.1.0"
new_tag='v0.1.0'
fi
tmpfile=$(mktemp --tmpdir --suffix=md "CHANGELOG.md-$new_tag-XXXXXX")
function cleanup() {
rm -f "$tmpfile"
}
trap cleanup EXIT INT
content=$(changelog "$prev_tag" HEAD)
if [[ -z $content ]]; then
echo >&2 "No new changelog content for '$changelog'"
echo >&2 " Is the current commit a merge commit?"
exit 42
fi
{
title="$new_tag - $(date +%FT%T)"
cat <<EOF
$title
$(echo -n "$title" | tr -c $'\0' '-')
$content
EOF
[[ -e $changelog ]] && cat "$changelog"
} > "$tmpfile"
if [[ $EDITOR == @(vi*|*/vi*) ]]; then
args=(-c 4)
fi
"$EDITOR" "$tmpfile" ${args[@]}
if ! diff -qbacs "$tmpfile" "$changelog" &>/dev/null; then
cp "$tmpfile" "$changelog"
git add "$changelog"
{ echo "Update $changelog for $new_tag"
echo
echo "$changelog updated by '${0##*/} $@' on $cur_branch"
} | git commit -m "$(</dev/stdin)"
message=$(sed -n '4p' "$changelog")
[[ -z $message ]] && message="$new_tag"
if (( under_gitflow == 1 )); then
git flow release finish -T "$new_tag" -m "$message"
else
git tag -a "$new_tag" -m "$message"
echo "Tag ($new_tag) not pushed .. when ready, issue"
echo " git push --tags"
fi
else
echo 'Empty release notes .. aborting'
exit 3
fi
# vi:ft=bash