adds Jenkinsfile
This commit is contained in:
153
Jenkinsfile
vendored
Normal file
153
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
def suites = ['threadx', 'smp']
|
||||
def presets = ['Debug32', 'Release32']
|
||||
|
||||
def runOneRegression(String suite, String preset, String simulatorPath) {
|
||||
def suiteDir = "test/${suite}"
|
||||
def buildDir = "../../build/${preset}/test/${suite}"
|
||||
|
||||
stage("${suite}-${preset}") {
|
||||
dir(suiteDir) {
|
||||
sh """
|
||||
set -eu
|
||||
test -n "${simulatorPath}"
|
||||
test -x "${simulatorPath}"
|
||||
cmake --preset "${preset}" \\
|
||||
-DTHREADX_TEST_SIMULATOR="${simulatorPath}"
|
||||
cmake --build "${buildDir}" --parallel "\$(nproc)"
|
||||
ctest \\
|
||||
--test-dir "${buildDir}" \\
|
||||
--output-on-failure \\
|
||||
--output-junit "${buildDir}/ctest-results.xml" \\
|
||||
--parallel "1"
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def resolveImageCommit(String image) {
|
||||
sh(
|
||||
script: """
|
||||
set -eu
|
||||
docker pull "${image}" >/dev/null
|
||||
docker image inspect --format='{{ index .Config.Labels "git-commit" }}' "${image}"
|
||||
""",
|
||||
returnStdout: true
|
||||
).trim()
|
||||
}
|
||||
|
||||
def runRegressionLane(String image, String simulatorPath, boolean allowFailure) {
|
||||
def parallelTasks = [:]
|
||||
|
||||
for (String suite : suites) {
|
||||
for (String preset : presets) {
|
||||
def suiteName = suite
|
||||
def presetName = preset
|
||||
def taskName = "${suiteName}-${presetName}"
|
||||
parallelTasks[taskName] = {
|
||||
if (allowFailure) {
|
||||
catchError(buildResult: 'UNSTABLE', stageResult: 'UNSTABLE') {
|
||||
runOneRegression(suiteName, presetName, simulatorPath)
|
||||
}
|
||||
} else {
|
||||
runOneRegression(suiteName, presetName, simulatorPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
docker.image(image).inside {
|
||||
sh '''
|
||||
set -eu
|
||||
cmake --version
|
||||
ctest --version
|
||||
'''
|
||||
parallel parallelTasks
|
||||
}
|
||||
}
|
||||
|
||||
properties([
|
||||
parameters([
|
||||
string(
|
||||
name: 'SIMULATOR_IMAGE_PINNED',
|
||||
defaultValue: 'git.minres.com/here/here-vp:ac4f736',
|
||||
description: 'Version-pinned Docker image used for the blocking regression lane'
|
||||
),
|
||||
string(
|
||||
name: 'SIMULATOR_IMAGE_LATEST',
|
||||
defaultValue: 'git.minres.com/here/here-vp:latest',
|
||||
description: 'Moving Docker image tag used for the canary lane'
|
||||
),
|
||||
string(
|
||||
name: 'THREADX_TEST_SIMULATOR',
|
||||
defaultValue: '/usr/local/bin/riscv-vp',
|
||||
description: 'Absolute path to the simulator executable inside the Docker image'
|
||||
)
|
||||
])
|
||||
])
|
||||
|
||||
def canaryShouldRun = true
|
||||
|
||||
node {
|
||||
timestamps {
|
||||
ansiColor('xterm') {
|
||||
try {
|
||||
stage('Checkout') {
|
||||
checkout scm
|
||||
}
|
||||
|
||||
stage('Check Canary Divergence') {
|
||||
def pinnedCommit = resolveImageCommit(params.SIMULATOR_IMAGE_PINNED)
|
||||
def latestCommit = resolveImageCommit(params.SIMULATOR_IMAGE_LATEST)
|
||||
|
||||
if (!pinnedCommit) {
|
||||
error "Missing git-commit label on ${params.SIMULATOR_IMAGE_PINNED}"
|
||||
}
|
||||
if (!latestCommit) {
|
||||
error "Missing git-commit label on ${params.SIMULATOR_IMAGE_LATEST}"
|
||||
}
|
||||
|
||||
canaryShouldRun = (pinnedCommit != latestCommit)
|
||||
|
||||
if (canaryShouldRun) {
|
||||
echo "Canary enabled: ${params.SIMULATOR_IMAGE_LATEST} (${latestCommit}) diverges from ${params.SIMULATOR_IMAGE_PINNED} (${pinnedCommit})"
|
||||
} else {
|
||||
echo "Canary skipped: ${params.SIMULATOR_IMAGE_LATEST} and ${params.SIMULATOR_IMAGE_PINNED} both use git-commit ${pinnedCommit}"
|
||||
}
|
||||
}
|
||||
|
||||
stage('Stable Regression') {
|
||||
runRegressionLane(params.SIMULATOR_IMAGE_PINNED, params.THREADX_TEST_SIMULATOR, false)
|
||||
}
|
||||
|
||||
stage('Simulator Canary') {
|
||||
if (canaryShouldRun) {
|
||||
runRegressionLane(params.SIMULATOR_IMAGE_LATEST, params.THREADX_TEST_SIMULATOR, true)
|
||||
} else {
|
||||
echo 'Skipping canary lane because latest and pinned images are identical.'
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
throw err
|
||||
} finally {
|
||||
junit allowEmptyResults: true, testResults: 'build/*/test/*/ctest-results.xml'
|
||||
archiveArtifacts artifacts: 'build/*/test/*/*.map,build/*/test/*/*.dis,build/*/test/*/Testing/**', allowEmptyArchive: true
|
||||
|
||||
if (currentBuild.currentResult == 'SUCCESS') {
|
||||
rocketSend ":thumbsup: ThreadX regression run passed, results at ${env.RUN_DISPLAY_URL} "
|
||||
} else if (currentBuild.currentResult == 'UNSTABLE') {
|
||||
rocketSend ":warning: ThreadX canary regression is unstable on ${params.SIMULATOR_IMAGE_LATEST}, please check ${env.RUN_DISPLAY_URL} "
|
||||
} else if (currentBuild.currentResult == 'FAILURE') {
|
||||
archiveArtifacts artifacts: 'failed_seeds_*.txt', followSymlinks: false, onlyIfSuccessful: false
|
||||
rocketSend ":thumbsdown: ThreadX regression failed, please check ${env.RUN_DISPLAY_URL} "
|
||||
emailext recipientProviders: [culprits(), requestor()],
|
||||
subject: "ThreadX Pipeline Failed: ${currentBuild.fullDisplayName}",
|
||||
body: """
|
||||
<p>Build Status: ${currentBuild.currentResult}</p>
|
||||
<p> Check logs at <a href='${env.BUILD_URL}console'> Build Console Logs </a> or at <a href='${env.RUN_DISPLAY_URL}'> Overview </a></p>
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user