lightweight developer provisioning with gradle and seu as-code

37
Lightweight Developer Provisioning with Gradle and SEU-as-code | JavaOne 2016 | task seuAsCode() << { println "created with and by @LeanderReimer" } 1

Upload: qaware-gmbh

Post on 08-Jan-2017

65 views

Category:

Data & Analytics


0 download

TRANSCRIPT

Page 1: Lightweight developer provisioning with gradle and seu as-code

Lightweight Developer

Provisioning with Gradle

and SEU-as-code| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 1

Page 2: Lightweight developer provisioning with gradle and seu as-code

About me

Mario-Leander ReimerChief Technologist, QAware [email protected]

twitter://@LeanderReimerhttp://speakerdeck.com/lreimerhttp://github.com/lreimerhttp://github.com/seu-as-codehttp://seu-as-code.iohttp://www.qaware.de

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 2

Page 3: Lightweight developer provisioning with gradle and seu as-code

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 3

Page 4: Lightweight developer provisioning with gradle and seu as-code

SEU: a German acronym;software development environment

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 4

Page 5: Lightweight developer provisioning with gradle and seu as-code

Definition of Software Industrialization

• This has nothing to do with cheap labor!

• Automation of repetitive and laborious tasks

• Better software quality through standardized, streamlined tooling

• Well integrated tool chain leads to a higher productivity and happiness of your team

• Better cost efficiency and competitiveness

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 5

Page 6: Lightweight developer provisioning with gradle and seu as-code

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 6

Page 7: Lightweight developer provisioning with gradle and seu as-code

The ideal.

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 7

Page 8: Lightweight developer provisioning with gradle and seu as-code

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 8

Page 9: Lightweight developer provisioning with gradle and seu as-code

The reality?

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 9

Page 10: Lightweight developer provisioning with gradle and seu as-code

What are the problems?

• Manual and error prone creation and update procedure of individual SEUs

• Individual SEUs produce different results and strange bugs

• Old versions of a SEU can't easily be restored

• The SEU for a new project is often a copy of a

previous project. ! Broken windows! !

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 10

Page 11: Lightweight developer provisioning with gradle and seu as-code

The solution ...

• Use a build tool for the automated creation and update of a SEU

• Software packages are expressed as dependencies

• Gradle tasks and Groovy are used instead of shell scripting

• Everything is version controlled just like ordinary source code

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 11

Page 12: Lightweight developer provisioning with gradle and seu as-code

Demo.

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 12

Page 13: Lightweight developer provisioning with gradle and seu as-code

The most minimalistic SEU

plugins { id 'de.qaware.seu.as.code.base' version '2.4.0'}

seuAsCode { seuHome = 'J:' projectName = 'JavaOne 2016'}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 13

Page 14: Lightweight developer provisioning with gradle and seu as-code

Multi platform SEUs for mixed teams

plugins { id 'de.qaware.seu.as.code.base' version '2.4.0'}

import static de.qaware.seu.as.code.plugins.base.Platform.isMac

