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

Automated library distribution to Maven

Jeroen Mols
February 16, 2016

Automated library distribution to Maven

Slides from my talk at GDG Brussels February 2016

Comprehensive talk about library distribution to either a public or private Maven repository, including topics such as:

- Introduction to Maven
- Maven adoption by Android
- Distributing to JCenter
- Distributing via JitPack
- Setting up your own Maven repository (Artifactory)
- Using Git as a Maven repository

Jeroen Mols

February 16, 2016
Tweet

More Decks by Jeroen Mols

Other Decks in Programming

Transcript

  1. @MOLSJEROEN WHAT IS MAVEN ▸ Build automation tool 1. Describes

    how software is built ‣ default conventions ‣ specify all exceptions 2. Describes dependencies ‣ locally installed repository ‣ remote Maven repository
  2. @MOLSJEROEN HOW MAVEN HANDLES DEPENDENCIES ▸ Release identified by ▸

    GroupId com.jeroenmols ▸ ArtifactId landscapevideocamera ▸ Version 1.1.3 ▸ Multiple artifacts possible ▸ Library landscapevideocamera.aar ▸ Documentation javadoc.jar ▸ Sources sources.jar
  3. @MOLSJEROEN IMPORTANT CONSIDERATIONS ▸ Maven can only be used if:

    ▸ Repository reachable and online forever ▸ Existing artifacts never modified ▸ New versions come from same developer ▸ Code must always build immediately after checkout ▸ When doubt: add artifacts to version control
  4. @MOLSJEROEN ADOPTION BY ANDROID ▸ Gradle ▸ Specify Maven repositories

    to use ▸ Define dependencies (and configuration) ▸ Upload your own artifacts ▸ Local maven repository ▸ Support libraries ▸ Google play services
  5. @MOLSJEROEN GRADLE - USE MAVEN 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.jeroenmols:landscapevideocamera:1.1.3'
 }
  6. @MOLSJEROEN GRADLE - USE MAVEN 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.jeroenmols:landscapevideocamera:1.1.3'
 }
  7. @MOLSJEROEN GRADLE - USE MAVEN 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.jeroenmols:landscapevideocamera:1.1.3'
 }
  8. @MOLSJEROEN GRADLE - USE MAVEN 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.jeroenmols:landscapevideocamera:1.1.3’
 } GroupId ArtifactId Version
  9. @MOLSJEROEN GRADLE - UPLOAD MAVEN 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 MAVEN 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 MAVEN 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. @MOLSJEROEN GRADLE - UPLOAD MAVEN 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'
 } } } }
  13. THERE IS AN EASY WAY AND A HARD WAY. THE

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

    ‣ Browse repository repositories {
 mavenCentral()
 } ‣ Sonatype ‣ Browse repository
  15. @MOLSJEROEN PUBLIC MAVEN REPOSITORIES repositories {
 jcenter()
 } ‣ Bintray

    ‣ Browse repository repositories {
 mavenCentral()
 } ‣ Sonatype ‣ Browse repository
  16. @MOLSJEROEN BINTRAY ▸ Attractive convenient UI ▸ Simple to use

    (no signing) ▸ Integrates with Github, Bitbucket, Twitter,… ▸ Download statistics ▸ Gradle/manual upload to staging ▸ Manually release to JCenter ▸ One click/automated sync to Maven Central
  17. @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'
 }
 }
  18. @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'
 }
 }
  19. @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.6'
 classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
 }
 }
  20. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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]'
 } apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  21. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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]'
 } apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  22. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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]'
 } apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  23. @MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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]'
 } apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'
  24. @MOLSJEROEN JITPACK.IO ▸ Zero configuration: no account, no set up,

    no opt-in ▸ Download statistics, Badges,… ▸ Supports snapshots ▸ No need to upload artifacts ▸ Builds any GitHub project (and more) ▸ Use Git tags to create a ‘formal’ release (optional) ▸ Gradle dependency on Jitpack repository
  25. @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'
 }
  26. @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'
 }
  27. @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'
 }
  28. @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'
 }
  29. @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: develop-SNAPSHOT‘
 }
  30. @MOLSJEROEN ▸ 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? REPOSITORY MANAGER - ARTIFACTORY RELATED BLOGPOSTS
  31. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 1 ‣ PROJECT_HOME/build.gradle buildscript {


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


    dependencies { classpath “org.jfrog.buildinfo: build-info-extractor-gradle:3.1.1"
 }
 }
  33. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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")
 } } }
  34. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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")
 } } }
  35. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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")
 } } }
  36. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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")
 } } }
  37. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 2 ‣ LIBRARY_HOME/build.gradle 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")
 } } }
  38. @MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 3 ‣ LIBRARY_HOME/build.gradle apply plugin:

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

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

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

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

    ‘com.jfrog.artifactory' artifactory {
 contextUrl = 'http://localhost:8081/artifactory'
 publish {
 repository {
 repoKey = 'libs-release-local'
 username = "admin"
 password = "password"
 }
 defaults {
 publications('aar')
 publishArtifacts = true
 publishPom = true
 }
 } }
  43. @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'
 }
  44. @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'
 }
  45. @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'
 }
  46. @MOLSJEROEN WAGON-GIT ▸ Use a Git as a Maven repository

    ▸ Supports GitHub and BitBucket (public or private) ▸ Open source (free) ▸ Maven plugin to do the upload ▸ Inherent backups and remote access RELATED BLOGPOST
  47. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 1 ▸ LIBRARY_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 ▸ PROJECT_HOME/gradle.properties USERNAME=<username_here>
 PASSWORD=<password_here>
  48. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 1 ▸ LIBRARY_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 ▸ PROJECT_HOME/gradle.properties USERNAME=<username_here>
 PASSWORD=<password_here>
  49. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 1 ▸ LIBRARY_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 ▸ PROJECT_HOME/gradle.properties USERNAME=<username_here>
 PASSWORD=<password_here>
  50. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 1 ▸ LIBRARY_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 ▸ PROJECT_HOME/gradle.properties USERNAME=<username_here>
 PASSWORD=<password_here>
  51. @MOLSJEROEN WAGON-GIT - UPLOAD ARTIFACTS 2 ▸ LIBRARY_HOME/build.gradle apply from:

    'https://raw.githubusercontent.com/JeroenMols/ GitAsMaven/master/publish-bitbucket.gradle' ▸ $ gradle assembleRelease uploadArchives
  52. @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>"
 }
  53. @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>"
 }
  54. @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>"
 }
  55. @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>"
 }
  56. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 1 ▸ PROJECT_HOME/build.gradle apply

    plugin: 'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + COMPANY + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  57. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 1 ▸ PROJECT_HOME/build.gradle apply

    plugin: 'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + COMPANY + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  58. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 1 ▸ PROJECT_HOME/build.gradle apply

    plugin: 'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + COMPANY + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  59. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 1 ▸ PROJECT_HOME/build.gradle apply

    plugin: 'maven' 
 uploadArchives {
 repositories.mavenDeployer {
 configuration = configurations.deployLibrary 
 repository(url: 'git:releases://[email protected]:' + COMPANY + '/' + REPOSITORY_NAME + '.git ')
 
 pom.project {
 groupId = ARTIFACT_PACKAGE
 version = ARTIFACT_VERSION
 artifactId = ARTIFACT_NAME
 packaging = ARTIFACT_PACKAGING
 } } }
  60. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 2 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
 }
  61. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 2 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
 }
  62. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 3 repositories {
 maven

    { url "https://raw.github.com/synergian/wagon-git/releases" } }
 
 configurations {
 deployLibrary
 }
 
 dependencies {
 deployLibrary "ar.com.synergian:wagon-git:0.2.0"
 }
  63. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 3 repositories {
 maven

    { url "https://raw.github.com/synergian/wagon-git/releases" } }
 
 configurations {
 deployLibrary
 }
 
 dependencies {
 deployLibrary "ar.com.synergian:wagon-git:0.2.0"
 }
  64. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - SIMPLIFY CONFIGURATION 3 repositories {
 maven

    { url "https://raw.github.com/synergian/wagon-git/releases" } }
 
 configurations {
 deployLibrary
 }
 
 dependencies {
 deployLibrary "ar.com.synergian:wagon-git:0.2.0"
 }
  65. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - EXISTING ARTIFACTS 1 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
 } }
  66. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - EXISTING ARTIFACTS 1 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
 } }
  67. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - EXISTING ARTIFACTS 1 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
 } }
  68. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - EXISTING ARTIFACTS 1 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
 } }
  69. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - EXISTING ARTIFACTS 1 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 PUBLISH-BITBUCKET SCRIPT - EXISTING ARTIFACTS 2 def urlExists(String repositoryUrl)

    {
 try {
 def conn = (HttpURLConnection) new URL(repositoryUrl).openConnection()
 
 conn.setRequestProperty("Authorization","Basic " + getBase64EncodedCredentials())
 conn.setConnectTimeout(10000)
 conn.setReadTimeout(10000)
 conn.setRequestMethod("HEAD")
 
 def responseCode = connection.getResponseCode()
 println("responseCode: " + responseCode)
 
 return (200 == responseCode) 
 } catch (IOException ignored) {
 return false
 } }
  71. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - EXISTING ARTIFACTS 2 def urlExists(String repositoryUrl)

    {
 try {
 def conn = (HttpURLConnection) new URL(repositoryUrl).openConnection()
 
 conn.setRequestProperty("Authorization","Basic " + getBase64EncodedCredentials())
 conn.setConnectTimeout(10000)
 conn.setReadTimeout(10000)
 conn.setRequestMethod("HEAD")
 
 def responseCode = connection.getResponseCode()
 println("responseCode: " + responseCode)
 
 return (200 == responseCode) 
 } catch (IOException ignored) {
 return false
 } }
  72. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - EXISTING ARTIFACTS 2 def urlExists(String repositoryUrl)

    {
 try {
 def conn = (HttpURLConnection) new URL(repositoryUrl).openConnection()
 
 conn.setRequestProperty("Authorization","Basic " + getBase64EncodedCredentials())
 conn.setConnectTimeout(10000)
 conn.setReadTimeout(10000)
 conn.setRequestMethod("HEAD")
 
 def responseCode = connection.getResponseCode()
 println("responseCode: " + responseCode)
 
 return (200 == responseCode) 
 } catch (IOException ignored) {
 return false
 } }
  73. @MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - BITBUCKET AUTHENTICATION def getBase64EncodedCredentials() {
 def

    s = USERNAME + ":" + PASSWORD;
 return s.bytes.encodeBase64().toString()
 }
  74. @MOLSJEROEN CREDITS ▸ Distributing Android Libraries via jCenter for Gradle

    Importing @attwellbrian ▸ A private Maven repository in 30 min @molsjeroen ▸ Getting the most out of Artifactory @molsjeroen ▸ Git as a secure private Maven repository @molsjeroen
  75. @MOLSJEROEN OTHER INTERESTING ARTICLES ▸ Gradle dependency and local repository

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