Slide 1

Slide 1 text

MAVEN LIBRARY DISTRIBUTION @MOLSJEROEN

Slide 2

Slide 2 text

@MOLSJEROEN @MOLSJEROEN

Slide 3

Slide 3 text

BEFORE SOFTWARE CAN BE REUSABLE IT FIRST HAS TO BE USABLE. Ralph Johnson

Slide 4

Slide 4 text

@MOLSJEROEN GOAL dependencies {
 … compile ‘com.jeroenmols:landscapevideocamera:1.1.4'
 }

Slide 5

Slide 5 text

MAVEN FUNDAMENTALS

Slide 6

Slide 6 text

@MOLSJEROEN WHAT IS MAVEN …a build automation tool used primarily for Java projects. 1. Describes how software is built ▸ Build system (like Ant) 2. Reuse/version dependencies ▸ Adopted by Gradle

Slide 7

Slide 7 text

@MOLSJEROEN HOW MAVEN HANDLES DEPENDENCIES ▸ Release identified by ▸ GroupId com.jeroenmols ▸ ArtifactId landscapevideocamera ▸ Version 1.1.4 ▸ Multiple artifacts possible ▸ Library landscapevideocamera.aar ▸ Documentation javadoc.jar ▸ Sources sources.jar

Slide 8

Slide 8 text

@MOLSJEROEN HOW MAVEN STORES DEPENDENCIES

Slide 9

Slide 9 text

@MOLSJEROEN DEPENDENCY MANAGEMENT ADOPTED BY ANDROID/GRADLE ▸ Define Maven repositories ▸ Local Maven repository in SDK ▸ Dependency configurations dependencies { compile ‘com.jeroenmols:landscapevideocamera:1.1.4’
 testCompile ‘org.mockito:mockito-core:2.0.54-beta’ androidTestCompile ‘com.android.support.test:runner:0.4’ }

Slide 10

Slide 10 text

@MOLSJEROEN DEPENDENCY MANAGEMENT ADOPTED BY ANDROID/GRADLE ▸ Define Maven repositories ▸ Local Maven repository in SDK ▸ Dependency configurations dependencies { compile ‘com.jeroenmols:landscapevideocamera:1.1.4’
 testCompile ‘org.mockito:mockito-core:2.0.54-beta’ androidTestCompile ‘com.android.support.test:runner:0.4’ }

Slide 11

Slide 11 text

@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.4'
 }

Slide 12

Slide 12 text

@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.4'
 }

Slide 13

Slide 13 text

@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.4'
 }

Slide 14

Slide 14 text

@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.4’
 } GroupId ArtifactId Version

Slide 15

Slide 15 text

@MOLSJEROEN IMPLICIT ASSUMPTIONS USING MAVEN 1. Repository reachable and online forever 2. Existing artifacts never modified 3. New versions come from same developer ▸ Code must always build immediately after checkout ▸ When doubt: add artifacts to version control

Slide 16

Slide 16 text

PUBLIC DISTRIBUTION

Slide 17

Slide 17 text

THERE IS AN EASY WAY AND A HARD WAY. THE HARD PART IS FINDING THE EASY WAY. Dr. Lloyd

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

@MOLSJEROEN 1. PUBLIC DISTRIBUTION - BINTRAY ▸ Attractive 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

Slide 21

Slide 21 text

@MOLSJEROEN

Slide 22

Slide 22 text

@MOLSJEROEN

Slide 23

Slide 23 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 1 ‣ LIBRARY_HOME/build.gradle ext {
 bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = ‘LandscapeVideoCamera’ libraryVersion = ‘1.1.4' 
 artifact = ‘library' 
 libraryDescription = 'Powerful custom Android Camera.’
 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'

Slide 24

Slide 24 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 1 ‣ LIBRARY_HOME/build.gradle ext {
 bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera' libraryVersion = ‘1.1.4’ artifact = 'library' 
 libraryDescription = 'Powerful custom Android Camera.’ 
 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'

Slide 25

Slide 25 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 1 ‣ LIBRARY_HOME/build.gradle ext {
 bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera' libraryVersion = ‘1.1.4’ artifact = 'library' 
 libraryDescription = 'Powerful custom Android Camera.’ 
 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'

Slide 26

Slide 26 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 1 ‣ LIBRARY_HOME/build.gradle ext {
 bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = ‘LandscapeVideoCamera' libraryVersion = '1.1.4'
 
 artifact = 'library' 
 libraryDescription = 'Powerful custom Android Camera.’ 
 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'

Slide 27

Slide 27 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 1 ‣ LIBRARY_HOME/build.gradle ext {
 bintrayRepo = 'maven'
 bintrayName = 'LandscapeVideoCamera'
 
 publishedGroupId = 'com.github.jeroenmols'
 libraryName = 'LandscapeVideoCamera' libraryVersion = ‘1.1.4’ artifact = ‘library' 
 libraryDescription = 'Powerful custom Android Camera.’ 
 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'

Slide 28

Slide 28 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ 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'
 }
 }

Slide 29

Slide 29 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ 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'
 }
 }

Slide 30

Slide 30 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 2 ‣ 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'
 }
 }

Slide 31

Slide 31 text

@MOLSJEROEN BINTRAY - UPLOAD ARTIFACTS 3 ‣ $ ./gradlew assembleRelease bintrayUpload

Slide 32

Slide 32 text

@MOLSJEROEN

Slide 33

Slide 33 text

