How to upload Android client libraries to Maven/Sonatype

Open SRP Client is now made up of various maven published aar libraries which are then included in a project's build to aggregate the various functionality it offers.

These modules/libraries are:

  • opensrp-client-core
  • opensrp-client-growth-monitoring
  • opensrp-client-native-form
  • opensrp-client-immunization

Uploading to Maven

All the above projects have the same structure as far as configuration.

To upload files to maven,

  • Update the gradle.properties file in the root of the project to change the VERSION_NAME  and/or the VERSION_CODE. If building for a snapshot, include the word 'SNAPSHOT' in the version name. If building for release DO NOT include the suffix. Thus for a Non-snapshot release, it would read VERSION_NAME=1.0.0

          

     fig.1: example for opensrp client core

  • Update the file located in ~/.gradle/gradle.properties with your credentials for nexus. If the file does not exist in your workstation, create it. 

         

     fig.2: example of gradle.properties file global setting

  • To publish to Maven Local, run the command 

                ./gradlew :<module name>:uploadArchives -PmavenLocal=true    (or just ./gradlew :<module name>:uploadArchives)

             To publish to Maven Central run the command

       ./gradlew :<module name>:uploadArchives -PmavenLocal=false


For example to publish to Maven Local for the android-json-form-wizard library, run the following command in the root of the project

./gradlew :android-json-form-wizard:uploadArchives -PmavenLocal=true

Viewing artifacts Maven

To see if the upload was successful you can visit: https://oss.sonatype.org/content/groups/public/org/smartregister/

Using/Including the artifacts in a project

In the project-level build.gradle, add the following maven repositories in the allprojects block.

allprojects {

     repositories {

          ...

          maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }

          maven { url 'https://s3.amazonaws.com/repo.commonsware.com' }

     }

}

In the projects , gradle.build file, use the following syntax to include the aar and its corresponding dependencies.

e.g. To use the client core aar artifact

    compile('org.smartregister:opensrp-client-core:1.0.0-SNAPSHOT@aar') {
transitive = true
}
NB: Remember to include transitive=true inorder for the aar dependencies to be included too

Uploading the Release Artifacts to Maven

For Release versions(after the Snapshot is stable and complete), the files must be signed before publishing to maven. This requires access to the PGP signing credentials as created for the project.

  • Update the file located in ~/.gradle/gradle.properties with your signing key id, password and secret key-ring file path. 

         

     fig.3: example of gradle.properties file global setting with the signing credentials
  • Update the gradle.properties file in the project and remove the '-SNAPSHOT' suffix. e.g for the opensrp-client-core example It should look like this now .

         

          fig.4: example of local gradle.properties file with the Release Versioning updated

After the release is uploaded to firstly goes to the staging environment on Nexus. To flag the deployment for release so that it's pushed to and is available on Maven Central, you need to login in the nexus interface(Repository Manager) using your sonatypeUsername and sonatypePassword and activate the release from there. Click here for the repository manager link.

Instructions on how to do this can be found here

Versioning Artifacts

Once you have created and tested and artifact on MavenLocal and it works correctly, Its time to upload it to the repo. Step one would be to check the existing latest version for that artifact.

Snapshot Versions

All artifacts for opensrp can be found under https://oss.sonatype.org/content/groups/public/org/smartregister/

e.g for the growth monitoring module

https://oss.sonatype.org/content/groups/public/org/smartregister/opensrp-client-growth-monitoring/

Using the MAJOR.MINOR.BUILD system for versioning, when you update the gradle.properties you increment the BUILD  value by one. e.g. if the last snapshot for Growth Monitoring was 1.0.1-SNAPSHOT/ you set the VERSION_NAME value to 1.0.2-SNAPSHOT

Release Versions

Once a release version is ready, the MAJOR.MINOR.BUILD  value for the very first one starts at 1.0.0. If an update to the release is made the BUILD  value is also incremented by one. If a new release is created from a new snapshot (whose versioning will start at 1.1.0 after the release) the next Release Version willl start at 1.1.0.

Major changes in the products will warrant an increment of the MAJOR value which will then increment by one, thus versioning starting at  2.0.0 and following the same format as above for future updates.

Development Hacks

Refreshing dependencies

When refreshing dependencies as you add code changes to the various modules in the org.smartregister package, you need to clear the local gradle and maven cache with the following in order the latest changes to reflect... so run

rm -rf ~/.m2/repository/org/smartregister/

and then run 

rm -rf ~/.gradle/caches/modules-2/files-2.1/org.smartregister/

and then

./gradlew clean build --refresh-dependencies


Development efficiency

During development it might be inefficient to publish minor updates to the library even on maven local just to test your new changes or during debugging. Thus when developing it is recommended to include the library dependency by using the compile project syntax. e.g when developing the opensrp-client-growth-monitoring library include the library in the sample project using this syntax in the sample's build.gradle

compile project(":opensrp-growth-monitoring")

Tagging Releases

It is recommended to tag releases and snapshots once you push to maven. Ideally, this should be on the master branch after merging the final PR that constitutes the artifact to be published

use the syntax, replacing v1.0.0 with the correct version of Snapshot or Release published 

git tag -a v1.0.0-SNAPSHOT -s -m "Snapshot Version 1.0.0" && git push origin v1.0.0-SNAPSHOT

In the case where the release fixes more than one bug or issue, it is recommended to update the message in multiple lines which is not possible with the above one liner. In such a case, you should use

git tag -a v1.0.0-SNAPSHOT -s && git push origin v1.0.0-SNAPSHOT

This will prompt you with your default editor to enter a Tag message/description where you can enter multiple lines and/or be more descriptive.

Closing and Promoting Releases

For Release versions, once you have uploaded the release artifacts using uploadArchives gradle task, you are now ready to push the artifact to the main Maven Repository. This can be done in two ways:

  1. Using the procedure in the above section Uploading the Release Artifacts to Maven
  2. By using the gradle task closeAndReleaseRepository right after running uploadArchives

NB: closeAndReleaseRepository task expects only one artifact of the group to be staged as ready for release. If more than one exists, log into nexus and delete one. 

You can also combine the uploadArchives and closeAndReleaseRepository task in one line as shown below

./gradlew :<module name>:clean :<module name>:uploadArchives closeAndReleaseRepository -PmavenLocal=false 

NB: Before you make a release to Maven Central, make sure there you have not committed any secrets/passwords because Maven Central artefacts cannot be deleted