Release Procedure

From 389 Directory Server

Contents

Versioning

Some background on version numbering is available here - http://en.wikipedia.org/wiki/Software_versioning.

Naming

A full version name will be PACKAGENAME - VERSIONNUMBER e.g. 389-ds-base-1.2.5. The PACKAGENAME part will be the name typically given to the binary package. This name will also be used in the source. For packages that use autoconf for building, this will be the PACKAGE_TARNAME setting. The goal is that the full version name and number used in the source tarball name is the same as the SCM tag name of the tag used to produce that source tarball, and is the same as the name of the binary package. For autoconf packages, this also means the same source tarball name as produced by a make dist.

NAME=<name of package>
VERSION=<version number>
SRCNAME=$NAME-$VERSION
TAG=$SRCNAME

git tag $TAG
git archive --prefix=$TAG/ $TAG | bzip2 > $SRCNAME.tar.bz2
make dist -> $SRCNAME.tar.bz2
rpmbuild $NAME.spec -> $NAME-$VERSION.<dist>.<platform>.rpm # for RPM platforms

There are a couple of important exceptions to this:

  • The DS base and admin packages use an autoconf package name of dirsrv and dirsrv-admin - this is the name used to name files and directory paths (e.g. /etc/dirsrv). This is not the same as the name of the source tarballs and binary packages.
  • For RPMs, the RPM version number cannot be the same as the source version number for pre-release builds only, due to the way RPM calculates package dependencies and upgrades - see below

Source Version

The source version is the version number/string assigned to the source code and the SCM tag. It is comprised of several parts. In general, the version numbers look like this:

MAJOR.MINOR.MAINTENANCE[.PRE-RELEASE]

examples:

1.2.3 # an official release
1.2.3.a1 # alpha 1 pre-release of 1.2.3
1.2.3.a4.git283abc3 # alpha 4 pre-release of 1.2.3 from a git commit with short commit hash 283abc3
1.2.3.rc1 # release candidate 1 of 1.2.3

The PRE-RELEASE part (explained below) is optional, and indicates software that has not been officially released, in alpha, in testing, or a release candidate. The fields in the version number are explained below:

  • MAJOR - an integer - the major version - this only changes for very large or incompatible changes in the code
  • MINOR - an integer - the minor version - this changes when substantial changes are in the code
  • MAINTENANCE - an integer - this can change when there are small but non-trivial changes to the code (new functionality, bug fixes, errata)
  • PRE-RELEASE - (optional) - a string
    • a - indicates an alpha release - should be followed by an integer indicating which alpha release this is e.g. a1
    • rc - indicates a release candidate - should be followed by an integer indicating which release candidate this is e.g. rc1
    • The first alpha release is a1, then a2, etc. The first rc release is rc1, then rc2, etc. - just bump the number by 1 each time
    • additional text may appear after the aN or rcN - for example, if you want to mark the build with a git commit hash:
      • 1.2.3.a3.git23ab3512
      • Note that if the source is tagged often, the VERSION.PRE-RELEASE will already correspond exactly to an SCM tag, so using a git commit hash like this is probably not necessary

Tag Version

The version number part of a tag name will be exactly the same as the Source Version described above. This will allow us to go from a source tarball name to a git tag (and therefore a complete git tree). In git, tags are cheap and don't have the restrictions that plague CVS tagging, so we should use tags as much as possible.

Package Version

In general, we follow the Fedora Packaging Guidelines - https://fedoraproject.org/wiki/Packaging:NamingGuidelines - However, this means that the source/tag will not be identical to the package name-version-release. This will involve some complication in the RPM spec file for pre-release builds and snapshot builds. Fedora uses VERSION - RELEASE (e.g. 1.2.3-1) for the full version numbering and package naming. The VERSION is the dotted triplet of integers corresponding to the MAJOR.MINOR.MAINTENANCE. For official, blessed releases, the RELEASE is just a single integer that increments each time the spec is changed. For pre-releases, the RELEASE will begin with a 0., followed by the regular monotonically increasing release number, followed by the PRE-RELEASE part of the source/tag version. Here are some examples.

Source Spec V-R Comment
1.2.3.a1 1.2.3-0.1.a1 first alpha pre-release of 1.2.3
1.2.3.a2 1.2.3-0.2.a2 second alpha pre-release of 1.2.3
1.2.3.a3.git83fad321 1.2.3-0.3.a3.git83fad321 third alpha pre-release with git commit hash appended
1.2.3.rc1 1.2.3-0.4.rc1 first release candidate pre-release
1.2.3.rc2 1.2.3-0.5.rc2 second release candidate pre-release
1.2.3 1.2.3-1 first official 1.2.3 release
1.2.3 1.2.3-2 1.2.3 rebuild - release number is bumped (e.g. spec file changed but not source)

Notice that for pre-releases, the release field changes each time, and does not necessarily correspond to the number associated with the a or the rc. For example, a1 -> 0.1, a2 -> 0.2, a3 -> 0.3, but rc1 -> 0.4. The RELEASE field behaves for pre-releases exactly the same way it behaves for regular releases, except that for pre-releases, it begins with a 0..

This means, however, that the spec file cannot use the Version: field for both the package version and the source version. The spec file will need some special handling to account for this and for pre-releases.

