Building a Continuous Delivery with Gradle and Jenkins
description
Transcript of Building a Continuous Delivery with Gradle and Jenkins
![Page 1: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/1.jpg)
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Continuous Delivery with Gradle and Jenkins
By Peter Niederwieser
![Page 2: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/2.jpg)
Releases don’t have to be painful
![Page 3: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/3.jpg)
Con4nuous Delivery
Deliver so8ware fast and frequently
![Page 4: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/4.jpg)
#1 Every commit can result in a release
![Page 5: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/5.jpg)
#1 Every commit can result in a release
#2 Automate everything!
![Page 6: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/6.jpg)
#1 Every commit can result in a release
#2 Automate everything!
#3 Automated tests are essen4al
![Page 7: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/7.jpg)
#1 Every commit can result in a release
#2 Automate everything!
#3 Automated tests are essen4al
#4 Done means released
![Page 8: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/8.jpg)
Build pipeline
Automated manifesta4on of delivery process
![Page 9: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/9.jpg)
Build quality in!
Establish automated quality gates
![Page 10: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/10.jpg)
Compile/Unit Tests
![Page 11: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/11.jpg)
Compile/Unit Tests
Integra4on Tests
![Page 12: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/12.jpg)
Compile/Unit Tests
Integra4on Tests
Code Analysis
![Page 13: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/13.jpg)
Test
Compile/Unit Tests
Integra4on Tests
Code Analysis
Package/Deploy
![Page 14: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/14.jpg)
Test
Compile/Unit Tests
Integra4on Tests
Code Analysis
Package/Deploy
Acceptance Tests
![Page 15: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/15.jpg)
Test
Compile/Unit Tests
Integra4on Tests
Code Analysis
Package/Deploy
UAT
Acceptance Tests
![Page 16: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/16.jpg)
Test
Compile/Unit Tests
Integra4on Tests
Code Analysis
Package/Deploy
UAT Prod
Acceptance Tests
![Page 17: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/17.jpg)
!
![Page 18: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/18.jpg)
! But how?
![Page 19: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/19.jpg)
The “revolu4onary” sample applica4on
Internet To Do applicationBrowser Data
store
Writes
Reads
![Page 20: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/20.jpg)
Mul4-‐project dependencies
Model
Web Repository
dependdepend
depend
![Page 21: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/21.jpg)
Project hierarchytodo
model
repository
build.gradle
settings.gradle
web
build.gradle
build.gradle
build.gradle
gradle
wrapper
xyz.gradle
gradlew
gradlew.bat
![Page 22: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/22.jpg)
Project hierarchytodo
model
repository
build.gradle
settings.gradle
web
build.gradle
build.gradle
build.gradle
gradle
wrapper
xyz.gradle
gradlew
gradlew.bat
![Page 23: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/23.jpg)
Project hierarchytodo
model
repository
build.gradle
settings.gradle
web
build.gradle
build.gradle
build.gradle
gradle
wrapper
xyz.gradle
gradlew
gradlew.bat
Define project-‐specific behavior
![Page 24: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/24.jpg)
Project hierarchy
include 'model'include 'repository'include 'web'
settings.gradle
Defines which projects are taking part in the build
todo
model
repository
build.gradle
settings.gradle
web
build.gradle
build.gradle
build.gradle
gradle
wrapper
xyz.gradle
gradlew
gradlew.bat
![Page 25: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/25.jpg)
Project hierarchytodo
model
repository
build.gradle
settings.gradle
web
build.gradle
build.gradle
build.gradle
gradle
wrapper
xyz.gradle
gradlew
gradlew.bat
Always use Wrapper to execute the build!
![Page 26: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/26.jpg)
Project hierarchytodo
model
repository
build.gradle
settings.gradle
web
build.gradle
build.gradle
build.gradle
gradle
wrapper
xyz.gradle
gradlew
gradlew.bat
Externalize concerns into script plugins and organize them in dedicated directory
![Page 27: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/27.jpg)
Project hierarchytodo
model
repository
build.gradle
settings.gradle
web
build.gradle
build.gradle
build.gradle
gradle
wrapper
xyz.gradle
gradlew
gradlew.bat
Externalize concerns into script plugins and organize them in dedicated directory
Examples: !! Versioning strategy ! Integra4on and func4onal test setup ! Deployment func4onality ! ...
![Page 28: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/28.jpg)
Project ar4facts
rootproject
modelproject
repositoryproject
webproject
JAR
JAR
WAR
![Page 29: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/29.jpg)
Project ar4facts
rootproject
modelproject
repositoryproject
webproject
JAR
JAR
WAR
Deployable ar4fact
![Page 30: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/30.jpg)
Stages in build pipeline
Acceptance stage
Functional tests
PublishBinaries
Commit stage
DeployBinaries
UAT
DeployBinaries
Production
IntegrationTests
Code Analysis
AssembleDistribution
CompileUnit Tests
RetrieveBinaries
DeployBinaries
Asserts that system works at a technical level
![Page 31: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/31.jpg)
Stages in build pipeline
Acceptance stage
Functional tests
PublishBinaries
Commit stage
DeployBinaries
UAT
DeployBinaries
Production
IntegrationTests
Code Analysis
AssembleDistribution
CompileUnit Tests
RetrieveBinaries
DeployBinaries
Asserts that system works on a func4onal/non-‐func4onal level
![Page 32: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/32.jpg)
Stages in build pipeline
Acceptance stage
Functional tests
PublishBinaries
Commit stage
DeployBinaries
UAT
DeployBinaries
Production
IntegrationTests
Code Analysis
AssembleDistribution
CompileUnit Tests
RetrieveBinaries
DeployBinaries
Trigger manuallyTrigger manually
![Page 33: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/33.jpg)
Commit stage: Compile/unit tests
Rapid feedback (< 5 mins)
Run on every VCS check-‐in
Priority: fix broken build
PublishBinaries
Commit stage
CompileUnit Tests
IntegrationTests
Code Analysis
AssembleDistribution
![Page 34: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/34.jpg)
Commit stage: Integra4on tests
Longer running tests
Require environment setup
Harder to maintain
PublishBinaries
Commit stage
CompileUnit Tests
IntegrationTests
Code Analysis
AssembleDistribution
![Page 35: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/35.jpg)
Separate tests in project layout
todo
model
repository
web
src
integTest
java
main
java
test
java
Produc4on Java sources
Unit test Java sources
![Page 36: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/36.jpg)
Separate tests in project layout
todo
model
repository
web
src
integTest
java
main
java
test
java
Integra4on test Java sources
Produc4on Java sources
Unit test Java sources
![Page 37: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/37.jpg)
Separate tests with SourceSets
sourceSets { integrationTest { java.srcDir file('src/integTest/java') resources.srcDir file('src/integTest/resources') compileClasspath = sourceSets.main.output + configurations.testRuntime runtimeClasspath = output + compileClasspath } } !task integrationTest(type: Test) { description = 'Runs the integration tests.' group = 'verification' testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath testResultsDir = file("$testResultsDir/integration") }
![Page 38: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/38.jpg)
Separate tests with SourceSets
sourceSets { integrationTest { java.srcDir file('src/integTest/java') resources.srcDir file('src/integTest/resources') compileClasspath = sourceSets.main.output + configurations.testRuntime runtimeClasspath = output + compileClasspath } } !task integrationTest(type: Test) { description = 'Runs the integration tests.' group = 'verification' testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath testResultsDir = file("$testResultsDir/integration") }
Set source and resources directory
![Page 39: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/39.jpg)
Separate tests with SourceSets
sourceSets { integrationTest { java.srcDir file('src/integTest/java') resources.srcDir file('src/integTest/resources') compileClasspath = sourceSets.main.output + configurations.testRuntime runtimeClasspath = output + compileClasspath } } !task integrationTest(type: Test) { description = 'Runs the integration tests.' group = 'verification' testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath testResultsDir = file("$testResultsDir/integration") }
Set source and resources directory
Set compile and run4me classpath
![Page 40: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/40.jpg)
Separate tests with SourceSets
sourceSets { integrationTest { java.srcDir file('src/integTest/java') resources.srcDir file('src/integTest/resources') compileClasspath = sourceSets.main.output + configurations.testRuntime runtimeClasspath = output + compileClasspath } } !task integrationTest(type: Test) { description = 'Runs the integration tests.' group = 'verification' testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath testResultsDir = file("$testResultsDir/integration") }
Custom test results directory
Set source and resources directory
Set compile and run4me classpath
![Page 41: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/41.jpg)
Separate tests with SourceSets
sourceSets { integrationTest { java.srcDir file('src/integTest/java') resources.srcDir file('src/integTest/resources') compileClasspath = sourceSets.main.output + configurations.testRuntime runtimeClasspath = output + compileClasspath } } !task integrationTest(type: Test) { description = 'Runs the integration tests.' group = 'verification' testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath testResultsDir = file("$testResultsDir/integration") }
Custom test results directory
Set source and resources directory
Set compile and run4me classpath
gradlew integrationTest
![Page 42: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/42.jpg)
Database integra4on tests
stopDatabasetest start
Databasebuild
Schemaintegration
Test check build...
![Page 43: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/43.jpg)
Database integra4on tests
stopDatabasetest start
Databasebuild
Schemaintegration
Test check build...
![Page 44: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/44.jpg)
Database integra4on tests
apply from: "$rootDir/gradle/databaseSetup.gradle" !integrationTest.dependsOn startAndPrepareDatabase integrationTest.finalizedBy stopDatabase !check.dependsOn integrationTest
stopDatabasetest start
Databasebuild
Schemaintegration
Test check build...
![Page 45: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/45.jpg)
Database integra4on tests
apply from: "$rootDir/gradle/databaseSetup.gradle" !integrationTest.dependsOn startAndPrepareDatabase integrationTest.finalizedBy stopDatabase !check.dependsOn integrationTest
stopDatabasetest start
Databasebuild
Schemaintegration
Test check build...
Separate complex setup logic into script plugin
![Page 46: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/46.jpg)
Database integra4on tests
apply from: "$rootDir/gradle/databaseSetup.gradle" !integrationTest.dependsOn startAndPrepareDatabase integrationTest.finalizedBy stopDatabase !check.dependsOn integrationTest
stopDatabasetest start
Databasebuild
Schemaintegration
Test check build...
Separate complex setup logic into script plugin
Integrate tasks into build lifecycle
![Page 47: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/47.jpg)
Picking the “right” code coverage tool
![Page 48: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/48.jpg)
Picking the “right” code coverage tool
Cobertura Offline bytecode instrumenta4on
![Page 49: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/49.jpg)
Picking the “right” code coverage tool
Cobertura Offline bytecode instrumenta4on
Offline bytecode instrumenta4on
![Page 50: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/50.jpg)
Picking the “right” code coverage tool
Cobertura Offline bytecode instrumenta4on
Source code instrumenta4on
Offline bytecode instrumenta4on
![Page 51: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/51.jpg)
Picking the “right” code coverage tool
Cobertura Offline bytecode instrumenta4on
Source code instrumenta4on
Offline bytecode instrumenta4on
On-‐the-‐fly bytecode instrumenta4on
![Page 52: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/52.jpg)
On-‐the-‐fly bytecode instrumenta4on
No modifica4on to source or bytecode
![Page 53: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/53.jpg)
Code coverage with JaCoCo
apply plugin: "jacoco"!task jacocoIntegrationTestReport(type: JacocoReport) { sourceSets sourceSets.main executionData integTest}
![Page 54: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/54.jpg)
Code coverage with JaCoCo
apply plugin: "jacoco"!task jacocoIntegrationTestReport(type: JacocoReport) { sourceSets sourceSets.main executionData integTest}
Apply JaCoCo plugin
![Page 55: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/55.jpg)
Code coverage with JaCoCo
apply plugin: "jacoco"!task jacocoIntegrationTestReport(type: JacocoReport) { sourceSets sourceSets.main executionData integTest}
Apply JaCoCo plugin
Also report code coverage for integra4on tests
![Page 56: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/56.jpg)
Genera4ng coverage reports
test integrationTest
... ... .exec
![Page 57: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/57.jpg)
Genera4ng coverage reports
test integrationTest
... ... .exec
jacocoTestReport
jacocoIntegrationTestReport
.exec .html
![Page 58: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/58.jpg)
Genera4ng coverage reports
test integrationTest
... ... .exec
jacocoTestReport
jacocoIntegrationTestReport
.exec .html
.html
![Page 59: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/59.jpg)
Commit stage: Code analysis
PublishBinaries
Commit stage
CompileUnit Tests
IntegrationTests
Code Analysis
AssembleDistribution
Perform code health check
Fail build for low quality
Record progress over 4me
![Page 60: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/60.jpg)
Sta4c code analysis tools
Checkstyle
FindBugs
apply plugin: 'pmd' pmd { ignoreFailures = true } tasks.withType(Pmd) { reports { xml.enabled = false html.enabled = true } }
apply plugin: 'jdepend’ jdepend { toolVersion = '2.9.1' ignoreFailures = true }
gradlew check
![Page 61: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/61.jpg)
Measure quality over 4me with Sonar
Sonardatabase
Gradle
Sonar Runner
root
model
repo.
web
analyzes
publishes reads / writes
Gradle project
![Page 62: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/62.jpg)
Applying the Sonar Runner plugin
apply plugin: "sonar-runner"!sonarRunner { sonarProperties { property "sonar.host.url", "http://my.server.com" property "sonar.jdbc.url", "jdbc:mysql://my.server.com/sonar" property "sonar.jdbc.driverClassName", "com.mysql.jdbc.Driver" property "sonar.jdbc.username", "Fred Flintstone" property "sonar.jdbc.password", "very clever" }}!subprojects { sonarRunner { sonarProperties { property "sonar.sourceEncoding", "UTF-8" } }}
gradlew sonarRunner
![Page 63: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/63.jpg)
![Page 64: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/64.jpg)
Commit stage: Assemble distribu4on
Exclude env. configura4on
Include build informa4on
Choose versioning strategy
PublishBinaries
Commit stage
CompileUnit Tests
IntegrationTests
Code Analysis
AssembleDistribution
![Page 65: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/65.jpg)
Versioning strategy
1.0-‐SNAPSHOT 1.0
during development when released
…the Maven way
Change version with Maven Release plugin
![Page 66: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/66.jpg)
Versioning strategy
1.0.134 1.0.134
during development when released
…the Con4nuous Delivery way
1.0.134Jenkins build numberProject version number
![Page 67: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/67.jpg)
Versioning strategy…implemented with Gradle
allprojects { apply from: "$rootDir/gradle/versioning.gradle" }
todo
model
repository
build.gradle
settings.gradle
web
gradle
versioning.gradle Contains version implementa4on
![Page 68: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/68.jpg)
Versioning strategy…implemented with Gradle
ext.buildTimestamp = new Date().format('yyyy-MM-dd HH:mm:ss') version = new ProjectVersion(1, 0, System.env.SOURCE_BUILD_NUMBER) class ProjectVersion { Integer major Integer minor String build ProjectVersion(Integer major, Integer minor, String build) { this.major = major this.minor = minor this.build = build } @Override String toString() { String fullVersion = "$major.$minor" if(build) { fullVersion += ".$build” } fullVersion } }
![Page 69: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/69.jpg)
Versioning strategy…implemented with Gradle
ext.buildTimestamp = new Date().format('yyyy-MM-dd HH:mm:ss') version = new ProjectVersion(1, 0, System.env.SOURCE_BUILD_NUMBER) class ProjectVersion { Integer major Integer minor String build ProjectVersion(Integer major, Integer minor, String build) { this.major = major this.minor = minor this.build = build } @Override String toString() { String fullVersion = "$major.$minor" if(build) { fullVersion += ".$build” } fullVersion } }
Jenkins Build Number
![Page 70: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/70.jpg)
Versioning strategy…implemented with Gradle
ext.buildTimestamp = new Date().format('yyyy-MM-dd HH:mm:ss') version = new ProjectVersion(1, 0, System.env.SOURCE_BUILD_NUMBER) class ProjectVersion { Integer major Integer minor String build ProjectVersion(Integer major, Integer minor, String build) { this.major = major this.minor = minor this.build = build } @Override String toString() { String fullVersion = "$major.$minor" if(build) { fullVersion += ".$build” } fullVersion } }
Jenkins Build Number
Builds version String representa4on
![Page 71: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/71.jpg)
Packaging the deployable ar4fact
project(':web') { apply plugin: 'war' task createBuildInfoFile << { def buildInfoFile = new File("$buildDir/build-info.properties") Properties props = new Properties() props.setProperty('version', project.version.toString()) props.setProperty('timestamp', project.buildTimestamp) props.store(buildInfoFile.newWriter(), null) } war { dependsOn createBuildInfoFile baseName = 'todo' from(buildDir) { include 'build-info.properties' into('WEB-INF/classes') } } }
![Page 72: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/72.jpg)
Packaging the deployable ar4fact
project(':web') { apply plugin: 'war' task createBuildInfoFile << { def buildInfoFile = new File("$buildDir/build-info.properties") Properties props = new Properties() props.setProperty('version', project.version.toString()) props.setProperty('timestamp', project.buildTimestamp) props.store(buildInfoFile.newWriter(), null) } war { dependsOn createBuildInfoFile baseName = 'todo' from(buildDir) { include 'build-info.properties' into('WEB-INF/classes') } } }
Creates file containing build informa4on
![Page 73: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/73.jpg)
Packaging the deployable ar4fact
project(':web') { apply plugin: 'war' task createBuildInfoFile << { def buildInfoFile = new File("$buildDir/build-info.properties") Properties props = new Properties() props.setProperty('version', project.version.toString()) props.setProperty('timestamp', project.buildTimestamp) props.store(buildInfoFile.newWriter(), null) } war { dependsOn createBuildInfoFile baseName = 'todo' from(buildDir) { include 'build-info.properties' into('WEB-INF/classes') } } }
Creates file containing build informa4on
Include build info file Into WAR distribu4on
![Page 74: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/74.jpg)
Packaging the deployable ar4fact
project(':web') { apply plugin: 'war' task createBuildInfoFile << { def buildInfoFile = new File("$buildDir/build-info.properties") Properties props = new Properties() props.setProperty('version', project.version.toString()) props.setProperty('timestamp', project.buildTimestamp) props.store(buildInfoFile.newWriter(), null) } war { dependsOn createBuildInfoFile baseName = 'todo' from(buildDir) { include 'build-info.properties' into('WEB-INF/classes') } } }
Creates file containing build informa4on
Include build info file Into WAR distribu4on
gradlew assemble
![Page 75: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/75.jpg)
Commit stage: Publish binaries
Version ar4fact(s)
Use binary repository
Publish once, then reuse
PublishBinaries
Commit stage
CompileUnit Tests
IntegrationTests
Code Analysis
AssembleDistribution
![Page 76: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/76.jpg)
Publishing the deployable ar4fact
1.0.34
1.0.32 1.0.33 1.0.34
![Page 77: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/77.jpg)
Defining build configura4onbinaryRepository { url = 'http://mycompany.bin.repo:8081/artifactory' username = 'admin' password = 'password' name = 'libs-release-local' } environments { test { server { hostname = 'mycompany.test' port = 8099 context = 'todo' username = 'manager' password = 'manager' } } uat { server { hostname = 'mycompany.uat' port = 8199 context = 'todo' username = 'manager' password = 'manager' } } ...
![Page 78: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/78.jpg)
Defining build configura4onbinaryRepository { url = 'http://mycompany.bin.repo:8081/artifactory' username = 'admin' password = 'password' name = 'libs-release-local' } environments { test { server { hostname = 'mycompany.test' port = 8099 context = 'todo' username = 'manager' password = 'manager' } } uat { server { hostname = 'mycompany.uat' port = 8199 context = 'todo' username = 'manager' password = 'manager' } } ...
Common configura4on
![Page 79: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/79.jpg)
Defining build configura4onbinaryRepository { url = 'http://mycompany.bin.repo:8081/artifactory' username = 'admin' password = 'password' name = 'libs-release-local' } environments { test { server { hostname = 'mycompany.test' port = 8099 context = 'todo' username = 'manager' password = 'manager' } } uat { server { hostname = 'mycompany.uat' port = 8199 context = 'todo' username = 'manager' password = 'manager' } } ...
Environment-‐specific configura4on
Common configura4on
![Page 80: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/80.jpg)
Defining build configura4onbinaryRepository { url = 'http://mycompany.bin.repo:8081/artifactory' username = 'admin' password = 'password' name = 'libs-release-local' } environments { test { server { hostname = 'mycompany.test' port = 8099 context = 'todo' username = 'manager' password = 'manager' } } uat { server { hostname = 'mycompany.uat' port = 8199 context = 'todo' username = 'manager' password = 'manager' } } ...
Environment-‐specific configura4on
Common configura4on Read creden4als
from gradle.proper4es
Read creden4als from gradle.proper4es
Read creden4als from gradle.proper4es
![Page 81: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/81.jpg)
Reading build configura4on
def env = project.hasProperty('env') ? project.getProperty('env') : 'test' logger.quiet "Loading configuration for environment '$env’." !def configFile = file("$rootDir/gradle/config/buildConfig.groovy") def parsedConfig = new ConfigSlurper(env).parse(configFile.toURL()) ext.config = parsedConfig
Initializationphase
Congurationphase
Executionphase
![Page 82: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/82.jpg)
Reading build configura4on
def env = project.hasProperty('env') ? project.getProperty('env') : 'test' logger.quiet "Loading configuration for environment '$env’." !def configFile = file("$rootDir/gradle/config/buildConfig.groovy") def parsedConfig = new ConfigSlurper(env).parse(configFile.toURL()) ext.config = parsedConfig
Initializationphase
Congurationphase
Executionphase
Assign configura4on to extra property
![Page 83: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/83.jpg)
Reading build configura4on
def env = project.hasProperty('env') ? project.getProperty('env') : 'test' logger.quiet "Loading configuration for environment '$env’." !def configFile = file("$rootDir/gradle/config/buildConfig.groovy") def parsedConfig = new ConfigSlurper(env).parse(configFile.toURL()) ext.config = parsedConfig
Initializationphase
Congurationphase
Executionphase
Assign configura4on to extra property
gradlew –Penv=uat ...
![Page 84: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/84.jpg)
Using the Maven Publishing plugin
apply plugin: 'maven-publish'
def fullRepoUrl = "$config.binaryRepository.url/$config.binaryRepository.name” publishing { publications { webApp(MavenPublication) { from components.web } } repositories { maven { url fullRepoUrl credentials { username = config.binaryRepository.username password = config.binaryRepository.password } } } }
![Page 85: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/85.jpg)
Using the Maven Publishing plugin
apply plugin: 'maven-publish'
def fullRepoUrl = "$config.binaryRepository.url/$config.binaryRepository.name” publishing { publications { webApp(MavenPublication) { from components.web } } repositories { maven { url fullRepoUrl credentials { username = config.binaryRepository.username password = config.binaryRepository.password } } } }
Build repository URL from configura4on
![Page 86: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/86.jpg)
Using the Maven Publishing plugin
apply plugin: 'maven-publish'
def fullRepoUrl = "$config.binaryRepository.url/$config.binaryRepository.name” publishing { publications { webApp(MavenPublication) { from components.web } } repositories { maven { url fullRepoUrl credentials { username = config.binaryRepository.username password = config.binaryRepository.password } } } }
Build repository URL from configura4on
Assign publica4on name and component
![Page 87: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/87.jpg)
Using the Maven Publishing plugin
apply plugin: 'maven-publish'
def fullRepoUrl = "$config.binaryRepository.url/$config.binaryRepository.name” publishing { publications { webApp(MavenPublication) { from components.web } } repositories { maven { url fullRepoUrl credentials { username = config.binaryRepository.username password = config.binaryRepository.password } } } }
Build repository URL from configura4on
gradlew publish
Assign publica4on name and component
![Page 88: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/88.jpg)
![Page 89: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/89.jpg)
Acceptance stage: Retrieve binaries
Request versioned ar4fact
Store in temp. directory
Acceptance stage
DeployBinaries
Functional Tests
RetrieveBinaries
![Page 90: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/90.jpg)
Downloading the deployable ar4fact
1.0.34
1.0.32 1.0.33 1.0.34
1.0.34
Test
UAT
Prod
![Page 91: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/91.jpg)
Task for downloading ar4fact
repositories { maven { url fullRepoUrl }}!configurations { war}!dependencies { war "$project.group:$project.name:$project.version"}!task downloadBinaryArchive(type: Copy) { from configurations.war into "$buildDir/download" }
![Page 92: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/92.jpg)
Task for downloading ar4fact
repositories { maven { url fullRepoUrl }}!configurations { war}!dependencies { war "$project.group:$project.name:$project.version"}!task downloadBinaryArchive(type: Copy) { from configurations.war into "$buildDir/download" }
Target loca4on for downloaded ar4fact
gradlew downloadBinaryArchive
![Page 93: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/93.jpg)
Acceptance stage: Deploy binaries
Deployment on request
Make it a reliable process
Acceptance stage
DeployBinaries
Functional Tests
RetrieveBinaries
Use process for all envs
![Page 94: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/94.jpg)
Deploying to mul4ple environments
Test
UAT
Prod
–Penv=prod
–Penv=uat
–Penv=test
![Page 95: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/95.jpg)
Deployment with the Cargo plugin
cargoDeployRemote.dependsOn downloadBinaryArchive, cargoUndeployRemote
cargoUndeployRemote { onlyIf appContextStatus } cargo { containerId = 'tomcat7x' port = config.server.port deployable { file = downloadedArtifact context = config.server.context } remote { hostname = config.server.hostname username = config.server.username password = config.server.password } }
![Page 96: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/96.jpg)
Deployment with the Cargo plugin
cargoDeployRemote.dependsOn downloadBinaryArchive, cargoUndeployRemote
cargoUndeployRemote { onlyIf appContextStatus } cargo { containerId = 'tomcat7x' port = config.server.port deployable { file = downloadedArtifact context = config.server.context } remote { hostname = config.server.hostname username = config.server.username password = config.server.password } }
Download ar4fact from binary repository and undeploy exis4ng one
![Page 97: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/97.jpg)
Deployment with the Cargo plugin
cargoDeployRemote.dependsOn downloadBinaryArchive, cargoUndeployRemote
cargoUndeployRemote { onlyIf appContextStatus } cargo { containerId = 'tomcat7x' port = config.server.port deployable { file = downloadedArtifact context = config.server.context } remote { hostname = config.server.hostname username = config.server.username password = config.server.password } }
Download ar4fact from binary repository and undeploy exis4ng one
Only undeploy if URL context exists
![Page 98: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/98.jpg)
Deployment with the Cargo plugin
cargoDeployRemote.dependsOn downloadBinaryArchive, cargoUndeployRemote
cargoUndeployRemote { onlyIf appContextStatus } cargo { containerId = 'tomcat7x' port = config.server.port deployable { file = downloadedArtifact context = config.server.context } remote { hostname = config.server.hostname username = config.server.username password = config.server.password } }
Download ar4fact from binary repository and undeploy exis4ng one
Only undeploy if URL context exists
Use environment-‐specific configura4on
![Page 99: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/99.jpg)
Deployment with the Cargo plugin
cargoDeployRemote.dependsOn downloadBinaryArchive, cargoUndeployRemote
cargoUndeployRemote { onlyIf appContextStatus } cargo { containerId = 'tomcat7x' port = config.server.port deployable { file = downloadedArtifact context = config.server.context } remote { hostname = config.server.hostname username = config.server.username password = config.server.password } }
Download ar4fact from binary repository and undeploy exis4ng one
Only undeploy if URL context exists
Use environment-‐specific configura4on
gradlew –Penv=uat cargoDeploy
![Page 100: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/100.jpg)
![Page 101: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/101.jpg)
Acceptance stage: Func4onal tests
Test UI permuta4ons
Test important use cases
Acceptance stage
DeployBinaries
Functional Tests
RetrieveBinaries
Run against different envs
![Page 102: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/102.jpg)
Execu4ng func4onal tests
def functionalTestReportDir = file("$testReportDir/functional") def functionalTestResultsDir = file("$testResultsDir/functional") def functionalCommonSystemProperties = ['geb.env': 'firefox', 'geb.build.reportsDir': reporting.file("$name/geb")] !task functionalTest(type: Test) { testClassesDir = sourceSets.functionalTest.output.classesDir classpath = sourceSets.functionalTest.runtimeClasspath testReportDir = functionalTestReportDir testResultsDir = functionalTestResultsDir systemProperties functionalCommonSystemProperties systemProperty 'geb.build.baseUrl', "http://$config.server.hostname:$config.server.port/$config.server.context/" }
![Page 103: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/103.jpg)
Execu4ng func4onal tests
def functionalTestReportDir = file("$testReportDir/functional") def functionalTestResultsDir = file("$testResultsDir/functional") def functionalCommonSystemProperties = ['geb.env': 'firefox', 'geb.build.reportsDir': reporting.file("$name/geb")] !task functionalTest(type: Test) { testClassesDir = sourceSets.functionalTest.output.classesDir classpath = sourceSets.functionalTest.runtimeClasspath testReportDir = functionalTestReportDir testResultsDir = functionalTestResultsDir systemProperties functionalCommonSystemProperties systemProperty 'geb.build.baseUrl', "http://$config.server.hostname:$config.server.port/$config.server.context/" }
Reuse setup proper4es
![Page 104: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/104.jpg)
Execu4ng func4onal tests
def functionalTestReportDir = file("$testReportDir/functional") def functionalTestResultsDir = file("$testResultsDir/functional") def functionalCommonSystemProperties = ['geb.env': 'firefox', 'geb.build.reportsDir': reporting.file("$name/geb")] !task functionalTest(type: Test) { testClassesDir = sourceSets.functionalTest.output.classesDir classpath = sourceSets.functionalTest.runtimeClasspath testReportDir = functionalTestReportDir testResultsDir = functionalTestResultsDir systemProperties functionalCommonSystemProperties systemProperty 'geb.build.baseUrl', "http://$config.server.hostname:$config.server.port/$config.server.context/" }
Build URL from env. configura4on
Reuse setup proper4es
![Page 105: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/105.jpg)
Execu4ng func4onal tests
def functionalTestReportDir = file("$testReportDir/functional") def functionalTestResultsDir = file("$testResultsDir/functional") def functionalCommonSystemProperties = ['geb.env': 'firefox', 'geb.build.reportsDir': reporting.file("$name/geb")] !task functionalTest(type: Test) { testClassesDir = sourceSets.functionalTest.output.classesDir classpath = sourceSets.functionalTest.runtimeClasspath testReportDir = functionalTestReportDir testResultsDir = functionalTestResultsDir systemProperties functionalCommonSystemProperties systemProperty 'geb.build.baseUrl', "http://$config.server.hostname:$config.server.port/$config.server.context/" }
gradlew –Penv=test remoteFunctionalTest
Build URL from env. configura4on
Reuse setup proper4es
![Page 106: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/106.jpg)
Let’s bring Jenkins into play!
Test
UAT
Prod
Deployment Acceptance Tests
Publish
Download
Trigger Build
Pull Source Code
![Page 107: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/107.jpg)
Model pipeline as series of jobs
![Page 108: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/108.jpg)
Model pipeline as series of jobs
Triggered job when change to SCM is detected
![Page 109: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/109.jpg)
Ini4al Jenkins Build Job
![Page 110: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/110.jpg)
Build Name Seker Plugin
![Page 111: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/111.jpg)
JaCoCo Plugin
![Page 112: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/112.jpg)
Parameterized Trigger Plugin
![Page 113: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/113.jpg)
Gradle Plugin
![Page 114: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/114.jpg)
Always use the Wrapper!
Gradle Plugin
![Page 115: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/115.jpg)
Always use the Wrapper!
Gradle Plugin
Run clean task to remove exis4ng ar4facts
![Page 116: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/116.jpg)
Build Name Seker Plugin
![Page 117: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/117.jpg)
Clearly iden4fy a build through an expressive build name
Build Name Seker Plugin
![Page 118: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/118.jpg)
Use Jenkins environment variable
Clearly iden4fy a build through an expressive build name
Build Name Seker Plugin
![Page 119: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/119.jpg)
Parameterized Trigger Plugin
![Page 120: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/120.jpg)
Next job to trigger if build is stable
Parameterized Trigger Plugin
![Page 121: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/121.jpg)
Next job to trigger if build is stable
Defines build number parameter provided to subsequent jobs
Parameterized Trigger Plugin
![Page 122: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/122.jpg)
Clone Workspace SCM Plugin
![Page 123: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/123.jpg)
Archive all files
Clone Workspace SCM Plugin
![Page 124: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/124.jpg)
Archive all files
Only archive if build was successful
Clone Workspace SCM Plugin
![Page 125: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/125.jpg)
JaCoCo Plugin
![Page 126: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/126.jpg)
Point to separated test results
JaCoCo Plugin
![Page 127: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/127.jpg)
Point to separated test results
JaCoCo Plugin
Point to JaCoCo files as well as source and class files
![Page 128: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/128.jpg)
Point to separated test results
Fail build of quality gate criteria are not met
JaCoCo Plugin
Point to JaCoCo files as well as source and class files
![Page 129: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/129.jpg)
Clone Workspace SCM Plugin Build Name Seker Plugin
![Page 130: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/130.jpg)
Reuse ini4al workspace
Clone Workspace SCM Plugin Build Name Seker Plugin
![Page 131: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/131.jpg)
Reuse ini4al workspace
Reuse ini4al build number
Clone Workspace SCM Plugin Build Name Seker Plugin
![Page 132: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/132.jpg)
Build Pipeline Plugin
![Page 133: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/133.jpg)
Define the target environment
Build Pipeline Plugin
![Page 134: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/134.jpg)
Define the target environment
Downstream job that requires manual execu4on
Build Pipeline Plugin
![Page 135: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/135.jpg)
Build Pipeline Plugin
Visualiza4on of chained pipeline jobs
![Page 136: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/136.jpg)
![Page 137: Building a Continuous Delivery with Gradle and Jenkins](https://reader035.fdocuments.us/reader035/viewer/2022062220/557d5ee3d8b42ae1438b4e9c/html5/thumbnails/137.jpg)
> gradle qa
:askQuestions
!
BUILD SUCCESSFUL
!
Total time: 300 secs