diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 0d6d1e987..1ab455a26 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -78,13 +78,26 @@ def presetFlags = [ def anyFailure = false def gitClone() { + /* Read git tag from environment or set the default one. */ if (env.GIT_COMMIT == null) env.GIT_COMMIT = 'master' println "[-] Using git tag [${env.GIT_COMMIT}]" - def scmVars = checkout scm: [$class: 'GitSCM', - branches: [[name: env.GIT_COMMIT]], - userRemoteConfigs: [[url: 'https://github.com/86Box/86Box.git']]] - env.GIT_COMMIT = scmVars.GIT_COMMIT + + /* Use stashes to avoid performing multiple clones. */ + if (env.GIT_STASHED != 'true') { + /* Perform clone/checkout. */ + def scmVars = checkout scm: [$class: 'GitSCM', + branches: [[name: env.GIT_COMMIT]], + userRemoteConfigs: [[url: 'https://github.com/86Box/86Box.git']]] + env.GIT_COMMIT = scmVars.GIT_COMMIT + + /* Stash data and mark it as stashed. */ + stash name: 'git' + env.GIT_STASHED = 'true' + } else { + /* Unstash data. */ + unstash name: 'git' + } } def removeDir(dir) { @@ -98,31 +111,37 @@ def runBuild(args) { if (isUnix()) sh "chmod u+x \"$WORKSPACE/.ci/build.sh\" && exec \"$WORKSPACE/.ci/build.sh\" $args" else - bat "C:\\msys64\\msys2_shell.cmd -msys2 -defterm -here -no-start -c 'exec \"\$(cygpath -u \\'%WORKSPACE%\\')\"/.ci/build.sh $args'" + bat "C:\\msys64\\msys2_shell.cmd -msys2 -defterm -here -no-start -c 'exec \"\$(cygpath -u \\'%WORKSPACE%\\')/.ci/build.sh\" $args'" } pipeline { agent none + environment { + DISCORD_WEBHOOK_URL = credentials('discord-webhook-url') + } + + options { + disableConcurrentBuilds() + quietPeriod(0) + } + parameters { string(name: 'BUILD_TYPE', defaultValue: 'beta', /* !!! CHANGE HERE !!! for build type */ description: "Build type to pass on to CMake. Don't change this, you should instead change the default value on .ci/Jenkinsfile") } - environment { - DISCORD_WEBHOOK_URL = credentials('discord-webhook-url') - } - stages { stage('Source Tarball') { agent none steps { script { - /* Cursed hack to extract the current HEAD commit from this build's - git polling log. This avoids a timing issue where HEAD changes - between polling and the nodes being available below. */ + /* Hack to extract the current HEAD commit from this build's git polling + log. This avoids a race condition where HEAD changes in the time period + between Jenkins polling the git repository and the first build node + performing the first git clone once ready. (See issue JENKINS-20518) */ if (env.GIT_COMMIT == null) { /* This must run on the master node to read the polling log. */ node('master') { @@ -141,7 +160,8 @@ pipeline { } catch (e) {} } - /* If the polling log parsing fails, run a dummy git clone on any node. */ + /* If the polling log parsing fails, perform a dummy git clone on any node. + Not quite as fast as reading the polling log, but it works as a backup. */ if (env.GIT_COMMIT == null) { node { /* Ignore exceptions again as this is not really critical. */ @@ -207,10 +227,12 @@ pipeline { removeDir('output') /* Switch to output directory. */ - dir("output/${dynarecNames[dynarec]}/$os - ${archNames[arch]}") { + dir('output') { /* Run build process. */ def packageName = "${env.JOB_BASE_NAME}${dynarecSlugs[dynarec]}${presetSlugs[preset]}-$os-$arch-b${env.BUILD_NUMBER}" - runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} -D \"BUILD_TYPE=$BUILD_TYPE\" -D \"EMU_BUILD=build ${env.BUILD_NUMBER}\" -D \"EMU_BUILD_NUM=${env.BUILD_NUMBER}\"") + dir("${dynarecNames[dynarec]}/$os - ${archNames[arch]}") { + runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} -D \"BUILD_TYPE=$BUILD_TYPE\" -D \"EMU_BUILD=build ${env.BUILD_NUMBER}\" -D \"EMU_BUILD_NUM=${env.BUILD_NUMBER}\"") + } /* Archive resulting artifacts. */ archiveArtifacts artifacts: "**/**/$packageName*"