#!/usr/bin/env groovy library 'status-jenkins-lib@v1.9.6' pipeline { agent { label 'linux && x86_64 && nix-2.19' } parameters { string( name: 'BRANCH', defaultValue: 'develop', description: 'Name of branch to build.' ) string( name: 'UNIT_TEST_COUNT', defaultValue: getDefaultUnitTestCount(), description: 'How many times to run tests?' ) booleanParam( name: 'UNIT_TEST_FAILFAST', defaultValue: isPRJob(), description: 'Should the job fail fast on first test failure?' ) booleanParam( name: 'UNIT_TEST_RERUN_FAILS', defaultValue: isPRJob(), description: 'Should the job rerun failed tests?' ) booleanParam( name: 'UNIT_TEST_USE_DEVELOPMENT_LOGGER', defaultValue: !isNightlyJob(), description: 'Should the job use detailed logging for tests, potentially generating large logs?' ) booleanParam( name: 'UNIT_TEST_REPORT_CODECLIMATE', defaultValue: !isNightlyJob(), description: 'Should the job report test coverage to CodeClimate?' ) booleanParam( name: 'UNIT_TEST_REPORT_CODECOV', defaultValue: !isNightlyJob(), description: 'Should the job report test coverage to Codecov?' ) booleanParam( name: 'UNIT_TEST_DRY_RUN', defaultValue: false, description: 'Should the job report ignore the actual test run and just print the test plan?' ) } options { timestamps() ansiColor('xterm') /* Prevent Jenkins jobs from running forever */ timeout(time: getDefaultTimeout(), unit: 'MINUTES') disableConcurrentBuilds() /* manage how many builds we keep */ buildDiscarder(logRotator( numToKeepStr: getAmountToKeep(), daysToKeepStr: '30', artifactNumToKeepStr: getAmountToKeep(), )) } environment { PLATFORM = 'tests' DB_CONT = "status-go-test-db-${env.EXECUTOR_NUMBER.toInteger() + 1}" DB_PORT = "${5432 + env.EXECUTOR_NUMBER.toInteger()}" TMPDIR = "${WORKSPACE_TMP}" GOPATH = "${WORKSPACE_TMP}/go" GOCACHE = "${WORKSPACE_TMP}/gocache" PATH = "${PATH}:${GOPATH}/bin" REPO_SRC = "${GOPATH}/src/github.com/status-im/status-go" BASE_BRANCH = "${env.CHANGE_TARGET}" NWAKU_CONT = "status-go-test-nwaku-${env.EXECUTOR_NUMBER.toInteger() + 1}" NWAKU_TCP_PORT = "${60000 + env.EXECUTOR_NUMBER.toInteger()}" NWAKU_UDP_PORT = "${9000 + env.EXECUTOR_NUMBER.toInteger()}" NWAKU_REST_PORT = "${9645 + env.EXECUTOR_NUMBER.toInteger()}" /* Hack-fix for params not being set in env on first job run. */ UNIT_TEST_FAILFAST = "${params.UNIT_TEST_FAILFAST}" UNIT_TEST_RERUN_FAILS = "${params.UNIT_TEST_RERUN_FAILS}" UNIT_TEST_USE_DEVELOPMENT_LOGGER = "${params.UNIT_TEST_USE_DEVELOPMENT_LOGGER}" UNIT_TEST_REPORT_CODECLIMATE = "${params.UNIT_TEST_REPORT_CODECLIMATE}" UNIT_TEST_REPORT_CODECOV = "${params.UNIT_TEST_REPORT_CODECOV}" UNIT_TEST_DRY_RUN = "${params.UNIT_TEST_DRY_RUN}" /* prevent sharing cache dir across different jobs */ GO_GENERATE_FAST_DIR = "${env.WORKSPACE_TMP}/go-generate-fast" } stages { stage('Prep') { steps { /* Go needs to find status-go in GOPATH. */ sh "mkdir -p \$(dirname ${REPO_SRC})" sh "ln -s ${WORKSPACE} ${REPO_SRC}" } } stage('Generate') { steps { script { nix.shell('make generate', pure: false) } } } stage('Vendor Check') { steps { script { nix.shell('make vendor', pure: false) /* fail build if vendoring hasn't been done */ nix.shell('git diff --exit-code --no-color --stat vendor/') } } } stage('Migration') { when { // https://github.com/status-im/status-go/issues/4993#issuecomment-2022685544 expression { isPRJob() } } steps { script { nix.shell('make migration-check', pure: false) } } } stage('Commit') { environment { BASE_BRANCH = "${env.BASE_BRANCH}" } when { // https://github.com/status-im/status-go/issues/4993#issuecomment-2022685544 expression { isPRJob() } } steps { script { nix.shell('make commit-check', pure: false) } } } stage('Lint') { steps { script { nix.shell('make lint', pure: true) } } } stage('Canary') { steps { script { nix.shell('make canary-test', pure: true) } } } stage('Unit Tests') { environment { TEST_POSTGRES_PORT = "${env.DB_PORT}" NWAKU_REST_PORT = "${env.NWAKU_REST_PORT}" } steps { script { def ipAddress = sh(script: "hostname -I | awk '{print \$1}'", returnStdout: true).trim() db = docker.image('postgres:9.6-alpine').withRun([ "--name=${DB_CONT}", "--env=POSTGRES_HOST_AUTH_METHOD=trust", "--publish=${DB_PORT}:${DB_PORT}", ].join(' '), "-p ${DB_PORT}") { c -> nwaku = docker.image('harbor.status.im/wakuorg/nwaku:latest').withRun([ "--name=${NWAKU_CONT}", "--publish=${NWAKU_TCP_PORT}:${NWAKU_TCP_PORT}/tcp", "--publish=${NWAKU_UDP_PORT}:${NWAKU_UDP_PORT}/udp", "--publish=${NWAKU_REST_PORT}:8645/tcp" ].join(' '), [ "--tcp-port=${NWAKU_TCP_PORT}", "--discv5-discovery=true", "--cluster-id=16", "--pubsub-topic=/waku/2/rs/16/32", "--pubsub-topic=/waku/2/rs/16/64", "--nat=extip:${ipAddress}", "--discv5-discovery", "--discv5-udp-port=${NWAKU_UDP_PORT}", "--rest-address=0.0.0.0", "--store", "--filter", "--lightpush" ].join(' ')) { c2 -> withCredentials([ string( credentialsId: 'codeclimate-test-reporter-id', variable: 'CC_TEST_REPORTER_ID' ), string( credentialsId: 'codecov-repository-upload-token', variable: 'CODECOV_TOKEN' ), ]) { nix.shell('make test-unit V=1', pure: false) } sh "mv c.out test-coverage.out" archiveArtifacts('report_*.xml, test_*.log, test-coverage.out, coverage/codeclimate.json, test-coverage.html, coverage_merged.out') } } } } post { cleanup { /* Leftover DB containers. */ sh "docker rm ${DB_CONT} || true" sh "docker rm ${NWAKU_CONT} || true" } } } } // stages post { always { script { env.PKG_URL = "${currentBuild.absoluteUrl}/consoleText" if (!isPRJob()) { archiveArtifacts('report_*.xml, test_*.log, test-coverage.html, test-coverage.out, coverage/codeclimate.json') } if (params.UNIT_TEST_RERUN_FAILS) { def rerunReports = findFiles(glob: 'report_rerun_fails_*.txt') if (rerunReports.length > 0) { archiveArtifacts('report_rerun_fails_*.txt') } } junit( testResults: 'report_*.xml', skipOldReports: true, skipPublishingChecks: true, skipMarkingBuildUnstable: true ) publishHTML(target: [ allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'reports', reportFiles: 'test_stats.txt', reportName: 'Reports', reportTitles: 'Test Stats' ]) } } success { script { github.notifyPR(true) } } failure { script { github.notifyPR(false) archiveArtifacts('**/test_*.log') } } cleanup { dir(env.TMPDIR) { deleteDir() } sh "make git-clean" } } // post } // pipeline def isNightlyJob() { env.JOB_BASE_NAME == 'tests-nightly' } def isDevelopJob() { env.JOB_BASE_NAME == 'tests-develop' } def isPRJob() { !isNightlyJob() && !isDevelopJob() } def getDefaultUnitTestCount() { isNightlyJob() ? '20' : '1' } def getDefaultTimeout() { isNightlyJob() ? 5*60 : 50 } def getAmountToKeep() { isNightlyJob() ? '14' : isDevelopJob() ? '10' : '5' }