diff options
Diffstat (limited to 'dist/makerelease')
-rwxr-xr-x | dist/makerelease | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/dist/makerelease b/dist/makerelease new file mode 100755 index 0000000..b46b9f9 --- /dev/null +++ b/dist/makerelease @@ -0,0 +1,355 @@ +#!/usr/bin/perl + +use strict; +use Pod::Usage; + + +my %opts; +my $descr; + +LocalGetOptions(\%opts, + ['r|regexp-ignore-steps=s','Ignore these REGEXP steps'], + ['s|start-at=s', 'Skip all steps until ARG'], + ['i|interactive', 'Prompt whether to do each step'], + ['n|dry-run', 'Dry run only. Don\'t actually do anything.'], + ['h|help', 'Help']); + +pod2usage(1) if ($opts{'h'}); +my $version = shift; +pod2usage( "No version supplied" ) if (!$version); +my $extrajunk = shift; +pod2usage( "Unexpected argument ($extrajunk)" ) if ($extrajunk); +my $vtag = $version; +my $branch = ""; +# Ensure we have both numeric and tag-style version labels +# plus the branch that we're working from (if relevant) +if ( $version =~ /^Ext/) { + $version =~ s/^Ext-//g; + $version =~ s/-/./g; +} else { + $vtag =~ s/\./-/g; + $vtag = "Ext-" . $vtag; +} +if ( $version =~ /^([0-9]\.[0-9])\.[0-9]/) { + ($branch = $version) =~ s/([0-9]\.[0-9])\.[0-9].*/\1/; + $branch =~ s/\./-/; + $branch = "V${branch}-patches"; +} + +# Make sure we're at the root of the build tree +# (if we're in the dist directory, then cd ..) +chdir("..") if (-f 'makerelease'); +die "Not at root of build tree" if (! -f 'configure.in'); + +# +# TESTING: +# +# Step 1) Ensure the build tree is up to date +System("update","svn -u status"); +System("update","svn -q update"); + +# Step 2) Change the libtool version information in Makefile.top +manualstep('version:manualedit', + "You (may) need to edit Makefile.top to update the library version numbering + (usually just for the first pre-release of a given version). + See the comments in RELEASE-INSTRUCTIONS + about LIBCURRENT, LIBAGE and LIBREVISION. + + I'll commit the file for you after you're done +"); +System("version:commit", + "svn commit -m \"version update\" Makefile.top"); + +# Step 3) configure and build and test it +my $transportargs = ""; +if ( $^O eq "linux" ) { + $transportargs = "--with-transports=IPX"; +} +my $configureargs = "--cache=config.cache --with-defaults ". + "--with-mib-modules=' examples examples/example ". + " testhandler smux Rmon' ". + " $transportargs --enable-ipv6 ". + "--enable-embedded-perl --enable-shared"; +System("build:distclean","make distclean") if (-f 'Makefile'); +System("build:configure","./configure $configureargs"); +System("build:make","make"); +System("build:test","make test TESTOPTS=-n"); + +# +# DOCUMENTATION +# +# Step 4) Update doxygen version number, and generate man pages +System("docs:doxygenconf", + "perl local/Version-Munge.pl -v $version -M -P -C -t doxygen"); +System("docs:make","make docs"); +System("docs:mancp","make mancp"); +System("docs:update","svn -u status man"); +manualstep('docs:manualaddnewman', + "Update man/Makefile.in with details of any new man pages, + and run 'svn add' on them. + I'll commit these changes for you after you're done +"); +System("docs:commit","svn commit -m \"documentation update\" man"); + +# Step 5) Check code for illegal constructs +System("code:checkcomments","make checks"); + +# Step 6) Update Makefile dependencies +System("code:makedepend","make distdepend"); +System("code:commitdepend","svn commit -m \"make depend\" `find . -name Makefile.depend`"); + +# Step 7) Update ChangeLog +# XXX: May need to extend the folding line-length, +# to avoid svn2cl mangling CHANGES/NEWS entries +System("changelog:svn2cl", + "svn2cl -f ChangeLog.add --break-before-msg --stop-on-copy"); +System("changelog:changelogfix", + "perl dist/changelogfix $branch < ChangeLog.add > ChangeLog.reallyadd"); +manualstep("changelog:manualedit", + "You need to manually insert the *relevent* portions of + 'ChangeLog.reallyadd' into the ChangeLog file. + I'll commit these changes for you afterwards"); +System("changelog:commit","svn commit -m \"version update\" ChangeLog"); + +# Step 8) Update README/NEWS/CHANGES +System("docs:newnews", + "perl dist/extractnews -s ----- -e ----- ChangeLog"); +System("docs:newnews", + "perl dist/extractnews -c CHANGES.new2 -n NEWS.new2 ChangeLog.reallyadd"); +manualstep("docs:README", + "You need to manually insert the relevent portions of + 'CHANGES.new' and 'NEWS.new' into the CHANGES and NEWS file. + (There are alternative versions in 'CHANGES.new2' and 'NEWS.new2') + You may wish to update the README file as well. + I'll commit these changes for you afterwards"); +System("docs:commit", + "svn commit -m \"version update\" README NEWS CHANGES"); + +# +# RELEASE +# +# Step 9) Resync code (omitted) +# Step 10) Update version +System("release:versionstamp", + "perl local/Version-Munge.pl -v $version -M -P -C"); + +# Step 11) Create the release tag checkpoint +my $root="https://net-snmp.svn.sourceforge.net/svnroot/net-snmp"; +if ( $branch ) { + System("release:tag", + "svn copy -m \"$version release\" $root/branches/$branch $root/tags/$vtag"); +} else { + System("release:tag", + "svn copy -m \"$version release\" $root/trunk $root/tags/$vtag"); +} + +# Step 12) Construct the tarball +my $tar = "star artype=ustar"; # XXX - check for star/gtar/etc +System("release:makedist", + "svn export $root/tags/${vtag}/net-snmp net-snmp-$version"); +System("release:removefiles", + "net-snmp-$version/remove-files net-snmp-$version"); +System("release:makedist", + "$tar -c -z -f net-snmp-${version}.tar.gz net-snmp-$version"); +System("release:makezipclean", + "rm -f net-snmp-${version}.zip"); +System("release:makezip", + "zip -r net-snmp-${version}.zip net-snmp-$version"); + + +# Step 13) Sign (or checksum) the package +my $sig1; +my $sig2; +my $pkg1 = "net-snmp-${version}.tar.gz"; +my $pkg2 = "net-snmp-${version}.zip"; + +System("release:searching-gpg-keys", + "gpg --list-secret-keys net-snmp-admin"); +if($? != 0) { + $sig1 = "${pkg1}.md5"; + $sig2 = "${pkg2}.md5"; + System("release:md5","md5sum $pkg1 > $sig1"); + System("release:md5","md5sum $pkg2 > $sig2"); +} else { + # currently only rstory and hardaker have the gpg keys till Wes + # sees someone else in person ;-) + $sig1 = "${pkg1}.asc"; + System("release:gpg","gpg -u net-snmp-admin -a --detach-sign $pkg1"); + $sig2 = "${pkg2}.asc"; + System("release:gpg","gpg -u net-snmp-admin -a --detach-sign $pkg2"); +} + +# +# RELEASE TESTING: +# +# Step 14) Unpack, build and test the release tarball +System("posttest:untar", "rm -rf net-snmp-${version}"); +System("posttest:untar", "tar xzf net-snmp-${version}.tar.gz"); +chdir("net-snmp-${version}"); +System("posttest:configure","./configure $configureargs"); +System("posttest:make","make"); +System("posttest:test","make test"); +chdir(".."); + +# Step 15) Double-check there are no outstanding changes +System("release:update","svn -u status"); + +# +# Steps 16 and following are NOT handled automatically. +# See the RELEASE-INSTRUCTIONS for full details. +# +print STDERR "**************************************** FINISHED ********************\n"; +print STDERR "\nDouble check the SVN status output above for any outstanding changes\n\n"; +print STDERR "Run the following command to upload the relase to SF:\n"; +print STDERR " rsync -v $pkg1 $pkg2 $sig1 $sig2 frs.sourceforge.net:uploads/\n"; +print STDERR "See RELEASE-INSTRUCTIONS for any additional steps\n"; + + +###################################################################### +sub System { + my $name = shift; + my $cmd = $descr = join(" ", @_); + my $rc; + while (dostep($name)) { + print STDERR " running: ",$cmd,"\n"; + last if ($opts{'n'}); + system(@_); + $rc = checkresult(); + last if ($rc == 0); + } +} + +sub checkresult { + if ($?) { + print STDERR "The above STEP failed. Continue anyway (y/n/r)? "; + my $ans = <STDIN>; + return 1 if ($ans =~ /^r/); + if ($ans =~ /^n/) { + print STDERR " EXITING\n"; + exit; + } + } + return 0; +} + +sub dostep { + my $name = shift; + print STDERR "\n********** STEP: $name ******************************\n"; + if ($descr) { + print STDERR " [$descr]\n"; + $descr = undef; + } + print "\n"; + if ($opts{'s'} && $name ne $opts{'s'}) { + print STDERR " [skipping]\n"; + return 0; + } + $opts{'s'} = ''; + if ($opts{r} && $name =~ /$opts{r}/) { + print STDERR " [skipping]\n"; + return 0; + } elsif ($opts{'i'}) { + print STDERR " Do this step (y/n/q)? "; + my $ans = <STDIN>; + if ($ans =~ /^n/) { + print STDERR " [skipping]\n"; + return 0; + } + if ($ans =~ /^q/) { + print STDERR " QUITTING\n"; + exit; + } + } + return 1; +} + +sub manualstep { + my $tag = shift; + + if (dostep($tag)) { + print STDERR "\n\n",join(" ",@_); + + print STDERR "\n\n Hit return when done: "; + + return 1 if ($opts{'n'}); + + my $bogus = <STDIN>; + return 1; + } + return 0; +} + +####################################################################### +# getopt long gui portability code +# +sub LocalGetOptions { + if (eval {require Getopt::GUI::Long;}) { + import Getopt::GUI::Long; + Getopt::GUI::Long::Configure(qw(display_help no_ignore_case)); + return GetOptions(@_); + } else { + require Getopt::Long; + Getopt::Long::Configure(qw(auto_help no_ignore_case)); + import Getopt::Long; + } + GetOptions(LocalOptionsMap(@_)); +} + +sub LocalOptionsMap { + my ($st, $cb, @opts) = ((ref($_[0]) eq 'HASH') + ? (1, 1, $_[0]) : (0, 2)); + for (my $i = $st; $i <= $#_; $i += $cb) { + if ($_[$i]) { + next if (ref($_[$i]) eq 'ARRAY' && $_[$i][0] =~ /^GUI:/); + push @opts, ((ref($_[$i]) eq 'ARRAY') ? $_[$i][0] : $_[$i]); + push @opts, $_[$i+1] if ($cb == 2); + } + } + return @opts; +} + +__END__ + +=head1 NAME + +makerelease - software package release script + +=head1 SYNOPSIS + +makerelease [options] version + +=head1 ARGUMENTS + +For full releases, the version should be specified in the form I<5.x.y> + +For pre-releases, the version should be specified in the form I<5.x.y.preN> + +For release candidates, the version should be specified in the form I<5.x.y.rcN> + +Alternatively, it is also possible to specify versions in the form Ext-5-x-y + +=head1 OPTIONS + +=over 8 + +=item B<-r {step}| --regexp-ignore-steps={step}> + +Ignore steps matching the regular expression {step} + +=item B<-s {step}| --start-at={step}> + +Skip all steps preceding the specified (exact) {step} + +=item B<-i | --interactive> + +Prompt whether or not to execute each step + +=item B<-n | --dry-run> + +Print the commands that would be executed, but do not execute them. + +=item B<-h | --help> + +Display this help message. + +=back |