| <?xml version="1.0" encoding="ISO-8859-1"?> | |
| <!-- | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| https://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, | |
| software distributed under the License is distributed on an | |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| KIND, either express or implied. See the License for the | |
| specific language governing permissions and limitations | |
| under the License. | |
| --> | |
| <document> | |
| <properties> | |
| <title>Notes on Releases with Git</title> | |
| <author email="dev@uima.apache.org"> Apache UIMA Documentation Team</author> | |
| </properties> | |
| <body> | |
| <section name="Suggested basic release flow"> | |
| <ol><li><p>Update the master in preparation for the release, including things like the Readme, release-notes, | |
| the Jira release pointer for ISSUES Fixed, API compatibility: previous version. | |
| See <a target="_blank" rel="nofollow noopener" | |
| href="checklist-release.html">checklist-release</a> | |
| </p></li> | |
| <li><p>(optional, but recommended) Make a release branch, and do all the work | |
| on that branch. Once the release is out, merge the branch back into the master (should have | |
| very little change, other than new pom SNAPSHOT version levels).</p></li> | |
| <li><p>Checkout the release branch, and run the normal maven release prepare / perform cycles.</p></li> | |
| <li><p>Once the vote passes, retag the last rc with the rel/tag-name (see below).</p></li> | |
| <li><p>If branched, merge the release branch back into the master (updating the pom SNAPSHOT version numbers).</p></li> | |
| </ol> | |
| <h2>Git Commands to use</h2> | |
| <h3>Make new Release branch</h3> | |
| <p>On github.com/apache/uima-xxx, use the website to create a new branch, suggested name rc/uimaxxx.x.y.z. | |
| Don't use a name starting with rel/ because those branches are "protected".</p> | |
| <p>First switch to the particular "master" (e.g. master or master-v2 or ... ). Then create the new branch, | |
| which will start by being a copy of whatever branch github was on.</p> | |
| <h3>Check out the new release branch</h3> | |
| <p>Checkout a new release branch to a specific spot. </p> | |
| <p>cd to your build spot; mkdir build-directory-rcX</p> | |
| <p><code>git clone -b rc/uimaxxx.x.y.z https://github.com/apache/uima-uimaj build-directory-rcX</code></p> | |
| </section> | |
| <section name="Tags"> | |
| <p>Tags are stored in the .git folder in the subfolder /refs/tags.</p> | |
| <p>When Apache Infra sets up a writable git project, they set | |
| <a target="_blank" rel="nofollow noopener" href="https://help.github.com/en/github/administering-a-repository/about-protected-branches"> | |
| github protection</a>. The protection is set on | |
| <ul><li>refs/heads/trunk</li> | |
| <li>refs/heads/master</li> | |
| <li>refs/heads/rel/</li> | |
| <li>refs/tags/rel/</li> | |
| </ul> | |
| </p> | |
| <p>After a release passes, make a new tag for the release with the name rel/...tag-name... Here's how:</p> | |
| <ul><li><code>git tag -m "proj-name-1.2.3 rcXXX released" rel/proj-name-x.y.z proj-name-x.y.z^{}</code> | |
| The strange notation ^{} peels the annotated tag and returns a ref to the actual commit.</li> | |
| <li><code>git push origin rel/proj-name-x.y.z</code> This updates the new tag to the remote repo</li> | |
| </ul> | |
| </section> | |
| <section name="What the maven release plugin does with GIT"> | |
| <h2>release:prepare</h2> | |
| <p> | |
| <ul> | |
| <li>Take all the poms in the project which start out at some x.y.z-SNAPSHOT version, and | |
| update the versions to x.y.z (without the -SNAPSHOT).</li> | |
| <li>Build the project.</li> | |
| </ul> | |
| </p> | |
| <p> | |
| <ul> | |
| <li>Create a commit with all the updated POMs, and commit that to whatever branch was checked out at the start.</li> | |
| <li>git push</li> | |
| <li>Create a tag</li> | |
| <li>git push</li> | |
| </ul> | |
| </p> | |
| <p> | |
| <ul> | |
| <li>Update all the poms to x.y.z + 0.0.1 -SNAPSHOT, and commit them</li> | |
| <li>git push</li> | |
| </ul> | |
| </p> | |
| <h2>release:perform</h2> | |
| <p>This does a build using the "tag" checkout, and uploads the artifacts to the maven staging repository.</p> | |
| <p>The tag is cloned into the target/checkout directory</p> | |
| <p>A build is done from the target/checkout spot, with maven artifacts uploaded to repository.apache.com staging area.</p> | |
| </section> | |
| <section name="How to roll back a release attempt"> | |
| <h2>(Optional) Reset the branch to last commit before release:prepare</h2> | |
| <p>If you don't do this, when you do the release:prepare again, it will increment the SNAPSHOT and release numbers, | |
| and you'll need to override those. It's fine to work this way, as long as you remember to override the release | |
| and SNAPSHOT numbers. | |
| </p> | |
| <p>The idea is to reset the branch being used to build, back to the commit just before the maven release:prepare | |
| commit, which is identified with the message <code>[maven-release-plugin] prepare for next development iteration</code>.</p> | |
| <p>Do this by working in a checkout of the branch being used to build, typing <code>git log ...</code> and finding the hash | |
| for the commit right before the prepare commit.</p> | |
| <p>Don't do this next step unless you know no one has fetched the previously pushed maven release changes. | |
| This is typically true, because only you are working on the release, and you typically will be working in | |
| a branch made just for this, which others are unlikely to access.</p> | |
| <ul><li><code>git log -5 --oneline</code> # shows the last 5 commits. Find the last commit before the maven prepare one.</li> | |
| <li><code>git reset --hard hash-of-commit</code> where hash-of-commit is from the log </li> | |
| <li><code>git push -f origin branch-name # force needed because removing history</code></li> | |
| </ul> | |
| <h2>Remove the previously created tag</h2> | |
| <p>Next, because the release:prepare created a tag, you need to remove it. Do this:</p> | |
| <ul><li><code>git tag</code> to list the tags</li> | |
| <li><code>git tag -d name-of-tag</code> to delete, e.g. uimaj-3.1.1. This deletes it locally only.</li> | |
| <li><code>git push origin :refs/tags/name-of-tag</code> to remove the tag in the remote.</li> | |
| </ul> | |
| <h2>Do any fixes, updates and then rerun the release</h2> | |
| </section> | |
| </body> | |
| </document> |