release-process.html   [plain text]


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css"> /* <![CDATA[ */
  @import "branding/css/tigris.css";
  @import "branding/css/inst.css";
  /* ]]> */</style>
<link rel="stylesheet" type="text/css" media="print"
  href="branding/css/print.css" />
<script type="text/javascript" src="branding/scripts/tigris.js"></script>
<title>The Subversion Release Procedure</title>
</head>

<body>
<div class="app">

<h1 style="text-align: center;">The Subversion Release Procedure</h1>

<p>If you are the current Release Manager for the Subversion project,
or aspire to be, you should read and follow this procedure.</p>

<pre>
$LastChangedDate: 2006-04-03 18:57:54 +0200 (Mon, 03 Apr 2006) $
</pre>


<!-- Other pages seem to use "h2" for ToC, but I think "h1" works
     better, because the ToC is fundamentally different from other
     sections and therefore it's confusing when it looks the same as
     the others. -->
<div class="h1"><!-- no 'id' or 'title' attribute for ToC -->
<h1>Table of Contents</h1>

<ol id="toc">
  <li><a href="#release-manager-role">Being the Release Manager</a></li>
  <li><a href="#release-branches">Creating and maintaining release branches</a></li>
  <li><a href="#porting-changes">Porting changes to release branches</a></li>
  <li><a href="#the-changes-file">Managing the <tt>CHANGES</tt> file</a>
  <ol>
    <li><a href="#writing-initial-changes">Writing the initial content for a branch</a></li>
    <li><a href="#adding-changes">Adding content for patch release</a></li>
  </ol>
  </li> <!-- the-changes-file -->
  <li><a href="#before-release">Preparing to roll a release</a></li>
  <li><a href="#rolling-release">Rolling a release</a></li>
  <li><a href="#blessing-release">Blessing a release</a></li>
  <li><a href="#releasing-release">The actual releasing</a></li>
  <li><a href="#afterwards">After a release has been made</a></li>
</ol>

</div> <!-- h1 -->


<div class="h2" id="release-manager-role" title="release-manager-role">
<h2>Being the Release Manager</h2>

<p>The role of the Release Manager in the Subversion project is to
handle the process of getting code stabilized, packaged and released
to the general public.  If we were building planes, the RM would be
the guy looking at the construction checklists, painting the airline
logo on the fuselage, and delivering the finished unit to the
customer.</p>

<p>As such, there is no real development associated with being an RM.
All the work you have to do is non-coding: coordinating people,
centralizing information, and being the public voice announcing new
stable releases.  A lot of the tasks that the RM has to do are
repetitive, and not automated either because nobody has broken down
and written the tools yet, or because the tasks require human
validation that makes automation a little superfluous.</p>

<p>You may be thinking at this stage that the RM's duty is
unglamorous, and you are kinda right.  If you are looking for a
position within the project that will bring fame and fortune, you're
better off implementing stuff that really needs to be done on trunk.
If you're looking for something that really helps people who don't
care about releases focus on code, then RMing is for you.</p>

<p>So, you are the Release Manager.  What do you need to do?  This is
what the rest of this document is about.</p>

</div> <!-- release-manager-role -->


<div class="h2" id="release-branches" title="release-branches">
<h2>Creating and maintaining release branches</h2>

<p>A new release branch is created for each new major and minor
release.  So, for example, a new release branch is created when
preparing to release version 2.0.0, or version 1.3.0.  However, when
preparing to release 1.3.1 (a patch-version increment), the release
branch created at the time of 1.3.0 is used.</p>

<p>If you are preparing for a patch release, then there is no release
branch to create. You just pick up where you left off in the current
minor version series release branch.</p>

<p>The time at which a new release branch needs to be created is fuzzy
at best.  Generally, we have a soft schedule of releasing a new minor
version every 6 months.  So, approximately 4 months after the previous
minor release is a good time to start proposing a branch. But remember
that this is flexible, depending on what features are being
developed.</p>

