pipeline { agent { label 'linux' } options { timestamps() /* Prevent Jenkins jobs from running forever */ timeout(time: 45, unit: 'MINUTES') /* Limit builds retained */ buildDiscarder(logRotator( numToKeepStr: '10', daysToKeepStr: '20', artifactNumToKeepStr: '10', )) } parameters { string( name: 'BUILD_TYPE', description: 'Specify build type. Values: pr / e2e / nightly / release', defaultValue: 'pr', ) } environment { LANG = "en_US.UTF-8" LC_ALL = "en_US.UTF-8" LANGUAGE = "en_US.UTF-8" TARGET = 'android' BUILD_ENV = 'prod' NIX_CONF_DIR = "${env.WORKSPACE}/nix" FASTLANE_DISABLE_COLORS = 1 /* We use EXECUTOR_NUMBER to avoid multiple instances clashing */ LEIN_HOME = "/var/tmp/lein-${EXECUTOR_NUMBER}" /* coverage report identification */ COVERALLS_SERVICE_NAME = "jenkins" COVERALLS_SERVICE_JOB_ID = "${JOB_NAME}#${BUILD_NUMBER}" } stages { stage('Prep') { steps { script { /* Necessary to load methods */ android = load 'ci/android.groovy' cmn = load 'ci/common.groovy' btype = cmn.utils.getBuildType() print "Running ${btype} build!" cmn.ci.abortPreviousRunningBuilds() /* Cleanup and Prep */ cmn.prep(btype) } } } stage('Implicit dependencies') { steps { /* Build implicit dependencies if needed (we run `lein deps :tree` but it's not really required, for this purpose) Implicit dependencies include building a patched node_modules, fetching maven dependencies, and anything else required. We do this before the parallel steps so we have a known starting situation. */ script { cmn.nix.shell('lein deps :tree', attr: 'shells.lein') } } } stage('Parallel Assemble') { parallel { stage('Checks') { stages { stage('Lint') { steps { script { cmn.nix.shell('lein cljfmt check', attr: 'shells.lein') } } } stage('Tests') { steps { script { cmn.nix.shell('lein test-cljs', attr: 'shells.lein') } } } } } stage('Build') { stages { stage('JSBundle') { steps { script { cmn.nix.shell('make jsbundle-android', pure: false) } } } stage('Bundle') { steps { script { apks = android.bundle() } } } } } } } stage('Parallel Upload') { parallel { stage('Archive') { steps { script { apks.each { archiveArtifacts it } } } } stage('Upload') { steps { script { def urls = apks.collect { cmn.uploadArtifact(it) } /* return only the universal APK */ if (urls.size() > 1) { env.PKG_URL = urls.find { it.contains('universal') } } else { /* if no universal is available pick first */ env.PKG_URL = urls.first() } /* build type specific */ switch (btype) { case 'nightly': env.DIAWI_URL = android.uploadToDiawi(); break; case 'e2e': env.SAUCE_URL = android.uploadToSauceLabs(); break; } } } } } } stage('Cleanup') { steps { sh 'make clean' } } } post { success { script { load('ci/github.groovy').notifyPR(true) } } failure { script { load('ci/github.groovy').notifyPR(false) } } always { sh 'make _fix-node-perms' } } }