# Android Automated Deployments & Version Strategy In order to support our developers we need to provide timely builds in a consistent manner that can be handled by any member of the Checkout Integrations team. At a high level this proposal will outline processes that I have built out for other projects in the past, most recently I built out this exact process for an open source library, [FakeK](https://github.com/CodyEngel/fakek). ### The process used with FakeK is as follows: 1. **Our branch used for releases is a protected branch, it can only be merged into via a Pull Request.** This project makes use of a single `main` branch and foregos the use of a `develop` branch. This allows for our deployment task to skip code checks (as it was checked prior to, and after merging changes into the main branch). **Using a single branch is not something I'm proposing for the Checkout SDK**, and instead want to delibrately call out that difference to avoid confusion. 2. **When we are ready to release a new version of the SDK** we tag the release on GitHub and provide release notes. Once a new tag is created the deployment process kicks off and the SDK version used to build the release is consumed from an environment variable on the CI Runner: `version = System.getenv("CIRCLE_TAG") ?: "0.0.1"` 3. **When the release process finishes we log into Bintray (JCenter) and approve the new release so it can roll out to users.** ## Checkout SDK Deployment Process I am proposing that for the time being we keep both `main` and `develop` branches. In the future if we have a need to consolidate them, we can always do that but that's out of scope for this work. ### Our process would be the following: 1. **Merge code from develop to main.** This is necessary to ensure that `main` has the most up-to-date code in anticipation for step 2. 2. **Tag the release.** We will then apply a tag to the release in the exact format we expect. For example, if this was the `1.0.0` release the tag would be `1.0.0`. 3. **Provide release notes on the tag.** This will help to outline what was included in the release and make it easier to communicate these changes to others inside and outside of PayPal. 4. **Jenkins starts building automatically.** At this point Jenkins should respond to the tag and start building the SDK. The steps are outlined below, a diagram is available under "CI Process" as well. 4a. We will first retrieve any dependencies required to build the SDK. 4b. We will then run our linters to catch any issues related to code quality. 4c. We will then run our unit test suite to ensure everything works as expected. 4d. We will then build all of our release artifacts. 4e. We will push those release artifacts to the central repositories staging site. 5. **Promote artifacts from staging to production.** This is a manual step, but should require that someone log into the central repositories staging site and click a button to promote to production. 5a. I would propose that everyone on Checkout Integrations have access to promote builds as well as providing access to others on the NXO team that will also be managing releases. ## Versioning We will use [Semantic Versioning 2.0.0](https://semver.org/) to easily communicate with developers what type of update this was. Major updates will communicate that there are breaking changes that will require code changes on the merchants side. Minor updates will communicate that we added new functionality without any breaking changes. Patch updates will communicate that we only included bug fixes which were backwards compatible. ### Breaking Changes We will strive to avoid breaking changes with our SDK. We should plan our breaking changes well in advance to ensure we are able to put together an easy to follow migration guide to encourage adoption of that update. ### End of Life Strategy We should commit to supporting all previous versions of the SDK for one year after being replaced by another major version of the SDK. We should make use of the `@Deprecrated` annotation whenever possible to allow for merchants to still use deprecated functionality while migrating away from it. We should start including the `@Deprecated` annotation as soon as a replacement option is available, anything annotated with `@Deprecated` for more than 1 year should be removed entirely from the SDK. ## Central Repository When it comes to the central repository we have a few options: JCenter or MavenCentral. Today we are publishing the SDK to MavenCentral, however I am proposing that we migrate to JCenter as part of our deployment updates. ### Reasons for JCenter 1. [JCenter](https://developer.android.com/studio/releases/gradle-plugin#behavior-changes_1) became the default repository used with Android's gradle plugin in 2015 and it's the repository referenced in their plugin docs today (alongside their `google()` repository used for JetPack). 2. JCenter is trusted by other influential open source libraries like [Kotlin Coroutines](https://bintray.com/kotlin/kotlinx/kotlinx.coroutines/1.4.2). 3. [GPG Signing is bulit into JCenter](https://www.jfrog.com/confluence/display/BT/Managing+Uploaded+Content#_gpg_signing), this means you can either use Bintray's internal key to sign uploaded artifacts or upload your own private/public key and they will manage signing the artifacts for you. 4. The [bintray](https://github.com/CodyEngel/fakek/blob/7d84f122a22a5ef5bd8558b73eb97ee85c40a63d/build.gradle.kts#L117-L140) plugin would be fairly easy to integrate with our existing build process. 5. The publishing process is more turn-key, we don't need to create an issue on Sonatype's JIRA board to add new users. Bintray (JCenter) offers a modern developer experience. 6. Existing integrations likely won't know the difference. While we are using MavenCentral today, all Android apps since 2015 have default to using JCenter. 7. If we decide we also want to publish to MavenCentral, [Bintray can manage this process for us as well](https://blog.bintray.com/2014/02/11/bintray-as-pain-free-gateway-to-maven-central/). ### Reasons against MavenCentral 1. The deployment process is cumbersome, it requires manually signing artifacts and managing the signing keys in our own CI/CD environment. 2. The developer experience can be cumbersome, in order to add a new user to the Sonatype account you have to go through a JIRA ticket and get approval from an existing member of the repository. ## Footnotes/Diagrams #### CI Process ![](https://i.imgur.com/4IVoStD.png)