<p>Once people agree that a new release branch should be made, the
Release Manager creates it with the following procedure (substitute
A.B with the version you're preparing, eg. 1.3, or 2.0):</p>

<ul>
<li><p>Create the new release branch with a server-side copy:</p>
    <pre>
      svn cp http://svn.collab.net/repos/svn/trunk \
             http://svn.collab.net/repos/svn/branches/A.B.x \
             -m "Create A.B.x release branch."
    </pre></li>

<li><p>Edit <tt>subversion/include/svn_version.h</tt> on trunk and
    increment the version numbers there.  Do not commit these changes
    yet.</p>
    <p>The version number on trunk always reflects the major/minor
    version that will immediately follow the one for which you just
    created a branch (eg. 2.1.0 for the 2.0.x branch, and 1.4.0 for
    the 1.3.x branch).</p></li>

<li><p>Edit <tt>CHANGES</tt> on trunk to introduce a new section for the
    upcoming release.  The section starts with:</p>
    <pre>
      Version A.B.0 (released ?? ????? 200X, from /branches/A.B.x)
      http://svn.collab.net/repos/svn/tags/A.B.0
    </pre>
    <p>Leave the release date blank for now. It will remain this way
    until rolling time.</p></li>

<li><p>Commit both these changes with the following log message:</p>
    <pre>
      Increment the trunk version number, and introduce a new CHANGES
      section for the upcoming A.B.0 release.

      * subversion/include/svn_version.h: Increment version number.

      * CHANGES: New section for A.B.0.
    </pre></li>
</ul>

</div> <!-- release-branches -->


<div class="h2" id="porting-changes" title="porting-changes">
<h2>Porting changes to release branches</h2>

<p>Once a release branch has been created, no development <i>ever</i>
takes place there.  The only changes permitted are ones made to
various bookkeeping files such as <tt>STATUS</tt>, and changes merged
in from trunk.</p>

<p>The protocol used to accept or refuse the merging of changes from
trunk is of interest to all Subversion developers, and as such is
documented in <a href="hacking.html#release-stabilization">the
release stabilization section of the hacking guide</a>.</p>

</div> <!-- porting-changes -->


<div class="h2" id="the-changes-file" title="the-changes-file">
<h2>Managing the <tt>CHANGES file</tt></h2>

<p>The <tt>CHANGES</tt> file is the project changelog file.  Before a
release, it must be brought up to date to list all changes since the
last release.</p>

<p>For patch-releases, this is fairly easy: you just need to walk
through the commit logs for the branch since the last "golden"
revision, and note all interesting merges.  For minor and major
releases, this is more complex: you need to traverse the commit log on
<em>trunk</em> since the last release branch was forked, and make note
of all changes there.  It's the same procedure, but a lot longer, and
somewhat more complex as it involves filtering out changesets that
have already been backported to previous release branches and released
from there.</p>

<p>Remember that <tt>CHANGES</tt> should <em>always</em> be edited on
trunk and then merged over to the release branch(es) when necessary.
It is very important that all changes of all releases be documented in
the <tt>CHANGES</tt> file on trunk, both for future reference and so that
future release branches contain the sum of all previous change
logs.</p>

<p>Keep the bullet point for each change concise, preferably no more
than one line long.  Sometimes that can be a challenge, but it really
adds to the overall readability of the document.  Think to yourself:
<i>If it takes more than one line to describe, maybe I'm getting too
detailed?</i></p>

<div class="h3" id="writing-initial-changes" title="writing-initial-changes">
<h3>Writing the initial content for a branch</h3>

<p>Run <code>svn log -rHEAD:BRANCH_POINT
http://svn.collab.net/repos/svn/branches/A.B.x</code>,where
BRANCH_POINT is the revnum where the previous major/minor release was
branched off of the trunk.  This should give you every change ever
made to the A.B.x line, including backports made to the A.B.x branch.
You then need to <em>remove</em> logs of changes that have already
been released in micro releases of the previous major/minor branch.
Run <code>svn log -q --stop-on-copy</code> on the previous release
branch, and then write a script to parse the revnums and remove them
from your primary log output.  (Karl and Ben used to use emacs macros
to do that, but suggest that we write a more general script.)</p>

<p>Read that log from oldest to newest, summarizing points as you go.
The trick is to know what level of detail to write at: you don't want
to mention every tiny little commit, but you don't want to be too
general either.  Set your filter-level by reading through a few pages
of the <tt>CHANGES</tt> file before starting on the new section, just to
keep things consistent.</p>

</div> <!-- writing-initial-changes -->

<div class="h3" id="adding-changes">
<h3>Adding content for patch release</h3>

<p>As part of <a href="/hacking.html#release-stabilization">release
stabilization</a>, <tt>CHANGES</tt> should be updated as bug fixes are
ported to the release branch.  Generally, if you merge a revision or group
of revisions (i.e., an item in <tt>STATUS</tt>) to the release branch, you
should also add an item to <tt>CHANGES</tt> on trunk, following the same
guidelines outlined above.  This list will then be merged to the release
branch when a patch release is made.</p>

</div> <!-- adding-changes -->

</div> <!-- the-changes-file -->


<div class="h2" id="before-release" title="before-release">
<h2>Preparing to roll a release</h2>

<p>So, a release branch has stabilized, and you are gearing up to roll
the release.  Before you can actually roll the archives, you need to
set up a white-room rolling environment.  This environment must
contain pristine versions of some build tools, as well as all the
relevant dependancies and other stuff that gets bundled into a
release tarball.</p>

<p>You need to grab vanilla source tarballs of the following build
tools before proceeding:</p>

<ul>
<li><p><b>Autoconf</b> 2.59 (2.60 is a significant compatibility break
from the 2.5x series, and is known to break APR)</p></li>
<li><p><b>Libtool</b> 1.5.22</p></li>
<li><p><b>SWIG</b> 1.3.25</p></li>
</ul>

<p>It is important that you do not use distribution shipped versions
of this software as they are often patched in ways that are not
portable.  The version numbers given above should normally be
reconsidered and increased to the latest stable upstream release in
the time leading up to an A.B.0 release.  Changing the version within
an A.B.x series should only be done with careful considereration.</p>

<p>Also grab the following source tarballs, parts of which will be
bundled in the Subversion release packages:</p>

<ul>
<li><p>The latest Unix <b>APR</b> and <b>APR-util</b> of the 0.9.x
line (currently 0.9.13)</p></li>
<li><p>The latest Win32 <b>APR</b>, <b>APR-util</b> and
<b>APR-iconv</b> of the 0.9.x line (currently 0.9.13)</p></li>
<li><p>The latest <b>Neon</b> 0.25.x release (currently
0.25.5)</p></li>
<li><p>The latest <b>zlib</b> release (currently 1.2.3)</p></li>
</ul>

<p>Once you have all this, you can start the following procedure.
When it is done, you will have a build environment ready to roll
tarballs.</p>

<p><b>Autoconf, Libtool and SWIG</b>: Pick a directory to contain your
special build tools for Subversion RM duties - for example
<tt>/opt/svnrm</tt>.  Configure, build and install the three pieces of
software with <tt>--prefix=/opt/svnrm</tt>, and remember, whenever you
run <tt>dist.sh</tt> to be sure that <tt>/opt/svnrm/bin</tt> is at the
front of your <tt>PATH</tt>.</p>

<p><b>Dependency source preparation</b>: You should create two
directories which will hold the dependencies which will be repackaged
with Subversion, one for Unix and one for Win32.  You might, for
example, choose <tt>/opt/svnrm/unix-dependencies</tt> and
<tt>/opt/svnrm/win32-dependencies</tt>.  Within the Unix one, you must
unpack the Unix APR and APR-util tarballs, and the Neon and zlib
tarballs, and then rename each top level directory so it does
<b>not</b> contain a version number, resulting in a directory
containing four directories: <tt>apr</tt>, <tt>apr-util</tt>,
<tt>neon</tt> and <tt>zlib</tt>.  Within the Win32 one, you must
unpack the Apache HTTP Server zipfile, move the <tt>apr</tt>,
<tt>apr-util</tt> and <tt>apr-iconv</tt> directories from the
<tt>srclib</tt> directory of the <tt>httpd</tt> zipfile into the
dependency directory, and delete the rest of the <tt>httpd</tt>
extract.  You must then copy the <tt>neon</tt> and <tt>zlib</tt>
directories from the Unix dependency directory into the Win32 one too.
Do not use symlinks, <tt>dist.sh</tt> does not support them.</p>

</div> <!-- before-release -->


<div class="h2" id="rolling-release" title="rolling-release">
<h2>Rolling a release</h2>

<p>Before rolling, first make sure that the latest version of the
<tt>CHANGES</tt> file from trunk is merged into the release branch, and that
the date at the top of <tt>CHANGES</tt> matches the planned release date of
the tarball.</p>

<p><b>Build the tarballs</b>: From within your Unix dependency
directory, run:</p>
<pre>
PATH="/opt/svnrm/bin:$PATH" ./dist.sh -v X.Y.Z -r 1234 -pr branches/X.Y.Z
</pre>
<p>Watch <tt>dist.sh</tt>'s output to make sure everything goes
smoothly; when it's done, you'll have tarballs in the cwd.</p> 
 
<p><b>Build the zipfiles</b>: From within your Win32 dependency
directory, run:</p>
<pre>
PATH="/opt/svnrm/bin:$PATH" ./dist.sh -v X.Y.Z -r 1234 -pr branches/X.Y.Z -zip
</pre>
<p>Watch <tt>dist.sh</tt>'s output to make sure everything goes
smoothly; when it's done, you'll have zipfiles in the cwd.</p> 
 
<pre>
Test one or both of the tarballs:
 
    a) tar zxvf subversion-X.Y.Z.tar.gz;  cd subversion-X.Y.Z
    b) ./configure
 
       See INSTALL, section III.B for detailed instructions on
       configuring/building Subversion.
 
       If you installed Apache in some place other than the default, as
       mentioned above, you will need to use the same
       --prefix=/usr/local/apache2 option as used to configure Apache.
 
       You may also want to use --enable-mod-activation, which will
       automatically enable the required Subversion modules in the
       Apache config file.
 
    c) make
    d) make check
    e) make install (this activates mod_dav)
    f) make davcheck
 
       For this, start up Apache after having configured according to
       the directions in subversion/tests/cmdline/README.
 
       Make sure, that if you maintain a development installation of
       apache, that you check the config file and update it for the
       new release area where you're testing the tar-ball.
 
       (Unless you rename the tree which gets extracted from the
       tarball to match what's in httpd.conf, you will need to edit
       httpd.conf)
 
    g) make svncheck
 
       First, start up svnserve with these args:
 
          $ subversion/svnserve/svnserve -d -r \
            `pwd`/subversion/tests/cmdline
 
       -d tells svnserve to run as a daemon
       -r tells svnserve to use the following directory as the
          logical file system root directory.
 
       After svnserve is running as a daemon 'make svncheck' should run
 
    h) Then test that you can check out the Subversion repository
       with this environment:
 
          subversion/svn/svn co https://svn.collab.net/repos/svn/trunk
 
    i) Verify that the perl and python swig bindings at least compile.
       If you can't do this, then have another developer verify.
 
       (see bindings/swig/INSTALL for details)
 
       Ensure that ./configure detected a suitable version of swig,
       perl, and python.  Then:
 
          make swig-py
          make check-swig-py
          sudo make install-swig-py
 
          make swig-pl
          make check-swig-pl
          sudo make install-swig-pl
 
    j) Verify that the javahl bindings at least compile.
       If you can't do this, then have another developer verify.
 
       (see bindings/java/javahl/README for details)
 
       Ensure that ./configure detected a suitable jdk, and then
       possibly re-run with '--enable-javahl' and '--with-jdk=':
 
          make javahl
          sudo make install-javahl
          make check-javahl