seuAsCode { // use closure or Elvis operator (no syntax highlighting :( seuHome = { if (isMac()) '/Volumes/JavaOne-2016' else 'J:' } projectName = 'JavaOne 2016'}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 14

Page 15: Lightweight developer provisioning with gradle and seu as-code

Software packages are dependencies

• Gradle has built-in support for dependencies

• Gradle supports different artifact repositories (Maven, Ivy, Directory)

• Transitive dependencies between software packages are supported

• Use dependency configurations to determine installation directory

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 15

Page 16: Lightweight developer provisioning with gradle and seu as-code

Software dependencies and configurations

repositories {

maven { url 'https://dl.bintray.com/seu-as-code/maven' }

jcenter()

}

dependencies {

seuac 'org.codehaus.groovy.modules.scriptom:scriptom:1.6.0'

seuac 'com.h2database:h2:1.4.188'

home 'de.qaware.seu.as.code:seuac-home:2.4.0'

software 'de.qaware.seu.as.code:seuac-environment:2.4.0:jdk8'

software 'org.gradle:gradle:2.14.1'

software "net.java:openjdk8:8u40:$osClassifier"

}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 16

Page 17: Lightweight developer provisioning with gradle and seu as-code

Secure passwords with Credentials plugin

plugins { id 'de.qaware.seu.as.code.credentials' version '2.4.0' }

repositories {

maven {

url 'https://your.company.com/nexus/repo'

credentials {

// access stored credentials via extra property

username project.credentials['Nexus'].username

password project.credentials['Nexus'].password

}

}

}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 17

Page 18: Lightweight developer provisioning with gradle and seu as-code

Platform plugin for OS specific builds

plugins { id 'de.qaware.seu.as.code.platform' version '1.0.0' }

platform { win { task helloSeuAsCode(group: 'Example') << { println 'Hello SEU-as-code on Windows.' } } mac { task helloSeuAsCode(group: 'Example') << { println 'Hello SEU-as-code on MacOS.' } }}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 18

Page 19: Lightweight developer provisioning with gradle and seu as-code

Manage sources with Git or SVN plugin

plugins { id 'de.qaware.seu.as.code.credentials' version '2.4.0' id 'de.qaware.seu.as.code.git' version '2.3.0'}

git { plugins { url 'https://github.com/seu-as-code/seu-as-code.plugins.git' directory file("$seuHome/codebase/plugins/") username project.credentials['Github'].username password project.credentials['Github'].password }}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 19

Page 20: Lightweight developer provisioning with gradle and seu as-code

Manage sources with Git or SVN plugin

plugins { id 'de.qaware.seu.as.code.credentials' version '2.4.0' id 'de.qaware.seu.as.code.svn' version '2.1.1'}

subversion { usersGuide { url 'https://github.com/seu-as-code/seu-as-code.users-guide.git' directory file("$seuHome/docbase/users-guide/") username project.credentials['Subversion'].username password project.credentials['Subversion'].password }}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 20

Page 21: Lightweight developer provisioning with gradle and seu as-code

Implement scripts using plain Gradle

• Gradle build scripts are code! Be creative.

• Gradle provides useful predefined tasks: Copy, Exec, Sync, Delete, ...

• Gradle tasks can easily reuse Ant tasks.

• Gradle tasks can be implemented in Groovy code.

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 21

Page 22: Lightweight developer provisioning with gradle and seu as-code

Example 1: Init and delete Derby DB

ext.derbyHome = System.env['DERBY_HOME']

// import SQL file via the provided Derby command line tooltask initDemoDb(type: Exec, group: 'Database') { workingDir "$derbyHome/bin" commandLine 'cmd', '/B', '/C', 'ij.bat', "$rootDir/scripts/init.sql"}

task deleteDemoDb(type: Delete, group: 'Database') { delete "$derbyHome/demo"}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 22

Page 23: Lightweight developer provisioning with gradle and seu as-code

Example 1: The Groovy SQL way

import groovy.sql.*

task initDemoDb(group: 'Database') << {

def derby = [

url: 'jdbc:derby://localhost:1527/demo;create=true',

driver: 'org.apache.derby.jdbc.ClientDriver',

user: 'admin',

password: 'secret'

]

Sql.withInstance(derby) {

execute file("$rootDir/scripts/database/init.sql").text

}

}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 23

Page 24: Lightweight developer provisioning with gradle and seu as-code

Example 2: Restore Solr index data

ext.cores = ['de_DE', 'en_GB', 'zh_CN']

task solrRestoreAll(group: 'Solr') { }

cores.each { coreName -> def name = coreName.replaceAll("_", "").capitalize()

task "solrRestore${name}"(type: Sync, group: 'Solr') { from zipTree("$rootDir/scripts/solr/${coreName}.zip") into "$seuHome/software/solr-4.7.2/example/solr/${coreName}" }

solrRestoreAll.dependsOn "solrRestore${name}"}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 24

Page 25: Lightweight developer provisioning with gradle and seu as-code

Don't use shell scripts. Use

Gradle instead!

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 25

Page 26: Lightweight developer provisioning with gradle and seu as-code

Building software packages is easy

• Software packages are essentially plain JAR files (software + customizations)

• 26 packages available via a Bintray repository https://bintray.com/seu-as-code/maven

• 44 package build blue-prints are available at Github, continuously growing.

• Software packages can be build with Gradle!

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 26

Page 27: Lightweight developer provisioning with gradle and seu as-code

Let's build our first package using Gradle!

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 27

Page 28: Lightweight developer provisioning with gradle and seu as-code

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 28

Page 29: Lightweight developer provisioning with gradle and seu as-code

Download the original binary distribution

plugins {

id 'de.undercouch.download' version '1.2'

}

import de.undercouch.gradle.tasks.download.Download

task downloadArchive(type: Download) {

src 'https://services.gradle.org/distributions/gradle-3.0-all.zip'

dest "$buildDir"

}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 29

Page 30: Lightweight developer provisioning with gradle and seu as-code

Unpack archive using simple Gradle task

task extractArchive(type: Copy, dependsOn: downloadArchive) { from { zipTree("$buildDir/${project.name}-${version}-all.zip") } into "$buildDir/files"}

// Best practice: directory name matches the package name// optionally rename the extracted directory if required

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 30

Page 31: Lightweight developer provisioning with gradle and seu as-code

Customize with additional files and hooks

// plain Groovy, place as a file under META-INF/hooks/

import org.codehaus.groovy.scriptom.*

Scriptom.inApartment{ def wshShell = new ActiveXObject("WScript.Shell") def shortcut = wshShell.CreateShortcut("$seuHome\\gradle.lnk") shortcut.TargetPath = "${seuLayout.software}\\go-gradle.bat" shortcut.WorkingDirectory = "${seuLayout.codebase}" shortcut.Save()}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 31

Page 32: Lightweight developer provisioning with gradle and seu as-code

Repackage all files as a normal JAR file

task buildPackage(type: Jar, dependsOn: extractArchive) { baseName project.name version version extension 'jar' // classifier 'x86' destinationDir buildDir from "$buildDir/files" // the extracted files from "files" // some extra files}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 32

Page 33: Lightweight developer provisioning with gradle and seu as-code

Publish JAR artifact to a repository server

publishing {

publications {

gradle(MavenPublication) {

artifact "${buildDir}/${project.name}-${version}.jar"

}

}

repositories {

maven {

// alternatively, use your private company repository server

url 'https://bintray.com/seu-as-code/maven'

credentials { ... }

}

}

}

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 33

Page 34: Lightweight developer provisioning with gradle and seu as-code

What's next?

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 34

Page 35: Lightweight developer provisioning with gradle and seu as-code

More features to come ...

• Continuously add more software packages

• Create plugin to build software packages

• Support for self-downloading packages

• Add support for other package managers

• Add Vault support for Credentials plugin

• Improve documentation and user’s guide

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 35

Page 36: Lightweight developer provisioning with gradle and seu as-code

Star SEU-as-code on Github!

$ git clone https://github.com/seu-as-code/seu-as-code.archetype.git

$ git clone https://github.com/seu-as-code/seu-as-code.plugins.git

$ git clone https://github.com/seu-as-code/seu-as-code.packages.git

$ git clone https://github.com/seu-as-code/seu-as-code.examples.git

$ git clone https://github.com/seu-as-code/seu-as-code.documentation.git

$ git clone https://github.com/seu-as-code/seu-as-code.users-guide.git

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 36

Page 37: Lightweight developer provisioning with gradle and seu as-code

Q & A

| JavaOne 2016 | task seuAsCode() << { println "created with ❤ and ☕ by @LeanderReimer" } 37