// 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
//
//   http://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.

= RELEASING KUDU

== Overview

This document gives the steps required to perform a Kudu release, and is a resource
for Kudu release managers. To edit or update this document, edit `RELEASING.adoc`
in `master`.

== Stating Intent to Release

. *A week before branching*: send an email to dev@kudu.apache.org to
  announce that the branch will be happening, including a deadline for when new
  commits will need gatekeeper approval.

. *A day before branching*: send another email to dev@kudu.apache.org
  to warn about it.

== Creating the Branch

. Create a new branch from master:
+
----
  git checkout master
  git pull
  git checkout -b branch-0.9.x
----

. Make a note of the SHA1 for the tip of the new branch, which is the first
  field of the result of this command:
+
----
  git log --oneline -n1
----

. Push the branch to public remotes https://github.com/cloudera/kudu.git and
http://git-wip-us.apache.org/repos/asf?p=incubator-kudu.git. The following example
assumes they are called `cloudera` and `apache`.
+
----
  git push branch-0.9.x cloudera
  git push branch-0.9.x apache
----

. Create a new branch on Gerrit. Go to
http://gerrit.cloudera.org:8080/#/admin/projects/kudu,branches and create a new
branch with the same name and the previously-noted SHA1.

. Notify Todd to fix the mirroring. He will know what that means.

. As needed, patches can be cherry-picked to the new branch.

== Updating Versions In Master

. Check out the `master` branch and bump the version in `version.txt`.

. Update the version for the Java client from within the `java` directory:
+
----
  cd java
  mvn versions:set -DnewVersion=0.X.0-SNAPSHOT
----

. Check to make sure the version number in `java/kudu-csd/pom.xml` under
  "com.cloudera.csd" matches. It’s listed in two places and some versions of
  maven apparently do not update both.

. If the python API has changed since the previous release, bump the Python version
  in `python/setup.py` in master. (the Python API uses separate versioning).

. After all the versions are updated, commit and push that change to Gerrit.

. Notify dev@kudu.apache.org that the new branch is available.


== Preparing A Release Candidate

. When close to building a release candidate, try building a source tarball
(on a supported platform):
+
----
  ./build-support/build_source_release.py
----

. Fix any issues it finds, such as RAT.

. Remove the -SNAPSHOT from the version string in `version.txt`.

. When ready, create a new lightweight tag and push it to the Apache Git repository.
+
----
  git tag 1.x.0-RC1
  git push apache 1.x.0-RC1
----

. Build a source tarball against the RC branch.

. Create a new folder in https://dist.apache.org/repos/dist/dev/kudu/.
  Copy the artifacts to this folder and commit (it is Subversion).
----
  svn co --depth=immediates https://dist.apache.org/repos/dist/dev/kudu/
  svn commit -m "Adding Kudu 1.x.0 RC1"
----

Initiating a Vote for an RC
----------------------------

. Send an email to dev@kudu.apache.org to start the RC process, using
  this
  link:http://mail-archives.apache.org/mod_mbox/kudu-dev/201606.mbox/%3CCAGpTDNduoQM0ktuZc1eW1XeXCcXhvPGftJ%3DLRB8Er5c2dZptvw%40mail.gmail.com%3E[example]
  as a template.

. Reminder that voting on a release requires a Majority Approval by the PMC.

. Cycle through as many RCs as required.

. Always send an email with a different subject to indicate the result. For
  link:http://mail-archives.apache.org/mod_mbox/kudu-dev/201606.mbox/%3CCAGpTDNeJdU%2BoUF4ZJneZt%3DCfFHY-HoqKgORwVuWWUMHq5jBNzA%40mail.gmail.com%3E[example].

. After the vote passes, send an email to dev@kudu.apache.org
  indicating the result.

== Release

. Create a new folder in https://dist.apache.org/repos/dist/release/kudu/,
  copy the files from the release candidate’s folder in dist/dev/kudu/, then commit.
+
----
  cd kudu
  mkdir 0.9.2
  cp <path_to_rc_artifacts>/* 0.9.2
  svn add 0.9.2
  svn commit -m "Adding files for Kudu 0.9.2 RC"
----

. In the Kudu git repo, create a signed tag from the RC’s tag, and push it to the
Apache Git repository:
+
----
  git tag -s 0.9.2 -m 'Release Apache Kudu 0.9.2' 0.9.2-RC1
  git push apache 0.9.2-RC1
----

. Generate the version-specific documentation from that branch following these
  link:https://github.com/apache/incubator-kudu/#updating-the-documentation-on-the-kudu-web-site[instructions].

. Replace the `apidocs` and `docs` folders in the `gh-pages` branch with the new documentation.

. Update the `index.md` file in the releases folder, add a new folder named after the release version,
  copy the `apidocs` and `docs` folders there, copy an `index.md` file from one
  of the other releases and modify it accordingly.

. Commit all these changes.

. Create a new review for all those new and updated files in `gh-pages`.

. Once the review is finished and the commit is pushed, update the website.

. About 24 hours after the first step was completed, send an email to
  user@kudu.apache.org, dev@kudu.apache.org, and announce@apache.org
  to announce the release. The email should be similar to
  link:http://mail-archives.us.apache.org/mod_mbox/www-announce/201606.mbox/%3CCAGpTDNeHW53US=qdpQPCQk0WaFBxx_KNx1E9b6NBBnbWpkSpmQ@mail.gmail.com%3E[this].

. About another 24 hours later, delete the previous minor version in the branch
  you released from, from SVN. For example, if you released 1.2.1, delete `1.2.0`.

. Update the version number on the branch you released from back to a SNAPSHOT
  for the next patch release, such as `0.9.2-SNAPSHOT` after the `0.9.1` release.