# since this is a pre-release, define the prerel field - comment out for official release
%define prerel .a4
# also need the relprefix field for a pre-release
%ifdef prerel
%define relprefix 0.
%endif
...
Name: 389-ds-base
Version: 1.2.3 # note - same as source version
# if this is an official release, prerel will be commented out and both prerel
# and relprefix will therefore not be defined, so %{?relprefix} and %{?prerel}
# will expand to nothing giving us a V-R of 1.2.3-1
# if prerel and relprefix are defined, we will have a V-R like 1.2.3-0.4.rc1
# if version or prerel changes, reset to %{?relprefix}1%{?prerel}%{?dist}
Release: %{?relprefix}1%{prerel}%{?dist}
...
Source0: http://port389.org/source/%{srcname}-%{version}%{?prerel}.tar.bz2
...
%prep
%setup -q -n %{srcname}-%{version}%{prerel}

Doing the numbering this way preserves RPMs ability to do upgrades, since X.Y.Z-1 > X.Y.Z-0.1.something

Changing the Version

Large packages that will have many version changes, such as the core directory server and admin server, will use a file called VERSION.sh that holds the version and other fields used to name the package. This will allow us to change the version without having to edit configure.ac, run autogen.sh, etc. Packages that don't change very often will just use the version field of AC_INIT in configure.ac, and will have to perform autogen.sh. This shouldn't be a big deal for packages that do not change very often.

Release Procedure

Official Release - Version and Tag

0. Use the git work flow specified at GIT_Rules to make sure you apply the version changes correctly and without merging.

1. Change the version number to remove any pre-release strings. For example, if the version were specified as 1.2.3.rc2 in VERSION.sh:

VERSION.sh:
...
VERSION_PREREL=rc2

just comment out the VERSION_PREREL

#VERSION_PREREL=rc2

If this is a project that just uses AC_INIT to specify the version and not VERSION.sh, edit configure.ac, change the version to remove the pre-release part, and run autogen.sh.

2. commit the changes to the SCM

git add VERSION.sh # or configure.ac, configure, Makefile.in, any other file changed by autogen.sh
# you could just use git commit -a -m instead of first doing git add, but you must make sure
# there are no other files which would be picked up by -a - git status
git commit -m "bump version to 1.2.3 for official release"

3. tag the release

# git rebase, checkout master, and merge if necessary - see GIT_Rules
# apply the tag on the main branch (e.g. master) you are working on, not on a private side branch
git tag 389-ds-base-1.2.3
# also apply the RELEASE tag - use -f to move the existing tag
git tag -f RELEASE

Note that with git a tag is just an "alias" for a commit - you can easily view the commit associated with the tag, including the timestamp, so there is no need to create timestamped tags. The RELEASE tag allows someone to get the latest official release.

4. push the version change commit and the tag to the upstream repo

git push fedora master
git push --tags fedora master # tags are not pushed by default

make sure you have no local tags that you do not want to push

5. check the upstream repo to verify your commit and tag - you can just web browse to http://git.fedorahosted.org/git/?p=389/ds.git

The active tree should always be in the pre-release state - anyone pulling the tree using the tag HEAD or git fetch/pull should always see a pre-release tree. The only way to get an officially released source code tree is to pull from an official release tag.

So, after making an official release, you will have to put the tree back in the pre-release state for the next release - see below.

Pre-Release - Version and Tag

As noted above, the tree should always be in the pre-release state, starting with a1. To move to the next pre-release:

1. Change the pre-release field

  • if moving from an official release to a pre-release, change the MAINT number to the next one, and change the pre-release number to a1
  • if moving to the next alpha or release candidate, just change the number after the a e.g. a2 -> a3
  • if moving to a release candidate, change the aN to rc1 e.g. a4 -> rc1
VERSION.sh:
VERSION_PREREL=a1

change to

VERSION_PREREL=a2

If this is a project that just uses AC_INIT to specify the version and not VERSION.sh, edit configure.ac, change the version (e.g. from 1.2.6.a1 to 1.2.6.a2), and run autogen.sh.

2. commit the changes to the SCM

git add VERSION.sh # or configure.ac, configure, Makefile.in, any other file changed by autogen.sh
# you could just use git commit -a -m instead of first doing git add, but you must make sure
# there are no other files which would be picked up by -a - git status
git commit -m "bump version to 1.2.6.a2 for alpha 2"

3. tag the release

# git rebase, checkout master, and merge if necessary - see GIT_Rules
# apply the tag on the main branch (e.g. master) you are working on, not on a private side branch
git tag 389-ds-base-1.2.6.a2

4. push the version change commit and the tag to the upstream repo

git push fedora master
git push --tags fedora master # tags are not pushed by default

make sure you have no local tags that you do not want to push

5. check the upstream repo to verify your commit and tag - you can just web browse to http://git.fedorahosted.org/git/?p=389/ds.git

Create the source tarball

Start from a TAG (PACKAGE-VERSION) which was created using the above tagging procedure.

You can use git:

git pull fedora master # get the latest changes and tags
git archive --prefix=TAG/ TAG | bzip2 > /path/to/TAG.tar.bz2

or you can use wget if the repo supports gitweb snapshots:

wget http://git.fedorahosted.org/git/?p=389/ds.git;a=snapshot;h=TAG;sf=tgz
# gitweb snapshot does not support bzip2, so we have to repackage:
tar xfz TAG.tar.gz
tar cfj TAG.tar.bz2 TAG
rm -rf TAG TAG.tar.gz