Jenkins: Commit new Jenkinsfile
This commit is contained in:
259
.ci/Jenkinsfile
vendored
259
.ci/Jenkinsfile
vendored
@@ -15,48 +15,92 @@
|
|||||||
* Copyright 2021 RichardG.
|
* Copyright 2021 RichardG.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Run this on /script to get all approvals required to sync build numbers across jobs:
|
def osArchs = [
|
||||||
|
'Windows': ['32', '64'],
|
||||||
|
'Linux': ['x86', 'x86_64', 'arm32', 'arm64']
|
||||||
|
]
|
||||||
|
|
||||||
def approval = org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval.get()
|
def archNames = [
|
||||||
approval.approveSignature('staticMethod jenkins.model.Jenkins getInstance')
|
'32': 'x86 (32-bit)',
|
||||||
approval.approveSignature('method hudson.model.ItemGroup getItem java.lang.String')
|
'x86': 'x86 (32-bit)',
|
||||||
approval.approveSignature('field hudson.model.Job nextBuildNumber')
|
'64': 'x64 (64-bit)',
|
||||||
approval.approveSignature('method hudson.model.Job saveNextBuildNumber')
|
'x86_64': 'x64 (64-bit)',
|
||||||
|
'arm32': 'ARM (32-bit)',
|
||||||
|
'arm64': 'ARM (64-bit)'
|
||||||
|
]
|
||||||
|
|
||||||
*/
|
def dynarecNames = [
|
||||||
|
'ODR': 'Old Recompiler (recommended)',
|
||||||
|
'NDR': 'New Recompiler (beta)',
|
||||||
|
'NoDR': 'No Dynamic Recompiler'
|
||||||
|
]
|
||||||
|
|
||||||
|
def dynarecArchs = [
|
||||||
|
'32': ['ODR', 'NDR'],
|
||||||
|
'x86': ['ODR', 'NDR'],
|
||||||
|
'64': ['ODR', 'NDR'],
|
||||||
|
'x86_64': ['ODR', 'NDR'],
|
||||||
|
'arm32': ['NDR'],
|
||||||
|
'ARM32': ['NDR'],
|
||||||
|
'arm64': ['NDR'],
|
||||||
|
'ARM64': ['NDR']
|
||||||
|
]
|
||||||
|
|
||||||
|
def dynarecFlags = [
|
||||||
|
'ODR': '-D NEW_DYNAREC=OFF',
|
||||||
|
'NDR': '-D NEW_DYNAREC=ON',
|
||||||
|
'NoDR': '-D DYNAREC=OFF'
|
||||||
|
]
|
||||||
|
|
||||||
|
def dynarecSlugs = [
|
||||||
|
'ODR': '',
|
||||||
|
'NDR': '-NDR',
|
||||||
|
'NoDR': ''
|
||||||
|
]
|
||||||
|
|
||||||
|
def presets = [
|
||||||
|
'Regular',
|
||||||
|
'Debug'
|
||||||
|
]
|
||||||
|
|
||||||
|
def presetSlugs = [
|
||||||
|
'Regular': '',
|
||||||
|
'Debug': '-Debug',
|
||||||
|
'Dev': '-Dev'
|
||||||
|
]
|
||||||
|
|
||||||
|
def presetFlags = [
|
||||||
|
'Regular': '--preset=regular',
|
||||||
|
'Debug': '--preset=debug',
|
||||||
|
'Dev': '--preset=experimental -D VNC=OFF'
|
||||||
|
]
|
||||||
|
|
||||||
|
def anyFailure = false
|
||||||
|
|
||||||
def gitClone() {
|
def gitClone() {
|
||||||
cleanWs()
|
|
||||||
if (env.GIT_COMMIT == null)
|
if (env.GIT_COMMIT == null)
|
||||||
env.GIT_COMMIT = BRANCH
|
env.GIT_COMMIT = 'master'
|
||||||
println "[-] Building git tag [${env.GIT_COMMIT}]"
|
println "[-] Using git tag [${env.GIT_COMMIT}]"
|
||||||
def scmVars = checkout scm: [$class: 'GitSCM',
|
def scmVars = checkout scm: [$class: 'GitSCM',
|
||||||
branches: [[name: env.GIT_COMMIT]],
|
branches: [[name: env.GIT_COMMIT]],
|
||||||
userRemoteConfigs: [[url: 'https://github.com/86Box/86Box.git']]]
|
userRemoteConfigs: [[url: 'https://github.com/86Box/86Box.git']]]
|
||||||
env.GIT_COMMIT = scmVars.GIT_COMMIT
|
env.GIT_COMMIT = scmVars.GIT_COMMIT
|
||||||
}
|
}
|
||||||
|
|
||||||
def windowsBuild() {
|
def removeDir(dir) {
|
||||||
bat 'C:\\msys64\\msys2_shell.cmd -msys2 -defterm -here -no-start -c "exec .ci/build.sh"'
|
if (isUnix())
|
||||||
|
sh "rm -rf \"$dir\" || exit 0"
|
||||||
|
else
|
||||||
|
bat "if exist \"$dir\" rd /s /q \"$dir\" & exit /b 0"
|
||||||
}
|
}
|
||||||
|
|
||||||
def unixBuild() {
|
def runBuild(args) {
|
||||||
sh 'chmod u+x .ci/build.sh && exec .ci/build.sh'
|
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'"
|
||||||
}
|
}
|
||||||
|
|
||||||
def saveArtifacts() {
|
|
||||||
archiveArtifacts artifacts: "${env.JOB_BASE_NAME}-*"
|
|
||||||
}
|
|
||||||
|
|
||||||
def successCount = 0
|
|
||||||
|
|
||||||
def buildChain = [
|
|
||||||
'86Box': '86Box-Dev',
|
|
||||||
'86Box-Dev': '86Box-DevODR',
|
|
||||||
'86Box-DevODR': '86Box-Debug',
|
|
||||||
'86Box-TestBuildPleaseIgnore': '86Box-TestBuildPleaseIgnore2'
|
|
||||||
]
|
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent none
|
agent none
|
||||||
|
|
||||||
@@ -64,9 +108,6 @@ pipeline {
|
|||||||
string(name: 'BUILD_TYPE',
|
string(name: 'BUILD_TYPE',
|
||||||
defaultValue: 'beta', /* !!! CHANGE HERE !!! for 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")
|
description: "Build type to pass on to CMake. Don't change this, you should instead change the default value on .ci/Jenkinsfile")
|
||||||
string(name: 'BRANCH',
|
|
||||||
defaultValue: 'master',
|
|
||||||
description: "Used internally to make sure all downstream builds use the same commit. Don't change this.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
@@ -74,41 +115,105 @@ pipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage('Build Windows') {
|
stage('Source Tarball') {
|
||||||
agent {
|
agent none
|
||||||
node {
|
|
||||||
label 'windows'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
|
||||||
gitClone()
|
|
||||||
windowsBuild()
|
|
||||||
saveArtifacts()
|
|
||||||
|
|
||||||
script {
|
script {
|
||||||
successCount += 1
|
/* Run a dummy git clone on any node to try and save the latest commit regardless of executor status.
|
||||||
}
|
This avoids a timing issue where HEAD changes between polling and the nodes being available below.
|
||||||
}
|
I talked to a few people, and we reached the conclusion that reading the polled commit from within
|
||||||
}
|
the pipeline is not really possible (maybe short of switching to a multi-branch pipeline), so we
|
||||||
}
|
have to live with this hack, which shortens but doesn't fully eliminate the timing issue's window. */
|
||||||
|
|
||||||
stage('Build Linux') {
|
|
||||||
agent {
|
|
||||||
node {
|
node {
|
||||||
label 'debian'
|
/* Ignore exceptions as this is not really critical. */
|
||||||
}
|
try {
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
|
||||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
|
||||||
gitClone()
|
gitClone()
|
||||||
unixBuild()
|
} catch (e) {}
|
||||||
saveArtifacts()
|
try {
|
||||||
|
cleanWs()
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
script {
|
/* Create source tarball. */
|
||||||
successCount += 1
|
node('Linux') {
|
||||||
|
try {
|
||||||
|
/* Run git clone. */
|
||||||
|
gitClone()
|
||||||
|
|
||||||
|
/* Switch to temp directory. */
|
||||||
|
dir(WORKSPACE_TMP) {
|
||||||
|
/* Clean output directory of potential stale old builds. */
|
||||||
|
removeDir('output')
|
||||||
|
|
||||||
|
/* Switch to output directory. */
|
||||||
|
dir('output') {
|
||||||
|
/* Run source tarball creation process. */
|
||||||
|
def packageName = "${env.JOB_BASE_NAME}-Source-b${env.BUILD_NUMBER}"
|
||||||
|
runBuild("-s \"$packageName\"")
|
||||||
|
|
||||||
|
/* Archive resulting artifacts. */
|
||||||
|
archiveArtifacts artifacts: "$packageName*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
/* Mark that a failure occurred. */
|
||||||
|
anyFailure = true
|
||||||
|
|
||||||
|
/* Force this stage to fail. */
|
||||||
|
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build here to avoid creating a redundant parent stage on the stage view. */
|
||||||
|
osArchs.each { os, thisOsArchs ->
|
||||||
|
thisOsArchs.each { arch ->
|
||||||
|
def thisArchDynarecs = dynarecArchs[arch]
|
||||||
|
if (!thisArchDynarecs)
|
||||||
|
thisArchDynarecs = ['NoDR']
|
||||||
|
thisArchDynarecs.each { dynarec ->
|
||||||
|
presets.each { preset ->
|
||||||
|
node(os) {
|
||||||
|
stage("$os $arch $dynarec $preset") {
|
||||||
|
try {
|
||||||
|
/* Run git clone. */
|
||||||
|
gitClone()
|
||||||
|
|
||||||
|
/* Switch to temp directory. */
|
||||||
|
dir(WORKSPACE_TMP) {
|
||||||
|
/* Clean output directory of potential stale old builds. */
|
||||||
|
removeDir('output')
|
||||||
|
|
||||||
|
/* Switch to output directory. */
|
||||||
|
dir('output') {
|
||||||
|
def packageName = "${env.JOB_BASE_NAME}${dynarecSlugs[dynarec]}${presetSlugs[preset]}-$os-$arch-b${env.BUILD_NUMBER}"
|
||||||
|
dir(dynarecNames[dynarec]) {
|
||||||
|
dir("$os - ${archNames[arch]}") {
|
||||||
|
/* Run build process. */
|
||||||
|
runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} -D \"BUILD_TYPE=$BUILD_TYPE\" -D \"EMU_BUILD=build ${env.BUILD_NUMBER}\" -D \"EMU_BUILD_NUMBER=${env.BUILD_NUMBER}\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Archive resulting artifacts. */
|
||||||
|
archiveArtifacts artifacts: "**/**/$packageName*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
/* Mark that a failure occurred. */
|
||||||
|
anyFailure = true
|
||||||
|
|
||||||
|
/* Force this stage to fail. */
|
||||||
|
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,36 +223,14 @@ pipeline {
|
|||||||
post {
|
post {
|
||||||
always {
|
always {
|
||||||
script {
|
script {
|
||||||
/* Trigger next job is applicable. */
|
if (anyFailure) {
|
||||||
if (buildChain[env.JOB_BASE_NAME]) {
|
|
||||||
def nextJob = buildChain[env.JOB_BASE_NAME]
|
|
||||||
|
|
||||||
/* Set next build number for the next job. */
|
|
||||||
try {
|
|
||||||
def job = Jenkins.instance.getItem(nextJob)
|
|
||||||
job.nextBuildNumber = env.BUILD_NUMBER as Integer
|
|
||||||
job.saveNextBuildNumber()
|
|
||||||
} catch (Exception e) {
|
|
||||||
println "[!] Could not set next build number for [$nextJob], make sure all required script approvals are in place"
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Trigger next job. */
|
|
||||||
build propagate: false,
|
|
||||||
wait: false,
|
|
||||||
job: nextJob,
|
|
||||||
parameters: [
|
|
||||||
string(name: 'BUILD_TYPE', value: BUILD_TYPE),
|
|
||||||
string(name: 'BRANCH', value: env.GIT_COMMIT)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (successCount < 2) {
|
|
||||||
println "[!] Failing build because a build stage failed"
|
println "[!] Failing build because a build stage failed"
|
||||||
currentBuild.result = 'FAILURE'
|
currentBuild.result = 'FAILURE'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!env.JOB_BASE_NAME.contains("TestBuildPleaseIgnore")) {
|
if (!env.JOB_BASE_NAME.contains("TestBuildPleaseIgnore")) {
|
||||||
try {
|
try {
|
||||||
|
/* Notify Discord. */
|
||||||
def result = currentBuild.currentResult.toLowerCase()
|
def result = currentBuild.currentResult.toLowerCase()
|
||||||
discordSend webhookURL: DISCORD_WEBHOOK_URL,
|
discordSend webhookURL: DISCORD_WEBHOOK_URL,
|
||||||
title: "${env.JOB_BASE_NAME} #${env.BUILD_NUMBER}",
|
title: "${env.JOB_BASE_NAME} #${env.BUILD_NUMBER}",
|
||||||
@@ -157,11 +240,15 @@ pipeline {
|
|||||||
enableArtifactsList: false,
|
enableArtifactsList: false,
|
||||||
showChangeset: true
|
showChangeset: true
|
||||||
|
|
||||||
node { /* IRC notifications need a node for whatever reason */
|
/* Notify IRC, which needs a node for whatever reason. */
|
||||||
|
node {
|
||||||
ircNotify()
|
ircNotify()
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (e) {
|
||||||
e.printStackTrace()
|
/* Force this stage to fail. */
|
||||||
|
catchError(buildResult: currentBuild.result, stageResult: 'FAILURE') {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user