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

Bootstrapping Your Org's CI and CD with Gradle

Bootstrapping Your Org's CI and CD with Gradle

Use Gradle to create a custom, tailored solution for your company's projects.

Does your company have multiple projects all based on the same framework? Do you want to enforce certain testing policies or code style across all your projects? Learn how to utilize Gradle and custom plugins to create a standard continuous integration and deployment environment from your company. We'll cover versioning, testing, static analysis and artifact publication.

John Engelman

June 12, 2015
Tweet

More Decks by John Engelman

Other Decks in Technology

Transcript

  1. John Engelman • Chief Technologist @ OPI • Ratpack Core

    Team • Author - Shadow Plugin • @johnrengelman • github.com/johnrengelman
  2. What is “bootstrapping”? • Going from 0 to 60 in

    4.4s • Providing a consistent set of sane configurations • Ensure the important things are ALWAYS there
  3. • Script Plugins • Quickly try new settings • Share

    using a hosted location • Packaged Library • If you need to include additional resources
  4. Good Things to Bootstrap • Versioning • IDE integration •

    Dependency Repositories • Testing/Static Analysis • Artifacts/Publishing • Credentials
  5. Gradle Project DSL It’s your friend. Read it. Use it.

    https://docs.gradle.org/current/dsl/org.gradle.api.Project.html
  6. 
 project.plugins.withType(JavaPlugin) {
 //Do stuff if Java has been added


    }
 
 project.plugins.withId('com.github.johnrengelman.shadow') {
 //Do stuff if Shadow has been added
 }
  7. 
 // Create codenarc.groovy file if missing
 File rules =

    new File("${project.rootDir}/gradle/codenarc.groovy")
 if (!rules.exists()) {
 rules.parentFile.mkdirs()
 rules.withWriter { BufferedWriter writer ->
 writer.write this.class.getResourceAsStream( "/${rules.name}").text
 }
 }
 } • Template standard files
  8. 
 project.gradle.taskGraph.whenReady { TaskExecutionGraph taskGraph ->
 project.tasks.withType(PublishToMavenRepository).matching { PublishToMavenRepository task

    ->
 task.repository.name == 'Demo'
 }.each { PublishToMavenRepository publishTask ->
 if (taskGraph.hasTask(publishTask)) {
 PasswordCredentials creds = publishTask.repository.credentials
 Map userCreds = getCredentials(project)
 creds.username = userCreds.username
 creds.password = userCreds.password
 }
 }
 } • Lookup and apply Credentials only when needed
  9. • Clone a template repo to start • Lazybones •

    https://github.com/pledbrook/lazybones • Yeoman • http://yeoman.io/ • Init Scripts • https://docs.gradle.org/current/userguide/init_scripts.html • Customized Gradle Distribution using Gradle Wrapper
  10. //buildSrc/build.gradle apply plugin: 'groovy' if (!project.plugins.collect { it.class.name }.any {

    it.endsWith(‘JetGradlePlugin') }) {
 sourceSets {
 main {
 groovy.srcDirs = ['src/main/groovy', '../src/main/groovy']
 resources.srcDirs = [‘../src/main/resources'] 
 }
 }
 }

  11. //buildSrc/build.gradle class ScriptHolder {
 Closure dependencies
 
 void dependencies(Closure c)

    { this.dependencies = c }
 void apply(Map map) {}
 } 
 ScriptHolder holder = new ScriptHolder()
 CompilerConfiguration cc = new CompilerConfiguration()
 cc.setScriptBaseClass(DelegatingScript.class.name)
 GroovyShell sh = new GroovyShell(Project.class.classLoader, new Binding(), cc)
  12. //buildSrc/build.gradle
 
 //Use this parse command because Groovy wants to

    use the file name as the classname which fails due to the '-'
 DelegatingScript script = (DelegatingScript)sh.parse( file('../gradle-plugins.gradle').text, 'GradlePlugins')
 script.setDelegate(holder)
 script.run()
 
 def closure = holder.dependencies.clone()
 closure.delegate = project.dependencies
 closure()