forked from ungleich-public/cdist
fe833fdfcb
If it fails then the whole release should not fail, signing git tag can be tried again.
442 lines
12 KiB
Bash
Executable file
442 lines
12 KiB
Bash
Executable file
#!/bin/sh
|
|
#
|
|
# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
|
|
#
|
|
# This file is part of cdist.
|
|
#
|
|
# cdist is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# cdist is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
#
|
|
# This file contains the heavy lifting found usually in the Makefile
|
|
#
|
|
|
|
basedir=${0%/*}/../
|
|
# Change to checkout directory
|
|
cd "$basedir"
|
|
|
|
version=$(git describe)
|
|
|
|
option=$1; shift
|
|
|
|
case "$option" in
|
|
changelog-changes)
|
|
if [ "$#" -eq 1 ]; then
|
|
start=$1
|
|
else
|
|
start="[[:digit:]]"
|
|
fi
|
|
|
|
end="[[:digit:]]"
|
|
|
|
awk -F: "BEGIN { start=0 }
|
|
{
|
|
if(start == 0) {
|
|
if (\$0 ~ /^$start/) {
|
|
start = 1
|
|
}
|
|
} else {
|
|
if (\$0 ~ /^$end/) {
|
|
exit
|
|
} else {
|
|
print \$0
|
|
}
|
|
}
|
|
}" "$basedir/docs/changelog"
|
|
;;
|
|
|
|
changelog-version)
|
|
# get version from changelog
|
|
grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/:.*//'
|
|
;;
|
|
|
|
check-date)
|
|
# verify date in changelog is today
|
|
date_today="$(date +%Y-%m-%d)"
|
|
date_changelog=$(grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/.*: //')
|
|
|
|
if [ "$date_today" != "$date_changelog" ]; then
|
|
echo "Date in changelog is not today"
|
|
echo "Changelog: $date_changelog"
|
|
exit 1
|
|
fi
|
|
;;
|
|
|
|
check-unittest)
|
|
"$0" test
|
|
;;
|
|
|
|
blog)
|
|
version=$1; shift
|
|
blogfile=$1; shift
|
|
dir=${blogfile%/*}
|
|
file=${blogfile##*/}
|
|
|
|
|
|
cat << eof > "$blogfile"
|
|
[[!meta title="Cdist $version released"]]
|
|
|
|
Here's a short overview about the changes found in version ${version}:
|
|
|
|
eof
|
|
|
|
$0 changelog-changes "$version" >> "$blogfile"
|
|
|
|
cat << eof >> "$blogfile"
|
|
For more information visit the [[cdist homepage|software/cdist]].
|
|
|
|
[[!tag cdist config unix]]
|
|
eof
|
|
cd "$dir"
|
|
git add "$file"
|
|
# Allow git commit to fail if there are no changes
|
|
git commit -m "cdist blog update: $version" "$blogfile" || true
|
|
;;
|
|
|
|
ml-release)
|
|
if [ $# -ne 1 ]; then
|
|
echo "$0 ml-release version" >&2
|
|
exit 1
|
|
fi
|
|
|
|
version=$1; shift
|
|
|
|
to_a=cdist
|
|
to_d=l.schottelius.org
|
|
to=${to_a}@${to_d}
|
|
|
|
from_a=nico-cdist
|
|
from_d=schottelius.org
|
|
from=${from_a}@${from_d}
|
|
|
|
(
|
|
cat << eof
|
|
From: Nico -telmich- Schottelius <$from>
|
|
To: cdist mailing list <$to>
|
|
Subject: cdist $version released
|
|
|
|
Hello .*,
|
|
|
|
cdist $version has been released with the following changes:
|
|
|
|
eof
|
|
|
|
"$0" changelog-changes "$version"
|
|
cat << eof
|
|
|
|
Cheers,
|
|
|
|
Nico
|
|
|
|
--
|
|
Automatisation at its best level. With cdist.
|
|
eof
|
|
) | /usr/sbin/sendmail -f "$from" "$to"
|
|
;;
|
|
|
|
|
|
release-git-tag)
|
|
target_version=$($0 changelog-version)
|
|
if git rev-parse --verify refs/tags/$target_version 2>/dev/null; then
|
|
echo "Tag for $target_version exists, aborting"
|
|
exit 1
|
|
fi
|
|
printf "Enter tag description for ${target_version}: "
|
|
read tagmessage
|
|
|
|
# setup for signed tags:
|
|
# gpg --fulL-gen-key
|
|
# gpg --list-secret-keys --keyid-format LONG
|
|
# git config --local user.signingkey <id>
|
|
# for exporting pub key:
|
|
# gpg --armor --export <id> > pubkey.asc
|
|
# gpg --output pubkey.gpg --export <id>
|
|
# show tag with signature
|
|
# git show <tag>
|
|
# verify tag signature
|
|
# git tag -v <tag>
|
|
#
|
|
# gpg verify signature
|
|
# gpg --verify <asc-file> <file>
|
|
# gpg --no-default-keyring --keyring <pubkey.gpg> --verify <asc-file> <file>
|
|
# Ensure gpg-agent is running.
|
|
export GPG_TTY=$(tty)
|
|
gpg-agent
|
|
|
|
git tag -s "$target_version" -m "$tagmessage"
|
|
git push --tags
|
|
;;
|
|
|
|
sign-git-release)
|
|
if [ $# -lt 2 ]
|
|
then
|
|
printf "usage: $0 sign-git-release TAG TOKEN [ARCHIVE]\n"
|
|
printf " if ARCHIVE is not specified then it is created\n"
|
|
exit 1
|
|
fi
|
|
tag="$1"
|
|
if ! git rev-parse -q --verify "${tag}" >/dev/null 2>&1
|
|
then
|
|
printf "Tag \"${tag}\" not found.\n"
|
|
exit 1
|
|
fi
|
|
token="$2"
|
|
if [ $# -gt 2 ]
|
|
then
|
|
archivename="$3"
|
|
else
|
|
archivename="cdist-${tag}.tar"
|
|
git archive --prefix="cdist-${tag}/" -o "${archivename}" "${tag}" \
|
|
|| exit 1
|
|
# make sure target version is generated
|
|
"$0" target-version
|
|
tar -x -f "${archivename}" || exit 1
|
|
cp cdist/version.py "cdist-${tag}/cdist/version.py" || exit 1
|
|
tar -c -f "${archivename}" "cdist-${tag}/" || exit 1
|
|
rm -r -f "cdist-${tag}/"
|
|
gzip "${archivename}" || exit 1
|
|
archivename="${archivename}.gz"
|
|
fi
|
|
gpg --armor --detach-sign "${archivename}" || exit 1
|
|
|
|
project="ungleich-public%2Fcdist"
|
|
sed_cmd='s/^.*"markdown":"\([^"]*\)".*$/\1/'
|
|
|
|
# upload archive
|
|
response_archive=$(curl -f -X POST \
|
|
-H "PRIVATE-TOKEN: ${token}" \
|
|
-F "file=@${archivename}" \
|
|
"https://code.ungleich.ch/api/v4/projects/${project}/uploads" \
|
|
| sed "${sed_cmd}") || exit 1
|
|
|
|
# upload archive signature
|
|
response_archive_sig=$(curl -f -X POST \
|
|
-H "PRIVATE-TOKEN: ${token}" \
|
|
-F "file=@${archivename}.asc" \
|
|
"https://code.ungleich.ch/api/v4/projects/${project}/uploads" \
|
|
| sed "${sed_cmd}") || exit 1
|
|
|
|
# make release
|
|
changelog=$("$0" changelog-changes "$1" | sed 's/^[[:space:]]*//')
|
|
release_notes=$(
|
|
printf "Release %s\n\n%s\n\n%s\n\n**Changelog**\n\n%s\n" \
|
|
"${tag}" "${response_archive}" "${response_archive_sig}" "${changelog}"
|
|
)
|
|
curl -f -X POST \
|
|
-H "PRIVATE-TOKEN: ${token}" \
|
|
-F "description=${release_notes}" \
|
|
"https://code.ungleich.ch/api/v4/projects/${project}/repository/tags/${tag}/release" \
|
|
|| exit 1
|
|
|
|
|
|
# remove generated files (archive and asc)
|
|
if [ $# -eq 2 ]
|
|
then
|
|
rm -f "${archivename}"
|
|
fi
|
|
rm -f "${archivename}.asc"
|
|
;;
|
|
|
|
release)
|
|
set -e
|
|
target_version=$($0 changelog-version)
|
|
target_branch=$($0 version-branch)
|
|
|
|
echo "Beginning release process for $target_version"
|
|
|
|
# First check everything is sane
|
|
"$0" check-date
|
|
"$0" check-unittest
|
|
"$0" check-pycodestyle
|
|
"$0" shellcheck
|
|
|
|
# Generate version file to be included in packaging
|
|
"$0" target-version
|
|
|
|
# Ensure the git status is clean, else abort
|
|
if ! git diff-index --name-only --exit-code HEAD ; then
|
|
echo "Unclean tree, see files above, aborting"
|
|
exit 1
|
|
fi
|
|
|
|
# Ensure we are on the master branch
|
|
masterbranch=yes
|
|
if [ "$(git rev-parse --abbrev-ref HEAD)" != "master" ]; then
|
|
echo "Releases are happening from the master branch, aborting"
|
|
|
|
echo "Enter the magic word to release anyway"
|
|
read magicword
|
|
|
|
if [ "$magicword" = "iknowwhatido" ]; then
|
|
masterbranch=no
|
|
else
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ "$masterbranch" = yes ]; then
|
|
# Ensure version branch exists
|
|
if ! git rev-parse --verify refs/heads/$target_branch 2>/dev/null; then
|
|
git branch "$target_branch"
|
|
fi
|
|
|
|
# Merge master branch into version branch
|
|
git checkout "$target_branch"
|
|
git merge master
|
|
fi
|
|
|
|
# Verify that after the merge everything works
|
|
"$0" check-date
|
|
"$0" check-unittest
|
|
|
|
# Generate documentation (man and html)
|
|
# First, clean old generated docs
|
|
make docs-clean
|
|
make docs
|
|
|
|
# Generate speeches (indirect check if they build)
|
|
make speeches
|
|
|
|
#############################################################
|
|
# Everything green, let's do the release
|
|
|
|
# Tag the current commit
|
|
"$0" release-git-tag
|
|
|
|
# Also merge back the version branch
|
|
if [ "$masterbranch" = yes ]; then
|
|
git checkout master
|
|
git merge "$target_branch"
|
|
fi
|
|
|
|
# Publish git changes
|
|
make pub
|
|
|
|
# publish man, speeches, website
|
|
if [ "$masterbranch" = yes ]; then
|
|
make web-release-all
|
|
else
|
|
make web-release-all-no-latest
|
|
fi
|
|
|
|
# Ensure that pypi release has the right version
|
|
"$0" version
|
|
|
|
# Create and publish package for pypi
|
|
make pypi-release
|
|
|
|
# Archlinux release is based on pypi
|
|
make archlinux-release
|
|
|
|
# sign git tag
|
|
printf "Enter upstream repository authentication token: "
|
|
read token
|
|
"$0" sign-git-release "${target_version}" "${token}"
|
|
|
|
# Announce change on ML
|
|
make ml-release
|
|
|
|
cat << eof
|
|
Manual steps post release:
|
|
|
|
- linkedin
|
|
- hackernews
|
|
- reddit
|
|
- twitter
|
|
|
|
eof
|
|
|
|
;;
|
|
|
|
test)
|
|
export PYTHONPATH="$(pwd -P)"
|
|
|
|
if [ $# -lt 1 ]; then
|
|
python3 -m cdist.test
|
|
else
|
|
python3 -m unittest "$@"
|
|
fi
|
|
;;
|
|
|
|
test-remote)
|
|
export PYTHONPATH="$(pwd -P)"
|
|
python3 -m cdist.test.exec.remote
|
|
;;
|
|
|
|
pycodestyle|pep8)
|
|
pycodestyle "${basedir}" "${basedir}/scripts/cdist" | less
|
|
;;
|
|
|
|
check-pycodestyle)
|
|
"$0" pycodestyle
|
|
printf "\\nPlease review pycodestyle report.\\n"
|
|
while true
|
|
do
|
|
echo "Continue (yes/no)?"
|
|
any=
|
|
read any
|
|
case "$any" in
|
|
yes)
|
|
break
|
|
;;
|
|
no)
|
|
exit 1
|
|
;;
|
|
*)
|
|
echo "Please answer with 'yes' or 'no' explicitly."
|
|
;;
|
|
esac
|
|
done
|
|
;;
|
|
|
|
shellcheck)
|
|
make helper=${helper} WEBDIR=${WEBDIR} shellcheck
|
|
printf "\\nPlease review shellcheck report.\\n"
|
|
while true
|
|
do
|
|
echo "Continue (yes/no)?"
|
|
any=
|
|
read any
|
|
case "$any" in
|
|
yes)
|
|
break
|
|
;;
|
|
no)
|
|
exit 1
|
|
;;
|
|
*)
|
|
echo "Please answer with 'yes' or 'no' explicitly."
|
|
;;
|
|
esac
|
|
done
|
|
;;
|
|
|
|
version-branch)
|
|
"$0" changelog-version | cut -d. -f '1,2'
|
|
;;
|
|
|
|
version)
|
|
echo "VERSION = \"$(git describe)\"" > cdist/version.py
|
|
;;
|
|
|
|
target-version)
|
|
target_version=$($0 changelog-version)
|
|
echo "VERSION = \"${target_version}\"" > cdist/version.py
|
|
;;
|
|
|
|
*)
|
|
echo "Unknown helper target $@ - aborting"
|
|
exit 1
|
|
;;
|
|
|
|
esac
|