</pre>

<p><b>Use GnuPG to sign release:</b></p>
<pre>
    gpg -ba subversion-X.Y.Z.tar.bz2
    gpg -ba subversion-X.Y.Z.tar.gz
    gpg -ba subversion-X.Y.Z.zip
    gpg -ba subversion-deps-X.Y.Z.tar.bz2
    gpg -ba subversion-deps-X.Y.Z.tar.gz
    gpg -ba subversion-deps-X.Y.Z.zip
</pre>

<p><b>Subversion Operations</b></p>
<p>Create the tag with the svn_version.h that reflects the final
release.  You do this by updating your working copy to the release
revision, 1234 in the example below.  Run svnversion to verify that
you do not have a mixed working copy or modified working copy, i.e.
svnversion outputs only the release revision (not 1234:1235 or 1234M).
Then place the svn_version.h.dist file in place in the working copy
and copy from the working copy to the tag URL.  For example:</p>

<pre>
    svn up -r 1234
    svnversion .
    cp svn_version.h.dist subversion/include/svn_version.h
    svn cp . \
           https://svn.collab.net/repos/svn/tags/X.Y.Z \
           -m "Tagging release X.Y.Z with svn_version.h matching tarball"
</pre>

<p>Note: Please always make a tag, even for release candidates.</p>

