blob: 70767c70377ea97c372ed3d1186825b9a58db94b [file] [log] [blame]
Joey Armstronga6af1522023-01-17 16:06:16 -05001#!/usr/bin/env bash
2
3# Copyright The OpenTelemetry Authors
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17readonly PROGNAME=$(basename "$0")
18readonly PROGDIR=$(readlink -m "$(dirname "$0")")
19
20readonly EXCLUDE_PACKAGES="internal/tools"
21readonly SEMVER_REGEX="v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?"
22
23usage() {
24 cat <<- EOF
25Usage: $PROGNAME [OPTIONS] SEMVER_TAG COMMIT_HASH
26
27Creates git tag for all Go packages in project.
28
29OPTIONS:
30 -h --help Show this help.
31
32ARGUMENTS:
33 SEMVER_TAG Semantic version to tag with.
34 COMMIT_HASH Git commit hash to tag.
35EOF
36}
37
38cmdline() {
39 local arg commit
40
41 for arg
42 do
43 local delim=""
44 case "$arg" in
45 # Translate long form options to short form.
46 --help) args="${args}-h ";;
47 # Pass through for everything else.
48 *) [[ "${arg:0:1}" == "-" ]] || delim="\""
49 args="${args}${delim}${arg}${delim} ";;
50 esac
51 done
52
53 # Reset and process short form options.
54 eval set -- "$args"
55
56 while getopts "h" OPTION
57 do
58 case $OPTION in
59 h)
60 usage
61 exit 0
62 ;;
63 *)
64 echo "unknown option: $OPTION"
65 usage
66 exit 1
67 ;;
68 esac
69 done
70
71 # Positional arguments.
72 shift $((OPTIND-1))
73 readonly TAG="$1"
74 if [ -z "$TAG" ]
75 then
76 echo "missing SEMVER_TAG"
77 usage
78 exit 1
79 fi
80 if [[ ! "$TAG" =~ $SEMVER_REGEX ]]
81 then
82 printf "invalid semantic version: %s\n" "$TAG"
83 exit 2
84 fi
85 if [[ "$( git tag --list "$TAG" )" ]]
86 then
87 printf "tag already exists: %s\n" "$TAG"
88 exit 2
89 fi
90
91 shift
92 commit="$1"
93 if [ -z "$commit" ]
94 then
95 echo "missing COMMIT_HASH"
96 usage
97 exit 1
98 fi
99 # Verify rev is for a commit and unify hashes into a complete SHA1.
100 readonly SHA="$( git rev-parse --quiet --verify "${commit}^{commit}" )"
101 if [ -z "$SHA" ]
102 then
103 printf "invalid commit hash: %s\n" "$commit"
104 exit 2
105 fi
106 if [ "$( git merge-base "$SHA" HEAD )" != "$SHA" ]
107 then
108 printf "commit '%s' not found on this branch\n" "$commit"
109 exit 2
110 fi
111}
112
113package_dirs() {
114 # Return a list of package directories in the form:
115 #
116 # package/directory/a
117 # package/directory/b
118 # deeper/package/directory/a
119 # ...
120 #
121 # Making sure to exclude any packages in the EXCLUDE_PACKAGES regexp.
122 find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; \
123 | grep -E -v "$EXCLUDE_PACKAGES" \
124 | sed 's/^\.\///' \
125 | sort
126}
127
128git_tag() {
129 local tag="$1"
130 local commit="$2"
131
132 git tag -a "$tag" -s -m "Version $tag" "$commit"
133}
134
135previous_version() {
136 local current="$1"
137
138 # Requires git > 2.0
139 git tag -l --sort=v:refname \
140 | grep -E "^${SEMVER_REGEX}$" \
141 | grep -v "$current" \
142 | tail -1
143}
144
145print_changes() {
146 local tag="$1"
147 local previous
148
149 previous="$( previous_version "$tag" )"
150 if [ -n "$previous" ]
151 then
152 printf "\nRaw changes made between %s and %s\n" "$previous" "$tag"
153 printf "======================================\n"
154 git --no-pager log --pretty=oneline "${previous}..$tag"
155 fi
156}
157
158main() {
159 local dir
160
161 cmdline "$@"
162
163 cd "$PROGDIR" || exit 3
164
165 # Create tag for root package.
166 git_tag "$TAG" "$SHA"
167 printf "created tag: %s\n" "$TAG"
168
169 # Create tag for all sub-packages.
170 for dir in $( package_dirs )
171 do
172 git_tag "${dir}/$TAG" "$SHA"
173 printf "created tag: %s\n" "${dir}/$TAG"
174 done
175
176 print_changes "$TAG"
177}
178main "$@"