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.

99ef9646867e17df7d846aa9c06652a5?s=128

John Engelman

June 12, 2015
Tweet

Transcript

  1. Bootstrapping Continuous Integration & Deployment

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

    Team • Author - Shadow Plugin • @johnrengelman • github.com/johnrengelman
  3. What is “bootstrapping”?

  4. None
  5. 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
  6. Java Groovy Codenarc Spring Boot Application Shadow Organization Rules/Conventions MyOrg.Service

    Core & 3rd Party Plugins Organization Plugins
  7. Where to start?

  8. • Script Plugins • Quickly try new settings • Share

    using a hosted location • Packaged Library • If you need to include additional resources
  9. https://github.com/nebula-plugins

  10. Good Things to Bootstrap • Versioning • IDE integration •

    Dependency Repositories • Testing/Static Analysis • Artifacts/Publishing • Credentials
  11. Things you might bootstrap • Common library versions (spock, joda-time,

    groovy)
  12. Gradle Project DSL It’s your friend. Read it. Use it.

    https://docs.gradle.org/current/dsl/org.gradle.api.Project.html
  13. • Make liberal use of PluginContainer • React to other

    plugins
  14. 
 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
 }
  15. 
 project.ext.isSnapshot = project.version.toString().endsWith(‘-SNAPSHOT') 
 project.ext.buildNumber = System.getenv('BUILD_NUMBER')
 project.ext.isCI =

    System.getenv('JENKINS_HOME') != null • Utilize Extra Properties for flags
  16. 
 // 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
  17. • Determine Version

  18. 
 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
  19. Bootstrapping Build Settings • Some things can’t be configured by

    plugins • buildscript • settings.gradle
  20. • 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
  21. Bootstrapping Plugin Project

  22. Plugin Project Applies Defines

  23. //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'] 
 }
 }
 }

  24. //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)
  25. //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()
  26. Questions?

  27. Thank you!