Skip to content

chore(Jenkinsfile) use spot agent with retries #502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 29, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 83 additions & 70 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
final String cronExpr = env.BRANCH_IS_PRIMARY ? '@daily' : ''

properties([
buildDiscarder(logRotator(numToKeepStr: '10')),
disableConcurrentBuilds(abortPrevious: true),
pipelineTriggers([cron(cronExpr)]),
])

def agentSelector(String imageType) {
// Linux agent
if (imageType == 'linux') {
return 'linux'
// This function is defined in the jenkins-infra/pipeline-library
if (infra.isTrusted()) {
return 'linux'
} else {
// Need Docker and a LOT of memory for faster builds (due to multi archs) or fallback to linux (trusted.ci)
return 'docker-highmem'
}
}
// Windows Server Core 2022 agent
if (imageType.contains('2022')) {
Expand All @@ -11,85 +25,82 @@ def agentSelector(String imageType) {
return 'windows-2019'
}

pipeline {
agent none
// Ref. https://github.com/jenkins-infra/pipeline-library/pull/917
def spotAgentSelector(String agentLabel, int counter) {
// This function is defined in the jenkins-infra/pipeline-library
if (infra.isTrusted()) {
// Return early if on trusted (no spot agent)
return agentLabel
}

options {
buildDiscarder(logRotator(daysToKeepStr: '10'))
if (counter > 1) {
return agentLabel + ' && nonspot'
}

stages {
stage('docker-ssh-agent') {
environment {
DOCKERHUB_ORGANISATION = "${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}"
}
matrix {
axes {
axis {
name 'IMAGE_TYPE'
values 'linux', 'nanoserver-1809', 'nanoserver-ltsc2019', 'nanoserver-ltsc2022', 'windowsservercore-ltsc2019', 'windowsservercore-ltsc2022'
}
}
stages {
stage('Main') {
agent {
label agentSelector(env.IMAGE_TYPE)
}
options {
timeout(time: 60, unit: 'MINUTES')
}
stages {
return agentLabel + ' && spot'
}

// Specify parallel stages
parallelStages = [failFast: false]
[
'linux',
'nanoserver-1809',
'nanoserver-ltsc2019',
'nanoserver-ltsc2022',
'windowsservercore-1809',
'windowsservercore-ltsc2019',
'windowsservercore-ltsc2022'
].each { imageType ->
parallelStages[imageType] = {
withEnv(["IMAGE_TYPE=${imageType}", "REGISTRY_ORG=${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}"]) {
int retryCounter = 0
retry(count: 2, conditions: [agent(), nonresumable()]) {
// Use local variable to manage concurrency and increment BEFORE spinning up any agent
final String resolvedAgentLabel = spotAgentSelector(agentSelector(imageType), retryCounter)
retryCounter++
node(resolvedAgentLabel) {
timeout(time: 60, unit: 'MINUTES') {
checkout scm
if (imageType == "linux") {
stage('Prepare Docker') {
when {
environment name: 'IMAGE_TYPE', value: 'linux'
}
steps {
sh 'make docker-init'
}
sh 'make docker-init'
}
stage('Build and Test') {
// This stage is the "CI" and should be run on all code changes triggered by a code change
when {
not { buildingTag() }
}
steps {
script {
if(isUnix()) {
sh 'make build'
sh 'make test'
// If the tests are passing for Linux AMD64, then we can build all the CPU architectures
sh 'make every-build'
}
// This function is defined in the jenkins-infra/pipeline-library
if (infra.isTrusted()) {
// trusted.ci.jenkins.io builds (e.g. publication to DockerHub)
stage('Deploy to DockerHub') {
withEnv([
"ON_TAG=true",
VERSION = "${env.TAG_NAME}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this was a syntax error. Hotfix with 5d3cfb3 when verifying the PR (fix used to deploy the 6.11.1 release)

]) {
// This function is defined in the jenkins-infra/pipeline-library
infra.withDockerCredentials {
if (isUnix()) {
sh 'make publish'
} else {
powershell '& ./build.ps1 test'
powershell '& ./build.ps1 publish'
}
}
}
post {
always {
junit(allowEmptyResults: true, keepLongStdio: true, testResults: 'target/**/junit-results.xml')
}
}
}
stage('Deploy to DockerHub') {
// This stage is the "CD" and should only be run when a tag triggered the build
when {
buildingTag()
}
environment {
ON_TAG = 'true'
VERSION = "${env.TAG_NAME}"
} else {
stage('Build and Test') {
// ci.jenkins.io builds (e.g. no publication)
if (isUnix()) {
sh 'make build'
sh 'make test'
} else {
powershell '& ./build.ps1 test'
archiveArtifacts artifacts: 'build-windows_*.yaml', allowEmptyArchive: true
}
steps {
script {
// This function is defined in the jenkins-infra/pipeline-library
infra.withDockerCredentials {
if (isUnix()) {
sh 'make publish'
} else {
powershell '& ./build.ps1 publish'
}
}
}
junit(allowEmptyResults: true, keepLongStdio: true, testResults: 'target/**/junit-results.xml')
}
// If the tests are passing for Linux AMD64, then we can build all the CPU architectures
if (isUnix()) {
stage('Multi-Arch Build') {

sh 'make every-build'
}
}
}
Expand All @@ -100,4 +111,6 @@ pipeline {
}
}

// vim: ft=groovy
// Execute parallel stages
parallel parallelStages
// // vim: ft=groovy