| nmittler | 483738e | 2015-06-08 14:32:37 -0700 | [diff] [blame] | 1 | How to Create a Release of GRPC Java (for Maintainers Only) |
| 2 | =============================================================== |
| 3 | |
| 4 | Build Environments |
| 5 | ------------------ |
| 6 | We deploy GRPC to Maven Central under the following systems: |
| 7 | - Ubuntu 14.04 with Docker 1.6.1 that runs CentOS 6.6 |
| 8 | - Windows 7 64-bit with MSYS2 with mingw32 and mingw64 |
| 9 | - Mac OS X 10.9.5 |
| 10 | |
| 11 | Other systems may also work, but we haven't verified them. |
| 12 | |
| 13 | Prerequisites |
| 14 | ------------- |
| 15 | |
| 16 | ### Setup OSSRH and Signing |
| 17 | |
| 18 | If you haven't deployed artifacts to Maven Central before, you need to setup |
| 19 | your OSSRH (OSS Repository Hosting) account and signing keys. |
| 20 | - Follow the instructions on [this |
| 21 | page](http://central.sonatype.org/pages/ossrh-guide.html) to set up an |
| 22 | account with OSSRH. |
| Carl Mastrangelo | 7a6b166 | 2015-08-12 13:52:45 -0700 | [diff] [blame] | 23 | - You only need to create the account, not set up a new project |
| 24 | - Contact a gRPC maintainer to add your account after you have created it. |
| nmittler | 483738e | 2015-06-08 14:32:37 -0700 | [diff] [blame] | 25 | - (For release deployment only) Install GnuPG and [generate your key |
| 26 | pair](https://www.gnupg.org/documentation/howtos.html). You'll also |
| 27 | need to [publish your public key](https://www.gnupg.org/gph/en/manual.html#AEN464) |
| 28 | to make it visible to the Sonatype servers |
| 29 | (e.g. `gpg --keyserver pgp.mit.edu --send-key <key ID>`). |
| 30 | - Put your GnuPG key password and OSSRH account information in |
| 31 | `<your-home-directory>/.gradle/gradle.properties`. |
| 32 | |
| 33 | ``` |
| 34 | # You need the signing properties only if you are making release deployment |
| 35 | signing.keyId=<8-character-public-key-id> |
| 36 | signing.password=<key-password> |
| 37 | signing.secretKeyRingFile=<your-home-directory>/.gnupg/secring.gpg |
| 38 | |
| 39 | ossrhUsername=<ossrh-username> |
| 40 | ossrhPassword=<ossrh-password> |
| 41 | checkstyle.ignoreFailures=false |
| 42 | ``` |
| 43 | |
| 44 | ### Build Protobuf |
| 45 | Protobuf libraries are needed for compiling the GRPC codegen. Despite that you |
| 46 | may have installed Protobuf on your system, you may want to build Protobuf |
| 47 | separately and install it under your personal directory, because |
| 48 | |
| 49 | 1. The Protobuf version installed on your system may be different from what |
| 50 | GRPC requires. You may not want to pollute your system installation. |
| 51 | 2. We will deploy both 32-bit and 64-bit versions of the codegen, thus require |
| 52 | both variants of Protobuf libraries. You don't want to mix them in your |
| 53 | system paths. |
| 54 | |
| 55 | Please see the [Main Readme](README.md) for details on building protobuf. |
| 56 | |
| 57 | Tagging the Release |
| 58 | ---------------------- |
| 59 | The first step in the release process is to create a release branch and then |
| 60 | from it, create a tag for the release. Our release branches follow the naming |
| 61 | convention of `v<major>.<minor>.x`, while the tags include the patch version |
| 62 | `v<major>.<minor>.<patch>`. For example, the same branch `v0.7.x` |
| 63 | would be used to create all `v0.7` tags (e.g. `v0.7.0`, `v0.7.1`). |
| 64 | |
| 65 | 1. Create the release branch: |
| 66 | |
| 67 | ```bash |
| 68 | $ git checkout -b v<major>.<minor>.x master |
| 69 | ``` |
| 70 | 2. Next, increment the version in `build.gradle` in `master` to the next |
| 71 | minor snapshot (e.g. ``0.8.0-SNAPSHOT``). |
| 72 | 3. In the release branch, change the `build.gradle` to the next release version |
| 73 | (e.g. `0.7.0`) |
| 74 | 4. Push the release branch to github |
| 75 | |
| 76 | ```bash |
| 77 | $ git push upstream v<major>.<minor>.x |
| 78 | ``` |
| 79 | 5. In the release branch, create the release tag using the `Major.Minor.Patch` |
| 80 | naming convention: |
| 81 | |
| 82 | ```bash |
| 83 | $ git tag -a v<major>.<minor>.<patch> |
| 84 | ``` |
| 85 | 6. Push the release tag to github: |
| 86 | |
| 87 | ```bash |
| 88 | $ git push upstream v<major>.<minor>.<patch> |
| 89 | ``` |
| 90 | 7. Update the `build.gradle` in the release branch to point to the next patch |
| 91 | snapshot (e.g. `0.7.1-SNAPSHOT`). |
| 92 | 8. Push the updated release branch to github. |
| 93 | |
| 94 | ```bash |
| 95 | $ git push upstream v<major>.<minor>.x |
| 96 | ``` |
| 97 | |
| 98 | Setup Build Environment |
| 99 | --------------------------- |
| 100 | |
| 101 | ### Linux |
| 102 | The deployment for Linux uses [Docker](https://www.docker.com/) running |
| 103 | CentOS 6.6 in order to ensure that we have a consistent deployment environment |
| 104 | on Linux. You'll first need to install Docker if not already installed on your |
| Carl Mastrangelo | 8f6562e | 2015-08-13 15:19:53 -0700 | [diff] [blame] | 105 | system. Make sure to have at least version 1.7.1 or later. |
| nmittler | 483738e | 2015-06-08 14:32:37 -0700 | [diff] [blame] | 106 | |
| 107 | 1. Under the [Protobuf source directory](https://github.com/google/protobuf), |
| 108 | build the `protoc-artifacts` image: |
| 109 | |
| 110 | ```bash |
| 111 | protobuf$ docker build -t protoc-artifacts protoc-artifacts |
| 112 | ``` |
| 113 | 2. Under the grpc-java source directory, build the `grpc-java-deploy` image: |
| 114 | |
| 115 | ```bash |
| 116 | grpc-java$ docker build -t grpc-java-deploy compiler |
| 117 | ``` |
| 118 | 3. Start a Docker container that has the deploy environment set up for you. The |
| 119 | GRPC source is cloned into `/grpc-java`. |
| 120 | |
| 121 | ```bash |
| 122 | $ docker run -it --rm=true grpc-java-deploy |
| 123 | ``` |
| 124 | |
| 125 | Note that the container will be deleted after you exit. Any changes you have |
| 126 | made (e.g., copied configuration files) will be lost. If you want to keep the |
| 127 | container, remove `--rm=true` from the command line. |
| 128 | 4. Next, you'll need to copy your OSSRH credentials and GnuPG keys to your docker container. |
| Kun Zhang | 2bd0887 | 2016-01-22 15:32:04 -0800 | [diff] [blame^] | 129 | In Docker: |
| 130 | ``` |
| 131 | # mkdir /root/.gradle |
| 132 | ``` |
| 133 | Find the container ID in your bash prompt, which is shown as `[root@<container-ID> ...]`. |
| 134 | In host: |
| 135 | ``` |
| 136 | $ docker cp ~/.gnupg <container-ID>:/root/ |
| 137 | $ docker cp ~/.gradle/gradle.properties <container-ID>:/root/.gradle/ |
| nmittler | 483738e | 2015-06-08 14:32:37 -0700 | [diff] [blame] | 138 | ``` |
| 139 | |
| 140 | You'll also need to update `signing.secretKeyRingFile` in |
| 141 | `/root/.gradle/gradle.properties` to point to `/root/.gnupg/secring.gpg`. |
| 142 | |
| 143 | ### Windows |
| 144 | |
| 145 | #### Windows 64-bit with MSYS2 (Recommended for Windows) |
| 146 | Because the gcc shipped with MSYS2 doesn't support multilib, you have to |
| 147 | compile and deploy 32-bit and 64-bit binaries in separate steps. |
| 148 | |
| 149 | ##### Under MinGW-w64 Win32 Shell |
| 150 | 1. Compile and install 32-bit protobuf: |
| 151 | |
| 152 | ```bash |
| 153 | protobuf$ ./configure --disable-shared --prefix=$HOME/protobuf-32 |
| 154 | protobuf$ make clean && make && make install |
| 155 | ``` |
| 156 | 2. Configure CXXFLAGS needed by the protoc plugin when building. |
| 157 | |
| 158 | ```bash |
| 159 | grpc-java$ export CXXFLAGS="-I$HOME/protobuf-32/include" \ |
| 160 | LDFLAGS="-L$HOME/protobuf-32/lib" |
| 161 | ``` |
| 162 | |
| 163 | ##### Under MinGW-w64 Win64 Shell |
| 164 | 1. Compile and install 64-bit protobuf: |
| 165 | |
| 166 | ```bash |
| 167 | protobuf$ ./configure --disable-shared --prefix=$HOME/protobuf-64 |
| 168 | protobuf$ make clean && make && make install |
| 169 | ``` |
| 170 | 2. Configure CXXFLAGS needed by the protoc plugin when building. |
| 171 | |
| 172 | ```bash |
| 173 | grpc-java$ export CXXFLAGS="-I$HOME/protobuf-64/include" \ |
| 174 | LDFLAGS="-L$HOME/protobuf-64/lib" |
| 175 | ``` |
| 176 | |
| 177 | #### Windows 64-bit with Cygwin64 (TODO: incomplete) |
| 178 | Because the MinGW gcc shipped with Cygwin64 doesn't support multilib, you have |
| 179 | to compile and deploy 32-bit and 64-bit binaries in separate steps. |
| 180 | |
| 181 | 1. Compile and install 32-bit protobuf. `-static-libgcc -static-libstdc++` are |
| 182 | needed for `protoc` to be successfully run in the unit test. |
| 183 | |
| 184 | ```bash |
| 185 | protobuf$ LDFLAGS="-static-libgcc -static-libstdc++" ./configure --host=i686-w64-mingw32 --disable-shared --prefix=$HOME/protobuf-32 |
| 186 | protobuf$ make clean && make && make install |
| 187 | ``` |
| 188 | |
| 189 | 2. Compile and install 64-bit protobuf: |
| 190 | |
| 191 | ```bash |
| 192 | protobuf$ ./configure --host=x86_64-w64-mingw32 --disable-shared --prefix=$HOME/protobuf-64 |
| 193 | protobuf$ make clean && make && make install |
| 194 | ``` |
| 195 | |
| 196 | ### Mac |
| 197 | Please refer to [Protobuf |
| 198 | README](https://github.com/google/protobuf/blob/master/README.md) for how to |
| 199 | set up GCC and Unix tools on Mac. |
| 200 | |
| 201 | Mac OS X has been 64-bit-only since 10.7 and we are compiling for 10.7 and up. |
| 202 | We only build 64-bit artifact for Mac. |
| 203 | |
| 204 | 1. Compile and install protobuf: |
| 205 | |
| 206 | ```bash |
| 207 | protobuf$ CXXFLAGS="-m64" ./configure --disable-shared --prefix=$HOME/protobuf |
| 208 | protobuf$ make clean && make && make install |
| 209 | ``` |
| 210 | 2. Configure CXXFLAGS needed by the protoc plugin when building. |
| 211 | |
| 212 | ```bash |
| 213 | grpc-java$ export CXXFLAGS="-I$HOME/protobuf/include" \ |
| 214 | LDFLAGS="$HOME/protobuf/lib/libprotobuf.a $HOME/protobuf/lib/libprotoc.a" |
| 215 | ``` |
| 216 | |
| 217 | Build and Deploy |
| 218 | ---------------- |
| 219 | We currently distribute the following OSes and architectures: |
| 220 | |
| 221 | | OS | x86_32 | x86_64 | |
| 222 | | --- | --- | --- | |
| 223 | | Linux | X | X | |
| 224 | | Windows | X | X | |
| 225 | | Mac | | X | |
| 226 | |
| 227 | Deployment to Maven Central (or the snapshot repo) is a two-step process. The only |
| 228 | artifact that is platform-specific is codegen, so we only need to deploy the other |
| 229 | jars once. So the first deployment is for all of the artifacts from one of the selected |
| 230 | OS/architectures. After that, we then deploy the codegen artifacts for the remaining |
| 231 | OS/architectures. |
| 232 | |
| 233 | **NOTE: _Before building/deploying, be sure to switch to the appropriate branch or tag in |
| 234 | the grpc-java source directory._** |
| 235 | |
| 236 | ### First Deployment |
| 237 | |
| 238 | As stated above, this only needs to be done once for one of the selected OS/architectures. |
| 239 | The following command will build the whole project and upload it to Maven |
| 240 | Central. |
| 241 | ```bash |
| 242 | grpc-java$ ./gradlew clean build && ./gradlew uploadArchives |
| 243 | ``` |
| 244 | |
| 245 | If the version has the `-SNAPSHOT` suffix, the artifacts will automatically |
| 246 | go to the snapshot repository. Otherwise it's a release deployment and the |
| 247 | artifacts will go to a freshly created staging repository. |
| 248 | |
| 249 | ### Deploy GRPC Codegen for Additional Platforms |
| 250 | The previous step will only deploy the codegen artifacts for the OS you run on |
| 251 | it and the architecture of your JVM. For a fully fledged deployment, you will |
| 252 | need to deploy the codegen for all other supported OSes and architectures. |
| 253 | |
| 254 | To deploy the codegen for an OS and architecture, you must run the following |
| 255 | commands on that OS and specify the architecture by the flag `-PtargetArch=<arch>`. |
| 256 | |
| 257 | If you are doing a snapshot deployment: |
| 258 | |
| 259 | ```bash |
| 260 | grpc-java$ ./gradlew clean grpc-compiler:build grpc-compiler:uploadArchives -PtargetArch=<arch> |
| 261 | ``` |
| 262 | |
| 263 | When deploying a Release, the first deployment will create |
| 264 | [a new staging repository](https://oss.sonatype.org/#stagingRepositories). You'll need |
| 265 | to look up the ID in the OSSRH UI (usually in the form of `iogrpc-*`). Codegen |
| 266 | deployment commands should include `-PrepositoryId=<repository-id>` in order to |
| 267 | ensure that the artifacts are pushed to the same staging repository. |
| 268 | |
| 269 | ```bash |
| 270 | grpc-java$ ./gradlew clean grpc-compiler:build grpc-compiler:uploadArchives -PtargetArch=<arch> \ |
| 271 | -PrepositoryId=<repository-id> |
| 272 | ``` |
| 273 | |
| 274 | Releasing on Maven Central |
| 275 | -------------------------- |
| 276 | Once all of the artifacts have been pushed to the staging repository, the |
| 277 | repository must first be `closed`, which will trigger several sanity checks |
| 278 | on the repository. If this completes successfully, the repository can then |
| 279 | be `released`, which will begin the process of pushing the new artifacts to |
| 280 | Maven Central (the staging repository will be destroyed in the process). You can |
| 281 | see the complete process for releasing to Maven Central on the [OSSRH site] |
| 282 | (http://central.sonatype.org/pages/releasing-the-deployment.html). |
| 283 | |
| 284 | Notify the Community |
| 285 | -------------------- |
| 286 | After waiting ~1 day and verifying that the release appears on [Maven Central] |
| 287 | (http://mvnrepository.com/), the last step is to document and publicize the release. |
| 288 | |
| 289 | 1. Add [Release Notes](https://github.com/grpc/grpc-java/releases) for the new tag. |
| 290 | The description should include any major fixes or features since the last release. |
| 291 | You may choose to add links to bugs, PRs, or commits if appropriate. |
| 292 | 2. Post a release announcement to [grpc-io](https://groups.google.com/forum/#!forum/grpc-io) |
| 293 | (`grpc-io@googlegroups.com`). The title should be something that clearly identifies |
| 294 | the release (e.g.`GRPC-Java <tag> Released`). |