@MOLSJEROEN 2. PUBLIC DISTRIBUTION - JITPACK.IO ▸ Zero configuration ▸ Download statistics, API, Badges,… ▸ Snapshot support ▸ No need to upload artifacts ▸ Builds any GitHub project (and more) ▸ Git tag to create a ‘formal’ release (optional) ▸ Add Jitpack repository

Slide 34

Slide 34 text

@MOLSJEROEN JITPACK.IO - UPLOAD ARTIFACTS DO NOTHING

Slide 35

Slide 35 text

@MOLSJEROEN

Slide 36

Slide 36 text

@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.4'
 }

Slide 37

Slide 37 text

@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.4'
 }

Slide 38

Slide 38 text

@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.4'
 }

Slide 39

Slide 39 text

@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'
 }

Slide 40

Slide 40 text

@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‘
 }

Slide 41

Slide 41 text

@MOLSJEROEN JITPACK.IO - CONSUME ARTIFACTS ‣ PROJECT_HOME/build.gradle allprojects {
 repositories {
 jcenter()
 maven { url "https://jitpack.io" }
 } } ‣ MODULE_HOME/build.gradle dependencies {
 compile ‘com.jeroenmols:LandscapeVideoCamera:1.1.4’
 }

Slide 42

Slide 42 text

PRIVATE DISTRIBUTION

Slide 43

Slide 43 text

I THINK, FUNDAMENTALLY, OPEN SOURCE DOES TEND TO BE MORE STABLE SOFTWARE. Linus Torvalds

Slide 44

Slide 44 text

@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? 1. PRIVATE DISTRIBUTION - ARTIFACTORY RELATED BLOGPOSTS

Slide 45

Slide 45 text

@MOLSJEROEN

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

@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")
 } } }

Slide 49

Slide 49 text

@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")
 } } }

Slide 50

Slide 50 text

@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")
 } } }

Slide 51

Slide 51 text

@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")
 } } }

Slide 52

Slide 52 text

@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")
 } } }

Slide 53

Slide 53 text

@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
 }
 } }

Slide 54

Slide 54 text

@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
 }
 } }

Slide 55

Slide 55 text

@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
 }
 } }

Slide 56

Slide 56 text

@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
 }
 } }

Slide 57

Slide 57 text

@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
 }
 } } to gradle.properties

Slide 58

Slide 58 text

@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
 }
 } }

Slide 59

Slide 59 text

@MOLSJEROEN ARTIFACTORY - UPLOAD ARTIFACTS 4 ▸ $ ./gradlew assembleRelease artifactoryPublish

Slide 60

Slide 60 text

@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'
 }

Slide 61

Slide 61 text

@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'
 }

Slide 62

Slide 62 text

@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'
 }

Slide 63

Slide 63 text

@MOLSJEROEN 2. PRIVATE DISTRIBUTION - WAGON-GIT ▸ 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

Slide 64

Slide 64 text

@MOLSJEROEN

Slide 65

Slide 65 text

@MOLSJEROEN

Slide 66

Slide 66 text

@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=
 PASSWORD=

Slide 67

Slide 67 text

@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=
 PASSWORD=

Slide 68

Slide 68 text

@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=
 PASSWORD=

Slide 69

Slide 69 text

@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=
 PASSWORD=

Slide 70

Slide 70 text

@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

Slide 71

Slide 71 text

@MOLSJEROEN PUBLISH-BITBUCKET SCRIPT ▸ Dramatically simplifies configuration ▸ Check for existing artifacts ▸ Bitbucket authentication ▸ Source: https://github.com/JeroenMols/GitAsMaven/blob/master/publish- bitbucket.gradle

Slide 72

Slide 72 text

@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
 } }

Slide 73

Slide 73 text

@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
 } }

Slide 74

Slide 74 text

@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
 } }

Slide 75

Slide 75 text

@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
 } }

Slide 76

Slide 76 text

@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
 } }

Slide 77

Slide 77 text

@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
 } }

Slide 78

Slide 78 text

@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
 } }

Slide 79

Slide 79 text

@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
 } }

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

WRAP UP

Slide 85

Slide 85 text

@MOLSJEROEN CONCLUSION ▸ Use Gradle to simplify Maven uploads ▸ Public distribution ▸ Use Jitpack initially ▸ Scale to Bintray once usage grows ▸ Private distirbution ▸ Use Artifactory when possible ($$$, infrastructure,…) ▸ Fallback to Git for limited usage

Slide 86

Slide 86 text

@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

Slide 87

Slide 87 text

@MOLSJEROEN GITHUB SAMPLES ▸ Bintray example @attwellbrian ▸ Artifactory example @molsjeroen ▸ Wagon-git example @molsjeroen

Slide 88

Slide 88 text

@MOLSJEROEN IMAGE CREDITS ▸ Philips Hue living room
 http://www.philips.de ▸ Pouring concrete
 http://www.precisionpouredconcrete.com/images/concrete-being-poured.jpg ▸ Flying drones
 https://s3.amazonaws.com/digitaltrends-uploads-prod/2014/12/Drones-packages.jpg ▸ Pneumatic tubes
 https://41.media.tumblr.com/107ae958bff7ce2261c55e7a4de8f79e/tumblr_nlt2wfG8gr1t3cxt2o1_500.jpg ▸ Judge hammer
 http://www.quickhr.biz/wp-content/uploads/2015/03/Judges-hammer.jpg

Slide 89

Slide 89 text

@MOLSJEROEN MANY THANKS ▸ Jeroen Mols (Belgium) ▸ @MolsJeroen ▸ http://jeroenmols.com/blog

Slide 90

Slide 90 text

@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