2014-02-20 02:05:13 +01:00
#!/usr/bin/perl
# creates a new release
# Copyright (C) 2014 Jürgen E. Fischer <jef@norbit.de>
# 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 2 of the License, or
# (at your option) any later version.
use strict ;
use warnings ;
use Getopt::Long ;
use Pod::Usage ;
2015-02-22 11:48:18 +01:00
my $ dryrun ;
sub updateCMakeLists ($$$$) {
my ( $ major , $ minor , $ patch , $ release ) = @ _ ;
if ( $ dryrun ) {
print "DRYRUN: Update CMakeLists.txt to $major.$minor.$patch ($release)\n" ;
return ;
}
rename "CMakeLists.txt" , "CMakeLists.txt.orig" or die "cannot rename CMakeLists.txt: $!" ;
open I , "CMakeLists.txt.orig" ;
open O , ">CMakeLists.txt" or die "cannot create CMakeLists.txt: $!" ;
while ( <I> ) {
s/SET\(CPACK_PACKAGE_VERSION_MAJOR "(\d+)"\)/SET(CPACK_PACKAGE_VERSION_MAJOR "$major")/ ;
s/SET\(CPACK_PACKAGE_VERSION_MINOR "(\d+)"\)/SET(CPACK_PACKAGE_VERSION_MINOR "$minor")/ ;
s/SET\(CPACK_PACKAGE_VERSION_PATCH "(\d+)"\)/SET(CPACK_PACKAGE_VERSION_PATCH "$patch")/ ;
s/SET\(RELEASE_NAME "(.+)"\)/SET(RELEASE_NAME "$release")/ ;
print O ;
}
close O ;
close I ;
}
sub run ($$) {
my ( $ cmd , $ errmsg ) = @ _ ;
if ( $ dryrun ) {
print "DRYRUN: $cmd\n" ;
} elsif ( system ( $ cmd ) != 0 ) {
print STDERR "error: $errmsg [$?]" ;
exit 1 ;
}
}
my $ newreleasename ;
2014-02-20 02:05:13 +01:00
my $ help ;
2015-02-22 11:48:18 +01:00
my $ domajor ;
my $ dominor ;
my $ dopoint ;
2015-03-01 22:00:46 +01:00
my $ doltr = 0 ;
2016-07-02 18:01:10 +02:00
my $ dopremajor = 0 ;
my $ skipts = 0 ;
2014-02-20 02:05:13 +01:00
my $ result = GetOptions (
2015-02-22 11:48:18 +01:00
"major" = > \ $ domajor ,
"minor" = > \ $ dominor ,
"point" = > \ $ dopoint ,
"releasename=s" = > \ $ newreleasename ,
"help" = > \ $ help ,
2015-03-01 22:00:46 +01:00
"ltr" = > \ $ doltr ,
2015-02-22 11:48:18 +01:00
"dryrun" = > \ $ dryrun ,
2016-07-02 18:01:10 +02:00
"premajor" = > \ $ dopremajor ,
"skipts" = > \ $ skipts ,
2014-02-20 02:05:13 +01:00
) ;
2015-02-22 11:48:18 +01:00
pod2usage ( 1 ) if $ help ;
2014-02-20 02:05:13 +01:00
2015-02-22 11:48:18 +01:00
my $ i = 0 ;
$ i + + if defined $ domajor ;
$ i + + if defined $ dominor ;
$ i + + if defined $ dopoint ;
pod2usage ( "Exactly one of -major, -minor or -point expected" ) if $ i != 1 ;
pod2usage ( "Release name for major and minor releases expected" ) if ! $ dopoint && ! defined $ newreleasename ;
2015-03-01 22:00:46 +01:00
pod2usage ( "Long term releases only for major and minor releases" ) if $ doltr && $ dopoint ;
2016-07-02 18:01:10 +02:00
pod2usage ( "Pre-major releases can only be minor releases" ) if $ dopremajor && ! $ dominor ;
2015-02-22 11:48:18 +01:00
pod2usage ( "No CMakeLists.txt in current directory" ) unless - r "CMakeLists.txt" ;
2014-02-20 02:05:13 +01:00
my $ major ;
my $ minor ;
2015-02-22 11:48:18 +01:00
my $ patch ;
my $ releasename ;
2014-02-20 02:05:13 +01:00
open F , "CMakeLists.txt" ;
while ( <F> ) {
if ( /SET\(CPACK_PACKAGE_VERSION_MAJOR "(\d+)"\)/ ) {
$ major = $ 1 ;
} elsif ( /SET\(CPACK_PACKAGE_VERSION_MINOR "(\d+)"\)/ ) {
$ minor = $ 1 ;
2015-02-22 11:48:18 +01:00
} elsif ( /SET\(CPACK_PACKAGE_VERSION_PATCH "(\d+)"\)/ ) {
$ patch = $ 1 ;
} elsif ( /SET\(RELEASE_NAME \"(.*)\"\)/ ) {
$ releasename = $ 1 ;
2014-02-20 02:05:13 +01:00
}
}
close F ;
2015-02-22 11:48:18 +01:00
my $ branch = `git rev-parse --abbrev-ref HEAD 2>/dev/null` ;
$ branch =~ s/\s+$// ;
pod2usage ( "Not on a branch" ) unless $ branch ;
2016-07-02 18:01:10 +02:00
pod2usage ( "Current branch is $branch. master or a release branch expected" ) if $ branch !~ /^(master.*|release-(\d+)_(\d+))$/ ;
2015-02-22 11:48:18 +01:00
pod2usage ( "Version mismatch ($2.$3 in branch $branch vs. $major.$minor in CMakeLists.txt)" ) if $ branch ne "master" && ( $ major != $ 2 || $ minor != $ 3 ) ;
pod2usage ( "Release name Master expected on master branch" ) if $ branch eq "master" && $ releasename ne "Master" ;
2016-07-02 18:01:10 +02:00
if ( $ branch =~ /^master.*/ ) {
2015-02-22 11:48:18 +01:00
pod2usage ( "No point releases on master branch" ) if $ dopoint ;
pod2usage ( "No new release name for major/minor release" ) unless $ newreleasename || $ newreleasename eq $ releasename ;
2014-02-20 02:05:13 +01:00
} else {
2015-02-22 11:48:18 +01:00
pod2usage ( "Only point releases on release branches" ) if ! $ dopoint ;
pod2usage ( "New release names only for new minor releases" ) if $ newreleasename ;
$ newreleasename = $ releasename ;
2014-02-20 02:05:13 +01:00
}
2015-02-22 11:48:18 +01:00
my $ newmajor ;
my $ newminor ;
my $ newpatch ;
if ( $ domajor ) {
$ newmajor = $ major + 1 ;
$ newminor = 0 ;
$ newpatch = 0 ;
} elsif ( $ dominor ) {
$ newmajor = $ major ;
2014-02-20 02:05:13 +01:00
$ newminor = $ minor + 1 ;
2015-02-22 11:48:18 +01:00
$ newpatch = 0 ;
} elsif ( $ dopoint ) {
$ newmajor = $ major ;
$ newminor = $ minor ;
$ newpatch = $ patch + 1 ;
} else {
pod2usage ( "No version change" ) ;
2014-02-20 02:05:13 +01:00
}
2016-02-26 14:33:07 +01:00
my $ splashwidth ;
2015-03-09 20:11:35 +01:00
unless ( $ dopoint ) {
pod2usage ( "Splash images/splash/splash-$newmajor.$newminor.png not found" ) unless - r "images/splash/splash-$newmajor.$newminor.png" ;
pod2usage ( "NSIS image ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp not found" ) unless - r "ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp" ;
2016-02-27 16:51:23 +01:00
my $ welcomeformat = `identify -format '%wx%h %m' ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp` ;
pod2usage ( "NSIS Image ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp mis-sized [$welcomeformat vs. 164x314 BMP3]" ) unless $ welcomeformat =~ /^164x314 / ;
2015-03-09 20:11:35 +01:00
}
2014-02-20 02:05:13 +01:00
print "Last pull rebase...\n" ;
2015-02-22 11:48:18 +01:00
run ( "git pull --rebase" , "git pull rebase failed" ) ;
2014-02-20 02:05:13 +01:00
my $ release = "$newmajor.$newminor" ;
2015-02-22 11:48:18 +01:00
my $ version = "$release.$newpatch" ;
2014-02-20 02:05:13 +01:00
my $ relbranch = "release-${newmajor}_${newminor}" ;
2015-03-01 22:00:46 +01:00
my $ ltrtag = $ doltr ? "ltr-${newmajor}_${newminor}" : "" ;
2015-02-22 11:48:18 +01:00
my $ reltag = "final-${newmajor}_${newminor}_${newpatch}" ;
2014-02-20 02:05:13 +01:00
2015-02-22 11:48:18 +01:00
unless ( $ dopoint ) {
2016-07-02 18:01:10 +02:00
unless ( $ skipts ) {
print "Pulling transifex translations...\n" ;
run ( "scripts/pull_ts.sh" , "pull_ts.sh failed" ) ;
run ( "git add i18n/*.ts" , "adding translations failed" ) ;
run ( "git commit -a -m \"translation update for $release from transifex\"" , "could not commit translation updates" ) ;
} else {
print "TRANSIFEX UPDATE SKIPPED!\n" ;
}
2015-02-22 11:48:18 +01:00
}
2015-02-20 08:42:46 +01:00
2015-02-20 12:41:24 +01:00
print "Updating changelog...\n" ;
2015-02-22 11:48:18 +01:00
run ( "scripts/create_changelog.sh" , "create_changelog.sh failed" ) ;
2014-02-20 02:05:13 +01:00
2015-02-22 11:48:18 +01:00
unless ( $ dopoint ) {
2016-07-02 18:01:10 +02:00
run ( "scripts/update-news.pl $newmajor $newminor '$newreleasename'" , "could not update news" ) if $ major > 2 || ( $ major == 2 && $ minor > 14 ) ;
2016-02-24 21:15:34 +01:00
run ( "git commit -a -m \"changelog and news update for $release\"" , "could not commit changelog and news update" ) ;
2014-06-20 11:40:35 +02:00
2015-02-22 11:48:18 +01:00
print "Creating and checking out branch...\n" ;
run ( "git checkout -b $relbranch" , "git checkout release branch failed" ) ;
2014-06-20 11:40:35 +02:00
}
2015-06-26 14:12:54 +02:00
updateCMakeLists ( $ newmajor , $ newminor , $ newpatch , $ newreleasename ) ;
2014-06-20 11:40:35 +02:00
2015-02-22 11:48:18 +01:00
print "Updating version...\n" ;
run ( "dch -r ''" , "dch failed" ) ;
run ( "dch --newversion $version 'Release of $version'" , "dch failed" ) ;
run ( "cp debian/changelog /tmp" , "backup changelog failed" ) ;
unless ( $ dopoint ) {
2016-07-02 12:54:37 +02:00
run ( "cp -v images/splash/splash-$newmajor.$newminor.png images/splash/splash.png" , "splash png switch failed" ) ;
2016-02-27 16:51:23 +01:00
run ( "convert -resize 164x314 ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp BMP3:ms-windows/Installer-Files/WelcomeFinishPage.bmp" , "installer bitmap switch failed" ) ;
2015-02-22 11:48:18 +01:00
if ( - f "images/splash/splash-release.xcf.bz2" ) {
run ( "cp -v images/splash/splash-$newmajor.$newminor.xcf.bz2 images/splash/splash.xcf.bz2" , "splash xcf switch failed" ) ;
} else {
print "WARNING: NO images/splash/splash-release.xcf.bz2\n" ;
}
2015-06-26 14:12:54 +02:00
run ( "git commit -a -m 'Release of $release ($newreleasename)'" , "release commit failed" ) ;
2015-03-01 22:00:46 +01:00
run ( "git tag $reltag -m 'Version $release'" , "release tag failed" ) ;
run ( "git tag $ltrtag -m 'Long term release $release'" , "ltr tag failed" ) if $ doltr ;
2014-06-20 11:40:35 +02:00
} else {
2015-02-22 11:48:18 +01:00
run ( "git commit -a -m 'Release of $version'" , "release commit failed" ) ;
run ( "git tag $reltag -m 'Version $version'" , "tag failed" ) ;
2014-06-20 11:40:35 +02:00
}
2014-02-20 02:05:13 +01:00
print "Producing archive...\n" ;
2016-02-26 13:46:13 +01:00
run ( "git archive --format tar --prefix=qgis-$version/ $reltag | bzip2 -c >qgis-$version.tar.bz2" , "git archive failed" ) ;
2015-02-22 11:48:18 +01:00
run ( "md5sum qgis-$version.tar.bz2 >qgis-$version.tar.bz2.md5" , "md5sum failed" ) ;
2016-07-02 18:01:10 +02:00
my @ topush ;
2015-02-22 11:48:18 +01:00
unless ( $ dopoint ) {
$ newminor + + ;
print "Updating master...\n" ;
run ( "git checkout master" , "checkout master failed" ) ;
2016-07-02 18:01:10 +02:00
if ( $ dopremajor ) {
print " Creating master_$newmajor...\n" ;
run ( "git checkout -b master_$newmajor" , "checkout master_$newmajor failed" ) ;
updateCMakeLists ( $ newmajor , $ newminor , 0 , "Master" ) ;
run ( "cp /tmp/changelog debian" , "restore changelog failed" ) ;
run ( "dch -r ''" , "dch failed" ) ;
run ( "dch --newversion $newmajor.$newminor.0 'New development version $newmajor.$newminor after branch of $release'" , "dch failed" ) ;
run ( "git commit -a -m 'New development branch for interim $newmajor.x releases'" , "bump version failed" ) ;
push @ topush , "master_$newmajor" ;
run ( "git checkout master" , "checkout master failed" ) ;
$ newminor = 999 ;
}
2015-02-22 11:48:18 +01:00
updateCMakeLists ( $ newmajor , $ newminor , 0 , "Master" ) ;
run ( "cp /tmp/changelog debian" , "restore changelog failed" ) ;
run ( "dch -r ''" , "dch failed" ) ;
run ( "dch --newversion $newmajor.$newminor.0 'New development version $newmajor.$newminor after branch of $release'" , "dch failed" ) ;
run ( "git commit -a -m 'Bump version to $newmajor.$newminor'" , "bump version failed" ) ;
2016-07-02 18:01:10 +02:00
push @ topush , "master" ;
2015-02-22 11:48:18 +01:00
}
2014-02-20 02:05:13 +01:00
2016-07-02 18:01:10 +02:00
push @ topush , $ relbranch ;
my $ topush = join ( " " , @ topush ) ;
2014-02-20 02:05:13 +01:00
print "Push dry-run...\n" ;
2016-05-04 12:29:16 +02:00
run ( "git push -n --follow-tags origin $topush" , "push dry run failed" ) ;
print "Now manually push and upload the tarballs :\n\tgit push --follow-tags origin $topush\n\trsync qgis-$version.tar.bz2* qgis.org:/var/www/downloads/\n\n" ;
2016-07-02 18:01:10 +02:00
print "WARNING: TRANSIFEX UPDATE SKIPPED!\n" if $ skipts ;
2014-02-20 02:05:13 +01:00
= head1 NAME
release . pl - create a new release
= head1 SYNOPSIS
2016-07-02 18:01:10 +02:00
release . pl { { - major | - minor [ - premajor ] } [ - skipts ] - releasename = releasename | - point } [ - ltr ]
2014-02-20 02:05:13 +01:00
Options:
2015-02-22 11:48:18 +01:00
- major do a new major release
- minor do a new minor release
- point do a new point release
- releasename = name new release name for master / minor release
2015-03-01 22:00:46 +01:00
- ltr new release is a long term release
2015-02-22 11:48:18 +01:00
- dryrun just echo but don ' t run any commands
2016-07-02 18:01:10 +02:00
- skipts skip transifex update
- premajor branch off a second "master" branch before
a major release
2015-03-09 20:11:35 +01:00
Major and minor releases also require a new splash screen
images /splash/s plash - M . N . png and bitmap for the NSIS
installer ms - windows /Installer-Files/ WelcomeFinishPage - M . N . bmp .
2016-07-02 18:01:10 +02:00
A pre - major minor release also produces a second branch
master_ $ currentmajor to allow more interim minor releases
while the new major version is being developed in master .
For that the minor version of the master branch leading
to the next major release is bumped to 999 .
2014-02-20 02:05:13 +01:00
= cut