File: prepare-release.sh

package info (click to toggle)
ndctl 81-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 3,436 kB
  • sloc: ansic: 41,432; sh: 3,931; makefile: 28
file content (200 lines) | stat: -rwxr-xr-x 5,818 bytes parent folder | download | duplicates (3)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/bin/bash -e

# Arguments:
#  fix - fixup release instead of a full release
#  ignore_rev - ignore the check for _REVISION in libtool versioning checks

# Notes:
#  - Checkout to the appropriate branch beforehand
#     main - for major release
#     ndctl-xx.y - for fixup release
#    This is important for generating the shortlog
#  - Add a temporary commit that updates the libtool versions as needed.
#    This will later become the release commit. Use --amend to add in the
#    git-version update and the message body.

# Pre-reqs:
#  - libabigail  (for abipkgdiff)
#  - fedpkg (for mock build)

# TODO
#  - auto generate a release commit/tag message template
#  - determine the most recent kernel release and add it to the above
#  - perform documentation update for pmem.io/ndctl

cleanup()
{
	rm -rf release
	mkdir release/
}

err()
{
	echo "$1"
	exit 1
}

parse_args()
{
	local args="$*"
	grep -q "fix" <<< "$args" && rel_fix="1" || rel_fix=""
	grep -q "ignore_rev" <<< "$args" && ignore_rev="1" || ignore_rev=""
}

check_branch()
{
	local cur=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
	if [ -n "$rel_fix" ]; then
		# fixup release, expect ndctl-xx.y branch
		if ! grep -Eq "^ndctl.[0-9]+\.y$" <<< "$cur"; then
			err "expected an ndctl-xx.y branch for fixup release"
		fi
	else
		# major release, expect main branch
		if ! grep -Eq "^main$" <<< "$cur"; then
			err "expected main branch for a major release"
		fi
	fi
	if ! git diff-index --quiet HEAD --; then
		err "$cur has uncommitted/unstaged changes"
	fi
}

last_maj()
{
	git tag  | sort -V | grep -E "v[0-9]+$" | tail -1
}

last_fix()
{
	local base="$1"
	git tag  | sort -V | grep -E "$base\.?[0-9]*$" | tail -1
}

next_maj()
{
	local last="$1"
	local num=${last#v}

	newnum="$((num + 1))"
	echo "v$newnum"
}

next_fix()
{
	local last="$1"
	local num=${last##*.}
	local base=${last%%.*}

	newnum=$((num + 1))
	echo "$base.$newnum"
}

gen_lists()
{
	local range="$1"

	git shortlog --no-merges "$range" > release/shortlog
	git log --no-merges --pretty=format:"%s" "$range" > release/commits
	c_count=$(git log --pretty=format:"%s" "$range" | wc -l)
}

# Check libtool versions in meson.build
# $1: lib name (currently libndctl, libdaxctl, or libcxl)
check_libtool_vers()
{
	local lib="$1"
	local lib_u="${lib^^}"
	local libdir="${lib##lib}/lib/"
	local symfile="${libdir}/${lib}.sym"
	local last_cur=$(git show $last_ref:meson.build | grep -E "^${lib_u}_CURRENT" | cut -d'=' -f2)
	local last_rev=$(git show $last_ref:meson.build | grep -E "^${lib_u}_REVISION" | cut -d'=' -f2)
	local last_age=$(git show $last_ref:meson.build | grep -E "^${lib_u}_AGE" | cut -d'=' -f2)
	local last_soname=$((last_cur - last_age))
	local next_cur=$(git show HEAD:meson.build | grep -E "^${lib_u}_CURRENT" | cut -d'=' -f2)
	local next_rev=$(git show HEAD:meson.build | grep -E "^${lib_u}_REVISION" | cut -d'=' -f2)
	local next_age=$(git show HEAD:meson.build | grep -E "^${lib_u}_AGE" | cut -d'=' -f2)
	local next_soname=$((next_cur - next_age))
	local soname_diff=$((next_soname - last_soname))

	# generally libtool versions either reset to zero or increase only by one
	# _CURRENT monotonically increases (by one)
	if [ "$((next_cur - last_cur))" -gt 1 ]; then
		err "${lib_u}_CURRENT can increase at most by 1"
	fi
	if [ "$next_rev" -ne 0 ]; then
		if [ "$((next_rev - last_rev))" -gt 1 ]; then
			err "${lib_u}_REVISION can increase at most by 1"
		fi
	fi
	if [ "$next_age" -ne 0 ]; then
		if [ "$((next_age - last_age))" -gt 1 ]; then
			err "${lib_u}_AGE can increase at most by 1"
		fi
	fi

	# test for soname change
	if [ "$soname_diff" -ne 0 ]; then
		err "${lib}: expected soname to stay unchanged"
	fi

	# tests based on whether symfile changed
	# compatibility breaking changes are left for libabigail to detect
	test -s "$symfile" || err "$symfile: not found"
	if [ -n "$(git diff --name-only $last_ref..HEAD $symfile)" ]; then
		# symfile has changed, cur and age should increase
		if [ "$((next_cur - last_cur))" -ne 1 ]; then
			err "based on $symfile, ${lib_u}_CURRENT should've increased by 1"
		fi
		if [ "$((next_age - last_age))" -ne 1 ]; then
			err "based on $symfile, ${lib_u}_AGE should've increased by 1"
		fi
	else
		# no changes to symfile, revision should've increased if source changed
		if [ -n "$ignore_rev" ]; then
			: # skip
		elif [ -n "$(git diff --name-only $last_ref..HEAD $libdir/)" ]; then
			if [ "$((next_rev - last_rev))" -ne 1 ]; then
				err "based on $symfile, ${lib_u}_REVISION should've increased by 1"
			fi
		fi
	fi
}


# main
cleanup
parse_args "$*"
check_branch
[ -e "COPYING" ] || err "Run from the top level of an ndctl tree"

last_maj=$(last_maj)
test -n "$last_maj" || err "Unable to determine last release"

last_fix=$(last_fix $last_maj)
test -n "$last_fix" || err "Unable to determine last fixup tag for $last_maj"

next_maj=$(next_maj "$last_maj")
next_fix=$(next_fix "$last_fix")
[ -n "$rel_fix" ] && last_ref="$last_fix" || last_ref="$last_maj"
[ -n "$rel_fix" ] && next_ref="$next_fix" || next_ref="$next_maj"

check_libtool_vers "libndctl"
check_libtool_vers "libdaxctl"
check_libtool_vers "libcxl"

# HEAD~1 because HEAD would be the release commit
gen_lists ${last_ref}..HEAD~1

# For ABI diff purposes, use the latest fixes tag
scripts/do_abidiff ${last_fix}..HEAD

# once everything passes, update the git-version
sed -i -e "s/DEF_VER=[0-9]\+.*/DEF_VER=${next_ref#v}/" git-version

echo "Ready to release ndctl-$next_ref with $c_count new commits."
echo "Add git-version to the top commit to get the updated version."
echo "Use release/commits and release/shortlog to compose the release message"
echo "The release commit typically contains the meson.build libtool version"
echo "update, and the git-version update."
echo "Finally, ensure the release commit as well as the tag are PGP signed."