Download - SF Gradle Meetup - Netflix OSS
Netflix OSS With GradleNetflix OSS With Gradle@netflixoss@netflixoss
@NetflixOSS Progression@NetflixOSS Progression
http://netflix.github.io/http://netflix.github.io/
My RoleMy Role• Engineering ToolsEngineering Tools
• We help, when and where we canWe help, when and where we can
• Build, Bake, Deploy, MonkeyBuild, Bake, Deploy, Monkey
• Lead on internal Gradle and Ant buildsLead on internal Gradle and Ant builds
EnvironmentsEnvironmentsAll of Maven CentralAll of Maven Central
Publish to SonatypePublish to Sonatype
Maven On The Maven On The OutsideOutside
Done in the publicDone in the public
Setup everythingSetup everything
No Maven CentralNo Maven Central
Publish to ArtifactoryPublish to Artifactory
Ivy On The InsideIvy On The Inside
Legacy ConventionsLegacy Conventions
Minimal SetupMinimal Setup
Phase 0: Use GradlePhase 0: Use Gradle
Phase 1: Naive Phase 1: Naive ApproachApproach• Copyable buildCopyable build
• build.gradlebuild.gradle
• gradle/conventions.gradlegradle/conventions.gradle
• gradle/maven.gradlegradle/maven.gradle
• gradle/netflix-oss.gradlegradle/netflix-oss.gradle
• Decent examples onlineDecent examples online
http://jedicoder.blogspot.com/2011/11/automated-gradle-project-deployment-to.htmlhttp://jedicoder.blogspot.com/2011/11/automated-gradle-project-deployment-to.html
ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = project.name // TEMPLATEapply from: project.name // TEMPLATEapply from: file('gradle/convention.gradle')apply from: file('gradle/convention.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/check.gradle')group = 'com.netflix'repositories file('gradle/check.gradle')group = 'com.netflix'repositories {mavenCentral()}dependencies { // TEMPLATEcompile {mavenCentral()}dependencies { // TEMPLATEcompile 'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile 'org.mockito:mockito-core:1.8.5'}'org.mockito:mockito-core:1.8.5'}ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = project.name // TEMPLATEapply from: project.name // TEMPLATEapply from: file('gradle/convention.gradle')apply from: file('gradle/convention.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/check.gradle')group = 'com.netflix'repositories file('gradle/check.gradle')group = 'com.netflix'repositories {mavenCentral()}dependencies { // TEMPLATEcompile {mavenCentral()}dependencies { // TEMPLATEcompile 'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile 'org.mockito:mockito-core:1.8.5'}'org.mockito:mockito-core:1.8.5'}ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = project.name // TEMPLATEapply from: project.name // TEMPLATEapply from: file('gradle/convention.gradle')apply from: file('gradle/convention.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/check.gradle')group = 'com.netflix'repositories file('gradle/check.gradle')group = 'com.netflix'repositories {mavenCentral()}dependencies { // TEMPLATEcompile {mavenCentral()}dependencies { // TEMPLATEcompile 'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile 'org.mockito:mockito-core:1.8.5'}'org.mockito:mockito-core:1.8.5'}ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = project.name // TEMPLATEapply from: project.name // TEMPLATEapply from: file('gradle/convention.gradle')apply from: file('gradle/convention.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/check.gradle')group = 'com.netflix'repositories file('gradle/check.gradle')group = 'com.netflix'repositories {mavenCentral()}dependencies { // TEMPLATEcompile {mavenCentral()}dependencies { // TEMPLATEcompile 'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile 'org.mockito:mockito-core:1.8.5'}'org.mockito:mockito-core:1.8.5'}ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = ext.releaseVersion = '1.1.3' // TEMPLATEext.githubName = project.name // TEMPLATEapply from: project.name // TEMPLATEapply from: file('gradle/convention.gradle')apply from: file('gradle/convention.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/maven.gradle')apply from: file('gradle/check.gradle')group = 'com.netflix'repositories file('gradle/check.gradle')group = 'com.netflix'repositories {mavenCentral()}dependencies { // TEMPLATEcompile {mavenCentral()}dependencies { // TEMPLATEcompile 'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-'javax.ws.rs:jsr311-api:1.1.1'compile 'com.sun.jersey:jersey-core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile core:1.11'testCompile 'org.testng:testng:6.1.1'testCompile 'org.mockito:mockito-core:1.8.5'}'org.mockito:mockito-core:1.8.5'}
build.gradlebuild.gradle
ext.performingRelease = project.hasProperty('release') && ext.performingRelease = project.hasProperty('release') && Boolean.parseBoolean(project.release)def versionPostfix = Boolean.parseBoolean(project.release)def versionPostfix = performingRelease?'':'-SNAPSHOT'version = "${releaseVersion}$performingRelease?'':'-SNAPSHOT'version = "${releaseVersion}${versionPostfix}"status = {versionPostfix}"status = performingRelease?'release':'snapshot'apply plugin: 'java' // performingRelease?'release':'snapshot'apply plugin: 'java' // Plugin as major conventionssourceCompatibility = 1.6// GRADLE-2087 Plugin as major conventionssourceCompatibility = 1.6// GRADLE-2087 workaround, perform after java pluginstatus = workaround, perform after java pluginstatus = rootProject.statustask sourcesJar(type: Jar, dependsOn:classes) rootProject.statustask sourcesJar(type: Jar, dependsOn:classes) {classifier = 'sources'{classifier = 'sources'from sourceSets.main.allSource}task javadocJar(type: Jar, from sourceSets.main.allSource}task javadocJar(type: Jar, dependsOn:javadoc) {classifier = 'javadoc' from dependsOn:javadoc) {classifier = 'javadoc' from javadoc.destinationDir} artifacts { archives javadoc.destinationDir} artifacts { archives jar archives sourcesJar archives javadocJar }}jar archives sourcesJar archives javadocJar }}from sourceSets.main.allSource}task javadocJar(type: Jar, from sourceSets.main.allSource}task javadocJar(type: Jar, dependsOn:javadoc) {classifier = 'javadoc' from dependsOn:javadoc) {classifier = 'javadoc' from javadoc.destinationDir} artifacts { archives javadoc.destinationDir} artifacts { archives jar archives sourcesJar archives javadocJar }}jar archives sourcesJar archives javadocJar }}from sourceSets.main.allSource}task javadocJar(type: Jar, from sourceSets.main.allSource}task javadocJar(type: Jar, dependsOn:javadoc) {classifier = 'javadoc' from dependsOn:javadoc) {classifier = 'javadoc' from javadoc.destinationDir} artifacts { archives javadoc.destinationDir} artifacts { archives jar archives sourcesJar archives javadocJar }}jar archives sourcesJar archives javadocJar }}from sourceSets.main.allSource}task javadocJar(type: Jar, from sourceSets.main.allSource}task javadocJar(type: Jar, dependsOn:javadoc) {classifier = 'javadoc' from dependsOn:javadoc) {classifier = 'javadoc' from javadoc.destinationDir} artifacts { archives javadoc.destinationDir} artifacts { archives jar archives sourcesJar archives javadocJar }}jar archives sourcesJar archives javadocJar }}from sourceSets.main.allSource}task javadocJar(type: Jar, from sourceSets.main.allSource}task javadocJar(type: Jar, dependsOn:javadoc) {classifier = 'javadoc' from dependsOn:javadoc) {classifier = 'javadoc' from javadoc.destinationDir} artifacts { archives javadoc.destinationDir} artifacts { archives jar archives sourcesJar archives javadocJar }}jar archives sourcesJar archives javadocJar }}
convention.gradleconvention.gradle
apply plugin: 'maven'apply plugin: 'signing'signing { sign configurations.archives}task uploadMavenCentral(type:Upload) {configuration = configurations.archivesdependsOn signArchivesdoFirst.repositories.mavenDeployer {beforeDeployment { signing.signPom(it) }repository(url: 'http://oss.sonatype.org/services/local/staging/deploy/maven2/') {authentication(userName: rroject.sonatypeUsername, password: project.sonatypePassword)}pom.project {url "https://github.com/Netflix/${project.githubName}"...
}}
}}}}}}
maven.gradlemaven.gradle
apply from: 'apply from: 'http://artifacts.netflix.com/gradle-netflix-local/artifactory.gradle'http://artifacts.netflix.com/gradle-netflix-local/artifactory.gradle'
netflix-oss.gradlenetflix-oss.gradle
gradle-templategradle-template• Be as visible as possibleBe as visible as possible
• Meant to be synced with (#git #ftw)Meant to be synced with (#git #ftw)
• Templates for multiple-module and single-Templates for multiple-module and single-module projectsmodule projects
• Used by other companiesUsed by other companies
• https://github.com/Netflix/gradle-templatehttps://github.com/Netflix/gradle-template
Phase 2: Full BuildPhase 2: Full Build• Release plugin [gradle-release]Release plugin [gradle-release]
• Publish snapshots, candidates and releasesPublish snapshots, candidates and releases
• Simpler signing in JenkinsSimpler signing in Jenkins
• License and Copyright Headers [license-License and Copyright Headers [license-gradle-plugin]gradle-plugin]
• Any plugins in BintrayAny plugins in Bintray
• Publishing JavadocPublishing Javadoc
• More code quality checksMore code quality checks
Continuous IntegrationContinuous Integration• Jenkins InternallyJenkins Internally
• Performs releasesPerforms releases
• Has KeysHas Keys
• Access to AWSAccess to AWS
• CloudBees DEV@CLOUD ExternallyCloudBees DEV@CLOUD Externally
• Builds Pull RequestsBuilds Pull Requests
• Shows Code Quality MetricsShows Code Quality Metrics
Problem AreasProblem Areas• Java plugin required for conf2scope mappings Java plugin required for conf2scope mappings
to workto work
• Java plugin resets status [GRADLE-2087]Java plugin resets status [GRADLE-2087]
• Parent poms caused problems, but aren’t Parent poms caused problems, but aren’t neededneeded
• Sonatype username/passwordSonatype username/password
• Signing keys needed locally with special Signing keys needed locally with special propertiesproperties
• Not all plugins were availableNot all plugins were available
FutureFuture• Roll features into pluginsRoll features into plugins
• Merge with internal buildMerge with internal build
• Hire more engineers to work on GradleHire more engineers to work on Gradle
@quidryan@quidryan @quidryan@quidryanhttp://www.slideshare.net/quidryanhttp://www.slideshare.net/quidryan
Thank YouThank YouQuestions?Questions?
@netflixoss #cloudprize@netflixoss #cloudprize