<p>Bump the svn_version.h for the original branch.  If you just did
1.0.2 then svn_version.h should have the proper values for 1.0.3 and
so on.</p>

</div> <!-- rolling-release -->


<div class="h2" id="blessing-release" title="blessing-release">
<h2>Blessing a release</h2>
</div> <!-- blessing-release -->


<div class="h2" id="releasing-release" title="releasing-release">
<h2>The actual releasing</h2>

<p><b>Upload the tarballs to
  http://subversion.tigris.org/downloads/.</b></p>
<p>The RM will be given details on how to do this via private
channels.</p>

<p><b>Update Tigris "Documents &amp; files" area</b></p>
<p>Update the links to the tarballs in the Documents &amp; files
Tigris webapp.</p>

<ol>
  <li>Log into <a href="http://subversion.tigris.org/">Tigris</a></li>
  <li>Click on 'Documents &amp; files'.</li>
  <li>Navigate to the 'subversion/Releases/Source code/' folder.</li>
  <li>For each of the 12 files:
  <ol>
    <li>Click on the 'Add new file' link.</li>
    <li>Fill in the following fields:
    <ul>
      <li>Name: &lt;file name&gt;</li>
      <li>Status: Stable</li>
      <li>Description: <i>(one of:)</i>
      <ul>
        <li>Subversion release X.Y.Z (MD5: &lt;md5sum of
        tarball&gt;)</li>
        <li>Subversion dependencies X.Y.Z (MD5: &lt;md5sum of
        tarball&gt;)</li>
        <li>PGP Signatures for Subversion release X.Y.Z.</li>
      </ul>
      </li>
      <li>Contents: <i>(choose 'Link', then enter:)</i>
      http://subversion.tigris.org/downloads/&lt;file name&gt;
      </li>
    </ul>
    </li>
    <li>Click Submit.</li>
  </ol>
  </li>
