Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Distributing to a public or private Maven repository

Jeroen Mols
November 09, 2015

Distributing to a public or private Maven repository

Slides from my talk at Droidcon Paris 2015
video: http://droidcon.fr/schedule/#session-410

In order to remain cost effective reusing code is one of the most essentials skills of a modern Android developer. Using open source libraries is one thing, but what if there isn't a library available that suits your need? How would you go about to develop and distribute this library yourself?

This talk aims at providing a complete solution for library distribution, either within your own organisation or with the entire open source community. You will learn how to setup your own private Maven repository, configure an account for Maven Central or JCenter and that even BitBucket/Github can be used as a Maven repository! Fully functional Gradle scripts will be provided for each alternative, taking important aspects like security and nested dependencies into account.

After this talk, there will be no more excuse to ramp up your game and start reusing your own code!

Jeroen Mols

November 09, 2015
Tweet

More Decks by Jeroen Mols

Other Decks in Programming

Transcript

  1. @MOLSJEROEN HOW MAVEN STORES ARTIFACTS ▸ Artifacts: artifact.aar, javadoc.jar, sources.jar,…

    ▸ Project Object Model ▸ GroupId ▸ ArtifactId ▸ Version
  2. @MOLSJEROEN GRADLE - CONSUME ARTIFACTS allprojects {
 repositories {
 jcenter()


    maven { url “http://mywebsite.com/mavenrepository" }
 }
 } dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile ‘com.android.support:appcompat-v7:23.1.0’ 
 compile ‘com.jakewharton:butterknife:7.0.1'
 }
  3. @MOLSJEROEN GRADLE - CONSUME ARTIFACTS allprojects {
 repositories {
 jcenter()


    maven { url “http://mywebsite.com/mavenrepository" }
 }
 } dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile ‘com.android.support:appcompat-v7:23.1.0’ 
 compile ‘com.jakewharton:butterknife:7.0.1'
 }
  4. @MOLSJEROEN GRADLE - CONSUME ARTIFACTS allprojects {
 repositories {
 jcenter()


    maven { url “http://mywebsite.com/mavenrepository" }
 }
 } dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile ‘com.android.support:appcompat-v7:23.1.0’ 
 compile ‘com.jakewharton:butterknife:7.0.1'
 }
  5. @MOLSJEROEN GRADLE - CONSUME ARTIFACTS allprojects {
 repositories {
 jcenter()


    maven { url “http://mywebsite.com/mavenrepository" }
 }
 } dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile ‘com.android.support:appcompat-v7:23.1.0’ 
 compile ‘com.jakewharton:butterknife:7.0.1'
 }
  6. @MOLSJEROEN GRADLE - CONSUME ARTIFACTS allprojects {
 repositories {
 jcenter()


    maven { url “http://mywebsite.com/mavenrepository" }
 }
 } dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile ‘com.android.support:appcompat-v7:23.1.0’ 
 compile ‘com.jakewharton:butterknife:7.0.1'
 }
  7. @MOLSJEROEN GRADLE - CONSUME ARTIFACTS allprojects {
 repositories {
 jcenter()


    maven { url “http://mywebsite.com/mavenrepository" }
 }
 } dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile ‘com.android.support:appcompat-v7:23.1.0’ 
 compile ‘com.jakewharton:butterknife:7.0.1'
 } GroupId ArtifactId Version
  8. @MOLSJEROEN GRADLE - UPLOAD ARTIFACTS apply plugin: ‘maven' uploadArchives {


    repositories {
 mavenDeployer {
 repository(url: 'http://mywebsite/mavenrepository') {
 authentication(userName: 'myUsername', password: 'myPassword')
 }
 
 pom.project {
 groupId = ‘packageName’ artifactId = 'libraryName'
 version = 'libraryVersion'
 packaging = 'aar'
 } } } }
  9. @MOLSJEROEN GRADLE - UPLOAD ARTIFACTS apply plugin: ‘maven' uploadArchives {


    repositories {
 mavenDeployer {
 repository(url: 'http://mywebsite/mavenrepository') {
 authentication(userName: 'myUsername', password: 'myPassword')
 }
 
 pom.project {
 groupId = ‘packageName’ artifactId = 'libraryName'
 version = 'libraryVersion'
 packaging = 'aar'
 } } } }
  10. @MOLSJEROEN GRADLE - UPLOAD ARTIFACTS apply plugin: ‘maven' uploadArchives {


    repositories {
 mavenDeployer {
 repository(url: 'http://mywebsite/mavenrepository') {
 authentication(userName: 'myUsername', password: 'myPassword')
 }
 
 pom.project {
 groupId = ‘packageName’ artifactId = 'libraryName'
 version = 'libraryVersion'
 packaging = 'aar'
 } } } }
  11. @MOLSJEROEN GRADLE - UPLOAD ARTIFACTS apply plugin: ‘maven' uploadArchives {


    repositories {
 mavenDeployer {
 repository(url: 'http://mywebsite/mavenrepository') {
 authentication(userName: 'myUsername', password: 'myPassword')
 }
 
 pom.project {
 groupId = ‘packageName’ artifactId = 'libraryName'
 version = 'libraryVersion'
 packaging = 'aar'
 } } } }
  12. THERE IS AN EASY WAY AND A HARD WAY. THE

    HARD PART IS FINDING THE EASY WAY. Dr. Lloyd
  13. @MOLSJEROEN PUBLIC MAVEN REPOSITORIES repositories {
 jcenter()
 } ‣ Bintray

    ‣ Browse repository repositories {
 mavenCentral()
 } ‣ Sonatype ‣ Browse repository
  14. @MOLSJEROEN NEXUS ▸ Cumbersome to set up ▸ Register and

    log a Jira issue ▸ Configure GnuGP to sign artifacts ▸ Upload to staging environment via Gradle ▸ Manually release the artifacts ▸ Wait for sync to Maven Central
  15. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 1 ‣ USER_HOME/.gradle/gradle.properties NEXUS_USERNAME=molsjeroen
 NEXUS_PASSWORD=g00dtry


    
 signing.keyId=ABCDEF12
 signing.password=n1c3try
 signing.secretKeyRingFile=~/.gnupg/secring.gpg
  16. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 1 ‣ USER_HOME/.gradle/gradle.properties NEXUS_USERNAME=molsjeroen
 NEXUS_PASSWORD=g00dtry


    
 signing.keyId=ABCDEF12
 signing.password=n1c3try
 signing.secretKeyRingFile=~/.gnupg/secring.gpg
  17. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 1 ‣ USER_HOME/.gradle/gradle.properties NEXUS_USERNAME=molsjeroen
 NEXUS_PASSWORD=g00dtry


    
 signing.keyId=ABCDEF12
 signing.password=n1c3try
 signing.secretKeyRingFile=~/.gnupg/secring.gpg
  18. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/gradle.properties VERSION_NAME=1.0.7
 VERSION_CODE=5


    GROUP=com.github.jeroenmols
 
 POM_DESCRIPTION=Powerful custom Android Camera.
 POM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideoCamera.git
 POM_SCM_DEV_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideo… POM_LICENCE_NAME=The Apache Software License, Version 2.0
 POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
 POM_LICENCE_DIST=repo
 POM_DEVELOPER_ID=JeroenMols
 POM_DEVELOPER_NAME=Jeroen Mols
  19. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/gradle.properties VERSION_NAME=1.0.7
 VERSION_CODE=5


    GROUP=com.github.jeroenmols
 
 POM_DESCRIPTION=Powerful custom Android Camera.
 POM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideoCamera.git
 POM_SCM_DEV_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideo… POM_LICENCE_NAME=The Apache Software License, Version 2.0
 POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
 POM_LICENCE_DIST=repo
 POM_DEVELOPER_ID=JeroenMols
 POM_DEVELOPER_NAME=Jeroen Mols
  20. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/gradle.properties VERSION_NAME=1.0.7
 VERSION_CODE=5


    GROUP=com.github.jeroenmols
 
 POM_DESCRIPTION=Powerful custom Android Camera.
 POM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideoCamera.git
 POM_SCM_DEV_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideo… POM_LICENCE_NAME=The Apache Software License, Version 2.0
 POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
 POM_LICENCE_DIST=repo
 POM_DEVELOPER_ID=JeroenMols
 POM_DEVELOPER_NAME=Jeroen Mols
  21. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/gradle.properties VERSION_NAME=1.0.7
 VERSION_CODE=5


    GROUP=com.github.jeroenmols
 
 POM_DESCRIPTION=Powerful custom Android Camera.
 POM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideoCamera.git
 POM_SCM_DEV_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideo… POM_LICENCE_NAME=The Apache Software License, Version 2.0
 POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
 POM_LICENCE_DIST=repo
 POM_DEVELOPER_ID=JeroenMols
 POM_DEVELOPER_NAME=Jeroen Mols
  22. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/gradle.properties VERSION_NAME=1.0.7
 VERSION_CODE=5


    GROUP=com.github.jeroenmols
 
 POM_DESCRIPTION=Powerful custom Android Camera.
 POM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideoCamera.git
 POM_SCM_DEV_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideo… POM_LICENCE_NAME=The Apache Software License, Version 2.0
 POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
 POM_LICENCE_DIST=repo
 POM_DEVELOPER_ID=JeroenMols
 POM_DEVELOPER_NAME=Jeroen Mols
  23. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/gradle.properties VERSION_NAME=1.0.7
 VERSION_CODE=5


    GROUP=com.github.jeroenmols
 
 POM_DESCRIPTION=Powerful custom Android Camera.
 POM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_URL=https://github.com/JeroenMols/LandscapeVideoCamera
 POM_SCM_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideoCamera.git
 POM_SCM_DEV_CONNECTION=scm:[email protected]:JeroenMols/LandscapeVideo… POM_LICENCE_NAME=The Apache Software License, Version 2.0
 POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
 POM_LICENCE_DIST=repo
 POM_DEVELOPER_ID=JeroenMols
 POM_DEVELOPER_NAME=Jeroen Mols
  24. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 3 ‣ MODULE_HOME/build.gradle apply from:

    'https://raw.github.com/chrisbanes/ gradle-mvn-push/master/gradle-mvn-push.gradle' ‣ $ ./gradlew clean build uploadArchives
  25. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 3 ‣ MODULE_HOME/build.gradle apply from:

    'https://raw.github.com/chrisbanes/ gradle-mvn-push/master/gradle-mvn-push.gradle' ‣ $ ./gradlew clean build uploadArchives
  26. @MOLSJEROEN NEXUS - UPLOAD ARTIFACTS 3 ‣ MODULE_HOME/build.gradle apply from:

    'https://raw.github.com/chrisbanes/ gradle-mvn-push/master/gradle-mvn-push.gradle' ‣ $ ./gradlew clean build uploadArchives
  27. @MOLSJEROEN BINTRAY ▸ Quite easy to set up ▸ Create

    account and new package ▸ No signing needed ▸ Gradle or manual upload to staging ▸ Manually release the artifacts ▸ Wait for sync to JCenter
  28. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 1 ‣ PROJECT_HOME/local.properties bintray.user=jeroenmols
 bintray.apikey=n1c3try

    ‣ PROJECT_HOME/build.gradle buildscript {
 dependencies {
 classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
 classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
 }
 }
  29. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 1 ‣ PROJECT_HOME/local.properties bintray.user=jeroenmols
 bintray.apikey=n1c3try

    ‣ PROJECT_HOME/build.gradle buildscript {
 dependencies {
 classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
 classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
 }
 }
  30. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 1 ‣ PROJECT_HOME/local.properties bintray.user=jeroenmols
 bintray.apikey=n1c3try

    ‣ PROJECT_HOME/build.gradle buildscript {
 dependencies {
 classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
 classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
 }
 }
  31. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/local.properties ext {


    bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera'
 artifact = 'library'
 
 libraryDescription = 'Powerful custom Android Camera.’ libraryVersion = '1.1.4'
 
 developerId = 'JeroenMols'
 developerName = 'Jeroen Mols'
 developerEmail = '[email protected]'
 
 user = 'jmols'
 apikey = '1a7704b39d7b4c884651c74475abb4fd80e47da3'
 } 
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  32. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/local.properties ext {


    bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera'
 artifact = 'library'
 
 libraryDescription = 'Powerful custom Android Camera.’ libraryVersion = '1.1.4'
 
 developerId = 'JeroenMols'
 developerName = 'Jeroen Mols'
 developerEmail = '[email protected]'
 
 user = 'jmols'
 apikey = '1a7704b39d7b4c884651c74475abb4fd80e47da3'
 } 
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  33. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/local.properties ext {


    bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera'
 artifact = 'library'
 
 libraryDescription = 'Powerful custom Android Camera.’ libraryVersion = '1.1.4'
 
 developerId = 'JeroenMols'
 developerName = 'Jeroen Mols'
 developerEmail = '[email protected]'
 
 user = 'jmols'
 apikey = '1a7704b39d7b4c884651c74475abb4fd80e47da3'
 } 
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  34. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/local.properties ext {


    bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera'
 artifact = 'library'
 
 libraryDescription = 'Powerful custom Android Camera.’ libraryVersion = '1.1.4'
 
 developerId = 'JeroenMols'
 developerName = 'Jeroen Mols'
 developerEmail = '[email protected]'
 
 user = 'jmols'
 apikey = '1a7704b39d7b4c884651c74475abb4fd80e47da3'
 } 
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  35. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/local.properties ext {


    bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera'
 artifact = 'library'
 
 libraryDescription = 'Powerful custom Android Camera.’ libraryVersion = '1.1.4'
 
 developerId = 'JeroenMols'
 developerName = 'Jeroen Mols'
 developerEmail = '[email protected]'
 
 user = 'jmols'
 apikey = '1a7704b39d7b4c884651c74475abb4fd80e47da3'
 } 
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  36. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/local.properties ext {


    bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera'
 artifact = 'library'
 
 libraryDescription = 'Powerful custom Android Camera.’ libraryVersion = '1.1.4'
 
 developerId = 'JeroenMols'
 developerName = 'Jeroen Mols'
 developerEmail = '[email protected]'
 
 user = 'jmols'
 apikey = '1a7704b39d7b4c884651c74475abb4fd80e47da3'
 } 
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  37. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ PROJECT_HOME/local.properties ext {


    bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera'
 artifact = 'library'
 
 libraryDescription = 'Powerful custom Android Camera.’ libraryVersion = '1.1.4'
 
 developerId = 'JeroenMols'
 developerName = 'Jeroen Mols'
 developerEmail = '[email protected]'
 
 user = 'jmols'
 apikey = '1a7704b39d7b4c884651c74475abb4fd80e47da3'
 } 
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  38. @MOLSJEROEN JITPACK.IO ▸ Extremely easy to use ▸ No account

    or set up required ▸ No signing required ▸ No upload to staging required ▸ Builds any GitHub project (and more)
  39. @MOLSJEROEN JITPACK.IO - CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories

    {
 jcenter()
 maven { url "https://jitpack.io" }
 } } ‣ MODULE_HOME/build.gradle dependencies {
 compile 'com.github.JeroenMols:LandscapeVideoCamera:1.1.1'
 }
  40. @MOLSJEROEN JITPACK.IO - CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories

    {
 jcenter()
 maven { url "https://jitpack.io" }
 } } ‣ MODULE_HOME/build.gradle dependencies {
 compile 'com.github.JeroenMols:LandscapeVideoCamera:1.1.1'
 }
  41. @MOLSJEROEN JITPACK.IO - CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories

    {
 jcenter()
 maven { url "https://jitpack.io" }
 } } ‣ MODULE_HOME/build.gradle dependencies {
 compile 'com.github.JeroenMols:LandscapeVideoCamera:1.1.1'
 }
  42. @MOLSJEROEN JITPACK.IO - CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories

    {
 jcenter()
 maven { url "https://jitpack.io" }
 } } ‣ MODULE_HOME/build.gradle dependencies {
 compile ‘com.github.JeroenMols:LandscapeVideoCamera: 3f900ec00b302f75f3d377cff0bdca37145fc89d'
 }
  43. @MOLSJEROEN REPOSITORY MANAGER - ARTIFACTORY ▸ Easy to set up

    Maven repository ▸ Cache remote repository artifacts ▸ Open source (free) ▸ Gradle plugin to do the upload ▸ Advanced features ▸ Backups? ▸ Cost/hassle of running a server?
  44. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 1 ‣ PROJECT_HOME/build.gradle buildscript {


    dependencies { classpath “org.jfrog.buildinfo: build-info-extractor-gradle:3.1.1"
 }
 }
  45. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 1 ‣ PROJECT_HOME/build.gradle buildscript {


    dependencies { classpath “org.jfrog.buildinfo: build-info-extractor-gradle:3.1.1"
 }
 }
  46. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ MODULE_HOME/build.gradle apply plugin:

    'com.jfrog.artifactory'
 apply plugin: 'maven-publish' def packageName = 'com.jeroenmols.awesomelibrary'
 def libraryVersion = '1.0.0' publishing {
 publications {
 aar(MavenPublication) {
 groupId = packageName
 version = libraryVersion
 artifactId = project.getName()
 artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
 } } }
  47. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ MODULE_HOME/build.gradle apply plugin:

    'com.jfrog.artifactory'
 apply plugin: 'maven-publish' def packageName = 'com.jeroenmols.awesomelibrary'
 def libraryVersion = '1.0.0' publishing {
 publications {
 aar(MavenPublication) {
 groupId = packageName
 version = libraryVersion
 artifactId = project.getName()
 artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
 } } }
  48. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ MODULE_HOME/build.gradle apply plugin:

    'com.jfrog.artifactory'
 apply plugin: 'maven-publish' def packageName = 'com.jeroenmols.awesomelibrary'
 def libraryVersion = '1.0.0' publishing {
 publications {
 aar(MavenPublication) {
 groupId = packageName
 version = libraryVersion
 artifactId = project.getName()
 artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
 } } }
  49. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ MODULE_HOME/build.gradle apply plugin:

    'com.jfrog.artifactory'
 apply plugin: 'maven-publish' def packageName = 'com.jeroenmols.awesomelibrary'
 def libraryVersion = '1.0.0' publishing {
 publications {
 aar(MavenPublication) {
 groupId = packageName
 version = libraryVersion
 artifactId = project.getName()
 artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
 } } }
  50. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ MODULE_HOME/build.gradle apply plugin:

    'com.jfrog.artifactory'
 apply plugin: 'maven-publish' def packageName = 'com.jeroenmols.awesomelibrary'
 def libraryVersion = '1.0.0' publishing {
 publications {
 aar(MavenPublication) {
 groupId = packageName
 version = libraryVersion
 artifactId = project.getName()
 artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
 } } }
  51. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ MODULE_HOME/build.gradle apply plugin:

    'com.jfrog.artifactory'
 apply plugin: 'maven-publish' def packageName = 'com.jeroenmols.awesomelibrary'
 def libraryVersion = '1.0.0' publishing {
 publications {
 aar(MavenPublication) {
 groupId = packageName
 version = libraryVersion
 artifactId = project.getName()
 artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
 } } }
  52. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 3 ‣ MODULE_HOME/build.gradle artifactory {


    contextUrl = 'http://localhost:8081/artifactory'
 publish {
 repository {
 repoKey = 'libs-release-local'
 username = "admin"
 password = "password"
 }
 defaults {
 publications('aar')
 publishArtifacts = true
 publishPom = true
 }
 } }
  53. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 3 ‣ MODULE_HOME/build.gradle artifactory {


    contextUrl = 'http://localhost:8081/artifactory'
 publish {
 repository {
 repoKey = 'libs-release-local'
 username = "admin"
 password = "password"
 }
 defaults {
 publications('aar')
 publishArtifacts = true
 publishPom = true
 }
 } }
  54. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 3 ‣ MODULE_HOME/build.gradle artifactory {


    contextUrl = 'http://localhost:8081/artifactory'
 publish {
 repository {
 repoKey = 'libs-release-local'
 username = "admin"
 password = "password"
 }
 defaults {
 publications('aar')
 publishArtifacts = true
 publishPom = true
 }
 } }
  55. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 3 ‣ MODULE_HOME/build.gradle artifactory {


    contextUrl = 'http://localhost:8081/artifactory'
 publish {
 repository {
 repoKey = 'libs-release-local'
 username = "admin"
 password = "password"
 }
 defaults {
 publications('aar')
 publishArtifacts = true
 publishPom = true
 }
 } }
  56. @MOLSJEROEN ARTIFACTORY - CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories

    {
 maven { url “http://localhost:8081/artifactory/libs-release-local" } } } ‣ PROJECT_HOME/build.gradle dependencies {
 compile 'com.jeroenmols.awesomelibrary:1.0.0'
 }
  57. @MOLSJEROEN ARTIFACTORY - CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories

    {
 maven { url “http://localhost:8081/artifactory/libs-release-local" } } } ‣ PROJECT_HOME/build.gradle dependencies {
 compile 'com.jeroenmols.awesomelibrary:1.0.0'
 }
  58. @MOLSJEROEN ARTIFACTORY - CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories

    {
 maven { url “http://localhost:8081/artifactory/libs-release-local" } } } ‣ PROJECT_HOME/build.gradle dependencies {
 compile 'com.jeroenmols.awesomelibrary:1.0.0'
 }
  59. @MOLSJEROEN WAGON-GIT ▸ Use a Git as a Maven repository

    ▸ Supports GitHub and BitBucket (public or private) ▸ Inherent backups and remote access ▸ Open source (free) ▸ Maven plugin to do the upload
  60. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 1 ▸ PROJECT_HOME/gradle.properties ARTIFACT_VERSION=1.0.0
 ARTIFACT_NAME=landscapevideocamera


    ARTIFACT_PACKAGE=com.jeroenmols.landscapevideocamera ARTIFACT_PACKAGING=aar
 
 BITBUCKET_TEAM=jmolsmobile
 REPOSITORY_NAME=maven_repository // encode "username:password" to base64
 BASE64CREDENTIALS=dXNlcm5hbWU6cGFzc3dvcmQ=
  61. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 1 ▸ PROJECT_HOME/gradle.properties ARTIFACT_VERSION=1.0.0
 ARTIFACT_NAME=landscapevideocamera


    ARTIFACT_PACKAGE=com.jeroenmols.landscapevideocamera ARTIFACT_PACKAGING=aar
 
 BITBUCKET_TEAM=jmolsmobile
 REPOSITORY_NAME=maven_repository // encode "username:password" to base64
 BASE64CREDENTIALS=dXNlcm5hbWU6cGFzc3dvcmQ=
  62. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 1 ▸ PROJECT_HOME/gradle.properties ARTIFACT_VERSION=1.0.0
 ARTIFACT_NAME=landscapevideocamera


    ARTIFACT_PACKAGE=com.jeroenmols.landscapevideocamera ARTIFACT_PACKAGING=aar
 
 BITBUCKET_TEAM=jmolsmobile
 REPOSITORY_NAME=maven_repository // encode "username:password" to base64
 BASE64CREDENTIALS=dXNlcm5hbWU6cGFzc3dvcmQ=
  63. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 1 ▸ PROJECT_HOME/gradle.properties ARTIFACT_VERSION=1.0.0
 ARTIFACT_NAME=landscapevideocamera


    ARTIFACT_PACKAGE=com.jeroenmols.landscapevideocamera ARTIFACT_PACKAGING=aar
 
 BITBUCKET_TEAM=jmolsmobile
 REPOSITORY_NAME=maven_repository // encode "username:password" to base64
 BASE64CREDENTIALS=dXNlcm5hbWU6cGFzc3dvcmQ=
  64. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 2 ▸ PROJECT_HOME/build.gradle apply plugin:

    'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + BITBUCKET_TEAM + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  65. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 2 ▸ PROJECT_HOME/build.gradle apply plugin:

    'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + BITBUCKET_TEAM + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  66. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 2 ▸ PROJECT_HOME/build.gradle apply plugin:

    'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + BITBUCKET_TEAM + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  67. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 2 ▸ PROJECT_HOME/build.gradle apply plugin:

    'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + BITBUCKET_TEAM + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  68. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 2 ▸ PROJECT_HOME/build.gradle apply plugin:

    'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + BITBUCKET_TEAM + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  69. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 3 uploadArchives.dependsOn lookForArtifacts task lookForArtifacts

    {
 doLast {
 def libraryName = ARTIFACT_NAME + '-' + ARTIFACT_VERSION + '.aar'
 def repoPath = ARTIFACT_PACKAGE.replace(".", "/") + "/" + ARTIFACT_NAME + "/" + ARTIFACT_VERSION + "/" + libraryName
 def repositoryUrl = 'https://api.bitbucket.org/1.0/repositories/' + COMPANY + '/' + REPOSITORY_NAME + '/raw/releases/' + repoPath
 if (urlExists(repositoryUrl)) {
 throw new RuntimeException(“Artifact exists:" + ARTIFACT_VERSION)
 }
 return true
 } }
  70. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 3 uploadArchives.dependsOn lookForArtifacts task lookForArtifacts

    {
 doLast {
 def libraryName = ARTIFACT_NAME + '-' + ARTIFACT_VERSION + '.aar'
 def repoPath = ARTIFACT_PACKAGE.replace(".", "/") + "/" + ARTIFACT_NAME + "/" + ARTIFACT_VERSION + "/" + libraryName
 def repositoryUrl = 'https://api.bitbucket.org/1.0/repositories/' + COMPANY + '/' + REPOSITORY_NAME + '/raw/releases/' + repoPath
 if (urlExists(repositoryUrl)) {
 throw new RuntimeException(“Artifact exists:" + ARTIFACT_VERSION)
 }
 return true
 } }
  71. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 3 uploadArchives.dependsOn lookForArtifacts task lookForArtifacts

    {
 doLast {
 def libraryName = ARTIFACT_NAME + '-' + ARTIFACT_VERSION + '.aar'
 def repoPath = ARTIFACT_PACKAGE.replace(".", "/") + "/" + ARTIFACT_NAME + "/" + ARTIFACT_VERSION + "/" + libraryName
 def repositoryUrl = 'https://api.bitbucket.org/1.0/repositories/' + COMPANY + '/' + REPOSITORY_NAME + '/raw/releases/' + repoPath
 if (urlExists(repositoryUrl)) {
 throw new RuntimeException(“Artifact exists:" + ARTIFACT_VERSION)
 }
 return true
 } }
  72. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 3 uploadArchives.dependsOn lookForArtifacts task lookForArtifacts

    {
 doLast {
 def libraryName = ARTIFACT_NAME + '-' + ARTIFACT_VERSION + '.aar'
 def repoPath = ARTIFACT_PACKAGE.replace(".", "/") + "/" + ARTIFACT_NAME + "/" + ARTIFACT_VERSION + "/" + libraryName
 def repositoryUrl = 'https://api.bitbucket.org/1.0/repositories/' + COMPANY + '/' + REPOSITORY_NAME + '/raw/releases/' + repoPath
 if (urlExists(repositoryUrl)) {
 throw new RuntimeException(“Artifact exists:" + ARTIFACT_VERSION)
 }
 return true
 } }
  73. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 3 uploadArchives.dependsOn lookForArtifacts task lookForArtifacts

    {
 doLast {
 def libraryName = ARTIFACT_NAME + '-' + ARTIFACT_VERSION + '.aar'
 def repoPath = ARTIFACT_PACKAGE.replace(".", "/") + "/" + ARTIFACT_NAME + "/" + ARTIFACT_VERSION + "/" + libraryName
 def repositoryUrl = 'https://api.bitbucket.org/1.0/repositories/' + COMPANY + '/' + REPOSITORY_NAME + '/raw/releases/' + repoPath
 if (urlExists(repositoryUrl)) {
 throw new RuntimeException(“Artifact exists:" + ARTIFACT_VERSION)
 }
 return true
 } }
  74. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 3 uploadArchives.dependsOn lookForArtifacts task lookForArtifacts

    {
 doLast {
 def libraryName = ARTIFACT_NAME + '-' + ARTIFACT_VERSION + '.aar'
 def repoPath = ARTIFACT_PACKAGE.replace(".", "/") + "/" + ARTIFACT_NAME + "/" + ARTIFACT_VERSION + "/" + libraryName
 def repositoryUrl = 'https://api.bitbucket.org/1.0/repositories/' + COMPANY + '/' + REPOSITORY_NAME + '/raw/releases/' + repoPath
 if (urlExists(repositoryUrl)) {
 throw new RuntimeException(“Artifact exists:" + ARTIFACT_VERSION)
 }
 return true
 } }
  75. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 4 def urlExists(String repositoryUrl) {


    try {
 def conn = (HttpURLConnection) new URL(repositoryUrl).openConnection()
 
 conn.setRequestProperty("Authorization","Basic " + BASE64CREDENTIALS)
 conn.setConnectTimeout(10000)
 conn.setReadTimeout(10000)
 conn.setRequestMethod("HEAD")
 
 def responseCode = connection.getResponseCode()
 println("responseCode: " + responseCode)
 
 return (200 == responseCode) 
 } catch (IOException ignored) {
 return false
 } }
  76. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 4 def urlExists(String repositoryUrl) {


    try {
 def conn = (HttpURLConnection) new URL(repositoryUrl).openConnection()
 
 conn.setRequestProperty("Authorization","Basic " + BASE64CREDENTIALS)
 conn.setConnectTimeout(10000)
 conn.setReadTimeout(10000)
 conn.setRequestMethod("HEAD")
 
 def responseCode = connection.getResponseCode()
 println("responseCode: " + responseCode)
 
 return (200 == responseCode) 
 } catch (IOException ignored) {
 return false
 } }
  77. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 5 repositories {
 maven {

    url "https://raw.github.com/synergian/wagon-git/releases" } }
 
 configurations {
 deployLibrary
 }
 
 dependencies {
 deployLibrary "ar.com.synergian:wagon-git:0.2.0"
 }
  78. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 5 repositories {
 maven {

    url "https://raw.github.com/synergian/wagon-git/releases" } }
 
 configurations {
 deployLibrary
 }
 
 dependencies {
 deployLibrary "ar.com.synergian:wagon-git:0.2.0"
 }
  79. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 5 repositories {
 maven {

    url "https://raw.github.com/synergian/wagon-git/releases" } }
 
 configurations {
 deployLibrary
 }
 
 dependencies {
 deployLibrary "ar.com.synergian:wagon-git:0.2.0"
 }
  80. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 5 repositories {
 maven {

    url "https://raw.github.com/synergian/wagon-git/releases" } }
 
 configurations {
 deployLibrary
 }
 
 dependencies {
 deployLibrary "ar.com.synergian:wagon-git:0.2.0"
 }
  81. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 6 task androidJavadocs(type: Javadoc) {


    failOnError false
 source = android.sourceSets.main.java.sourceFiles
 }
 
 task androidSourcesJar(type: Jar) {
 classifier = 'sources'
 from android.sourceSets.main.java.sourceFiles
 }
 
 task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
 classifier = 'javadoc'
 from androidJavadocs.destinationDir
 }
 
 artifacts {
 archives androidSourcesJar
 archives androidJavadocsJar
 }
  82. @MOLSJEROEN CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories {
 maven

    {
 credentials {
 username '<bitbucket_username>'
 password ‘<bitbucket_password>'
 }
 url "https://api.bitbucket.org/1.0/repositories/" + “<bitbucket_team>/<repository>/raw/releases"
 } } } ‣ MODULE_HOME/build.gradle dependencies {
 compile "com.jeroenmols:landscapevideocamera:<version>"
 }
  83. @MOLSJEROEN CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories {
 maven

    {
 credentials {
 username '<bitbucket_username>'
 password ‘<bitbucket_password>'
 }
 url "https://api.bitbucket.org/1.0/repositories/" + “<bitbucket_team>/<repository>/raw/releases"
 } } } ‣ MODULE_HOME/build.gradle dependencies {
 compile “com.jeroenmols:landscapevideocamera:<version>"
 }
  84. @MOLSJEROEN CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories {
 maven

    {
 credentials {
 username '<bitbucket_username>'
 password ‘<bitbucket_password>'
 }
 url "https://api.bitbucket.org/1.0/repositories/" + “<bitbucket_team>/<repository>/raw/releases"
 } } } ‣ MODULE_HOME/build.gradle dependencies {
 compile “com.jeroenmols:landscapevideocamera:<version>"
 }
  85. @MOLSJEROEN CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories {
 maven

    {
 credentials {
 username '<bitbucket_username>'
 password ‘<bitbucket_password>'
 }
 url "https://api.bitbucket.org/1.0/repositories/" + “<bitbucket_team>/<repository>/raw/releases"
 } } } ‣ MODULE_HOME/build.gradle dependencies {
 compile "com.jeroenmols:landscapevideocamera:<version>"
 }
  86. @MOLSJEROEN CREDITS ▸ Gradle Maven Push script @chrisbanes ▸ Distributing

    Android Libraries via jCenter for Gradle Importing @attwellbrian ▸ A private Maven repository in 30 min @molsjeroen ▸ Getting the most out of Artifactory @molsjeroen
  87. @MOLSJEROEN OTHER INTERESTING ARTICLES ▸ Gradle dependency and local repository

    @turhanoz ▸ Creating and publishing an Android library @Etienne_Lawlor ▸ Publish with Gradle on BitBucket @mul0w