At the beginning of the "UIMA Release Process" there must be consensus in the developer community
about the JIRA issues that should be part of the next release and the time frame for the release.
(Optional) The result of this discussion should be published in a release plan to the UIMA wiki, if it is
complex.
This release plan should be kept up-to-date any time so that everybody can have a look at the target dates
to calculate personal ToDos.

The build includes a generated set of Jira issues fixed (closed or resolved) in this release.
To make this accurate, go through the Jiras and ensure the ones you are including in the release
are closed/resolved, and that the "Fixed in release xxx" is set for each Jira issue that is part of the
release.

There is a saved "filter" you can adjust for this that will display all fixed Jira issues with no Fixed in release xxx
assigned. You can go through subsets of this (use the filter to pick the subset you want)
and do "bulk Jira changes" to update multiples of these in parallel, if that makes sense.

Make sure that each release artifact that should be released has the correct version number.
These are normally updated automatically when the previous release is done.

Make sure that any README files have been updated with the latest release information
and release numbers.

Update the release notes for the release.

Edit the POM of the top level thing being released, to add the property:

<jiraVersion>123456</jiraVersion>

replacing the 123456 with the actual Jira internal version number
(or numbers, separated by a comma) for the Jira release(s) being
done. This value is used during release processing to automatically
generate a report of the list of Jira issues that are included in this release.
Change "123456" to be the actual jira internal version number, which you can get
from the Jira url (see parameter fixfor=xxxxxx or fixforversion=xxxxxx)
by going to https://issues.apache.org/jira/browse/UIMA
and selecting "Releases" or "Versions" and then going to the
particular version and looking in the url for
that version.

You can also generate this report manually (for instance, if you want to
have a look at what it will produce) by going to top level project
being released (e.g., uimaj-distr) and issuing the maven command:

mvn changes:jira-report -N

Each time this plugin is run, it creates an updated report in the
top level of this project. This report doesn't need to be checked into SVN.
It will be regenerated and copied into the distribution archives (source and binary)
during a release. The RELEASE_NOTES.html files have been updated to
refer to this generated report.

Running the mvn release... command will cause this report to be generated or
updated, every time the command is run. So it is important that the POM
is updated to include the internal Jira version number, so the
right report is generated.

There are several projects in the build tooling.
The following special procedure is used to release updates to these.

The parent-pom has the uima-build-resources's version number encoded as the
"property"

<uimaBuildResourcesVersion>XXXXXX</uimaBuildResourcesVersion>

This value will normally be set to the last released version number of the uima-build-resources artifact.

If that artifact is changing, during development, this will be set to the XX-SNAPSHOT value corresponding to
the development version. When releasing, first do a release (to the Nexus Staging repository, as usual) of
the uima-build-resources artifact, which will create a version without the -SNAPSHOT. Then change the
<uimaBuildResourcesVersion> value to correspond to the non-SNAPSHOT version number of this, before
proceeding to release the parent-pom artifact.

Prior to releasing, you must do the
one-time setup
required for releasing. Be sure to use a Java 1.5 level, in order to catch
accidental dependencies on later Java features.

We use the maven-release-plugin to do the releasing. In the prepare phase, it updates the
trunk artifacts to remove the -SNAPSHOT suffix, commits it to trunk, and then does an
SVN copy of the trunk to create the tag. Then it updates the trunk artifacts to the next
version-SNAPSHOT, and commits that.

The release:perform checks out the tag and builds/tests/installs and deploys it to the
NEXUS staging repository.

During release:prepare, the release plugin asks what the next levels should be and what the tag name
should be, and unless there's a good reason, we take the defaults (by just hitting enter).

In the past, we added a suffix representing the release candidate to the tag,
e.g. "-rc1" for release candidate 1, etc. However, the URL for this tag becomes part
of the released POM. After a successful vote, we would have upgraded the release candidate to
the final release by renaming the tag in SVN. At that point, the URL in the
POM would have become invalid. For this reason, it was decided not to add the -rc1 to the
tag anymore.

The release plugin automatically signs everything that needs signing using gpg. It also
builds the sources.jar, and one overall (for multi-module projects) source-release.zip file,
which can be later obtained and
should be an (approximate) copy of the SVN tag for that artifact, and once unzipped, should be buildable,
using mvn install.

Steps:

Make sure all changes are checked into SVN. Then checkout (not export) from SVN the project(s)
you'll be building, into a new "build" location, and do all the building from there.

If you instead choose to build from your "working" SVN checkout, insure it's up-to-date with
all changes that others may have checked into trunk.

