Apache Subversion - Community Guide - Making Subversion Releases
[You can also view
the
single-page version
of this
document.]
General Overview
Community Roles
Coding and Commit Conventions
Building and Testing
Debugging Subversion
Web Site Changes
Mailing Lists
Bugs/Issues
Making Subversion Releases
Localization
Making Subversion Releases
Subversion release process
Release numbering
Inter-release compatibility
Custom releases
Deprecation
Stabilizing and maintaining releases
Creating a Subversion release
Notify translators
Preparing to roll a release
Rolling a release
Signing source distribution packages (a.k.a tarballs)
The actual releasing
Creating and maintaining release branches
Preparing to create a new minor release branch
Creating a new minor release branch
Porting changes to a release branch
Managing the CHANGES file
Writing the initial content for a branch
Adding content for patch release
How
not
to make a Subversion release
This document can generally be broken into three parts, in increasing
order of specificity:
High-level release planning and policies, such as version numbering and
compatibility. This answers questions like "When does a tarball get
created?" and "What should be the content of a tarball?"
What steps to take when it is time to create a release. This section
addresses the question of "How do I manage a release?"
How to construct a set of release tarballs. This section discusses
the steps required to go from source code in the repository to a set of
distributable
.tar.gz
or
.zip
files with the
desired content.
Subversion release managers use a set of steps codified in a Python script
named
release.py
This script can be used to perform most of the automated steps
in the release process. Run it with the
-h
option to get more
information.
In addition to the following project-specific guidelines, aspiring release
managers may also want to read up on the general
Apache release policies
They can seem a bit patchwork at times, but give a good idea of general
best practice and how Subversion fits in the larger ASF ecosystem.
Subversion release process
Release numbering
Subversion uses "MAJOR.MINOR.PATCH" release numbers. We do not use the
"even==stable, odd==unstable" convention; any unqualified triplet indicates
a stable release:
1.0.1 --> first stable patch release of 1.0
1.1.0 --> next stable minor release of 1.x after 1.0.x
1.1.1 --> first stable patch release of 1.1.x
1.1.2 --> second stable patch release of 1.1.x
1.2.0 --> next stable minor release after that
The order of releases is semi-nonlinear — a 1.0.3
might
come out after a 1.1.0. But it's only "semi"-nonlinear
because eventually we declare a patch line defunct and tell people to
upgrade to the next minor release, so over the long run the numbering
is basically linear.
The numbers may have multiple digits. For example, 1.7.19 is the nineteenth
patch release in the 1.7.x line; it was released three years after 1.7.2, and
three months before 1.7.20.
Subversion releases may be qualified by text following the
version number, which all represent various steps in the pre-release process.
In order from least- to most-stable:
Qualifier
Meaning
Example
Output of
svn --version
Alpha
We know or expect there to be problems, but solicit testing from
interested individuals.
subversion-1.7.0-alpha2
version 1.7.0 (Alpha 2)
Beta
We don't expect there to be problems, but be wary just in case.
subversion-1.7.0-beta1
version 1.7.0 (Beta 1)
RC (Release Candidate)
This release is a candidate to become the final proposed version. If
no serious bugs are found, the
-rc
tag will be dropped, and
the contents of this release will be declared stable.
subversion-1.7.0-rc4
version 1.7.0 (Release Candidate 4)
When you '
make install
' subversion-1.7.0-rc1,
it still installs as
though it were "1.7.0", of course. The qualifiers are metadata on the
release; we want each subsequent prerelease release to overwrite the
previous one, and the final release to overwrite the last
prerelease.
For working copy builds, there is no tarball name to worry about,
but '
svn --version
' still produces special output:
version 1.7.1-dev (under development)
The version number is the next version that project is working
towards. The important thing is to say "
under development
".
This indicates
that the build came from a working copy, which is useful in bug
reports.
Alpha and beta releases
When we want new features to get wide testing before we enter the
formal
stabilization period
we'll sometimes release alpha and beta tarballs. There is no requirement to
do any beta releases even if there were "alpha1", "alpha2", etc
releases; we could just jump straight to "rc1". However, there are
circumstances where a beta can be useful: for example, if we're unsure
of a UI decision and want to get wider user feedback before
solidifying it into a formal release candidate.
Alphas and betas are only for people who want to help test, and who
understand that there may be incompatible changes before
the final release. The signature requirements are at the release
manager's discretion. Typically, the RM will require only 1 or 2
signatures for each platform, and to tell signers that they can still
sign even if their testing reveals minor failures, as long as they
think the code is solid enough to make testing by others worthwhile.
The RM should request that signers include a description of any errors
along with their signatures, so the problems can be published when the
alpha or beta release is announced.
When the alpha or beta is publicly announced, distribution packagers
should be firmly warned off packaging it. See
this mail from Hyrum K. Wright
for a good model.
Breaking compatibility
Our compatibility rules (as detailed
below
only start to apply once a
final
x.y.0 version has been blessed and
released. Any API's, wire protocols, and on-disk formats that appeared on
trunk or in an alpha/beta/rc pre-release are not subject to
any
compatibility promises; we may change them arbitrarily until the final
release, if we find a good reason to do so. We might even remove entirely
an interface or serialization format that we are not comfortable with.
This is particularly a problem for persistent data (working copies and
repositories), since we might not provide an upgrade path—code paths or
designated scripts for the legacy format—with the final release. (Of
course, we might provide such scripts for the benefit of developers and users
who test our pre-releases; but we do not obligate ourselves to do so.)
Consequently, pre-releases should
never
be trusted with any
data meant for long-term safe-keeping.
At the same time, we wish to remind the reader that the best time to point
out API design bugs is before they are released and set in stone—in
other words, during the initial design and pre-release stages.
Reuse of release names
If a release or candidate release needs to be quickly re-issued due
to some non-code problem (say, a packaging glitch), it's okay to reuse
the same name, as long as the tarball hasn't been
blessed by signing
yet. However, if it has
been uploaded to the standard distribution area with signatures, or if
the re-issue was due to a change in code a user might run, then the
old name must be tossed and the next name used.
If the old name is tossed before the would-be release tarball was published
and announced to users, the tossed name is considered a non-public release, and
documentation (such as CHANGES and the tag's log message) should be updated to
reflect that. (See 1.8.7 for an example.) Tags and tarballs of tossed releases
remain in the repository history, but they are not supported for general use
(on the contrary, they are known to have release-blocker bugs).
Inter-release compatibility
Subversion follows strict compatibility, with the same
guidelines as APR (see
), plus a few extensions,
described later. These guidelines are in place to ensure various forms of
client/server interoperability, and make sure users have a clear upgrade
path between MAJOR.MINOR Subversion releases.
Compatibility can span a number of axes: everything from APIs and ABIs to
command line output formats. We try to balance the need to modify the existing
architecture to support new features, while still supporting current users
to the greatest extent possible. The general idea is:
Upgrading/downgrading between different patch releases in the
same MAJOR.MINOR line never breaks code. It may cause bugfixes
to disappear/reappear, but API signatures and semantics remain
the same. (Of course, the semantics may change in the trivial
ways appropriate for bugfixes, just not in ways that would
force adjustments in calling code.)
Upgrading to a new minor release in the same major line may
cause new APIs to appear, but not remove any APIs. Any code
written to the old minor number will work with any later minor
number in that line. However, downgrading afterwards may not
work, if new code has been written that takes advantage of the
new APIs.
(Occasionally, bugs are found which require the behavior of old APIs
to be modified slightly. This typically only manifests itself in
various corner cases and other uncommon areas. These changes are
documented as
API errata
for each MAJOR.MINOR release.)
When the major number changes, all bets are off. This is the
only opportunity for a full reset of the APIs, and while we try
not to gratuitously remove interfaces, we will use it to clean
house a bit.
Subversion extends the APR guidelines to cover client/server
compatibility questions:
A patch or minor number release of a server (or client) never
breaks compatibility with a client (or server) in the same
major line. However, new features offered by the release might
be unsupported without a corresponding upgrade to the other
side of the connection. For updating ra_svn code specifically,
please observe these principles:
Fields can be added to any tuple; old clients will simply
ignore them. (Right now, the marshalling implementation
does not let you put number or boolean values in the
optional part of a tuple, but changing that will not affect
the protocol.)
We can use this mechanism when information is added to an
API call.
At connection establishment time, clients and servers exchange
a list of capability keywords.
We can use this mechanism for more complicated changes,
like introducing pipelining or removing information from
API calls.
New commands can be added; trying to use an unsupported
command will result in an error which can be checked and dealt
with.
The protocol version number can be bumped to allow graceful
refusal of old clients or servers, or to allow a client or
server to detect when it has to do things the old way.
This mechanism is a last resort, to be used when capability
keywords would be too hard to manage.
Working copy and repository formats are backward- and
forward-compatible for all patch releases in the same minor
series. They are forward-compatible for all minor releases in
the same major series; however, a minor release is allowed to
make a working copy or repository that doesn't work with
previous minor releases, where "make" could mean "upgrade" as
well as "create".
Security releases
Occasionally, security issues are reported or discovered in the Subversion
which warrant special treatment when releasing. The general release process
is the same, and details of how the developers treat these issues is covered
elsewhere
Custom releases
Subversion does not distribute binary packages, but instead relies upon
third-party packagers
to do so. Luckily, many
individuals and companies have stepped in to volunteer their efforts in this
regard, and we are grateful for their efforts.
If you are a third-party packager, you may encounter instances when a bug
fix or other change is important for your users, and you want to get it to
them more quickly than the standard Subversion release cycle. Or you may
maintain a set of patches locally which benefit your target audience.
If possible, it is preferred to use the
patch process
and
have your changes accepted and applied to trunk to be released on the normal
Subversion release schedule.
However, if you feel that you need to make changes that would not be widely
accepted by the Subversion developer community, or need to provide early
access to unreleased features, you should follow the guidelines below. They
are intended to help prevent confusion in the user community, and make both
your distribution and the official Subversion releases as successful as
possible.
First, make sure you follow the
ASF
trademark policy
. You will need to differentiate your release
from the standard Subversion releases to reduce any potential
confusion caused by your custom release.
Second, consider creating a branch in the public Subversion
repository to track your changes and to potentially allow your custom
changes to be merged into mainline Subversion. (If you do not have it
already,
ask for commit access
.)
Third, if your custom release is likely to generate bug reports
that would not be relevant to mainline Subversion, please stay in
touch with the users of the custom release so you can intercept and
filter those reports. But of course, the best option would be not to
be in that situation in the first place — the more
your custom release diverges from mainline Subversion, the more
confusion it invites. If you must make custom releases, please try to
keep them as temporary and as non-divergent as possible.
Deprecation
When a new, improved version of an API is introduced, the old one
remains for compatibility, at least until the next major release (2.0.0).
However, we mark the old one as deprecated and point to the new one,
so people know to write to the new API if at all possible. When
deprecating, mention the release after which the deprecation was
introduced, and point to the new API. If possible, replace the old
API documentation with a diff to the new one. For example:
/**
* Similar to svn_repos_dump_fs3(), but with a @a feedback_stream instead of
* handling feedback via the @a notify_func handler
* @since New in 1.1.
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
svn_error_t *
svn_repos_dump_fs2(svn_repos_t *repos,
svn_stream_t *dumpstream,
svn_stream_t *feedback_stream,
svn_revnum_t start_rev,
svn_revnum_t end_rev,
svn_boolean_t incremental,
svn_boolean_t use_deltas,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool);
When the major release number changes, the "best" new API in a
series generally replaces all the previous ones (assuming it subsumes
their functionality), and it will take the name of the original API.
Thus, marking '
svn_repos_dump_fs
' as deprecated in
1.1.x doesn't mean
that 2.0.0 doesn't have '
svn_repos_dump_fs
', it just means the
function's signature will be different: it will have the signature
held by
svn_repos_dump_fs2
(or
svn_repos_dump_fs3
, or whatever) in
1.1.x. The numbered-suffix names disappear, and there is a single
(shiny, new)
svn_repos_dump_fs
again.
One exception to this replacement strategy is when the old function
has a totally unsatisfying name anyway. Deprecation is a chance to
fix that: we give the new API a totally new name, mark the old API as
deprecated, point to the new API; then at the major version change, we
remove the old API, but don't rename the new one to the old name,
because its new name is fine.
Stabilizing and maintaining releases
Overview
Minor and major number releases go through a stabilization period
before release, and remain in maintenance (bugfix) mode after release.
To start the release process, we
create an "
A.B.x
" branch
based on the
latest trunk.
The stabilization period for a new A.B.0 release normally lasts
four weeks, and allows us to make conservative bugfixes and discover
showstopper issues. The stabilization period begins with a release
candidate tarball with the version A.B.0-rc1. Further release
candidate tarballs may be made as blocking bugs are fixed; for
example, if a set of language bindings is found to be broken, it is
prudent to make a new release candidate when they are fixed so that
those language bindings may be tested.
Once the A.B.x branch has been created, no source code changes are
ever committed to it directly; changes are backported from trunk to the A.B.x
branch after being voted on, by the process described in the next sections.
At the beginning of the final week of the stabilization period, a
new release candidate tarball should be made if there are any
showstopper changes
pending since the last one. The final week of the stabilization
period is reserved for critical bugfixes; fixes for minor bugs should
be deferred to the A.B.1 release. A critical bug is a non-edge-case
crash, a data corruption problem, a major security hole, or something
equally serious.
Under some circumstances, the stabilization period will be
extended:
svn-soak-management.png
If a potentially destabilizing change must be made in order to
fix a bug, the entire four-week stabilization period is
restarted. A potentially destabilizing change is one which
could affect many parts of Subversion in unpredictable ways, or
which involves adding a substantial amount of new code. Any
incompatible API change (only allowable in the first place if
the new release is an A.0.0 release) should be considered a
potentially destabilizing change.
If a critical bugfix is made during the final week of the
stabilization period, the final week is restarted. The final
A.B.0 release is always identical to the release candidate made
one week before (with the exceptions discussed below).
After the A.B.0 release is out, patch releases (A.B.1, A.B.2, etc.)
follow when bugfixes warrant them. Patch releases do not require a
four week soak, because only conservative changes go into the
line.
What changes are eligible for backport
Certain kinds of commits can go into A.B.0 without restarting the
soak period, or into a later release without affecting the testing
schedule or release date:
Without voting:
Changes to the
STATUS
file.
Documentation fixes.
Changes that are a normal part of release bookkeeping, for
example, the steps listed in
Rolling a release
and
Creating and maintaining release branches
Changes to
dist.sh
by, or approved by, the
release manager.
Changes to message translations in
.po
files or
additions of
new
.po
files.
With voting:
Anything affecting only
tools/
packages/
or
bindings/
Changes to printed output, such as error and usage messages, as
long as format string "
" codes and their args are not
touched.
NOTE: The requirements on message translation changes are looser
than for text messages in C code. Changing format specifiers in
.po
files is allowed because their validity can be checked mechanically
(with the -c flag on msgfmt of GNU gettext). This is done at build
time if GNU gettext is in use.
Core code changes, of course, require voting, and restart the soak
or test period, since otherwise the change could be undertested.
Voting overview and the electorate
A change to the A.B.x line must be first proposed in the
A.B.x/STATUS
file. Each proposal consists of a short identifying
block (e.g., the revision number of a trunk or related-line commit, or
perhaps an issue number), a brief description of the change, an
at-most-one-line justification of why it should be in A.B.x, perhaps
some notes/concerns, and finally the votes. The notes and concerns
are meant to be brief summaries to help a reader get oriented.
Don't use the
STATUS
file for actual discussion; use dev@ instead.
Here's an example, probably as complex as an entry would ever
get:
* r98765 (issue #56789)
Make commit editor take a closure object for future mindreading.
Justification:
API stability, as prep for future enhancement.
Branch: 1.8.x-r98765
Notes:
There was consensus on the desirability of this feature in
the near future; see thread at http://... (Message-Id: blahblah).
Merge with --accept=mc.
Concerns:
Vetoed by jerenkrantz due to privacy concerns with the
implementation; see thread at http://... (Message-Id: blahblah)
Votes:
+1: ghudson, bliss
+0: cmpilato
-0: gstein
-1: jerenkrantz
Anyone may vote, but only full committers and partial committers for the
involved areas have binding votes. When committers cast a non-binding vote
(such as a partial committer voting for a change outside his nominated area),
they should annotate their vote as
non-binding
, like this:
* r31833
svndumpfilter: Don't match prefixes to partial path components.
Fixes #desc4 of issue #1853.
Votes:
+1: danielsh, hwright
+1 (non-binding): stylesen
This distinction is made in all kinds of voting—backport voting, release
voting, and the mythical
votes caused by failure to reach consensus
—but for different reasons.
In release votes, this distinction is legally required for the release to enter
ASF's legal shield, whereas in backport votes, it's closer to being an advisory
distinction. After all, if someone votes -1 on a change for a sound reason,
their accreditations don't matter; if their analysis is correct, the change
won't be backported. Likewise, if a change fails to receive
the required number
of binding
+1 votes but has some non-binding +1 votes, that may help it be approved.
In other words, the purpose of the backport process is to ensure
destabilizing changes won't enter patch releases. Voting serves that purpose
by forcing each change to undergo a certain amount of review. Since karma is
not transferable, we measure "amount of review" in terms of binding votes—but
as ever, anyone can give input to the process and be listened to.
Types of votes
The voter's opinion of a change is encoded as +1, -1, +0, or -0.
Define "veto" or refer to a definition
If you cast a veto (i.e. -1), please state the reason in the
concerns field, and include a url / message-id for the list discussion
if any. You can go back and add the link later if the thread isn't
available at the time you commit the veto.
A -0 vote means you somewhat object to a change—state your reasons in on
dev@, or summarize them in a parenthetical—but won't stand in the way of
consensus.
Voting +1 on a change doesn't just mean you approve of it in
principle. It means you have thoroughly reviewed the change, and find
it correct and as nondisruptive as possible. When it is committed to
the release branch, the log message will include the names of all who
voted for it, as well as the original author and the person making the
commit. All of these people are considered equally answerable for
bugs. Committers are trusted to know what they don't know and not
cast +1 votes lightly.
If you've reviewed a patch, and like it but have some reservations,
you can write "+1 (concept)" and then ask questions on the list about
your concerns. You can write "+0" if you like the general idea but
haven't reviewed the patch carefully. Neither of these votes counts
toward the total, but they can be useful for tracking down people who
are following the change and might be willing to spend more time on
it.
How many votes are required
A change is approved if it receives
three +1s
and no vetoes. (Only
binding votes count; see above.)
A change that
affects only areas that are
not core code
(for example,
tools/, packages/, bindings/, test scripts, etc.),
and that does
not affect the build system
can go in with
one +1
from a full committer or a
partial committer for that area, at least
one +0
or "concept +1" from
any other committer, and no vetoes.
The goal is to get at least two
pairs of eyes on the change, without demanding that every reviewer
have the same amount of expertise as the area maintainer. This way
one can review for general sanity, accurate comments, obvious
mistakes, etc, without being forced to assert "Yes, I understand these
changes in every detail and have tested them."
How to nominate changes into STATUS
Before proposing a change in
STATUS
, you should try merging it onto
the branch to ensure that it doesn't produce merge conflicts. If
conflicts occur, please create a new temporary branch from the release
branch with your changes merged and the conflicts resolved. The
branch should be named
A.B.x-rYYYY
, where YYYY is the first revision
of your change in the
STATUS
file. Add a note in the
STATUS
file
about the existence of the temporary branch in the form of a
Branch:
A.B.x-rYYYY
or
Branch: ^/subversion/branches/A.B.x-rYYYY
header (use this
exact form; scripts parse it). If the change involves
further work, you can merge those revisions to the branch. When the
entry for this change is removed from
STATUS
, this temporary branch
should also be removed to avoid cluttering the /branches
directory.
A temporary branch is also used in the rare case that a change should
be made to the A.B.x branch that isn't a backport of a change from trunk.
If you nominate an entry that causes merge conflicts until another
nomination is merged, note that in the nomination. Put a "Depends:" header
in the entry; that will keep the GitHub Actions "backportbot" job green.
(The value of the "Depends:" header is not parsed.)
The tools/dist/nominate.pl script (in trunk) automates the process of adding
a new nomination. The same script also has a REPL loop that helps with the
process of reviewing nominations and casting votes; see
tools/dist/README.backport (in trunk).
NOTE: Changes to
STATUS
regarding the temporary branch, including
voting, are always kept on the main release branch.
Editing STATUS and annotating votes
When adding revisions to a nomination that others have already voted on,
annotate their entries with "(rX only)" to clarify what parts they have and
haven't voted on, like this:
* r30643, r30653, r30785
Update bash completion script.
Votes:
+1: arfrever (r30785 only), stylesen
Obvious fixes
do not require '(rX only)' to be mentioned.
If you commit someone else's vote that was communicated via other
means, note that in your log message.
Creating a Subversion release
Notify translators
Before the actual release, send an e-mail to the translators to
request updates of the
.po
files. Take their e-mail addresses
from the
COMMITTERS
file in trunk, using a command such as:
sed -e '/^ *Translat.*:$/,/:$/!d' -e 's/^ *[^ ]* *\([^>]*>\).*/\1/;t;d' COMMITTERS
Include a translation status report produced by:
./tools/po/l10n-report.py
This should be done after all localised strings have stabilised in
their final form for the release, but sufficiently in advance of the
actual release to allow the translators to do their work. As a rule of
thumb, send the notification at the least one week, preferably more,
prior to the intended release. If many strings have changed, as would
be the case for the first release from a new branch, then let more
time pass.
Preparing to roll a release
Install pristine versions of some build tools
So, a release branch has stabilized, and you are gearing up to roll
the release. The details of the rolling process are automated by the
release.py
helper script. To run this script, you'll need a Subversion trunk working
copy. Run
release.py -h
to get a
list of available subcommands.
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.
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 (e.g., Debian's libtool patch:
#291641
#320698
.)
The version numbers given in
tools/dist/release-lines.yaml
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 consideration.
Autoconf, Libtool and SWIG
: Pick a directory to contain your
special build tools for Subversion RM duties - for example
/opt/svnrm
. Configure, build and install the three pieces of
software with the
release.py build-env
command.
mkdir -p /opt/svnrm && cd /opt/svnrm && $SVN_SRC_DIR/tools/dist/release.py build-env X.Y.Z
Install some more build tools
The rolling scripts also require the following commands to be available:
pax
xgettext
m4
and
python -c 'import yaml'
Install these from your OS packages.
(On Debian systems, that'd be
apt install pax gettext m4 python-yaml subversion
.)
Rolling a release
Before rolling
Make sure that the latest version of the
CHANGES
file from trunk is
merged into the release branch, and that the date at the top of
CHANGES
matches the planned release date of the tarball.
(See
Managing the CHANGES file
.)
Make sure that get-deps.sh works on the release branch.
Create the tarballs
Run:
./release.py roll X.Y.Z 1234
When release.py is done you'll have tarballs within the
/opt/svnrm/deploy
directory.
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.apache.org/repos/asf/subversion/trunk
i) Verify that the perl, python, and ruby 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, python, and ruby. 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
make swig-rb
make check-swig-rb
sudo make install-swig-rb
j) Verify that the javahl bindings at least compile.
If you can't do this, then have another developer verify.
(see subversion/bindings/javahl/README for details)
Ensure that ./configure detected a suitable jdk, and then
possibly re-run with '--enable-javahl', '--with-jdk=' and
'--with-junit=':
make javahl
sudo make install-javahl
make check-javahl
k) Verify that the ctypes python bindings at least compile.
If you can't do this then have another developer verify.
(see subversion/bindings/ctypes-python/README for details)
Ensure that ./configure detected a suitable ctypesgen, and
then possibly re-run with '--with-ctypesgen':
make ctypes-python
sudo make install-ctypes-python
make check-ctypes-python
l) Verify that get-deps.sh works and does not emit any errors.
./get-deps.sh
Use GnuPG to sign release:
Use release.py to sign the release:
release.py sign-candidates X.Y.Z
This will run the equivalent of the following commands for you:
gpg -ba subversion-X.Y.Z.tar.bz2
gpg -ba subversion-X.Y.Z.tar.gz
gpg -ba subversion-X.Y.Z.zip
and append gpg signatures to the corresponding .asc files.
Subversion Operations
Create the tag with the
svn_version.h
that reflects the final
release. You do this using:
release.py create-tag X.Y.Z 1234
Note: Please always make a tag, even for release candidates.
create-tag
will bump the version number in the
STATUS
and
svn_version.h
files for the original
branch. If you just did 1.0.2 then both files should have the proper value for
1.0.3 and so on.
Commit the tarballs, signatures and checksums to
There is a release.py subcommand that automates this step:
release.py post-candidates 1.7.0
Announce that the candidates are available for testing and signing:
send an email to the dev@ list, something like
this
Subject: Subversion X.Y.Z up for testing/signing
The X.Y.Z release artifacts are now available for testing/signing.
Please get the tarballs from
and add your signatures there.
Thanks!
adjust the topic on #svn-dev to mention
"X.Y.Z is up for testing/signing"
Update the issue tracker to have appropriate versions/milestones
. If
releasing a new minor release a version for 1.MINOR.x should be added. All
releases should add a version for the next release (i.e. 1.MINOR.x+1). If
you do not have permissions to do so please send an email to
the dev@ list.
Signing source distribution packages (a.k.a tarballs)
Why releases are signed
Subversion releases are distributed through a global
Content
Distribution Network
(CDN). (This replaced the former
ASF mirror network
as
of late 2021. Nevertheless, there may exist other organizations that choose
to continue mirroring ASF releases.)
It is important that end-users be able to verify the authenticity of the
source code packages they download. Checksums are sufficient to detect
corruption in the download process, but to prevent a malicious individual or
mirror operator from distributing replacement packages, each source code
package must be
cryptographically
signed
by members of the Subversion PMC. These
signatures are done using each committer's private PGP key, and are then
published with the release so that end users can verify the integrity of the
downloaded packages.
Voting and signing requirements
Before a Subversion release is officially made public, it requires:
three +1 votes from members of the Subversion PMC
ASF policy
, and
testing and signatures from at least one PMC member on
each
of the major platforms we support: Windows and *nix
[project policy]
How to sign a release
When creating the initial set of tarballs, the release manager will also
create the first set of signatures. While the tarballs themselves may be
built on
people.apache.org
, it is important that the signatures are
not
generated there. Signing tarballs requires a private key, and
storing private keys on ASF hardware is
strongly discouraged
. After
signing the tarballs (using the process below) the release manager should
upload the signatures to the preliminary distribution location, and place them
in the same directory as the tarballs.
Members of the PMC, as well as enthusiastic community members are encouraged to
download the tarballs from the preliminary distribution location, run the
tests, and then provide their signatures. The public keys for these signatures
should be included in the ASF LDAP instance through
id.apache.org
. (A list of the
current
public keys
of Subversion committers and PMC members is autogenerated
from LDAP each day.)
The release manager is encouraged to wait at least 5 days for the signatures
before announcing the release to allow anybody testing the version to complete
signing the release before its announcement.
Signing a tarball means that you assert certain things about it. When
announcing your signature, indicate in the mail what steps you've taken to
verify that the tarball is correct, such as verifying the contents against
the proper tag in the repository. Running
make check
over all RA
layers and FS backends is also a good idea, as well as building and testing
the bindings.
To obtain the release candidate, check out a working copy of
Verify the release manager's PGP signatures on the tarballs. release.py
automates this step:
release.py get-keys
release.py --target
/path/to/dist/dev/subversion/wc
check-sigs
1.7.0-rc4
After having verified, extracted, and tested the tarball,
you should sign by creating
an armored detached signature using
gpg
To append your signature to a .asc file, use a command like:
gpg -ba -o - subversion-1.7.0-rc4.tar.bz2 >> subversion-1.7.0-rc4.tar.bz2.asc
The release.py script can automate this step:
release.py --target
/path/to/dist/dev/subversion/wc
sign-candidates
1.7.0-rc4
After adding your signatures, commit the locally modified .asc files
to the dist.apache.org repository.
If you've downloaded and tested a
.tar.bz2
file, it is possible to
sign a
.tar.gz
file with the same contents without having
to download and test it separately. The trick is to extract the
.bz2
file, and pack it using
gzip
like this:
bzip2 -cd subversion-1.7.0-rc4.tar.bz2 \
| gzip -9n > subversion-1.7.0-rc4.tar.gz
The resulting file should be identical to the file generated by the
release manager, and thus can be signed as described above.
To verify that the files are identical, you may use either the checksums
or the release manager's signature, both of which should be provided with the
tarballs.
But, if the checksum is not identical it doesn't have to be the case that
the file signature is wrong, or the file has been tampered with. It could very
well be the case that you don't have an identical gzip version as the release
manager.
The actual releasing
After the tarballs are created, and all the signatures are created and
validated, the release is ready for publication. This section outlines the
steps needed to publish a Subversion release.
Uploading the release
Subversion artifacts are distributed through a global
Content
Distribution Network
(CDN). The source
code
download page
automatically assists users
in selecting a suitable download link. We usually host only the latest
stable release for the supported release lines on the project's distribution
directory, while all previous Subversion releases are available in the
archives
To upload a release to the CDN:
release.py move-to-dist 1.7.0
This moves the tarballs, signatures and checksums from
^/dev/subversion
to
^/release/subversion
It takes the content delivery network (CDN) approximately 15 minutes to
pick up the new release. The archive will also automatically pick up the
release. Although running
move-to-dist
will move the signature files,
committers are still able to commit new signatures
to
^/release/subversion
; however it will take up to 15 minutes for
those signatures to appear on the CDN. Any such signatures cannot be included
in the release announcement unless 15 minutes have passed since they were
committed.
At this point, the release may be publicly available, but its still a good
idea to hold off on announcing it until after the CDN has picked it up. After
the 15 minute period has passed, giving the CDN enough time to sync, the
release manager will send the announcement and publish the changes to the
Subversion website, as described below.
It's also a good time to clean out any old releases from
^/release/subversion
; only
the most recent release for each supported release line should be in that
directory. Releases that have been available at
^/release/subversion
for at least 24 hours will continue to remain available in the archives. You
can clean old releases using:
release.py clean-dist
Submit the version number of the new release on
reporter.apache.org
. The following command
curl -u
USERNAME
"https://reporter.apache.org/addrelease.py?date=`date +%s`&committee=subversion&version=
VERSION
&xdate=`date +%F`"
will add the release, it should probably be added to release.py.
Update the website
Even though the steps below indicate to update the published website
directly, you may prepare the changes on
^/subversion/site/staging
In that case:
Do a catch-up merge from
^/subversion/site/publish
Commit any changes to
^/subversion/site/staging
and
check the results on
When ready to publish, merge the changes back to
^/subversion/site/publish
(review the merge in case there are
other changes on staging not ready to be merged).
For any release, including pre-releases (alpha/beta/rc):
Edit
^/subversion/site/publish/download.html
to note the latest release.
Use
release.py write-downloads
to generate the table.
If this is a stable release, update the
[version]
or
[supported]
ezt macro definition (e.g.
[define version]1.7.0[end]
);
If this is a pre-release, uncomment the
if this is a 1.x.0 release that obsoletes the pre-release, comment it back out.
Add new News item to
^/subversion/site/publish/news.html
announcing the release. Add the same item to the News list on
^/subversion/site/publish/index.html
, also removing the
oldest News item from that page. Use
release.py write-news
to
generate a template news item, which should then be customized.
In the news item there is a section that should contain a link to the
announcement mail. For now it is commented out, the link is added later.
Check that the date is correct if you generated the template in advance of
the release date.
In addition, if this is a stable release X.Y.Z (not alpha/beta/rc):
List the new release on
^/subversion/site/publish/doap.rdf
There should be a
release with the
to the current release date and patch release number. Do not change
anything else in the file (in particular the
List the new release on
^/subversion/site/publish/docs/release-notes/release-history.html
In addition, if this is a new minor release X.Y.0:
Update the community release support levels on the "Supported Versions"
section of
^/subversion/site/publish/docs/release-notes/index.html
Update
supported_release_lines
in release.py, removing old
lines as necessary.
Remove the "draft" warning from
^/subversion/site/publish/docs/release-notes/X.Y.html
Create or update the versioned documentation snapshots in
^/site/publish/docs/api/X.Y
and
^/site/publish/docs/javahl/X.Y
, and
ensure that the "
latest
" symlinks which are siblings of those
directories always point to the directories of the latest release
series.
Example:
VER=1.12
DOCS_WC=~/src/svn/site/staging/docs
TAG_BUILD_DIR=~/src/svn/tags/$VER.x/obj-dir
cd $TAG_BUILD_DIR
make doc
cp -a doc/doxygen/html $DOCS_WC/api/$VER
cp -a doc/javadoc $DOCS_WC/javahl/$VER
for D in $DOCS_WC/api $DOCS_WC/javahl; do
svn add $D/$VER
rm $D/latest && ln -s $VER $D/latest
done
svn ci -m "In 'staging': Add $VER API docs." $DOCS_WC/api $DOCS_WC/javahl
Update the links to the API docs on the index page
docs/index.html#api
Commit the modifications to "publish" (or merge them from "staging" to
"publish") on the release date.
Press releases for 1.x.0 releases
New minor releases (numbered 1.x.0) may be accompanied by press releases.
All details of the prospective press release are handled on the
private@
list, in coordination with
press@a.o
As a rule of thumb, start a thread on private@ / press@
at the start of the soak
; it is better
to give press@ too long an advance warning than too short one.
Announcing the release
Write a release announcement, referring to previous ones for
guidance. Remember to include the URL and checksums in the
announcement! The
release.py write-announcement
subcommand
creates a template announcement which can be customized for specific
circumstances. If the release fixes security issues, pass
the
--security
flag, in order to generate the correct Subject,
Cc, and description in the output.
If the community support levels are changing with this
release, be sure to update the
recommended_release
variable in release.py
before using it to generate the announcement.
Send the announcement from your @apache.org email address.
(Mail to announce@ will bounce if sent from any other address.
For best results, follow the instructions on the
committer email
page and send your message through the official mail relay.)
Ensure that your mailer doesn't wrap the URLs over multiple lines.
NOTE: We update the website before announcing the release to make sure any
links in the release announcement are valid. After announcing the release,
links to the release announcement e-mail are added to the website.
There are two announce@ mailing lists where the release announcement gets
posted: The Subversion project's announce@subversion.apache.org list, and the ASF-wide announce@apache.org
list. It is possible that your message to the ASF-wide announce@ list will be
rejected. This generates a moderation notification with a Subject line such as:
Returned post for announce@apache.org
. The moderator who ordered the
mailing list software to reject the message may neglect to sign their name to
the rejection message, making the rejection anonymous, and the grounds for the
rejection may be invalid. Be that as it may, keep calm and forward the
rejection to the dev@ mailing list so the project can discuss whether anything
needs to be done about it. (If necessary, announce@ mailing list moderators can
be contacted via the announce-owner@ handle.)
If this is an X.Y.0 release, update the community support level at the very
top of the
STATUS
files of any branches that have changed support
status.
Add links to the release announcement e-mail in the website
Update
^/subversion/site/publish/news.html
and
^/subversion/site/publish/index.html
, uncommenting and adding the
link to the release announcement e-mail.
It is then time for the release manager to go and enjoy his
$favorite_beverage.
Creating and maintaining release branches
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.
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.
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.
Preparing to create a new minor release branch
Review the
Roadmap
. Should any of the outstanding
items be addressed before branching?
Review the incumbent stable branch's STATUS file for outstanding
-0 and -1 votes. Was code that is going to be included in the new
branch objected to? (Even if yes, that should not block branching, but
discussion should be started in order to resolve the issue before
rolling release branches.)
Do any tree-wide, mechanical changes. (Non-mechanical changes should
have happened earlier to allow for review.) This eases merging later.
Examples include
stripping trailing whitespace
and
plugging error leaks
and
fixing invariants in C headers
another case
and
code search and replace
(This is also a good time to do other periodical housekeeping tasks
such as
static
analysis
.)
Review new and changed APIs for design and style (e.g. Doxygen mark-up,
undocumented parameters, deprecation, public/private status, etc.).
abi-laboratory.pro Subversion
may be useful.
Run compatibility
tests against the incumbent minor release
Creating a new minor release branch
Once people agree that a new release branch should be made, the
Release Manager creates it with one of the following procedures (substitute
A.B with the version you're preparing, eg. 1.3, or 2.0).
Automated Procedure with release.py
Most of the work to create a release branch can be automated by
tools/dist/release.py:
Run this in an empty-ish directory where it will make some temporary checkouts:
release.py --verbose create-release-branch A.B.0
If not done previously, create the release notes template for the project
website:
release.py --verbose write-release-notes A.B.0 > .../docs/release-notes/A.B.html
svn add .../docs/release-notes/A.B.html
svn ci -m "Add release notes template." .../docs/release-notes/A.B.html
Some steps are not automated by release.py and must be
done manually—skip to the end of the following section, where they are
highlighted:
Manual Procedure
Most of the steps in this section can be automated by
tools/dist/release.py—see above—but are documented here in case
the Release Manager wants to do them manually:
Make sure the backport conflict detection job will monitor the
soon-to-be-created branch:
Add "A.B.x" to the branches array in
This must be done before the branch is created (or the change must
be merged back to the branch if done after creation).
Create the new release branch with a server-side copy:
svn cp ^/subversion/trunk \
^/subversion/branches/A.B.x \
-m "Create the A.B.x release branch."
Edit
subversion/include/svn_version.h
on trunk and
increment the version numbers there. Do not commit these changes
yet.
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).
Edit
subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java
on trunk and increment
SVN_VER_MINOR
. Do not commit these changes
yet.
Edit
subversion/tests/cmdline/svntest/main.py
on trunk and
increment
SVN_VER_MINOR
. Do not commit these changes
yet.
Edit
CHANGES
on trunk to introduce a new section for the
upcoming release if it is not already there, and also a new section
for the next minor release to be made in the future. Each section
starts with:
Version A.B.0
(?? ??? 20XX, from /branches/A.B.x)
Leave the release date blank for now. It will remain this way
until rolling time.
Commit these changes with a log message something like the
following:
Increment the trunk version number to A.$((B+1)), and introduce a new CHANGES
section, following the creation of the A.B.x release branch.
* subversion/include/svn_version.h,
subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java,
subversion/tests/cmdline/svntest/main.py
(SVN_VER_MINOR): Increment to $((B+1)).
* CHANGES: New section for A.$((B+1)).0.
Create a new
STATUS
file on the release branch.
Create a template release-notes document,
site/publish/docs/release-notes/A.B.html
The following steps must be done manually, even when
using release.py to automate most of the other steps:
Ask someone with appropriate access to add the A.B.x branch to the
backport merge bot
Decide whether the release would be regular or LTS and record the
decision in
lts_release_lines
in
tools/dist/release-lines.yaml
for release.py.
Managing the Backport Merge Bot
The backport merge bot runs nightly on the
svn-qavm1
machine,
under the
svnsvn
local user account, making commits
using the
svn-role
Subversion account name.
This configuration currently requires someone with admin access to
the machine, to manage changes to the set of branches.
The bot merges approved backports on each branch A.B.x for which a
WC directory exists at
~svnsvn/src/svn/A.B.x
The checkout there was created by running (as
svnsvn
user,
e.g. with sudo) something like:
svn checkout --depth=empty https://svn-master.apache.org/repos/asf/subversion/branches ~svnsvn/src/svn
svn up ~svnsvn/src/svn/
A.B.x
# for each supported branch
The repo URL is
svn-master.a.o
because the backports merger runs
svn ci && svn up
in a loop, and assumes
svn up
will
update it to the revision it just committed. That's
not guaranteed
when updating from a mirror (and
svn.a.o
may point to a
mirror).
Each branch is in a subdirectory of the WC root. To add a new
branch, populate the source tree with
svn up
sudo -H -u svnsvn svn up ~svnsvn/src/svn/A.B.x
To remove a no-longer-supported branch, use
svn up -r0
sudo -H -u svnsvn svn up -r0 ~svnsvn/src/svn/Z.Z.x
More notes on the setup can be found in
machines/svn-qavm1/
and
in the Subversion PMC's
private repository
. There are also historical notes on previous
incarnations in the history of
machines/
Porting changes to a release branch
Once a release branch has been created, no development
ever
takes place there. The only changes permitted are ones made to
various bookkeeping files such as
STATUS
, and changes merged
in from trunk. In rare cases, a feature branch may be created from the
A.B.x branch to address issues specific to the release branch (for example,
to fix a bug that does not affect trunk).
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
the
release stabilization section
Managing the CHANGES file
The
CHANGES
file is the project changelog file. Before a
release, it must be brought up to date to list all changes since the
last release.
Below, we describe the manual process. For partial automation, see
release.py write-changelog
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
trunk
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.
Remember that
CHANGES
should
always
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
CHANGES
file on trunk, both for future reference and so that
future release branches contain the sum of all previous change
logs.
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:
If it takes more than one line to describe, maybe I'm getting too
detailed?
Writing the initial content for a branch
Run
svn log --stop-on-copy ^/subversion/branches/A.B.x
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
remove
logs of changes that have already
been released in micro releases of the previous major/minor branch.
Run
svn log -q --stop-on-copy
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.)
(Update: nowadays,
svn mergeinfo --show-revs eligible
should simplify obtaining the set of relevant revisions—use
the minor branch as the source, and the
previous
minor branch
as the target.)
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
CHANGES
file before starting on the new section, just to
keep things consistent.
Adding content for patch release
As part of
release
stabilization
CHANGES
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
STATUS
) to the release branch, you
should also add an item to
CHANGES
on trunk, following the same
guidelines outlined above. This list will then be merged to the release
branch when a patch release is made.
In practice, CHANGES does not get updated each time a fix is
backported to the release branch. Normally, the release manager updates
CHANGES as one of the first steps to make a patch release.
A convenient way to get the list of backports that should be mentioned
in CHANGES is to use the same tool that populates
Coming up in the next patch release
on the Subversion website. This is
the
upcoming.py
script in
. Run it while
the current working directory is the root of a working copy of the minor
branch.
How
not
to make a Subversion release
For an enlightening case study of the bungled Subversion 1.5 release
cycle, see
this
paper