Slide 1

Slide 1 text

AUTOMATED LIBRARY DISTRIBUTION TO MAVEN @MOLSJEROEN

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

MAVEN FUNDAMENTALS

Slide 4

Slide 4 text

@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

Slide 5

Slide 5 text

@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

Slide 6

Slide 6 text

@MOLSJEROEN HOW MAVEN STORES DEPENDENCIES

Slide 7

Slide 7 text

@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

Slide 8

Slide 8 text

@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

Slide 9

Slide 9 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.3'
 }

Slide 10

Slide 10 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.3'
 }

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.3'
 }

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

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

PUBLIC DISTRIBUTION

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 PUBLIC MAVEN REPOSITORIES repositories {
 jcenter()
 } ‣ Bintray ‣ Browse repository repositories {
 mavenCentral()
 } ‣ Sonatype ‣ Browse repository

Slide 21

Slide 21 text

@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

Slide 22

Slide 22 text

@MOLSJEROEN

Slide 23

Slide 23 text

@MOLSJEROEN

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

@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 = 'jmolsmobile@gmail.com'
 } 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 ‣ 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 = 'jmolsmobile@gmail.com'
 } apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'

Slide 29

Slide 29 text

@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 = 'jmolsmobile@gmail.com'
 } apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'

Slide 30

Slide 30 text

@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 = 'jmolsmobile@gmail.com'
 } apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle'
 apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle'

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

Slide 34

Slide 34 text

@MOLSJEROEN JITPACK.IO - UPLOAD ARTIFACTS DO NOTHING

Slide 35

Slide 35 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.1'
 }

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.1'
 }

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.1'
 }

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: 3f900ec00b302f75f3d377cff0bdca37145fc89d'
 }

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: develop-SNAPSHOT‘
 }

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

PRIVATE DISTRIBUTION

Slide 42

Slide 42 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? REPOSITORY MANAGER - ARTIFACTORY RELATED BLOGPOSTS

Slide 43

Slide 43 text

@MOLSJEROEN

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 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 47

Slide 47 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 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 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 52

Slide 52 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 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 4 ▸ $ gradle assembleRelease artifactoryPublish

Slide 57

Slide 57 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 58

Slide 58 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 59

Slide 59 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 60

Slide 60 text

@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

Slide 61

Slide 61 text

@MOLSJEROEN

Slide 62

Slide 62 text

@MOLSJEROEN

Slide 63

Slide 63 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 64

Slide 64 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 65

Slide 65 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 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 2 ▸ LIBRARY_HOME/build.gradle apply from: 'https://raw.githubusercontent.com/JeroenMols/ GitAsMaven/master/publish-bitbucket.gradle' ▸ $ gradle assembleRelease uploadArchives

Slide 68

Slide 68 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 69

Slide 69 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 70

Slide 70 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 71

Slide 71 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 72

Slide 72 text

@MOLSJEROEN PUBLISH-BITBUCKET SCRIPT ▸ Dramatically simplifies configuration ▸ Check for existing artifacts ▸ Bitbucket authentication

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 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 83

Slide 83 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 84

Slide 84 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 85

Slide 85 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 86

Slide 86 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 87

Slide 87 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 88

Slide 88 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 89

Slide 89 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 90

Slide 90 text

@MOLSJEROEN PUBLISH-BITBUCKET SCRIPT - BITBUCKET AUTHENTICATION def getBase64EncodedCredentials() {
 def s = USERNAME + ":" + PASSWORD;
 return s.bytes.encodeBase64().toString()
 }

Slide 91

Slide 91 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 92

Slide 92 text

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

Slide 93

Slide 93 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

Slide 94

Slide 94 text

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