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."
|