Skip to content

Commit 49eb031

Browse files
authored
Merge pull request #502 from dduportal/chore/Jenkinsfile/retry-spot
chore(Jenkinsfile) use spot agent with retries
2 parents bde2f97 + b9f6f5e commit 49eb031

File tree

1 file changed

+83
-70
lines changed

1 file changed

+83
-70
lines changed

Jenkinsfile

Lines changed: 83 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
1+
final String cronExpr = env.BRANCH_IS_PRIMARY ? '@daily' : ''
2+
3+
properties([
4+
buildDiscarder(logRotator(numToKeepStr: '10')),
5+
disableConcurrentBuilds(abortPrevious: true),
6+
pipelineTriggers([cron(cronExpr)]),
7+
])
8+
19
def agentSelector(String imageType) {
210
// Linux agent
311
if (imageType == 'linux') {
4-
return 'linux'
12+
// This function is defined in the jenkins-infra/pipeline-library
13+
if (infra.isTrusted()) {
14+
return 'linux'
15+
} else {
16+
// Need Docker and a LOT of memory for faster builds (due to multi archs) or fallback to linux (trusted.ci)
17+
return 'docker-highmem'
18+
}
519
}
620
// Windows Server Core 2022 agent
721
if (imageType.contains('2022')) {
@@ -11,85 +25,82 @@ def agentSelector(String imageType) {
1125
return 'windows-2019'
1226
}
1327

14-
pipeline {
15-
agent none
28+
// Ref. https://github.com/jenkins-infra/pipeline-library/pull/917
29+
def spotAgentSelector(String agentLabel, int counter) {
30+
// This function is defined in the jenkins-infra/pipeline-library
31+
if (infra.isTrusted()) {
32+
// Return early if on trusted (no spot agent)
33+
return agentLabel
34+
}
1635

17-
options {
18-
buildDiscarder(logRotator(daysToKeepStr: '10'))
36+
if (counter > 1) {
37+
return agentLabel + ' && nonspot'
1938
}
2039

21-
stages {
22-
stage('docker-ssh-agent') {
23-
environment {
24-
DOCKERHUB_ORGANISATION = "${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}"
25-
}
26-
matrix {
27-
axes {
28-
axis {
29-
name 'IMAGE_TYPE'
30-
values 'linux', 'nanoserver-1809', 'nanoserver-ltsc2019', 'nanoserver-ltsc2022', 'windowsservercore-ltsc2019', 'windowsservercore-ltsc2022'
31-
}
32-
}
33-
stages {
34-
stage('Main') {
35-
agent {
36-
label agentSelector(env.IMAGE_TYPE)
37-
}
38-
options {
39-
timeout(time: 60, unit: 'MINUTES')
40-
}
41-
stages {
40+
return agentLabel + ' && spot'
41+
}
42+
43+
// Specify parallel stages
44+
parallelStages = [failFast: false]
45+
[
46+
'linux',
47+
'nanoserver-1809',
48+
'nanoserver-ltsc2019',
49+
'nanoserver-ltsc2022',
50+
'windowsservercore-1809',
51+
'windowsservercore-ltsc2019',
52+
'windowsservercore-ltsc2022'
53+
].each { imageType ->
54+
parallelStages[imageType] = {
55+
withEnv(["IMAGE_TYPE=${imageType}", "REGISTRY_ORG=${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}"]) {
56+
int retryCounter = 0
57+
retry(count: 2, conditions: [agent(), nonresumable()]) {
58+
// Use local variable to manage concurrency and increment BEFORE spinning up any agent
59+
final String resolvedAgentLabel = spotAgentSelector(agentSelector(imageType), retryCounter)
60+
retryCounter++
61+
node(resolvedAgentLabel) {
62+
timeout(time: 60, unit: 'MINUTES') {
63+
checkout scm
64+
if (imageType == "linux") {
4265
stage('Prepare Docker') {
43-
when {
44-
environment name: 'IMAGE_TYPE', value: 'linux'
45-
}
46-
steps {
47-
sh 'make docker-init'
48-
}
66+
sh 'make docker-init'
4967
}
50-
stage('Build and Test') {
51-
// This stage is the "CI" and should be run on all code changes triggered by a code change
52-
when {
53-
not { buildingTag() }
54-
}
55-
steps {
56-
script {
57-
if(isUnix()) {
58-
sh 'make build'
59-
sh 'make test'
60-
// If the tests are passing for Linux AMD64, then we can build all the CPU architectures
61-
sh 'make every-build'
68+
}
69+
// This function is defined in the jenkins-infra/pipeline-library
70+
if (infra.isTrusted()) {
71+
// trusted.ci.jenkins.io builds (e.g. publication to DockerHub)
72+
stage('Deploy to DockerHub') {
73+
withEnv([
74+
"ON_TAG=true",
75+
VERSION = "${env.TAG_NAME}"
76+
]) {
77+
// This function is defined in the jenkins-infra/pipeline-library
78+
infra.withDockerCredentials {
79+
if (isUnix()) {
80+
sh 'make publish'
6281
} else {
63-
powershell '& ./build.ps1 test'
82+
powershell '& ./build.ps1 publish'
6483
}
6584
}
6685
}
67-
post {
68-
always {
69-
junit(allowEmptyResults: true, keepLongStdio: true, testResults: 'target/**/junit-results.xml')
70-
}
71-
}
7286
}
73-
stage('Deploy to DockerHub') {
74-
// This stage is the "CD" and should only be run when a tag triggered the build
75-
when {
76-
buildingTag()
77-
}
78-
environment {
79-
ON_TAG = 'true'
80-
VERSION = "${env.TAG_NAME}"
87+
} else {
88+
stage('Build and Test') {
89+
// ci.jenkins.io builds (e.g. no publication)
90+
if (isUnix()) {
91+
sh 'make build'
92+
sh 'make test'
93+
} else {
94+
powershell '& ./build.ps1 test'
95+
archiveArtifacts artifacts: 'build-windows_*.yaml', allowEmptyArchive: true
8196
}
82-
steps {
83-
script {
84-
// This function is defined in the jenkins-infra/pipeline-library
85-
infra.withDockerCredentials {
86-
if (isUnix()) {
87-
sh 'make publish'
88-
} else {
89-
powershell '& ./build.ps1 publish'
90-
}
91-
}
92-
}
97+
junit(allowEmptyResults: true, keepLongStdio: true, testResults: 'target/**/junit-results.xml')
98+
}
99+
// If the tests are passing for Linux AMD64, then we can build all the CPU architectures
100+
if (isUnix()) {
101+
stage('Multi-Arch Build') {
102+
103+
sh 'make every-build'
93104
}
94105
}
95106
}
@@ -100,4 +111,6 @@ pipeline {
100111
}
101112
}
102113

103-
// vim: ft=groovy
114+
// Execute parallel stages
115+
parallel parallelStages
116+
// // vim: ft=groovy

0 commit comments

Comments
 (0)