blob: d97a7406578873ae8708ae369db03630a39f7fa8 [file] [log] [blame]
////////////////////////////////////////////////////////////
//
// Common Vars and Branch List
//
// Help on syntax see https://ci-cassandra.apache.org/plugin/job-dsl/api-viewer/index.html
//
// To update the variable via the Jenkins UI, use the EnvInject plugin
// example: https://github.com/apache/cassandra-builds/pull/19#issuecomment-610822772
//
////////////////////////////////////////////////////////////
def jobDescription = '''
<p><img src="http://cassandra.apache.org/img/cassandra_logo.png" />
<br/>Apache Cassandra DSL-generated job - DSL git repo: <a href="https://github.com/apache/cassandra-builds">cassandra-builds</a></p>
<p>Logs and test results are archived in <a href="https://nightlies.apache.org/cassandra/">nightlies.apache.org</a>
<br/><i>protip: it is required to look in the pipeline's console log to find the stage build numbers for a specific pipeline run</i></p>
<p>A basic mirror of all build summary pages (classic and blue ocean ui) is found here <a href="https://nightlies.apache.org/cassandra/ci-cassandra.apache.org/">here</a></p>
'''
def jdkLabel = 'jdk_1.8_latest'
if(binding.hasVariable("CASSANDRA_JDK_LABEL")) {
jdkLabel = "${CASSANDRA_JDK_LABEL}"
}
// architectures. blank is amd64
def archs = ['', '-arm64']
arm64_enabled = true
arm64_test_label_enabled = false
def use_arm64_test_label() { return arm64_enabled && arm64_test_label_enabled }
def slaveLabel = 'cassandra'
slaveDtestLabel = 'cassandra-dtest'
slaveDtestLargeLabel = 'cassandra-dtest-large'
slaveArm64Label = 'cassandra-arm64'
slaveArm64DtestLabel = 'cassandra-arm64-dtest'
slaveArm64DtestLargeLabel = 'cassandra-arm64-dtest-large'
def mainRepo = "https://github.com/apache/cassandra.git"
def githubRepo = "https://github.com/apache/cassandra"
if(binding.hasVariable("CASSANDRA_GIT_URL")) {
mainRepo = "${CASSANDRA_GIT_URL}"
// just presume custom repos are github, not critical if they are not
githubRepo = "${mainRepo}".minus(".git")
}
def buildsRepo = "https://github.com/apache/cassandra-builds.git"
if(binding.hasVariable("CASSANDRA_BUILDS_GIT_URL")) {
buildsRepo = "${CASSANDRA_BUILDS_GIT_URL}"
}
def buildsBranch = "trunk"
if(binding.hasVariable("CASSANDRA_BUILDS_BRANCH")) {
buildsBranch = "${CASSANDRA_BUILDS_BRANCH}"
}
def dtestRepo = "https://github.com/apache/cassandra-dtest.git"
if(binding.hasVariable("CASSANDRA_DTEST_GIT_URL")) {
dtestRepo = "${CASSANDRA_DTEST_GIT_URL}"
}
def buildDescStr = 'REF = ${GIT_BRANCH} <br /> COMMIT = ${GIT_COMMIT}'
// Cassandra active branches
def cassandraBranches = ['cassandra-2.2', 'cassandra-3.0', 'cassandra-3.11', 'cassandra-4.0', 'cassandra-4.0.0', 'trunk']
if(binding.hasVariable("CASSANDRA_BRANCHES")) {
cassandraBranches = "${CASSANDRA_BRANCHES}".split(",")
}
// Ant test targets
def testTargets = ['test', 'test-burn', 'test-cdc', 'test-compression', 'stress-test', 'fqltool-test', 'long-test', 'jvm-dtest', 'jvm-dtest-upgrade', 'microbench']
if(binding.hasVariable("CASSANDRA_ANT_TEST_TARGETS")) {
testTargets = "${CASSANDRA_ANT_TEST_TARGETS}".split(",")
}
def testDockerImage = 'apache/cassandra-testing-ubuntu2004-java11-w-dependencies'
// Dtest test targets
def dtestTargets = ['dtest', 'dtest-novnode', 'dtest-offheap', 'dtest-large', 'dtest-large-novnode', 'dtest-upgrade']
if(binding.hasVariable("CASSANDRA_DTEST_TEST_TARGETS")) {
dtestTargets = "${CASSANDRA_DTEST_TEST_TARGETS}".split(",")
}
def dtestDockerImage = 'apache/cassandra-testing-ubuntu2004-java11'
// expected longest job runtime
def maxJobHours = 12
if(binding.hasVariable("MAX_JOB_HOURS")) {
maxJobHours = ${MAX_JOB_HOURS}
}
// how many splits are dtest jobs matrixed into
def testSplits = 8
def dtestSplits = 64
def dtestLargeSplits = 8
def isSplittableTest(targetName) {
return targetName == 'test' || targetName == 'test-cdc' || targetName == 'test-compression' || targetName == 'test-burn' || targetName == 'long-test' || targetName == 'jvm-dtest' || targetName == 'jvm-dtest-upgrade';
}
////////////////////////////////////////////////////////////
//
// Job Templates
// - disabled by default
// - running jobs use templates for most configurations
// and set details like branch
//
////////////////////////////////////////////////////////////
/**
* Artifacts and eclipse-warnings template
*/
matrixJob('Cassandra-template-artifacts') {
disabled(true)
description(jobDescription)
concurrentBuild()
compressBuildLog()
logRotator {
numToKeep(10)
artifactNumToKeep(5)
artifactDaysToKeep(1)
}
wrappers {
timeout {
noActivity(300)
}
timestamps()
}
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(1)
}
}
scm {
git {
remote {
url(mainRepo)
}
branch('*/null')
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
steps {
buildDescription('', buildDescStr)
shell("""
git clean -xdff ;
git clone --depth 1 --single-branch -b ${buildsBranch} ${buildsRepo} ;
echo "cassandra-builds at: `git -C cassandra-builds log -1 --pretty=format:'%h %an %ad %s'`" ;
""")
}
publishers {
extendedEmail {
recipientList('builds@cassandra.apache.org')
triggers {
failure {
sendTo {
recipientList()
developers()
requester()
culprits()
}
}
fixed {
sendTo {
recipientList()
developers()
requester()
culprits()
}
}
}
}
}
}
/**
* Ant test template
*/
matrixJob('Cassandra-template-test') {
disabled(true)
description(jobDescription)
concurrentBuild()
compressBuildLog()
logRotator {
numToKeep(10)
artifactNumToKeep(5)
artifactDaysToKeep(1)
}
wrappers {
timeout {
noActivity(5400)
}
timestamps()
}
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(3)
}
}
scm {
git {
remote {
url(mainRepo)
}
branch('*/null')
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
steps {
buildDescription('', buildDescStr)
shell("""
git clean -xdff -e build/test/jmh-result.json ;
git clone --depth 1 --single-branch -b ${buildsBranch} ${buildsRepo} ;
echo "cassandra-builds at: `git -C cassandra-builds log -1 --pretty=format:'%h %an %ad %s'`" ;
echo "\${BUILD_TAG}) cassandra: `git log -1 --pretty=format:'%h %an %ad %s'`" > \${BUILD_TAG}.head
""")
}
publishers {
archiveArtifacts {
pattern('build/test/**/TEST-*.xml, **/*.head')
allowEmpty()
fingerprint()
}
}
}
/**
* Dtest template
*/
matrixJob('Cassandra-template-dtest-matrix') {
disabled(true)
description(jobDescription)
concurrentBuild()
compressBuildLog()
logRotator {
numToKeep(10)
artifactNumToKeep(5)
artifactDaysToKeep(1)
}
wrappers {
timeout {
noActivity(5400)
}
timestamps()
}
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(7)
}
}
scm {
git {
remote {
url(mainRepo)
}
branch('*/null')
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
steps {
buildDescription('', buildDescStr)
shell("""
git clean -xdff ;
git clone --depth 1 --single-branch -b ${buildsBranch} ${buildsRepo} ;
echo "cassandra-builds at: `git -C cassandra-builds log -1 --pretty=format:'%h %an %ad %s'`" ;
echo "\${BUILD_TAG}) cassandra: `git log -1 --pretty=format:'%h %an %ad %s'`" > \${BUILD_TAG}.head ;
""")
}
}
/**
* cqlsh template
*/
matrixJob('Cassandra-template-cqlsh-tests') {
disabled(true)
description(jobDescription)
concurrentBuild()
compressBuildLog()
logRotator {
numToKeep(10)
artifactNumToKeep(5)
artifactDaysToKeep(1)
}
wrappers {
timeout {
noActivity(1200)
}
timestamps()
}
throttleConcurrentBuilds {
categories(['Cassandra'])
}
axes {
text('cython', 'yes', 'no')
jdk(jdkLabel)
if (use_arm64_test_label()) {
label('label', slaveLabel, slaveArm64Label)
} else {
label('label', slaveLabel)
}
}
// this should prevent long path expansion from the axis definitions
childCustomWorkspace('.')
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(3)
}
}
scm {
git {
remote {
url(mainRepo)
}
branch('*/null')
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
steps {
buildDescription('', buildDescStr)
shell("""
git clean -xdff ;
./pylib/cassandra-cqlsh-tests.sh \$WORKSPACE ;
echo "\${BUILD_TAG}) cassandra: `git log -1 --pretty=format:'%h %an %ad %s'`" > \${BUILD_TAG}.head ;
wget --retry-connrefused --waitretry=1 "\${BUILD_URL}/timestamps/?time=HH:mm:ss&timeZone=UTC&appendLog" -qO - > console.log.xz || echo wget failed
""")
}
}
////////////////////////////////////////////////////////////
//
// Branch Job Definitions
// - set to disabled(false)
// - running jobs use templates for most configurations
// and set details like branch
//
////////////////////////////////////////////////////////////
cassandraBranches.each {
def branchName = it
def jobNamePrefix = "Cassandra-${branchName}".replaceAll('cassandra-', '')
/**
* Main branch artifacts and eclipse-warnings job
*/
matrixJob("${jobNamePrefix}-artifacts") {
disabled(false)
using('Cassandra-template-artifacts')
axes {
if (branchName == 'trunk' || branchName == 'cassandra-4.0.0' || branchName == 'cassandra-4.0') {
jdk('jdk_1.8_latest','jdk_11_latest')
} else {
jdk('jdk_1.8_latest')
}
if (arm64_enabled) {
label('label', slaveLabel, slaveArm64Label)
} else {
label('label', slaveLabel)
}
}
configure { node ->
node / scm / branches / 'hudson.plugins.git.BranchSpec' / name(branchName)
}
steps {
shell("""
./cassandra-builds/build-scripts/cassandra-artifacts.sh ;
wget --retry-connrefused --waitretry=1 "\${BUILD_URL}/timestamps/?time=HH:mm:ss&timeZone=UTC&appendLog" -qO - > console.log.xz || echo wget failed
""")
}
publishers {
publishOverSsh {
server('Nightlies') {
transferSet {
sourceFiles("console.log.xz, build/apache-cassandra-*.tar.gz, build/apache-cassandra-*.jar, build/apache-cassandra-*.pom, build/cassandra*.deb, build/cassandra*.rpm")
remoteDirectory("cassandra/${branchName}/${jobNamePrefix}-artifacts/\${BUILD_NUMBER}/\${JOB_NAME}/")
}
retry(9, 5000)
}
failOnError(false)
}
postBuildTask {
// docker needs to (soon or later) prune its volumes too, but that can only be done when the agent is idle
// if the agent is busy, just prune everything that is older than maxJobHours
task('.', """
echo "Cleaning project"; git clean -xdff ;
echo "Pruning docker" ;
if pgrep -af "cassandra-builds/build-scripts" ; then docker system prune --all --force --filter "until=${maxJobHours}h" || true ; else docker system prune --all --force --volumes || true ; fi;
echo "Reporting disk usage"; df -h ;
echo "Cleaning tmp";
find . -type d -name tmp -delete 2>/dev/null ;
find /tmp -type f -atime +2 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null || echo clean tmp failed ;
echo "For test report and logs see https://nightlies.apache.org/cassandra/${branchName}/${jobNamePrefix}-artifacts/\${BUILD_NUMBER}/\${JOB_NAME}/"
""")
}
}
}
/**
* Main branch ant test target jobs
*/
testTargets.each {
def targetName = it
// Skip tests that don't exist before cassandra-3.11
if ((targetName == 'test-cdc' || targetName == 'stress-test') && ((branchName == 'cassandra-2.2') || (branchName == 'cassandra-3.0'))) {
println("Skipping ${targetName} on branch ${branchName}")
// Skip tests that don't exist before cassandra-4.0
} else if ((targetName == 'fqltool-test') && ((branchName == 'cassandra-2.2') || (branchName == 'cassandra-3.0') || (branchName == 'cassandra-3.11'))) {
println("Skipping ${targetName} on branch ${branchName}")
} else {
matrixJob("${jobNamePrefix}-${targetName}") {
disabled(false)
using('Cassandra-template-test')
def _testSplits = ''
axes {
if (isSplittableTest(targetName)) {
List<String> values = new ArrayList<String>()
(1..testSplits).each { values << it.toString() }
text('split', values)
_testSplits = "/${testSplits}"
}
// jvm-dtest-upgrade would require mixed JDK compilations to support JDK11+
if ((branchName == 'trunk' || branchName == 'cassandra-4.0.0' || branchName == 'cassandra-4.0') && targetName != 'jvm-dtest-upgrade') {
jdk(jdkLabel,'jdk_11_latest')
} else {
jdk(jdkLabel)
}
if (use_arm64_test_label()) {
label('label', slaveLabel, slaveArm64Label)
} else {
label('label', slaveLabel)
}
}
configure { node ->
node / scm / branches / 'hudson.plugins.git.BranchSpec' / name(branchName)
}
steps {
shell("""
./cassandra-builds/build-scripts/cassandra-test-docker.sh apache ${branchName} ${buildsRepo} ${buildsBranch} ${testDockerImage} ${targetName} \${split}${_testSplits} ;
./cassandra-builds/build-scripts/cassandra-test-report.sh ;
xz TESTS-TestSuites.xml ;
wget --retry-connrefused --waitretry=1 "\${BUILD_URL}/timestamps/?time=HH:mm:ss&timeZone=UTC&appendLog" -qO - > console.log.xz || echo wget failed
""")
}
publishers {
if (targetName == 'microbench') {
jmhReport {
resultPath('build/test/jmh-result.json')
}
archiveJunit('build/test/**/TEST-*.xml') {
allowEmptyResults(true)
}
} else {
archiveJunit('build/test/**/TEST-*.xml') {
testDataPublishers {
publishTestStabilityData()
}
}
}
publishOverSsh {
server('Nightlies') {
transferSet {
sourceFiles("console.log.xz,TESTS-TestSuites.xml.xz,build/test/logs/**,build/test/jmh-result.json")
remoteDirectory("cassandra/${branchName}/${jobNamePrefix}-${targetName}/\${BUILD_NUMBER}/\${JOB_NAME}/")
}
retry(9, 5000)
}
failOnError(false)
}
postBuildTask {
// docker needs to (soon or later) prune its volumes too, but that can only be done when the agent is idle
// if the agent is busy, just prune everything that is older than maxJobHours
task('.', """
echo "Cleaning project…"; git clean -xdff -e build/test/jmh-result.json ;
echo "Pruning docker…" ;
if pgrep -af "cassandra-builds/build-scripts" ; then docker system prune --all --force --filter "until=${maxJobHours}h" || true ; else docker system prune --all --force --volumes || true ; fi;
echo "Reporting disk usage…"; du -xm / 2>/dev/null | sort -rn | head -n 30 ; df -h ;
echo "Cleaning tmp…";
find . -type d -name tmp -delete 2>/dev/null ;
find /tmp -type f -atime +2 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null || echo clean tmp failed ;
echo "For test report and logs see https://nightlies.apache.org/cassandra/${branchName}/${jobNamePrefix}-${targetName}/\${BUILD_NUMBER}/\${JOB_NAME}/"
""")
}
}
}
}
}
/**
* Main branch dtest variation jobs
*/
archs.each {
def arch = it
dtestTargets.each {
def targetName = it
def targetArchName = targetName + arch
// Skip dtest-offheap on cassandra-3.0 branch
if ((targetName == 'dtest-offheap') && (branchName == 'cassandra-3.0')) {
println("Skipping ${targetArchName} on branch ${branchName}")
} else {
matrixJob("${jobNamePrefix}-${targetArchName}") {
disabled(false)
using('Cassandra-template-dtest-matrix')
axes {
List<String> values = new ArrayList<String>()
if (targetName == 'dtest-large' || targetName == 'dtest-large-novnode') {
splits = dtestLargeSplits
} else {
splits = dtestSplits
}
(1..splits).each { values << it.toString() }
text('split', values)
if (targetName == 'dtest-large' || targetName == 'dtest-large-novnode') {
if (arch == "-arm64") {
label('label', slaveArm64DtestLargeLabel)
} else {
label('label', slaveDtestLargeLabel)
}
} else {
if (arch == "-arm64") {
label('label', slaveArm64DtestLabel)
} else {
label('label', slaveDtestLabel)
}
}
}
configure { node ->
node / scm / branches / 'hudson.plugins.git.BranchSpec' / name(branchName)
}
steps {
if (arch == "-arm64") {
shell("""
# docker image has to be built on arm64 (they are not currently published to dockerhub)
cd cassandra-builds/docker/testing ;
docker build -t ${dtestDockerImage}:latest -f ubuntu2004_j11.docker .
""")
}
shell("""
./cassandra-builds/build-scripts/cassandra-dtest-pytest-docker.sh apache ${branchName} https://github.com/apache/cassandra-dtest.git trunk ${buildsRepo} ${buildsBranch} ${dtestDockerImage} ${targetName} \${split}/${splits} ;
wget --retry-connrefused --waitretry=1 "\${BUILD_URL}/timestamps/?time=HH:mm:ss&timeZone=UTC&appendLog" -qO - > console.log.xz || echo wget failed
""")
}
publishers {
publishOverSsh {
server('Nightlies') {
transferSet {
sourceFiles("console.log.xz,**/nosetests.xml,**/test_stdout.txt.xz,**/ccm_logs.tar.xz")
remoteDirectory("cassandra/${branchName}/${jobNamePrefix}-${targetArchName}/\${BUILD_NUMBER}/\${JOB_NAME}/")
}
retry(9, 5000)
}
failOnError(false)
}
archiveArtifacts {
pattern('**/nosetests.xml,**/*.head')
allowEmpty()
fingerprint()
}
archiveJunit('nosetests.xml') {
testDataPublishers {
publishTestStabilityData()
}
}
postBuildTask {
// docker needs to (soon or later) prune its volumes too, but that can only be done when the agent is idle
// if the agent is busy, just prune everything that is older than maxJobHours
task('.', """
echo "Cleaning project"; git clean -xdff ;
echo "Pruning docker" ;
if pgrep -af "cassandra-builds/build-scripts" ; then docker system prune --all --force --filter "until=${maxJobHours}h" || true ; else docker system prune --all --force --volumes || true ; fi;
echo "Reporting disk usage"; df -h ;
echo "Cleaning tmp";
find . -type d -name tmp -delete 2>/dev/null ;
find /tmp -type f -atime +2 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null || echo clean tmp failed ;
echo "For test report and logs see https://nightlies.apache.org/cassandra/${branchName}/${jobNamePrefix}-${targetArchName}/\${BUILD_NUMBER}/\${JOB_NAME}/"
""")
}
}
}
}
}
}
/**
* Main branch cqlsh jobs
*/
if (branchName == 'cassandra-2.2') {
println("Skipping ${jobNamePrefix}-cqlsh-tests, not supported on branch ${branchName}")
} else {
matrixJob("${jobNamePrefix}-cqlsh-tests") {
disabled(false)
using('Cassandra-template-cqlsh-tests')
configure { node ->
node / scm / branches / 'hudson.plugins.git.BranchSpec' / name(branchName)
}
publishers {
publishOverSsh {
server('Nightlies') {
transferSet {
sourceFiles("console.log.xz,**/cqlshlib.xml,**/*.head")
remoteDirectory("cassandra/${branchName}/${jobNamePrefix}-cqlsh-tests/\${BUILD_NUMBER}/\${JOB_NAME}/")
}
retry(9, 5000)
}
failOnError(false)
}
archiveArtifacts {
pattern('**/cqlshlib.xml,**/*.head')
allowEmpty()
fingerprint()
}
archiveJunit('**/cqlshlib.xml') {
testDataPublishers {
publishTestStabilityData()
}
}
postBuildTask {
// docker needs to (soon or later) prune its volumes too, but that can only be done when the agent is idle
// if the agent is busy, just prune everything that is older than maxJobHours
task('.', """
echo "Cleaning project…"; git clean -xdff ;
echo "Pruning docker…" ;
if pgrep -af "cassandra-builds/build-scripts" ; then docker system prune --all --force --filter "until=${maxJobHours}h" || true ; else docker system prune --all --force --volumes || true ; fi;
echo "Reporting disk usage…"; df -h ;
echo "Cleaning tmp…";
find . -type d -name tmp -delete 2>/dev/null ;
find /tmp -type f -atime +2 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null || echo clean tmp failed ;
echo "For test report and logs see https://nightlies.apache.org/cassandra/${branchName}/${jobNamePrefix}-cqlsh-tests/\${BUILD_NUMBER}/\${JOB_NAME}/"
""")
}
}
}
}
/**
* Branch Pipelines
*/
pipelineJob("${jobNamePrefix}") {
description(jobDescription)
logRotator {
numToKeep(30)
artifactNumToKeep(10)
}
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(1)
}
}
definition {
cpsScm {
scm {
git {
remote {
url(mainRepo)
}
branch("${branchName}")
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
scriptPath('.jenkins/Jenkinsfile')
}
}
triggers {
scm('H/5 * * * *')
}
}
}
////////////////////////////////////////////////////////////
//
// Parameterized Dev Branch Job Definitions
//
////////////////////////////////////////////////////////////
/**
* Parameterized Artifacts
*/
matrixJob('Cassandra-devbranch-artifacts') {
description(jobDescription)
concurrentBuild()
axes {
jdk(jdkLabel,'jdk_11_latest')
if (arm64_enabled) {
label('label', slaveLabel, slaveArm64Label)
} else {
label('label', slaveLabel)
}
}
compressBuildLog()
logRotator {
numToKeep(90)
artifactNumToKeep(5)
artifactDaysToKeep(1)
}
wrappers {
timeout {
noActivity(300)
}
timestamps()
}
parameters {
stringParam('REPO', 'apache', 'The github user/org to clone cassandra repo from')
stringParam('BRANCH', 'trunk', 'The branch of cassandra to checkout')
}
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(1)
}
}
scm {
git {
remote {
url('https://github.com/${REPO}/cassandra.git')
}
branch('${BRANCH}')
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
steps {
buildDescription('', buildDescStr)
shell("""
git clean -xdff ;
git clone --depth 1 --single-branch -b ${buildsBranch} ${buildsRepo} ;
echo "cassandra-builds at: `git -C cassandra-builds log -1 --pretty=format:'%h %an %ad %s'`" ;
./cassandra-builds/build-scripts/cassandra-artifacts.sh ;
wget --retry-connrefused --waitretry=1 "\${BUILD_URL}/timestamps/?time=HH:mm:ss&timeZone=UTC&appendLog" -qO - > console.log.xz || echo wget failed
""")
}
publishers {
publishOverSsh {
server('Nightlies') {
transferSet {
sourceFiles("console.log.xz,build/apache-cassandra-*.tar.gz, build/apache-cassandra-*.jar, build/apache-cassandra-*.pom, build/cassandra*.deb, build/cassandra*.rpm")
remoteDirectory("cassandra/devbranch/Cassandra-devbranch-artifacts/\${BUILD_NUMBER}/\${JOB_NAME}/")
}
retry(9, 5000)
}
failOnError(false)
}
postBuildTask {
// docker needs to (soon or later) prune its volumes too, but that can only be done when the agent is idle
// if the agent is busy, just prune everything that is older than maxJobHours
task('.', """
echo "Cleaning project…"; git clean -xdff ;
echo "Pruning docker…" ;
if pgrep -af "cassandra-builds/build-scripts" ; then docker system prune --all --force --filter "until=${maxJobHours}h" || true ; else docker system prune --all --force --volumes || true ; fi;
echo "Reporting disk usage…"; df -h ;
echo "Cleaning tmp…";
find . -type d -name tmp -delete 2>/dev/null ;
find /tmp -type -f -atime +3 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null || echo clean tmp failed ;
echo "For test report and logs see https://nightlies.apache.org/cassandra/devbranch/Cassandra-devbranch-artifacts/\${BUILD_NUMBER}/\${JOB_NAME}/"
""")
}
}
}
/**
* Parameterized Dev Branch `ant test`
*/
testTargets.each {
def targetName = it
matrixJob("Cassandra-devbranch-${targetName}") {
description(jobDescription)
concurrentBuild()
def _testSplits = ''
axes {
if (isSplittableTest(targetName)) {
List<String> values = new ArrayList<String>()
(1..testSplits).each { values << it.toString() }
text('split', values)
_testSplits = "/${testSplits}"
}
jdk(jdkLabel,'jdk_11_latest')
if (use_arm64_test_label()) {
label('label', slaveLabel, slaveArm64Label)
} else {
label('label', slaveLabel)
}
}
compressBuildLog()
logRotator {
numToKeep(90)
artifactNumToKeep(5)
artifactDaysToKeep(1)
}
wrappers {
timeout {
noActivity(5400)
}
timestamps()
}
parameters {
stringParam('REPO', 'apache', 'The github user/org to clone cassandra repo from')
stringParam('BRANCH', 'trunk', 'The branch of cassandra to checkout')
}
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(3)
}
}
scm {
git {
remote {
url('https://github.com/${REPO}/cassandra.git')
}
branch('${BRANCH}')
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
steps {
buildDescription('', buildDescStr)
shell("""
git clean -xdff ${targetName == 'microbench' ? '-e build/test/jmh-result.json' : ''};
git clone --depth 1 --single-branch -b ${buildsBranch} ${buildsRepo} ;
echo "cassandra-builds at: `git -C cassandra-builds log -1 --pretty=format:'%h %an %ad %s'`" ;
""")
shell("""
echo "Cassandra-devbranch-${targetName}) cassandra: `git log -1 --pretty=format:'%h %an %ad %s'`" > Cassandra-devbranch-${targetName}.head ;
./cassandra-builds/build-scripts/cassandra-test-docker.sh \${REPO} \${BRANCH} ${buildsRepo} ${buildsBranch} ${testDockerImage} ${targetName} \${split}${_testSplits} ;
./cassandra-builds/build-scripts/cassandra-test-report.sh ;
xz TESTS-TestSuites.xml ;
wget --retry-connrefused --waitretry=1 "\${BUILD_URL}/timestamps/?time=HH:mm:ss&timeZone=UTC&appendLog" -qO - > console.log.xz || echo wget failed
""")
}
publishers {
publishOverSsh {
server('Nightlies') {
transferSet {
sourceFiles("TESTS-TestSuites.xml.xz,build/test/logs/**,build/test/jmh-result.json")
remoteDirectory("cassandra/devbranch/Cassandra-devbranch-${targetName}/\${BUILD_NUMBER}/\${JOB_NAME}/")
}
retry(9, 5000)
}
failOnError(false)
}
archiveArtifacts {
pattern('console.log.xz,build/test/**/TEST-*.xml,**/*.head')
allowEmpty()
fingerprint()
}
archiveJunit('build/test/**/TEST-*.xml') {
allowEmptyResults()
}
postBuildTask {
// docker needs to (soon or later) prune its volumes too, but that can only be done when the agent is idle
// if the agent is busy, just prune everything that is older than maxJobHours
task('.', """
echo "Cleaning project…"; git clean -xdff ${targetName == 'microbench' ? '-e build/test/jmh-result.json' : ''};
echo "Pruning docker…" ;
if pgrep -af "cassandra-builds/build-scripts" ; then docker system prune --all --force --filter "until=${maxJobHours}h" || true ; else docker system prune --all --force --volumes || true ; fi;
echo "Reporting disk usage…"; du -xm / 2>/dev/null | sort -rn | head -n 30 ; df -h ;
echo "Cleaning tmp…";
find . -type d -name tmp -delete 2>/dev/null ;
find /tmp -type f -atime +2 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null || echo clean tmp failed ;
echo "For test report and logs see https://nightlies.apache.org/cassandra/devbranch/Cassandra-devbranch-${targetName}/\${BUILD_NUMBER}/\${JOB_NAME}/"
""")
}
}
}
}
/**
* Parameterized Dev Branch dtest in docker.
*
* Only the vanilla dtest target is used in the Cassandra-devbranch pipeline,
* but they are all added here for developers needing to pre-commit test them specifically.
*/
archs.each {
def arch = it
dtestTargets.each {
def targetName = it
def targetArchName = targetName + arch
matrixJob("Cassandra-devbranch-${targetArchName}") {
description(jobDescription)
concurrentBuild()
compressBuildLog()
compressBuildLog()
logRotator {
numToKeep(90)
artifactNumToKeep(5)
artifactDaysToKeep(1)
}
wrappers {
timeout {
noActivity(5400)
}
timestamps()
}
parameters {
stringParam('REPO', 'apache', 'The github user/org to clone cassandra repo from')
stringParam('BRANCH', 'trunk', 'The branch of cassandra to checkout')
stringParam('DTEST_REPO', "${dtestRepo}", 'The cassandra-dtest repo URL')
stringParam('DTEST_BRANCH', 'trunk', 'The branch of cassandra-dtest to checkout')
stringParam('DOCKER_IMAGE', "${dtestDockerImage}", 'Docker image for running dtests')
}
axes {
List<String> values = new ArrayList<String>()
if (targetName == 'dtest-large' || targetName == 'dtest-large-novnode') {
splits = dtestLargeSplits
} else {
splits = dtestSplits
}
(1..splits).each { values << it.toString() }
text('split', values)
if (targetName == 'dtest-large' || targetName == 'dtest-large-novnode') {
if (arch == "-arm64") {
label('label', slaveArm64DtestLargeLabel)
} else {
label('label', slaveDtestLargeLabel)
}
} else {
if (arch == "-arm64") {
label('label', slaveArm64DtestLabel)
} else {
label('label', slaveDtestLabel)
}
}
}
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(6)
}
}
scm {
git {
remote {
url('https://github.com/${REPO}/cassandra.git')
}
branch('${BRANCH}')
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
steps {
buildDescription('', buildDescStr)
shell("""
git clean -xdff ;
git clone --depth 1 --single-branch -b ${buildsBranch} ${buildsRepo} ;
echo "cassandra-builds at: `git -C cassandra-builds log -1 --pretty=format:'%h %an %ad %s'`" ;
echo "Cassandra-devbranch-${targetArchName}) cassandra: `git log -1 --pretty=format:'%h %an %ad %s'`" > Cassandra-devbranch-${targetArchName}.head ;
""")
if (arch == "-arm64") {
shell("""
# docker image has to be built on arm64 (they are not currently published to dockerhub)
cd cassandra-builds/docker/testing ;
docker build -t \$DOCKER_IMAGE:latest -f ubuntu2004_j11.docker .
""")
}
shell("""
./cassandra-builds/build-scripts/cassandra-dtest-pytest-docker.sh \$REPO \$BRANCH \$DTEST_REPO \$DTEST_BRANCH ${buildsRepo} ${buildsBranch} \$DOCKER_IMAGE ${targetName} \${split}/${splits} ;
wget --retry-connrefused --waitretry=1 "\${BUILD_URL}/timestamps/?time=HH:mm:ss&timeZone=UTC&appendLog" -qO - > console.log.xz || echo wget failed
""")
}
publishers {
publishOverSsh {
server('Nightlies') {
transferSet {
sourceFiles("console.log.xz,**/nosetests.xml,**/test_stdout.txt.xz,**/ccm_logs.tar.xz")
remoteDirectory("cassandra/devbranch/Cassandra-devbranch-${targetArchName}/\${BUILD_NUMBER}/\${JOB_NAME}/")
}
retry(9, 5000)
}
failOnError(false)
}
archiveArtifacts {
pattern('**/nosetests.xml,**/*.head')
allowEmpty()
fingerprint()
}
archiveJunit('nosetests.xml')
postBuildTask {
// docker needs to (soon or later) prune its volumes too, but that can only be done when the agent is idle
// if the agent is busy, just prune everything that is older than maxJobHours
task('.', """
echo "Cleaning project" ; git clean -xdff ;
echo "Pruning docker" ;
if pgrep -af "cassandra-builds/build-scripts" ; then docker system prune --all --force --filter "until=${maxJobHours}h" || true ; else docker system prune --all --force --volumes || true ; fi;
echo "Reporting disk usage"; df -h ;
echo "Cleaning tmp";
find . -type d -name tmp -delete 2>/dev/null ;
find /tmp -type f -atime +2 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null || echo clean tmp failed ;
echo "For test report and logs see https://nightlies.apache.org/cassandra/devbranch/Cassandra-devbranch-${targetArchName}/\${BUILD_NUMBER}/\${JOB_NAME}/"
""")
}
}
}
}
}
/**
* Parameterized Dev Branch cqlsh-tests
*/
matrixJob('Cassandra-devbranch-cqlsh-tests') {
description(jobDescription)
concurrentBuild()
compressBuildLog()
logRotator {
numToKeep(90)
artifactNumToKeep(5)
artifactDaysToKeep(1)
}
wrappers {
timeout {
noActivity(1200)
}
timestamps()
}
throttleConcurrentBuilds {
categories(['Cassandra'])
}
parameters {
stringParam('REPO', 'apache', 'The github user/org to clone cassandra repo from')
stringParam('BRANCH', 'trunk', 'The branch of cassandra to checkout')
stringParam('DTEST_REPO', "${dtestRepo}", 'The cassandra-dtest repo URL')
stringParam('DTEST_BRANCH', 'trunk', 'The branch of cassandra-dtest to checkout')
}
axes {
text('cython', 'yes', 'no')
jdk(jdkLabel)
if (use_arm64_test_label()) {
label('label', slaveLabel, slaveArm64Label)
} else {
label('label', slaveLabel)
}
}
// this should prevent long path expansion from the axis definitions
childCustomWorkspace('.')
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(3)
}
}
scm {
git {
remote {
url('https://github.com/${REPO}/cassandra.git')
}
branch('${BRANCH}')
extensions {
cleanAfterCheckout()
cloneOption {
shallow(false)
reference('.')
honorRefspec(true)
noTags(true)
timeout(maxJobHours * 60)
}
}
}
}
steps {
buildDescription('', buildDescStr)
shell("""
git clean -xdff ;
echo "Cassandra-devbranch-cqlsh-tests) cassandra: `git log -1 --pretty=format:'%h %an %ad %s'`" > Cassandra-devbranch-cqlsh-tests.head ;
./pylib/cassandra-cqlsh-tests.sh \$WORKSPACE ;
wget --retry-connrefused --waitretry=1 "\${BUILD_URL}/timestamps/?time=HH:mm:ss&timeZone=UTC&appendLog" -qO - > console.log.xz || echo wget failed
""")
}
publishers {
publishOverSsh {
server('Nightlies') {
transferSet {
sourceFiles("console.log.xz,**/test_stdout.txt.xz,**/ccm_logs.tar.xz")
remoteDirectory("cassandra/devbranch/Cassandra-devbranch-cqlsh-tests/\${BUILD_NUMBER}/\${JOB_NAME}/")
}
retry(9, 5000)
}
failOnError(false)
}
archiveArtifacts {
pattern('**/cqlshlib.xml,**/*.head')
allowEmpty()
fingerprint()
}
archiveJunit('**/cqlshlib.xml')
postBuildTask {
// docker needs to (soon or later) prune its volumes too, but that can only be done when the agent is idle
// if the agent is busy, just prune everything that is older than maxJobHours
task('.', """
echo "Cleaning project…"; git clean -xdff ;
echo "Pruning docker…" ;
if pgrep -af "cassandra-builds/build-scripts" ; then docker system prune --all --force --filter "until=${maxJobHours}h" || true ; else docker system prune --all --force --volumes || true ; fi;
echo "Reporting disk usage…"; df -h ;
echo "Cleaning tmp…";
find . -type d -name tmp -delete 2>/dev/null ;
find /tmp -type f -atime +2 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null || echo clean tmp failed ;
echo "For test report and logs see https://nightlies.apache.org/cassandra/devbranch/Cassandra-devbranch-cqlsh-tests/\${BUILD_NUMBER}/\${JOB_NAME}/"
""")
}
}
}
/**
* Parameterized Dev Branch Pipeline
*/
pipelineJob('Cassandra-devbranch') {
description(jobDescription)
logRotator {
numToKeep(90)
artifactNumToKeep(10)
}
parameters {
stringParam('REPO', 'apache', 'The github user/org to clone cassandra repo from')
stringParam('BRANCH', 'trunk', 'The branch of cassandra to checkout')
stringParam('DTEST_REPO', "${dtestRepo}", 'The cassandra-dtest repo URL')
stringParam('DTEST_BRANCH', 'trunk', 'The branch of cassandra-dtest to checkout')
stringParam('DOCKER_IMAGE', "${dtestDockerImage}", 'Docker image for running dtests')
}
properties {
githubProjectUrl(githubRepo)
priorityJobProperty {
useJobPriority(true)
priority(1)
}
}
definition {
cps {
// Cassandra-devbranch still needs custom Jenkinsfile because of the parameters passed into the build jobs.
script(readFileFromWorkspace('Cassandra-Job-DSL', 'jenkins-dsl/cassandra_pipeline.groovy'))
}
}
}
////////////////////////////////////////////////////////////
//
// Jobs for Other Cassandra Projects
//
////////////////////////////////////////////////////////////
job('cassandra-website') {
description(jobDescription)
label('git-websites')
compressBuildLog()
logRotator {
numToKeep(10)
artifactNumToKeep(10)
}
wrappers {
preBuildCleanup()
timeout {
noActivity(300)
}
timestamps()
}
properties {
githubProjectUrl('https://github.com/apache/cassandra-website/')
priorityJobProperty {
useJobPriority(true)
priority(1)
}
}
scm {
git {
remote {
url('https://gitbox.apache.org/repos/asf/cassandra-website.git')
credentials('9b041bd0-aea9-4498-a576-9eeb771411dd') // "jenkins"
}
branch('*/trunk')
extensions {
wipeOutWorkspace()
cleanBeforeCheckout()
cleanAfterCheckout()
}
}
}
triggers {
scm('H/5 * * * *')
}
steps {
buildDescription('', buildDescStr)
// the chmod below is a hack for INFRA-20814
// for debugging it can be useful to add a `git show --stat HEAD` before the push
shell("""
git checkout asf-staging ;
git reset --hard origin/trunk ;
docker-compose build --build-arg UID=`id -u` --build-arg GID=`id -g` cassandra-website ;
chmod -R 777 src content ;
docker-compose run cassandra-website ;
git add content/ src/doc/ ;
git commit -a -m "generate docs for `git rev-parse --short HEAD`" ;
git push -f origin asf-staging ;
""")
}
}