Purge your local maven repository of artifacts being built by running in the
top level directory you'll be building from:

mvn dependency:purge-local-repository

Note that this will immediately re-resolve the dependencies from the maven repositories
you have configured.

For many multi-module projects, this will fail because it purges things that other modules need.
So, the alternative is to just delete the .m2/.../uima/... directory on your build machine.

Do a trial build of the release candidate:

cd **directory for doing the release**
mvn deploy -Papache-release

The -Papache-release is used to have the build mimic the
build actions that would be taken when the release plugin is running
the release build.

mvn release:prepare -DautoVersionSubmodules

mvn release:perform

Normally, everything built is uploaded to the Apache's Nexus Staging repository. However, for the
(large) distribution objects, such as the source and binary distributions for UIMA Java SDK etc.,
the "deploy" step is skipped. These artifacts, instead of being "distributed" using the
Maven central repository, are distributed using the Apache Mirroring System.

You can upload to the Nexus Staging repository several independent artifacts; they will
all get added to the same unique temporary staging repository Nexus creates. Once all the
artifacts are in place, you log into
https://repository.apache.org using your
LDAP credentials, go to your staging repository, and "close" the repository. After that,
nothing more can be added. If you deploy another artifact, it will create a new
staging repository.

If you forget to close the repo, it will be open when you do your next
release candidate, and then you'll have in the repo both release candidates, (with
later files overwriting newer), which if any file names have changed, will create
a mess. So be sure to close (and drop as appropriate) any previous repo before starting a release:perform for a new
release candidate, so they deploy into a "fresh" empty staging repo.

If you have several artifacts to release, and you want subsequent artifacts to
depend on the released versions of earlier ones, you can do this, by releasing the
first one, then releasing subsequent ones that depend on that, etc. This works because
the first one you release will get built with the release version and installed to your
local repository, as well as the Nexus staging repository. So subsequent ones that depend on
the release version of previous ones, will find that in your local repository.

If you forget something and close the staging repository too soon, just continue as if you hadn't.
Subsequent release artifacts will go into another newly created staging spot on Nexus.
The downside of this is that you'll have to tell the "voters" about multiple staging repos.

The release is done using the commands mvn release:prepare and mvn release:perform.

Having all submodules at the same version:
When releasing a multi-module project where all the submodules have the same release version as the
root project (e.g., uimaj-distr), you can have the release plugin set the version for all the submodules
the same value as the root, automatically, just use this form of the release:prepare:

mvn release:prepare -DautoVersionSubmodules

Trying out the release build: You can build the artifacts that the release would build by using:

mvn package -Papache-release

Re-doing release candidates: There are two ways to reset things back so you can do
another release candidate; depending on how far through the release process you've progressed.

[mvn release:prepare] If you've just done release:prepare,
you can reset things back to as they were before that command by issuing
mvn release:rollback. Check to confirm that the svn tag for the
release candidate is deleted; if not, remove it manually.

[mvn release:perform] If you've done a release:perform, to
reset the source, try doing the release:rollback; this may work if you haven't done a release:clean.

Otherwise,
you have to change the <version>x.y.z-SNAPSHOT> back to their previous value.
You can use Eclipse's search/replace to do this, or the mvn versions plugin.

If you've
"closed" the Nexus repo - you have to drop it. If you haven't, you can just re-run the
release:perform when you're ready, and that will overwrite the staging repo data in Nexus. But see
the next tip.

Nexus staging repositories and your source computer The staging repo that
receives the output of mvn release:perform has as part of its name, the
IP address where the deploy comes from. If you have a laptop, and do part of the release
at "work", and then another part at "home", the IP address will be different, and
multiple staging repositories will be created. This is not a problem, usually, unless
you are updating a release by redoing it, and are expecting the previous version
to be overwritten. In case it isn't, you can just use the Nexus command line interface
to delete the old version from the "other" staging repo.

POMs can refer to other artifacts in several ways, for example via the <parent-pom>
element, or via a <dependency> element. Often, a release will involve releasing together
multiple modules (all at -SNAPSHOT levels) that refer to one another using these elements.
When that happens, the references in these two elements are automatically updated
during the release process, from xx-SNAPSHOT to xx for the tag, and then to the next development level,
for the trunk.

Exception to this: -SNAPSHOT suffixes are not updated for references within plugins.

Note that any JARs, Zips, Tars, tar.gz artifacts must be signed by the Release Manager.

