forked from ungleich-public/cdist
2f93320627
Speeches should be generated on demand when needed and the cdist website should be updated.
408 lines
11 KiB
Bash
Executable file
408 lines
11 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
|
|
;;
|
|
|
|
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 \
|
|
--http1.1 \
|
|
-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 \
|
|
--http1.1 \
|
|
-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
|
|
|
|
#############################################################
|
|
# 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
|
|
|
|
# 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:
|
|
|
|
- cdist-web
|
|
- 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 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
|