diff options
Diffstat (limited to '')
-rw-r--r-- | packaging/README.md | 53 | ||||
-rwxr-xr-x | packaging/check-files | 126 | ||||
-rwxr-xr-x | packaging/git-build | 40 | ||||
-rw-r--r-- | packaging/packaging.functions | 316 | ||||
-rwxr-xr-x | packaging/release-msg | 59 | ||||
-rwxr-xr-x | packaging/tar-compare | 62 | ||||
-rwxr-xr-x | packaging/update-tags | 149 |
7 files changed, 805 insertions, 0 deletions
diff --git a/packaging/README.md b/packaging/README.md new file mode 100644 index 00000000..664f588e --- /dev/null +++ b/packaging/README.md @@ -0,0 +1,53 @@ +Packaging Tools +=============== + +The programs in this folder are used when packaging from within git +and are not included in source or binary packages. + +For the most part they are used from the git commit hooks (copy +`../hooks/*` to `../.git/hooks` to automate checking and the release +process. + +The check-files script pulls in `*.functions` and `*/*.functions` to +do the actual work. + +`packaging.functions` contains generic checks on e.g `ChangeLog` +and `configure.ac` and automates release version, checking, tagging +and post-release update. + +Programs and packages with specific needs should create extra +`whatever.functions` and supporting scripts in a subdirectory. + +Making a release +---------------- +` +Just update ChangeLog and configure.ac to specify a suitable version +suffix: + + empty - final release + pre.# - pre-release candidate + rc.# - pre-release candidate + +If it is a final release and there is a package.spec.in, add a new +entry to the top of the %changelog section and update: + PACKAGE_RPM_RELEASE="1" + +The hooks will take over and if everything is OK will tag the release +(you will be asked to sign the tag) and then update the files ready +for further development. + +The release is not pushed out automatically, so if you want to undo +it, run: + +~~~~ +git reset --hard HEAD^^ +git tag -d vx.y.z +~~~~ + +Otherwise you can just push the results; the script outputs the required +instructions upon success. + +Once pushed the infrastructure will build a set of tar-files on the server. +For information on how to verify, sign and make these available, see: + + https://github.com/firehol/infrastructure/raw/master/doc/release.txt diff --git a/packaging/check-files b/packaging/check-files new file mode 100755 index 00000000..4827f563 --- /dev/null +++ b/packaging/check-files @@ -0,0 +1,126 @@ +#!/bin/bash + +# +# check-files +# +scriptname=check-files +if ! MYTMP=$(mktemp -d -t $scriptname-XXXXXX) +then + echo >&2 + echo >&2 + echo >&2 "Cannot create temporary directory." + echo >&2 + exit 1 +fi + +cleanup() { + status=$? + rm -rf "${MYTMP}" + exit $status +} + +# clean up if we get stopped by Crtl-C or forced logout or normal exit +trap cleanup INT +trap cleanup HUP +trap cleanup 0 + +set -e +if [ "$1" = "--debug" ] +then + set -x + shift +fi + +if [ $# -lt 1 ] +then + echo "check-files [--debug] -|filenames" + echo "e.g." + echo " git diff | ./packaging/check-files -" + echo "or in .git/hooks/pre-commit:" + echo " exec git diff --cached | ./packaging/check-files -" + exit 1 +fi + +if [ ! -x packaging/check-files ] +then + echo "Must be run from base directory" + exit 1 +fi + +if [ "$1" = "-" ] +then + from_cache=Y + f="" +else + from_cache= + for f in "$@" + do + if [ ! -f "$f" ] + then + echo "$f: no such file" + exit 1 + fi + done + + git status --porcelain "$@" | grep "^?" | cut -c4- > $MYTMP/missing.lst + + while read missing + do + git update-index --add --cacheinfo \ + 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 $missing + done < $MYTMP/missing.lst + + empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904 + git diff $empty_tree -- "$@" > $MYTMP/diff.full + f=$MYTMP/diff.full + + while read missing + do + git update-index --force-remove $missing + done < $MYTMP/missing.lst +fi + +> $MYTMP/diff.lst sed -e "/^+++ b/{p;s:^+++ b/::;w $MYTMP/files.lst" -e "d;}" $f + +#cat $MYTMP/diff.lst +#cat $MYTMP/files.lst + +dirname="${0%/*}" +if [ "$dirname" = "$0" ]; then dirname="."; fi + +for i in $dirname/*.functions $dirname/*/*.functions +do + if [ -f "$i" ] + then + source $i + echo $i | sed -e 's:.*/::' -e 's/\.functions$//' -e 's/\./_/g' >> $MYTMP/fns + fi +done + +status=0 +while read fn +do + "${fn}_check_init" $filename || status=1 +done < $MYTMP/fns + +while read filename +do + #echo Checking $filename + while read fn + do + if [ $status -eq 0 ] + then + "${fn}_check_file" $filename || status=1 + fi + done < $MYTMP/fns +done < $MYTMP/files.lst + +if [ $status -eq 0 ] +then + while read fn + do + "${fn}_check_fin" $filename || status=1 + done < $MYTMP/fns +fi + +exit $status diff --git a/packaging/git-build b/packaging/git-build new file mode 100755 index 00000000..e33d2355 --- /dev/null +++ b/packaging/git-build @@ -0,0 +1,40 @@ +#!/bin/sh + +# When run from the top-level repository, performs a complete clean +# and maintainer-mode rebuild of the FireHOL package. + +if [ ! -f .gitignore -o ! -f configure.ac -o ! -x autogen.sh ] +then + echo "Run as ./packaging/git-build from an autotools git repository" + exit 1 +fi + +# If we are genuinely in a git repo, try to clean it up, otherwise +# just make the assumption +if [ -d .git ] +then + clean=$(git status -s | grep "^?") + + if [ "$clean" ] + then + if [ "$1" != "-ok" ] + then + echo "Warning: this script runs: git clean -d -f -x" + echo " ensure all required ?? files are added, then re-run with '-ok'" + git status -s | grep '^?' + exit 1 + fi + fi + + set -e + git clean -d -f -x + set +e +fi + +set -e +./autogen.sh +./configure --enable-maintainer-mode +set +e +make dist +status=$? +exit $status diff --git a/packaging/packaging.functions b/packaging/packaging.functions new file mode 100644 index 00000000..397157fc --- /dev/null +++ b/packaging/packaging.functions @@ -0,0 +1,316 @@ +#!/bin/bash + +packaging_check_init() { + version_check= +} + +packaging_check_file() { + local filename="$1" status=0 + + case $filename in + configure.ac) + check_versions || status=1 + version_check=Y + ;; + *.spec.in) + check_versions || status=1 + version_check=Y + ;; + ChangeLog) + check_versions || status=1 + version_check=Y + if [ $status -eq 0 ] + then + check_changelog || status=1 + fi + ;; + *) + #echo "No checks found for $filename" + : + ;; + esac + return $status +} + +packaging_check_fin() { + if [ "$version_check" ] + then + version=`get_configure_ac_version` + case "$(match_version $version)" in + prerelease|candidate|release) + try_build || status=1 + if [ $status -eq 0 ] + then + cp $MYTMP/build/*.tar.* . + echo "Check $(cd $MYTMP/build && ls *.tar.gz) before pushing tags" + fi + ;; + esac + fi +} + +get_staged_file() { + local optional=0 + if [ "$1" = "-o" ] + then + optional=1 + shift + fi + + local dir="${1%/*}" + if [ "$dir" = "$1" ]; then dir="."; fi + mkdir -p $MYTMP/files/$dir + + test -f $MYTMP/files/$1 && return 0 + + if [ "$from_cache" ] + then + if [ $optional -eq 1 ] + then + git show :$1 > $MYTMP/files/$1 2> /dev/null || rm -f $MYTMP/files/$1 + else + git show :$1 > $MYTMP/files/$1 + fi + else + if [ $optional -eq 0 -o -f $1 ] + then + cp $1 $MYTMP/files/$1 + fi + fi +} + +try_build() { + if [ -f $MYTMP/success ]; then return 0; fi + mkdir -p $MYTMP/build + git archive HEAD | tar -xf - -C "$MYTMP/build" + git diff --staged | patch -p1 -d "$MYTMP/build" + (cd $MYTMP/build; ./packaging/git-build || touch $MYTMP/fail) + if [ -f $MYTMP/fail ]; then return 1; fi + (cd $MYTMP/build; ./packaging/tar-compare . *.tar.gz || touch $MYTMP/fail) + if [ -f $MYTMP/fail ]; then return 1; fi + touch $MYTMP/success + return 0 +} + +get_changelog_version() { + get_staged_file ChangeLog + local v=`sed -ne '1s/.*(\(.*\)).*/\1/p' $MYTMP/files/ChangeLog` + if [ ! "$v" ]; then v="No version in ChangeLog!"; fi + echo "$v" +} + +get_configure_ac_version() { + get_staged_file configure.ac + local v=`sed -n \ + -e '/define(\[VERSION_\(MINOR\|FIX\)/s/.*\[\([^[]*\)\].*/.\1/p' \ + -e '/define(\[VERSION_\(MAJOR\|SUFFIX\)/s/.*\[\([^[]*\)\].*/\1/p' \ + $MYTMP/files/configure.ac | tr -d '\n'` + if [ ! "$v" ]; then v="No version in configure.ac!"; fi + echo "$v" +} + +get_configure_ac_package() { + get_staged_file configure.ac + local v=`sed -n -e 's/AC_INIT(\[\([^]]*\)\].*/\1/p' configure.ac` + if [ ! "$v" ]; then v="noname"; fi + echo "$v" +} + +get_configure_ac_rpmrel() { + get_staged_file configure.ac + local v=`sed -n -e 's/PACKAGE_RPM_RELEASE="\([^"]*\)".*/\1/p' configure.ac` + if [ ! "$v" ]; then v="norpmrel"; fi + echo "$v" +} + +get_spec_version() { + get_staged_file "$1".spec.in + test -f $MYTMP/files/"$1".spec.in || return 0 # Spec file is optional + sed -n -e '1,/^%changelog/d' -e '/^*/{s/.*- \([0-9].*\)/\1/p;q}' "$1".spec.in +} + +splitver() { + local maj min fix sfx IFS=.-_ + + maj=$1 + min=$2 + fix=$3 + sfx=$4 + + set -- $5 + eval $maj=\$1 $min=\$2 $fix=\$3 $sfx=\$4 +} + +match_version() { + case "$1" in + [0-9]*.[0-9]*.[0-9]*_*) + # x.y.z_ZZZZ = development branch (can be before or after pre/rc) + echo "development" + ;; + [0-9]*.[0-9]*.[0-9]-pre[0-9]*) + echo "prerelease" + ;; + [0-9]*.[0-9]*.[0-9]-rc.[0-9]*) + echo "candidate" + ;; + [0-9]*.[0-9]*.[0-9]*) + echo "release" + ;; + *) + # Unknown + : + ;; + esac +} + +check_versions() { + local status=0 exact=0 prerelease=0 + + if [ -f $MYTMP/version-checked ] + then + read status < $MYTMP/version-checked + return $status + fi + + local confver=`get_configure_ac_version` + case "$(match_version $confver)" in + development) + : + ;; + prerelease|candidate|release) + exact=1 + ;; + *) + echo "Unrecognised version in configure.ac ($confver)" + status=1 + ;; + esac + + local clogver=`get_changelog_version` + case "$(match_version $clogver)" in + development) + echo "Do not include development branch version in ChangeLog ($clogver)" + status=1 + ;; + prerelease|candidate) + prerelease=1 + ;; + release) + : + ;; + *) + echo "Unrecognised version format in ChangeLog ($clogver)" + status=1 + ;; + esac + + local package=`get_configure_ac_package` + local specver=`get_spec_version $package` + + local clogmaj clogmin clogfix clogsfx + local confmaj confmin conffix confsfx + local specmaj specmin specfix specsfx + + splitver clogmaj clogmin clogfix clogsfx "$clogver" + splitver confmaj confmin conffix confsfx "$confver" + splitver specmaj specmin specfix specsfx "$specver" + + if [ "$specver" ] + then + if [ $specmaj -ne $clogmaj \ + -o $specmin -ne $clogmin \ + -o $specfix -ne $clogfix ] + then + echo "Main version of $package.spec.in ($specver) differs from ChangeLog ($clogver)" + status=1 + fi + fi + + if [ $status -eq 0 -a $exact -eq 0 ] + then + + if [ $confmaj -gt $clogmaj \ + -o $confmin -gt $clogmin \ + -o $conffix -gt $clogfix ] + then + : + elif [ $confmaj -eq $clogmaj \ + -a $confmin -eq $clogmin \ + -a $conffix -eq $clogfix \ + -a $prerelease -eq 1 ] + then + : + else + echo "Version in configure.ac ($confver) lesser than ChangeLog ($clogver)" + status=1 + fi + fi + + if [ $exact -eq 1 ] + then + echo "Running additional release checks" + + if [ "$confver" != "$clogver" ] + then + echo "Version in configure.ac ($confver) differs from ChangeLog ($clogver)" + status=1 + elif [ "$(git tag -l v$confver)" ] + then + echo "Tag v$confver already exists" + status=1 + fi + + if [ "$specver" ] + then + local confrpmrel=`get_configure_ac_rpmrel` + if [ "$specsfx" != "$confrpmrel" ] + then + echo "%changelog suffix in $package.spec.in ($specsfx) differs from configure.ac PACKAGE_RPM_RELEASE ($confrpmrel)" + status=1 + fi + fi + + if [ "$(git config user.signingkey)" = "" ] + then + echo "You need to set up a PGP signing key e.g.:" + echo " gpg --list-keys" + echo "and" + echo " git config user.signingkey SHORTID" + echo "or" + echo " git config --global user.signingkey SHORTID" + status=1 + fi + + git status -s | grep "^?" > $MYTMP/needclean + if [ -s $MYTMP/needclean ] + then + echo "The following files must be dealt with before commit:" + cat $MYTMP/needclean + echo "e.g. add them to .gitignore or remove with 'git clean -fdx'" + status=1 + fi + fi + + echo $status > $MYTMP/version-checked + return $status +} + +check_changelog() { + local status=0 + + if [ -f $MYTMP/changelog-checked ] + then + read status < $MYTMP/changelog-checked + return $status + fi + + local version=`sed -ne '1s/.*(\(.*\)).*/\1/p' $filename` + if [ "`echo $version | grep '[[:space:]]'`" != "" ] + then + echo "ChangeLog version contains whitespace! Fix it!" + status=1 + fi + + echo $status > $MYTMP/changelog-checked + return $status +} diff --git a/packaging/release-msg b/packaging/release-msg new file mode 100755 index 00000000..01ec3814 --- /dev/null +++ b/packaging/release-msg @@ -0,0 +1,59 @@ +#!/bin/bash + +# +# release-msg +# +scriptname=release-msg +if ! MYTMP=$(mktemp -d -t $scriptname-XXXXXX) +then + echo >&2 + echo >&2 + echo >&2 "Cannot create temporary directory." + echo >&2 + exit 1 +fi + +cleanup() { + status=$? + rm -rf "${MYTMP}" + exit $status +} + +# clean up if we get stopped by Crtl-C or forced logout or normal exit +trap cleanup INT +trap cleanup HUP +trap cleanup 0 + +set -e +if [ "$1" = "--debug" ] +then + set -x + shift +fi + +if [ $# -lt 1 ] +then + echo "Use only from .git/hooks/prepare-commit-msg" + exit 1 +fi + +if [ ! -x packaging/release-msg ] +then + echo "Must be run from base directory" + exit 1 +fi + +dirname="${0%/*}" +if [ "$dirname" = "$0" ]; then dirname="."; fi +source $dirname/packaging.functions + +mkdir -p $MYTMP/files +git show :configure.ac > $MYTMP/files/configure.ac +version=`get_configure_ac_version` +case "$(match_version $version)" in + prerelease|candidate|release) + sed -i -e "1s/.*/Prepare release $version/" "$1" + ;; +esac + +exit 0 diff --git a/packaging/tar-compare b/packaging/tar-compare new file mode 100755 index 00000000..02ec3c29 --- /dev/null +++ b/packaging/tar-compare @@ -0,0 +1,62 @@ +#!/bin/sh + +# When provided with a git repo, which has been used to produce a +# distribution tar.gz (with make dist) and the resultant tar-file, +# lists files which appear in one or the other only, to help check +# for missing EXTRA_DIST entries in Makefile.am files. + +scriptname=tar-compare +if ! MYTMP=$(mktemp -d -t $scriptname-XXXXXX) +then + echo >&2 + echo >&2 + echo >&2 "Cannot create temporary directory." + echo >&2 + exit 1 +fi + +cleanup() { + status=$? + rm -rf "${MYTMP}" + exit $status +} + +# clean up if we get stopped by Crtl-C or forced logout or normal exit +trap cleanup INT +trap cleanup HUP +trap cleanup 0 + +if [ $# -ne 2 ] +then + echo "tar-compare git-dir tar-gz-file" + exit 1 +fi + +mkdir $MYTMP/unpack +tar xfzC "$2" $MYTMP/unpack +diff -r "$1" $MYTMP/unpack/* | grep "^Only" | sed \ + -e '/: autom4te\.cache$/d' \ + -e '/: \.deps$/d' \ + -e '/: \.git$/d' \ + -e '/: \.gitattributes$/d' \ + -e '/: \.gitignore$/d' \ + -e '/: config\.log$/d' \ + -e '/: config\.status$/d' \ + -e '/: config\.h.*$/d' \ + -e '/: Makefile$/d' \ + -e '/: hooks$/d' \ + -e '/: packaging$/d' \ + -e '/: stamp-h1$/d' \ + -e '/: README\.md$/d' \ + -e '/: tmp-anchor-links$/d' \ + -e '/: tmp-manproc$/d' \ + -e '/: .*\.tar\.\(gz\|bz2\|xz\)$/d' \ + -e '/: unittest$/d' \ + -e '/: iprange$/d' \ + -e '/: .*\.o$/d' \ + -e '/sbin: \(firehol\|fireqos\|link-balancer\)$/d' \ + -e '/sbin: \(update-ipsets\|vnetbuild\|commands.sed\)$/d' > $MYTMP/out + +cat $MYTMP/out +test -s $MYTMP/out && exit 1 +exit 0 diff --git a/packaging/update-tags b/packaging/update-tags new file mode 100755 index 00000000..6823fce1 --- /dev/null +++ b/packaging/update-tags @@ -0,0 +1,149 @@ +#!/bin/bash + +# +# update-tags +# +scriptname=update-tags +if ! MYTMP=$(mktemp -d -t $scriptname-XXXXXX) +then + echo >&2 + echo >&2 + echo >&2 "Cannot create temporary directory." + echo >&2 + exit 1 +fi + +cleanup() { + status=$? + if [ $status -ne 0 ] + then + echo "FAILED." + if [ "$TAGVER" ] + then + git tag -d "$TAGVER" + fi + echo "To re-run manually:" + echo " git diff HEAD^ | ./packaging/update-tags -" + echo "To undo commit:" + echo " git reset HEAD^" + fi + rm -rf "${MYTMP}" + exit $status +} + +# clean up if we get stopped by Crtl-C or forced logout or normal exit +trap cleanup INT +trap cleanup HUP +trap cleanup 0 + +set -e +if [ "$1" = "--debug" ] +then + set -x + shift +fi + +if [ $# -lt 1 ] +then + echo "Use only from .git/hooks/post-commit" + exit 1 +fi + +if [ ! -x packaging/update-tags ] +then + echo "Must be run from base directory" + exit 1 +fi + +if [ "$1" = "-" ] +then + from_cache=Y + f="" +else + from_cache= + for f in "$@" + do + if [ ! -f "$f" ] + then + echo "$f: no such file" + exit 1 + fi + done + + git status --porcelain "$@" | grep "^?" | cut -c4- > $MYTMP/missing.lst + + while read missing + do + git update-index --add --cacheinfo \ + 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 $missing + done < $MYTMP/missing.lst + + empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904 + git diff $empty_tree -- "$@" > $MYTMP/diff.full + f=$MYTMP/diff.full + + while read missing + do + git update-index --force-remove $missing + done < $MYTMP/missing.lst +fi + +> $MYTMP/diff.lst sed -e "/^+++ b/{p;s:^+++ b/::;w $MYTMP/files.lst" -e "d;}" $f + +#cat $MYTMP/diff.lst +#cat $MYTMP/files.lst + +dirname="${0%/*}" +if [ "$dirname" = "$0" ]; then dirname="."; fi +source $dirname/packaging.functions + +status=0 +while read filename +do + #echo Checking $filename + case $filename in + configure.ac|ChangeLog) + mkdir -p $MYTMP/files + git show HEAD:configure.ac > $MYTMP/files/configure.ac + version=`get_configure_ac_version` + case "$(match_version $version)" in + prerelease|candidate|release) + do_release=Y + ;; + esac + ;; + *) + #echo "No checks found for $filename" + : + ;; + esac +done < $MYTMP/files.lst + +if [ "$do_release" ] +then + echo "Tagging new release with:" + echo " git tag -s \"v$version\" -m \"Release version $version\"" + git tag -s "v$version" -m "Release version $version" + TAGVER="v$version" + + splitver confmaj confmin conffix confsfx "$version" + if [ ! "$confsfx" ] + then + echo "Incrementing version in configure.ac:" + conffix=`expr $conffix + 1` + sed -i -e "s/define(\[VERSION_FIX\], \[.*])/define([VERSION_FIX], [$conffix])/" configure.ac + fi + + echo "Resetting suffix in configure.ac:" + sed -i -e 's/define(\[VERSION_SUFFIX\], \[.*])/define([VERSION_SUFFIX], [_master])/' configure.ac + sed -i -e 's:^PACKAGE_RPM_RELEASE=.*:PACKAGE_RPM_RELEASE="0.0.$(echo VERSION_SUFFIX | sed s/^_//)":' configure.ac + + echo "Committing new configure.ac:" + git commit --no-verify -m "Post release $version" -- configure.ac + echo "" + echo "Verify, then:" + echo " git push origin" + echo " git push origin tag $TAGVER" +fi + +exit $status |