</ol>

<p><b>Announcements</b></p>
<p>Write a release announcement, referring to previous ones for
guidance.  Remember to include the URL and MD5 checksums in the
announcement!</p>

<p>Post a project news item <a
href="http://subversion.tigris.org/servlets/ProjectNewsList">here</a>.
If the link reads "Suggest an announcement" instead of "Add new
announcement", then you do not have the required permission - ask to
be granted the 'Release Manager' Tigris role.  Note that the
Tigris news items are in HTML format not plain text.</p>

<p>Send an announcement to dev@, users@, and announce@ lists.  Ensure
that your mailer doesn't wrap the URLs over multiple lines.</p>

<p>You should also notify Freshmeat of the new release.  For a regular
final release, this involves adding the new release to the "Stable"
Freshmeat project branch (click the "add release" link in the top
navigation bar); alpha, beta, and RC releases get filed the say way,
but under the "Development" branch.  You need to be listed as a
release manager or admin for the <a
href="http://freshmeat.net/projects/subversion/" >Subversion project
on Freshmeat</a>.  Contact one of the folks who are already listed if
you need access.  Your submission will also be tweaked by the
freshmeat crew before it goes public.</p>

<p><b>Update the website</b></p>
<ol>
  <li>Edit the www/project_status.html file appropriately in /trunk
  *NOT* in the release branch and commit. Remember edit a search term
  at the end of release's issue link.</li>
  <li>Update the best available version on the front page and at the
  top of www/getting.html</li>
  <li>Update the "Latest Release" section of www/index.html to point
  to the new announcement.</li>
  <li>Commit the modifications.</li>
</ol>

<p>If you've made it this far, go and enjoy your $favorite_beverage now.</p>

</div> <!-- releasing-release -->


<div class="h2" id="afterwards" title="afterwards">
<h2>After a release has been made</h2>

<p>When someone with administrative access to <tt>svn.collab.net</tt>
has time available, they will upgrade it to the latest release or
release candidate.  (This person is not usually the release
manager.)</p>

</div> <!-- afterwards -->


</div> <!-- app -->
</body>
</html>