You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
8.8 KiB
232 lines
8.8 KiB
#!/usr/bin/env groovy |
|
|
|
def boards = [] |
|
def examples = [] |
|
def tests = [] |
|
def driver_tests = [] |
|
def pkg_tests = [] |
|
def periph_tests = [] |
|
def other_tests = [] |
|
def unittests = [] |
|
|
|
/* stop running jobs */ |
|
abortPreviousBuilds() |
|
|
|
stage('setup') { |
|
node ('master') { |
|
sh '(( "\${RIOT_MIRROR}" )) && git -C "\${RIOT_MIRROR_DIR}" fetch --all' |
|
|
|
deleteDir() |
|
|
|
fetchPR(env.CHANGE_ID, "--depth=1", "") |
|
|
|
/* get all boards */ |
|
boards = sh(returnStdout: true, |
|
script: 'find $(pwd)/boards/* -maxdepth 0 -type d \\! -name "*-common" -exec basename {} \\;' |
|
).trim().split('\n') |
|
/* get all examples */ |
|
examples = sh(returnStdout: true, |
|
script: 'find examples/* -maxdepth 1 -name Makefile -print0 | xargs -0 -n1 dirname' |
|
).trim().split('\n') |
|
/* get all tests */ |
|
tests = sh(returnStdout: true, |
|
script: 'find tests/* -maxdepth 1 -name Makefile -print0 | xargs -0 -n1 dirname' |
|
).trim().split('\n') |
|
|
|
/* split tests into smaller sets */ |
|
for (int i=0; i < tests.size(); i++) { |
|
if (tests[i].startsWith("tests/driver_")) { |
|
driver_tests << tests[i] |
|
} |
|
else if (tests[i].startsWith("tests/pkg_")) { |
|
pkg_tests << tests[i] |
|
} |
|
else if (tests[i].startsWith("tests/periph_")) { |
|
periph_tests << tests[i] |
|
} |
|
else if (tests[i].startsWith("tests/unittests")) { |
|
unittests << tests[i] |
|
} |
|
else { |
|
other_tests << tests[i] |
|
} |
|
} |
|
deleteDir() |
|
} |
|
} |
|
|
|
stage('static-tests') { |
|
node('linux && boards') { |
|
deleteDir() |
|
|
|
fetchPR(env.CHANGE_ID, "", "master:master") |
|
|
|
def ret = sh(returnStatus: true, |
|
script: """#!/bin/bash +x |
|
declare -i RESULT=0 |
|
./dist/tools/static-tests.sh >> success_static-tests.log 2>&1 || RESULT=1 |
|
if ((\$RESULT)); then |
|
mv success_static-tests.log error_static-tests.log; |
|
fi; |
|
exit \$RESULT""") |
|
if (ret) { |
|
currentBuild.result = 'UNSTABLE' |
|
} |
|
step([$class: 'ArtifactArchiver', artifacts: "*_static-tests.log", fingerprint: true, allowEmptyArchive: true]) |
|
deleteDir() |
|
} |
|
} |
|
|
|
stage("unittests") { |
|
def builds = [:] |
|
|
|
/* setup all concurrent builds */ |
|
def boardName = "" |
|
for (int i=0; i < boards.size(); i++) { |
|
boardName = boards[i] |
|
builds['linux_unittests_' + boardName] = make_build("linux && boards && native", boardName, "linux_unittests", unittests) |
|
} |
|
/* distribute all builds to the slaves */ |
|
parallel (builds) |
|
|
|
abortOnError("unittests failed") |
|
} |
|
|
|
stage("tests") { |
|
def builds = [:] |
|
|
|
/* setup all concurrent builds */ |
|
def boardName = "" |
|
for (int i=0; i < boards.size(); i++) { |
|
boardName = boards[i] |
|
builds['linux_driver_tests_' + boardName] = make_build("linux && boards && native", boardName, "linux_driver_tests", driver_tests) |
|
builds['linux_pkg_tests_' + boardName] = make_build("linux && boards && native", boardName, "linux_pkg_tests", pkg_tests) |
|
builds['linux_periph_tests_' + boardName] = make_build("linux && boards && native", boardName, "linux_periph_tests", periph_tests) |
|
builds['linux_other_tests_' + boardName] = make_build("linux && boards && native", boardName, "linux_other_tests", other_tests) |
|
} |
|
|
|
|
|
/* ignore macOS builds for now - macOS is currently broken for native |
|
builds['macOS_driver_tests_native'] = make_build("macOS && native", "native", "macOS_driver_tests", driver_tests) |
|
builds['macOS_pkg_tests_native'] = make_build("macOS && native", "native", "macOS_pkg_tests", pkg_tests) |
|
builds['macOS_periph_tests_native'] = make_build("macOS && native", "native", "macOS_periph_tests", periph_tests) |
|
builds['macOS_other_tests_native'] = make_build("macOS && native", "native", "macOS_other_tests", other_tests) |
|
*/ |
|
/* ignore raspi builds for now - slows down the build (needs investigation) |
|
builds['raspi_driver_tests_native'] = make_build("raspi && native", "native", "raspi_driver_tests", driver_tests) |
|
builds['raspi_pkg_tests_native'] = make_build("raspi && native", "native", "raspi_pkg_tests", pkg_tests) |
|
builds['raspi_periph_tests_native'] = make_build("raspi && native", "native", "raspi_periph_tests", periph_tests) |
|
builds['raspi_other_tests_native'] = make_build("raspi && native", "native", "raspi_other_tests", other_tests) |
|
*/ |
|
|
|
/* distribute all builds to the slaves */ |
|
parallel (builds) |
|
|
|
abortOnError("tests failed") |
|
} |
|
|
|
stage("examples") { |
|
def builds = [:] |
|
|
|
/* setup all concurrent builds */ |
|
def boardName = "" |
|
for (int i=0; i < boards.size(); i++) { |
|
boardName = boards[i] |
|
builds['linux_examples_' + boardName] = make_build("linux && boards && native", boardName, "linux_examples", examples) |
|
} |
|
|
|
/* ignore macOS builds for now - macOS is currently broken for native |
|
builds['macOS_examples_native'] = make_build("macOS && native", "native", "macOS_examples", examples) |
|
*/ |
|
/* ignore raspi builds for now - slows down the build (needs investigation) |
|
builds['raspi_examples_native'] = make_build("raspi && native", "native", "raspi_examples", examples) |
|
*/ |
|
|
|
/* distribute all builds to the slaves */ |
|
parallel (builds) |
|
|
|
abortOnError("examples failed") |
|
} |
|
|
|
if (currentBuild.result == null) { |
|
currentBuild.result = 'SUCCESS' |
|
} |
|
|
|
/* create a job */ |
|
def make_build(label, board, desc, arg) |
|
{ |
|
return { |
|
node(label) { |
|
try { |
|
deleteDir() |
|
fetchPR(env.CHANGE_ID, "--depth=1", "") |
|
def build_dir = pwd() |
|
sh "./dist/tools/git/git-cache init" |
|
timestamps { |
|
def apps = arg.join(' ') |
|
echo "building ${apps} for ${board} on nodes with ${label}" |
|
withEnv([ |
|
"BOARD=${board}", |
|
"CCACHE_BASEDIR=${build_dir}", |
|
"RIOT_CI_BUILD=1"]) { |
|
def ret = sh(returnStatus: true, |
|
script: """#!/bin/bash +ex |
|
declare -i RESULT=0 |
|
for app in ${apps}; do |
|
if [[ \$(make -sC \$app info-boards-supported | tr ' ' '\n' | sed -n '/^${board}\$/p') ]]; then |
|
echo \"\n\nBuilding \$app for ${board}\" >> success_${board}_${desc}.log |
|
rm -rf jenkins_bin; mkdir jenkins_bin |
|
CFLAGS_DBG=\"\" BINDIR=\$(pwd)/jenkins_bin make -j\${NPROC} -C \$app all >> success_${board}_${desc}.log 2>&1 || RESULT=1 |
|
fi; |
|
done; |
|
if ((\$RESULT)); then |
|
mv success_${board}_${desc}.log error_${board}_${desc}.log |
|
fi; |
|
exit \$RESULT""") |
|
if (ret) { |
|
currentBuild.result = 'FAILURE' |
|
} |
|
step([$class: 'ArtifactArchiver', artifacts: "*_${board}_${desc}.log", fingerprint: true, allowEmptyArchive: true]) |
|
} |
|
} |
|
} catch(e) { |
|
echo "${e.toString()}" |
|
currentBuild.result = 'FAILURE' |
|
} finally { |
|
deleteDir() |
|
} |
|
} |
|
} |
|
} |
|
|
|
/* abort previous, running builds */ |
|
def abortPreviousBuilds() |
|
{ |
|
def buildnum = env.BUILD_NUMBER.toInteger() |
|
def job = Jenkins.instance.getItemByFullName(env.JOB_NAME) |
|
for (build in job.builds) { |
|
if (!build.isBuilding() || (buildnum == build.getNumber().toInteger())) { |
|
continue; |
|
} |
|
build.doStop(); |
|
} |
|
} |
|
|
|
def abortOnError(msg) |
|
{ |
|
if ((currentBuild.result != null) && (currentBuild.result == 'FAILURE')) { |
|
error msg |
|
} |
|
} |
|
|
|
def fetchPR(prNum, fetchArgs, extraRefSpec) |
|
{ |
|
sh """git init |
|
if (( "\${RIOT_MIRROR}" )); then RIOT_URL="\${RIOT_MIRROR_URL}"; else RIOT_URL="https://github.com/RIOT-OS/RIOT"; fi |
|
git remote add origin "\${RIOT_URL}" |
|
for RETRIES in {1..3}; do |
|
timeout 30 git fetch -u -n ${fetchArgs} origin ${extraRefSpec} pull/${prNum}/merge:pull_${prNum} && break |
|
done |
|
[[ "\$RETRIES" -eq 3 ]] && exit 1 |
|
git checkout pull_${prNum}""" |
|
}
|
|
|