|
|
@ -9,6 +9,28 @@ def retryWithDelay(int maxRetries, int delay, Closure body) { |
|
|
|
throw Exception("Failed after ${maxRetries} retries") |
|
|
|
throw Exception("Failed after ${maxRetries} retries") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if started by timer: https://stackoverflow.com/questions/43516025/how-to-handle-nightly-build-in-jenkins-declarative-pipeline |
|
|
|
|
|
|
|
@NonCPS |
|
|
|
|
|
|
|
def isJobStartedByTimer() { |
|
|
|
|
|
|
|
def startedByTimer = false |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
def buildCauses = currentBuild.rawBuild.getCauses() |
|
|
|
|
|
|
|
for ( buildCause in buildCauses ) { |
|
|
|
|
|
|
|
if (buildCause != null) { |
|
|
|
|
|
|
|
def causeDescription = buildCause.getShortDescription() |
|
|
|
|
|
|
|
echo "shortDescription: ${causeDescription}" |
|
|
|
|
|
|
|
if (causeDescription.contains("Started by timer")) { |
|
|
|
|
|
|
|
startedByTimer = true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} catch(theError) { |
|
|
|
|
|
|
|
echo "Error getting build cause" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return startedByTimer |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
def device(String ip, String step_label, String cmd) { |
|
|
|
def device(String ip, String step_label, String cmd) { |
|
|
|
withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) { |
|
|
|
withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) { |
|
|
|
def ssh_cmd = """ |
|
|
|
def ssh_cmd = """ |
|
|
@ -151,15 +173,31 @@ def build_release(String channel_name) { |
|
|
|
deviceStage("build git", "tici-needs-can", [], [ |
|
|
|
deviceStage("build git", "tici-needs-can", [], [ |
|
|
|
["build ${channel_name}", "RELEASE_BRANCH=${channel_name} $SOURCE_DIR/release/build_release.sh"], |
|
|
|
["build ${channel_name}", "RELEASE_BRANCH=${channel_name} $SOURCE_DIR/release/build_release.sh"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_casync_release(String channel_name, def release) { |
|
|
|
|
|
|
|
def extra_env = release ? "RELEASE=1" : "" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return deviceStage("build casync", "tici-needs-can", [], [ |
|
|
|
|
|
|
|
["build", "${extra_env} BUILD_DIR=/data/openpilot CASYNC_DIR=/data/casync/openpilot $SOURCE_DIR/release/create_casync_build.sh"], |
|
|
|
|
|
|
|
["create manifest", "$SOURCE_DIR/release/create_release_manifest.py /data/openpilot /data/manifest.json && cat /data/manifest.json"], |
|
|
|
|
|
|
|
["upload and cleanup", "PYTHONWARNINGS=ignore $SOURCE_DIR/release/upload_casync_release.py /data/casync && rm -rf /data/casync"], |
|
|
|
|
|
|
|
]) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_stage() { |
|
|
|
|
|
|
|
return parallel ( |
|
|
|
|
|
|
|
'nightly': { |
|
|
|
|
|
|
|
build_release("nightly", true); |
|
|
|
}, |
|
|
|
}, |
|
|
|
"${channel_name} (casync)": { |
|
|
|
'master': { |
|
|
|
deviceStage("build casync", "tici-needs-can", [], [ |
|
|
|
build_release("master", false); |
|
|
|
["build", "RELEASE=1 BUILD_DIR=/data/openpilot CASYNC_DIR=/data/casync/openpilot $SOURCE_DIR/release/create_casync_build.sh"], |
|
|
|
|
|
|
|
["create manifest", "$SOURCE_DIR/release/create_release_manifest.py /data/openpilot /data/manifest.json && cat /data/manifest.json"], |
|
|
|
|
|
|
|
["upload and cleanup", "PYTHONWARNINGS=ignore $SOURCE_DIR/release/upload_casync_release.py /data/casync && rm -rf /data/casync"], |
|
|
|
|
|
|
|
]) |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
"publish agnos": { |
|
|
|
'publish agnos': { |
|
|
|
pcStage("publish agnos") { |
|
|
|
pcStage("publish agnos") { |
|
|
|
sh "release/create_casync_agnos_release.py /tmp/casync/agnos /tmp/casync_tmp" |
|
|
|
sh "release/create_casync_agnos_release.py /tmp/casync/agnos /tmp/casync_tmp" |
|
|
|
sh "PYTHONWARNINGS=ignore ${env.WORKSPACE}/release/upload_casync_release.py /tmp/casync" |
|
|
|
sh "PYTHONWARNINGS=ignore ${env.WORKSPACE}/release/upload_casync_release.py /tmp/casync" |
|
|
@ -168,7 +206,6 @@ def build_release(String channel_name) { |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
node { |
|
|
|
node { |
|
|
|
env.CI = "1" |
|
|
|
env.CI = "1" |
|
|
|
env.PYTHONWARNINGS = "error" |
|
|
|
env.PYTHONWARNINGS = "error" |
|
|
@ -183,12 +220,23 @@ node { |
|
|
|
'testing-closet*', 'hotfix-*'] |
|
|
|
'testing-closet*', 'hotfix-*'] |
|
|
|
def excludeRegex = excludeBranches.join('|').replaceAll('\\*', '.*') |
|
|
|
def excludeRegex = excludeBranches.join('|').replaceAll('\\*', '.*') |
|
|
|
|
|
|
|
|
|
|
|
if (env.BRANCH_NAME != 'master') { |
|
|
|
def nightlyBranch = "master" |
|
|
|
properties([ |
|
|
|
|
|
|
|
disableConcurrentBuilds(abortPrevious: true) |
|
|
|
def props = []; |
|
|
|
]) |
|
|
|
|
|
|
|
|
|
|
|
if (env.BRANCH_NAME == nightlyBranch) { |
|
|
|
|
|
|
|
props.add(pipelineTriggers([ |
|
|
|
|
|
|
|
pollSCM('* * * * *'), // every commit |
|
|
|
|
|
|
|
cron('0 2 * * *') // and at 2am every night |
|
|
|
|
|
|
|
])) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (env.branch != "master") { |
|
|
|
|
|
|
|
props.add(disableConcurrentBuilds(abortPrevious: true)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
properties(props); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
if (env.BRANCH_NAME == 'devel-staging') { |
|
|
|
if (env.BRANCH_NAME == 'devel-staging') { |
|
|
|
build_release("release3-staging") |
|
|
|
build_release("release3-staging") |
|
|
@ -199,74 +247,79 @@ node { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!env.BRANCH_NAME.matches(excludeRegex)) { |
|
|
|
if (!env.BRANCH_NAME.matches(excludeRegex)) { |
|
|
|
parallel ( |
|
|
|
parallel ( |
|
|
|
// tici tests |
|
|
|
// tici tests |
|
|
|
'onroad tests': { |
|
|
|
'onroad tests': { |
|
|
|
deviceStage("onroad", "tici-needs-can", [], [ |
|
|
|
deviceStage("onroad", "tici-needs-can", [], [ |
|
|
|
// TODO: ideally, this test runs in master-ci, but it takes 5+m to build it |
|
|
|
// TODO: ideally, this test runs in master-ci, but it takes 5+m to build it |
|
|
|
//["build master-ci", "cd $SOURCE_DIR/release && TARGET_DIR=$TEST_DIR $SOURCE_DIR/scripts/retry.sh ./build_devel.sh"], |
|
|
|
//["build master-ci", "cd $SOURCE_DIR/release && TARGET_DIR=$TEST_DIR $SOURCE_DIR/scripts/retry.sh ./build_devel.sh"], |
|
|
|
["build openpilot", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build openpilot", "cd selfdrive/manager && ./build.py"], |
|
|
|
["check dirty", "release/check-dirty.sh"], |
|
|
|
["check dirty", "release/check-dirty.sh"], |
|
|
|
["onroad tests", "pytest selfdrive/test/test_onroad.py -s"], |
|
|
|
["onroad tests", "pytest selfdrive/test/test_onroad.py -s"], |
|
|
|
["time to onroad", "pytest selfdrive/test/test_time_to_onroad.py"], |
|
|
|
["time to onroad", "pytest selfdrive/test/test_time_to_onroad.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
}, |
|
|
|
}, |
|
|
|
'HW + Unit Tests': { |
|
|
|
'HW + Unit Tests': { |
|
|
|
deviceStage("tici-hardware", "tici-common", ["UNSAFE=1"], [ |
|
|
|
deviceStage("tici-hardware", "tici-common", ["UNSAFE=1"], [ |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"], |
|
|
|
["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"], |
|
|
|
["test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"], |
|
|
|
["test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"], |
|
|
|
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"], |
|
|
|
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"], |
|
|
|
["test pigeond", "pytest system/ubloxd/tests/test_pigeond.py"], |
|
|
|
["test pigeond", "pytest system/ubloxd/tests/test_pigeond.py"], |
|
|
|
["test manager", "pytest selfdrive/manager/test/test_manager.py"], |
|
|
|
["test manager", "pytest selfdrive/manager/test/test_manager.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
}, |
|
|
|
}, |
|
|
|
'loopback': { |
|
|
|
'loopback': { |
|
|
|
deviceStage("loopback", "tici-loopback", ["UNSAFE=1"], [ |
|
|
|
deviceStage("loopback", "tici-loopback", ["UNSAFE=1"], [ |
|
|
|
["build openpilot", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build openpilot", "cd selfdrive/manager && ./build.py"], |
|
|
|
["test boardd loopback", "pytest selfdrive/boardd/tests/test_boardd_loopback.py"], |
|
|
|
["test boardd loopback", "pytest selfdrive/boardd/tests/test_boardd_loopback.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
}, |
|
|
|
}, |
|
|
|
'camerad': { |
|
|
|
'camerad': { |
|
|
|
deviceStage("AR0231", "tici-ar0231", ["UNSAFE=1"], [ |
|
|
|
deviceStage("AR0231", "tici-ar0231", ["UNSAFE=1"], [ |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["test camerad", "pytest system/camerad/test/test_camerad.py"], |
|
|
|
["test camerad", "pytest system/camerad/test/test_camerad.py"], |
|
|
|
["test exposure", "pytest system/camerad/test/test_exposure.py"], |
|
|
|
["test exposure", "pytest system/camerad/test/test_exposure.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
deviceStage("OX03C10", "tici-ox03c10", ["UNSAFE=1"], [ |
|
|
|
deviceStage("OX03C10", "tici-ox03c10", ["UNSAFE=1"], [ |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["test camerad", "pytest system/camerad/test/test_camerad.py"], |
|
|
|
["test camerad", "pytest system/camerad/test/test_camerad.py"], |
|
|
|
["test exposure", "pytest system/camerad/test/test_exposure.py"], |
|
|
|
["test exposure", "pytest system/camerad/test/test_exposure.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
}, |
|
|
|
}, |
|
|
|
'sensord': { |
|
|
|
'sensord': { |
|
|
|
deviceStage("LSM + MMC", "tici-lsmc", ["UNSAFE=1"], [ |
|
|
|
deviceStage("LSM + MMC", "tici-lsmc", ["UNSAFE=1"], [ |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["test sensord", "pytest system/sensord/tests/test_sensord.py"], |
|
|
|
["test sensord", "pytest system/sensord/tests/test_sensord.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
deviceStage("BMX + LSM", "tici-bmx-lsm", ["UNSAFE=1"], [ |
|
|
|
deviceStage("BMX + LSM", "tici-bmx-lsm", ["UNSAFE=1"], [ |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["test sensord", "pytest system/sensord/tests/test_sensord.py"], |
|
|
|
["test sensord", "pytest system/sensord/tests/test_sensord.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
}, |
|
|
|
}, |
|
|
|
'replay': { |
|
|
|
'replay': { |
|
|
|
deviceStage("model-replay", "tici-replay", ["UNSAFE=1"], [ |
|
|
|
deviceStage("model-replay", "tici-replay", ["UNSAFE=1"], [ |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build", "cd selfdrive/manager && ./build.py"], |
|
|
|
["model replay", "selfdrive/test/process_replay/model_replay.py"], |
|
|
|
["model replay", "selfdrive/test/process_replay/model_replay.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
}, |
|
|
|
}, |
|
|
|
'tizi': { |
|
|
|
'tizi': { |
|
|
|
deviceStage("tizi", "tizi", ["UNSAFE=1"], [ |
|
|
|
deviceStage("tizi", "tizi", ["UNSAFE=1"], [ |
|
|
|
["build openpilot", "cd selfdrive/manager && ./build.py"], |
|
|
|
["build openpilot", "cd selfdrive/manager && ./build.py"], |
|
|
|
["test boardd loopback", "SINGLE_PANDA=1 pytest selfdrive/boardd/tests/test_boardd_loopback.py"], |
|
|
|
["test boardd loopback", "SINGLE_PANDA=1 pytest selfdrive/boardd/tests/test_boardd_loopback.py"], |
|
|
|
["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"], |
|
|
|
["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"], |
|
|
|
["test amp", "pytest system/hardware/tici/tests/test_amplifier.py"], |
|
|
|
["test amp", "pytest system/hardware/tici/tests/test_amplifier.py"], |
|
|
|
["test hw", "pytest system/hardware/tici/tests/test_hardware.py"], |
|
|
|
["test hw", "pytest system/hardware/tici/tests/test_hardware.py"], |
|
|
|
["test qcomgpsd", "pytest system/qcomgpsd/tests/test_qcomgpsd.py"], |
|
|
|
["test qcomgpsd", "pytest system/qcomgpsd/tests/test_qcomgpsd.py"], |
|
|
|
]) |
|
|
|
]) |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (env.BRANCH_NAME == nightlyBranch && isJobStartedByTimer()) { |
|
|
|
|
|
|
|
stage('build release') { |
|
|
|
|
|
|
|
build_stage() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
} catch (Exception e) { |
|
|
|
currentBuild.result = 'FAILED' |
|
|
|
currentBuild.result = 'FAILED' |
|
|
|