Although we have a spot in the distribution SVN under dev/uima for all the artifacts to be released
via the Apache mirror system, you probably should not use this for
release candidates, unless you suspect there won't be many of these (or they're small). This is because
SVN retains forever all the files you put into it, so if we go through 8 release candidates, each having
several multi-megabyte zip/tar files, these will just waste space in SVN.

The alternative is to copy the release candidate for voting into your personal people.apache.org/~[user-id] space, and
let testers/voters pull it from there.

Be sure to copy artifacts from the build-from tag spot, which should have a path like:
...[top level project]/target/checkout/target. Note this is not from [top level project]/target.
Doing this will guarantee that you're posting the artifacts built from the tag (which could be
different from the release:prepare build in /target if someone snuck in a svn commit at the right moment.)

If you do use the distribution SVN for the release candidates,
follow the
saving-svn-space tricks if reasonable.
Typically, for each release, we create a new directory for that, and place
all files pertaining to that release underneath that directory.

For a general background on how we build P2 sites, including Composite
update sites, see eclipse-update-site page.

The component being released, if it has Eclipse features, will have its own
Eclipse update (sub) site, which should be built along with the normal build of
the entire component, as part of that component's release.

In building that component's update site, you may need to edit/update the affected
component's feature project(s), and the category.xml file in the update-site, before
building it. For releases, run the signEclipseUpdateSite.sh (on Windows - inside Cygwin)
to sign the Jars. (Optional:) There's also a verifySignsEclipseUpdateSite.sh you can run to verify
the signing was successful.

If a new Eclipse update site is being added to the composite, edit in the composite
project (.../build/uima-eclipse-composite-update-site) the buildCompositeRepository.xml
file to add the new update site. If doing a release, run the signing script for the
composite site too.

The actual creation of the update site is done in several steps, following
the conventions to
save SVN resources.
The Maven build for Eclipse update sites
will end up with files in .../target/eclipse-update-site/[subsite] which
should be copied to some accessible spot for Voting/ testing.
(After the vot passes, the files in the target site can be svn switched to the release directory and committed.)

Test the result: using the extended composite repository in various versions of
Eclipse, and verify it installs OK.

If you changed the composite site, bump up the version of .../build/uima-eclipse-composite-site/pom.xml
and commit project changes to the trunk, and tag it.
The component's individual update sites should be built and tagged as part of that project's release.

The source and binary distributions are manually copied by the
release manager to the Apache distribution SVN in the dev/uima spot,
to make them available for review. The Maven module artifacts
are found in the Nexus staging repository, and are available once
the release manager "closes" the repository.

After things are staged, you write a note to the dev list, asking for an approval vote.
You need to provide the url(s) of the closed staging repository in the note so the approvers
can find the code to check, the SVN tag corresponding to the release, and
if needed, and the place in the distribution SVN where the source and binary
distributions being proposed are found.
The [VOTE] email should be based on similar previous votes, and
include instructions to testers on how to set up their maven settings.xml file to specify
the particular staging repository (or repositories, if more than one is being used).
For an example, see this dev-list post.

If Eclipse plugins are being released,
the update site build will have under the target/eclipse-update-site/[subsite]
the sub-site, as checked out of the .../dist/... svn.
You can check things by doing an svn status command. "cd" to the The features
subdirectory, and do an svn add *2.5.0*,
followed by an svn commit -m "uimaj 2.5.0 release [ replace with the right message]".
Repeat for the plugins subdirectory.
Then go up to the subsite directory, and do another svn commit -m "[message]" to update
the artifacts and contents stuff.

Update
the download page of the UIMA website to make the new release artifacts available.
This is done indirectly, by editing both the downloads.xml page and also by
adding entries to the xdocs/stylesheets/project.xml page - follow the previous examples.

Things not needed to be mirrored go into our website:
in the docs/d directory.
Currently, this includes the RELEASE_NOTES (plus issuesFixed) for the release,
the new docbooks, and the Javadocs. Arrange to update these in a way that
preserves SVN resources.

Copy RELEASE_NOTES and issuesFixed
from the top level project (where
the mvn release:perform was done from) in the directory
target/checkout/ ... to the the website in docs/d/[project-version].

and describe the major changes of the release.
Announcements should be posted from the release manager's apache.org address,
and signed by the release manager using the same code-signing key as was used to sign the release.
For more details please refer to
A Guide To Release Management During Incubation.

Our main uima website has a "News" section that should be updated with news of the release.
There are 2 place to update: One is the index.xml file, which has a one-line summary (at the bottom) that references
a link within the new.xml page; and a new entry in the news.xml page itself. Follow previous examples.