Hi Steven, as we discussed and tested on IRC, this is the framework to do releases from git.
Left to do: - tune the build-aux/release.mk publish target for you environment (including/optionally gpgsign). - add warning in main.c when using test versions. the build-aux/git* scripts have been taken from coreutils/gnulib. The patch needs to go in every branch you expect to release from. Testing shows that cherry pick in flatiron will give 2 conflicts (Makefile.am and corosync.spec.in). Please let me know if you want to do the rediff yourself or you prefer me to send you another patch. Fabio
diff --git a/Makefile.am b/Makefile.am index c944d8e..6d9e009 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,7 +34,12 @@ SPEC = $(PACKAGE_NAME).spec TARFILE = $(PACKAGE_NAME)-$(VERSION).tar.gz EXTRA_DIST = autogen.sh conf/corosync.conf.example $(SPEC).in \ - conf/lenses/tests/test_corosync.aug conf/lenses/corosync.aug + build-aux/git-version-gen \ + build-aux/gitlog-to-changelog \ + build-aux/release.mk \ + conf/lenses/tests/test_corosync.aug \ + conf/lenses/corosync.aug \ + .version AUTOMAKE_OPTIONS = foreign @@ -101,10 +106,19 @@ clean-generic: $(SPEC): $(SPEC).in rm -f $...@-t $@ LC_ALL=C date="$(shell date "+%a %b %d %Y")" && \ - alphatag="$(shell svnversion | sed -e "s#.*:##g" -e "s#[MS]##g")" && \ + gitver="$(shell git describe --abbrev=4 --match='v*' HEAD 2>/dev/null)" && \ + rpmver=`echo $$gitver | sed -e "s/^v//" -e "s/-.*//g"` && \ + alphatag=`echo $$gitver | sed -e "s/.*-//" -e "s/^g//"` && \ + vtag=`echo $$gitver | sed -e "s/-.*//g"` && \ + numcomm=`git rev-list $$vtag..HEAD | wc -l` && \ + git update-index --refresh > /dev/null 2>&1 || true && \ + dirty=`git diff-index --name-only HEAD 2>/dev/null` && \ + if [ -n "$$dirty" ]; then dirty="dirty"; else dirty=""; fi && \ sed \ - -e "s...@alphatag@#r$$alphatag#g" \ - -e "s...@version@#$(VERSION)#g" \ + -e "s...@version@#$$rpmver#g" \ + -e "s...@alphatag@#$$alphatag#g" \ + -e "s...@numcomm@#$$numcomm#g" \ + -e "s...@dirty@#$$dirty#g" \ -e "s...@date@#$$date#g" \ $< > $...@-t chmod a-w $...@-t @@ -126,3 +140,21 @@ srpm: clean rpm: clean $(MAKE) $(SPEC) $(TARFILE) rpmbuild $(RPMBUILDOPTS) -ba $(SPEC) + +# release/versioning +BUILT_SOURCES = .version +.version: + echo $(VERSION) > $...@-t && mv $...@-t $@ + +dist-hook: gen-ChangeLog + echo $(VERSION) > $(distdir)/.tarball-version + +gen_start_date = 2000-01-01 +.PHONY: gen-ChangeLog +gen-ChangeLog: + if test -d .git; then \ + $(top_srcdir)/build-aux/gitlog-to-changelog \ + --since=$(gen_start_date) > $(distdir)/cl-t; \ + rm -f $(distdir)/ChangeLog; \ + mv $(distdir)/cl-t $(distdir)/ChangeLog; \ + fi diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen new file mode 100755 index 0000000..795a98b --- /dev/null +++ b/build-aux/git-version-gen @@ -0,0 +1,161 @@ +#!/bin/sh +# Print a version string. +scriptversion=2010-10-13.20; # UTC + +# Copyright (C) 2007-2010 Free Software Foundation, Inc. +# +# This program 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. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + +# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/. +# It may be run two ways: +# - from a git repository in which the "git describe" command below +# produces useful output (thus requiring at least one signed tag) +# - from a non-git-repo directory containing a .tarball-version file, which +# presumes this script is invoked like "./git-version-gen .tarball-version". + +# In order to use intra-version strings in your project, you will need two +# separate generated version string files: +# +# .tarball-version - present only in a distribution tarball, and not in +# a checked-out repository. Created with contents that were learned at +# the last time autoconf was run, and used by git-version-gen. Must not +# be present in either $(srcdir) or $(builddir) for git-version-gen to +# give accurate answers during normal development with a checked out tree, +# but must be present in a tarball when there is no version control system. +# Therefore, it cannot be used in any dependencies. GNUmakefile has +# hooks to force a reconfigure at distribution time to get the value +# correct, without penalizing normal development with extra reconfigures. +# +# .version - present in a checked-out repository and in a distribution +# tarball. Usable in dependencies, particularly for files that don't +# want to depend on config.h but do want to track version changes. +# Delete this file prior to any autoconf run where you want to rebuild +# files to pick up a version string change; and leave it stale to +# minimize rebuild time after unrelated changes to configure sources. +# +# It is probably wise to add these two files to .gitignore, so that you +# don't accidentally commit either generated file. +# +# Use the following line in your configure.ac, so that $(VERSION) will +# automatically be up-to-date each time configure is run (and note that +# since configure.ac no longer includes a version string, Makefile rules +# should not depend on configure.ac for version updates). +# +# AC_INIT([GNU project], +# m4_esyscmd([build-aux/git-version-gen .tarball-version]), +# [bug-proj...@example]) +# +# Then use the following lines in your Makefile.am, so that .version +# will be present for dependencies, and so that .tarball-version will +# exist in distribution tarballs. +# +# BUILT_SOURCES = $(top_srcdir)/.version +# $(top_srcdir)/.version: +# echo $(VERSION) > $...@-t && mv $...@-t $@ +# dist-hook: +# echo $(VERSION) > $(distdir)/.tarball-version + +case $# in + 1|2) ;; + *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version" \ + '[TAG-NORMALIZATION-SED-SCRIPT]' + exit 1;; +esac + +tarball_version_file=$1 +tag_sed_script="${2:-s/x/x/}" +nl=' +' + +# Avoid meddling by environment variable of the same name. +v= + +# First see if there is a tarball-only version file. +# then try "git describe", then default. +if test -f $tarball_version_file +then + v=`cat $tarball_version_file` || exit 1 + case $v in + *$nl*) v= ;; # reject multi-line output + [0-9]*) ;; + *) v= ;; + esac + test -z "$v" \ + && echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2 +fi + +if test -n "$v" +then + : # use $v +# Otherwise, if there is at least one git commit involving the working +# directory, and "git describe" output looks sensible, use that to +# derive a version string. +elif test "`git log -1 --pretty=format:x . 2>&1`" = x \ + && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \ + || git describe --abbrev=4 HEAD 2>/dev/null` \ + && v=`printf '%s\n' "$v" | sed "$tag_sed_script"` \ + && case $v in + v[0-9]*) ;; + *) (exit 1) ;; + esac +then + # Is this a new git that lists number of commits since the last + # tag or the previous older version that did not? + # Newer: v6.10-77-g0f8faeb + # Older: v6.10-g0f8faeb + case $v in + *-*-*) : git describe is okay three part flavor ;; + *-*) + : git describe is older two part flavor + # Recreate the number of commits and rewrite such that the + # result is the same as if we were using the newer version + # of git describe. + vtag=`echo "$v" | sed 's/-.*//'` + numcommits=`git rev-list "$vtag"..HEAD | wc -l` + v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`; + ;; + esac + + # Change the first '-' to a '.', so version-comparing tools work properly. + # Remove the "g" in git describe's output string, to save a byte. + v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`; +else + v=UNKNOWN +fi + +v=`echo "$v" |sed 's/^v//'` + +# Don't declare a version "dirty" merely because a time stamp has changed. +git update-index --refresh > /dev/null 2>&1 + +dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty= +case "$dirty" in + '') ;; + *) # Append the suffix only if there isn't one already. + case $v in + *-dirty) ;; + *) v="$v-dirty" ;; + esac ;; +esac + +# Omit the trailing newline, so that m4_esyscmd can use the result directly. +echo "$v" | tr -d "$nl" + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog new file mode 100755 index 0000000..7660af5 --- /dev/null +++ b/build-aux/gitlog-to-changelog @@ -0,0 +1,191 @@ +eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}' + & eval 'exec perl -wS "$0" $argv:q' + if 0; +# Convert git log output to ChangeLog format. + +my $VERSION = '2009-10-30 13:46'; # UTC +# The definition above must lie within the first 8 lines in order +# for the Emacs time-stamp write hook (at end) to update it. +# If you change this file with Emacs, please let the write hook +# do its job. Otherwise, update this string manually. + +# Copyright (C) 2008-2010 Free Software Foundation, Inc. + +# This program 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. + +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + +# Written by Jim Meyering + +use strict; +use warnings; +use Getopt::Long; +use POSIX qw(strftime); + +(my $ME = $0) =~ s|.*/||; + +# use File::Coda; # http://meyering.net/code/Coda/ +END { + defined fileno STDOUT or return; + close STDOUT and return; + warn "$ME: failed to close standard output: $!\n"; + $? ||= 1; +} + +sub usage ($) +{ + my ($exit_code) = @_; + my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); + if ($exit_code != 0) + { + print $STREAM "Try `$ME --help' for more information.\n"; + } + else + { + print $STREAM <<EOF; +Usage: $ME [OPTIONS] [ARGS] + +Convert git log output to ChangeLog format. If present, any ARGS +are passed to "git log". To avoid ARGS being parsed as options to +$ME, they may be preceded by '--'. + +OPTIONS: + + --since=DATE convert only the logs since DATE; + the default is to convert all log entries. + --format=FMT set format string for commit subject and body; + see 'man git-log' for the list of format metacharacters; + the default is '%s%n%b%n' + + --help display this help and exit + --version output version information and exit + +EXAMPLE: + + $ME --since=2008-01-01 > ChangeLog + $ME -- -n 5 foo > last-5-commits-to-branch-foo + +EOF + } + exit $exit_code; +} + +# If the string $S is a well-behaved file name, simply return it. +# If it contains white space, quotes, etc., quote it, and return the new string. +sub shell_quote($) +{ + my ($s) = @_; + if ($s =~ m![^\w+/.,-]!) + { + # Convert each single quote to '\'' + $s =~ s/\'/\'\\\'\'/g; + # Then single quote the string. + $s = "'$s'"; + } + return $s; +} + +sub quoted_cmd(@) +{ + return join (' ', map {shell_quote $_} @_); +} + +{ + my $since_date = '1970-01-01 UTC'; + my $format_string = '%s%n%b%n'; + GetOptions + ( + help => sub { usage 0 }, + version => sub { print "$ME version $VERSION\n"; exit }, + 'since=s' => \$since_date, + 'format=s' => \$format_string, + ) or usage 1; + + my @cmd = (qw (git log --log-size), "--since=$since_date", + '--pretty=format:%ct %an <%ae>%n%n'.$format_string, @ARGV); + open PIPE, '-|', @cmd + or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n" + . "(Is your Git too old? Version 1.5.1 or later is required.)\n"); + + my $prev_date_line = ''; + while (1) + { + defined (my $in = <PIPE>) + or last; + $in =~ /^log size (\d+)$/ + or die "$ME:$.: Invalid line (expected log size):\n$in"; + my $log_nbytes = $1; + + my $log; + my $n_read = read PIPE, $log, $log_nbytes; + $n_read == $log_nbytes + or die "$ME:$.: unexpected EOF\n"; + + my @line = split "\n", $log; + my $author_line = shift @line; + defined $author_line + or die "$ME:$.: unexpected EOF\n"; + $author_line =~ /^(\d+) (.*>)$/ + or die "$ME:$.: Invalid line " + . "(expected date/author/email):\n$author_line\n"; + + my $date_line = sprintf "%s $2\n", strftime ("%F", localtime ($1)); + # If this line would be the same as the previous date/name/email + # line, then arrange not to print it. + if ($date_line ne $prev_date_line) + { + $prev_date_line eq '' + or print "\n"; + print $date_line; + } + $prev_date_line = $date_line; + + # Omit "Signed-off-by..." lines. + @line = grep !/^Signed-off-by: .*>$/, @line; + + # If there were any lines + if (@line == 0) + { + warn "$ME: warning: empty commit message:\n $date_line\n"; + } + else + { + # Remove leading and trailing blank lines. + while ($line[0] =~ /^\s*$/) { shift @line; } + while ($line[$#line] =~ /^\s*$/) { pop @line; } + + # Prefix each non-empty line with a TAB. + @line = map { length $_ ? "\t$_" : '' } @line; + + print "\n", join ("\n", @line), "\n"; + } + + defined ($in = <PIPE>) + or last; + $in ne "\n" + and die "$ME:$.: unexpected line:\n$in"; + } + + close PIPE + or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; + # FIXME-someday: include $PROCESS_STATUS in the diagnostic +} + +# Local Variables: +# mode: perl +# indent-tabs-mode: nil +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "my $VERSION = '" +# time-stamp-format: "%:y-%02m-%02d %02H:%02M" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "'; # UTC" +# End: diff --git a/build-aux/release.mk b/build-aux/release.mk new file mode 100644 index 0000000..6837d8d --- /dev/null +++ b/build-aux/release.mk @@ -0,0 +1,75 @@ +# to build official release tarballs, handle tagging and publish. + +# signing key +gpgsignkey= + +project=corosync + +all: checks setup tag tarballs sha256 sign + +checks: +ifeq (,$(version)) + @echo ERROR: need to define version= + @exit 1 +endif + @if [ ! -d .git ]; then \ + echo This script needs to be executed from top level cluster git tree; \ + exit 1; \ + fi + +setup: checks + ./autogen.sh + ./configure + make maintainer-clean + +tag: setup ./tag-$(version) + +tag-$(version): +ifeq (,$(release)) + @echo Building test release $(version), no tagging +else + git tag -a -m "v$(version) release" v$(version) HEAD + @touch $@ +endif + +tarballs: tag + ./autogen.sh + ./configure + make distcheck + +sha256: tarballs $(project)-$(version).sha256 + +$(project)-$(version).sha256: +ifeq (,$(release)) + @echo Building test release $(version), no sha256 +else + sha256sum $(project)-$(version)*tar* | sort -k2 > $@ +endif + +sign: sha256 $(project)-$(version).sha256.asc + +$(project)-$(version).sha256.asc: $(project)-$(version).sha256 +ifeq (,$(gpgsignkey)) + @echo No GPG signing key defined +else +ifeq (,$(release)) + @echo Building test release $(version), no sign +else + gpg --default-key $(gpgsignkey) \ + --detach-sign \ + --armor \ + $< +endif +endif + +publish: +ifeq (,$(release)) + @echo Building test release $(version), no publishing! +else + @echo CHANGEME git push --tags origin + @echo CHANGEME scp $(project)-$(version).* \ + fedorahosted.org:$(project) +endif + +clean: + rm -rf $(project)-* tag-* diff --git a/configure.ac b/configure.ac index ad4b6c1..0a26adf 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,10 @@ # bootstrap / init AC_PREREQ([2.61]) -AC_INIT([corosync], [1.2.8], [open...@lists.osdl.org]) +AC_INIT([corosync], + m4_esyscmd([build-aux/git-version-gen .tarball-version]), + [open...@lists.osdl.org]) + AM_INIT_AUTOMAKE([-Wno-portability]) AC_CONFIG_SRCDIR([lib/coroipcc.c]) @@ -14,11 +17,6 @@ AC_CANONICAL_HOST AC_LANG([C]) -# Define SVN revision -AC_DEFINE([SVN_REVISION],["m4_esyscmd([svnversion >/dev/null 2>&1 && \ - svnversion -n || \ - echo -n exported])"], [SVN revision]) - dnl Fix default variables - "prefix" variable if not specified if test "$prefix" = "NONE"; then prefix="/usr" diff --git a/corosync.spec.in b/corosync.spec.in index ed531c3..ea46f7b 100644 --- a/corosync.spec.in +++ b/corosync.spec.in @@ -1,5 +1,6 @@ %global alphatag @alphatag@ - +%global numcomm @numcomm@ +%global dirty @dirty@ # Conditionals # Invoke "rpmbuild --without <feature>" or "rpmbuild --with <feature>" @@ -11,11 +12,11 @@ Name: corosync Summary: The Corosync Cluster Engine and Application Programming Interfaces Version: @version@ -Release: 1%{?alphatag:.%{alphatag}}%{?dist} +Release: 1%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist} License: BSD Group: System Environment/Base URL: http://www.openais.org -Source0: http://developer.osdl.org/dev/openais/downloads/%{name}-%{version}/%{name}-%{version}.tar.gz +Source0: http://developer.osdl.org/dev/openais/downloads/%{name}-%{version}/%{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}.tar.gz # Runtime bits Requires: corosynclib = %{version}-%{release} @@ -38,7 +39,7 @@ BuildRequires: libibverbs-devel librdmacm-devel BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) %prep -%setup -q -n %{name}-%{version} +%setup -q -n %{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}} %build %if %{buildtrunk} @@ -273,5 +274,5 @@ The Corosync Cluster Engine APIs. %{_mandir}/man8/sam_overview.8* %changelog -* @date@ Autotools generated version <nob...@nowhere.org> - @vers...@-1.@alphatag@ +* @date@ Autotools generated version <nob...@nowhere.org> - @vers...@-1-@numc...@.@alpha...@.@dirty@ - Autotools generated version diff --git a/exec/main.c b/exec/main.c index b994648..cd6cb83 100644 --- a/exec/main.c +++ b/exec/main.c @@ -1523,7 +1523,7 @@ int main (int argc, char **argv, char **envp) setprio = 0; break; case 'v': - printf ("Corosync Cluster Engine, version '%s' SVN revision '%s'\n", VERSION, SVN_REVISION); + printf ("Corosync Cluster Engine, version '%s'\n", VERSION); printf ("Copyright (c) 2006-2009 Red Hat, Inc.\n"); return EXIT_SUCCESS;
_______________________________________________ Openais mailing list Openais@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/openais