#!/usr/bin/env groovy library 'status-jenkins-lib@v1.7.16' /* Options section can't access functions in objects. */ def isPRBuild = utils.isPRBuild() pipeline { agent { label 'linux && x86_64 && qt-5.15.2' } parameters { booleanParam( name: 'RELEASE', description: 'Decides whether binaries are built with debug symbols.', defaultValue: params.RELEASE ?: false ) string( name: 'SQUISH_SUITE', description: 'Name of test suite to run in Squish. Defaults to all.', defaultValue: forcePRDefaults(params.SQUISH_SUITE, '*') ) string( name: 'SQUISH_TAGS', description: 'List of tags to use for Squish tests separated by spaces.', defaultValue: forcePRDefaults(params.SQUISH_TAGS, '~mayfail ~merge ~relyon-mailserver') ) choice( name: 'VERBOSE', description: 'Level of verbosity based on nimbus-build-system setup.', choices: ['0', '1', '2'] ) string( name: 'NIMFLAGS', description: 'Extra Nim flags. Examples: --verbosity:2 --passL:"-v" --passC:"-v"', defaultValue: '--colors:off' ) } options { timestamps() /* Prevent Jenkins jobs from running forever */ timeout(time: 120, unit: 'MINUTES') /* manage how many builds we keep */ buildDiscarder(logRotator( numToKeepStr: '10', daysToKeepStr: '30', artifactNumToKeepStr: '3', )) /* Throttle number of concurrent builds. */ throttleJobProperty( throttleEnabled: true, throttleOption: 'category', maxConcurrentPerNode: 1, maxConcurrentTotal: 9 ) /* Abort old PR builds. */ disableConcurrentBuilds( abortPrevious: isPRBuild ) } environment { TARGET = 'tests/e2e' /* Improve make performance */ MAKEFLAGS = "-j4 V=${params.VERBOSE}" /* Makefile assumes the compiler folder is included */ QTDIR = '/opt/qt/5.15.2/gcc_64' PATH = "${env.QTDIR}/bin:${env.PATH}" /* Avoid weird bugs caused by stale cache. */ QML_DISABLE_DISK_CACHE = "true" /* Include library in order to compile the project */ LD_LIBRARY_PATH = "$QTDIR/lib:$WORKSPACE/vendor/status-go/build/bin:$WORKSPACE/vendor/status-keycard-go/build/libkeycard/" /* Container ports */ RPC_PORT = "${8545 + env.EXECUTOR_NUMBER.toInteger()}" P2P_PORT = "${6010 + env.EXECUTOR_NUMBER.toInteger()}" /* Ganache config */ GANACHE_RPC_PORT = "${9545 + env.EXECUTOR_NUMBER.toInteger()}" GANACHE_MNEMONIC = 'pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial' /* Runtime flag to make testing of the app easier. */ STATUS_RUNTIME_TEST_MODE = '1' } stages { stage('Deps') { steps { sh 'make update' sh 'make deps' } } stage('status-go') { steps { sh 'make status-go' } } stage('Client') { environment { GANACHE_NETWORK_RPC_URL = "http://localhost:${env.GANACHE_RPC_PORT}" /* Hack-fix for wrong config path location causing: * Error: unhandled exception: Read-only file system */ RESOURCES_LAYOUT = '-d:production' } steps { script { /* Temporary hack-fix for failing Linux builds: * https://github.com/status-im/infra-ci/issues/88 */ timeout(10) { retry(20) { sh 'make nim_status_client' } } } } } stage('Containers') { parallel { stage('Ganache') { steps { script { ganache = docker.image( 'trufflesuite/ganache:v7.4.1' ).run( ["-p 127.0.0.1:${env.GANACHE_RPC_PORT}:8545", "-v ${env.WORKSPACE}/test/ui-test/fixtures/ganache-dbs/goerli:/goerli-db"].join(' '), ["-m='${GANACHE_MNEMONIC}'", "-e=10", '--chain.chainId=5', '--database.dbPath=/goerli-db'].join(' ') ) } } } stage('Nim-Waku') { steps { script { nimwaku = docker.image( 'statusteam/nim-waku:v0.13.0' ).run( ["-p 127.0.0.1:${env.RPC_PORT}:8545", "-p 127.0.0.1:${env.P2P_PORT}:30303/tcp", "-p 127.0.0.1:${env.P2P_PORT}:30303/udp", "-v ${env.WORKSPACE}/ci/mailserver/config.json:/config.json"].join(' '), ['--store=true', '--keep-alive=true', '--rpc-address=0.0.0.0', '--nat=none'].join(' ') ) env.TEST_PEER_ENR = getPeerAddress() } } } } } stage('Tests') { options { throttle(categories: ['status-desktop-e2e-tests']) } steps { script { /* Combine specified tags with --tags flag for each. */ def tags = params.SQUISH_TAGS.split(' ') def flags = Collections.nCopies(tags.size(), "--tags") def tagsFlags = [flags, tags].transpose().flatten() wrap([ $class: 'Xvfb', autoDisplayName: true, parallelBuild: true, screen: '2560x1440x24', ]) { script { def result = squish([ extraOptions: (tagsFlags + [ '--retry', '2', '--config', 'addAUT', 'nim_status_client', "${WORKSPACE}/bin", ]).join('\n'), squishPackageName: 'squish-7.1-20230222-1555-qt515x-linux64', testSuite: "${WORKSPACE}/test/ui-test/testSuites/${params.SQUISH_SUITE}", ]) print("Squish run result: ${result}") if (!['SUCCESS'].contains(result)) { throw new Exception('Squish run failed!') } } } } } post { failure { script { sh("docker logs ${nimwaku.id}") sh("docker logs ${ganache.id}") } } } } } post { success { script { github.notifyPR(true) } } failure { script { github.notifyPR(false) } } always { script { /* No artifact but a PKG_URL is necessary. */ env.PKG_URL = "${currentBuild.absoluteUrl}/consoleText" } } cleanup { script { sh './scripts/clean-git.sh' if (binding.hasVariable('ganache')) { ganache.stop() } if (binding.hasVariable('nimwaku')) { nimwaku.stop() } } } } } def getPeerAddress() { def rpcResp = sh( script: "${env.WORKSPACE}/scripts/rpc.sh get_waku_v2_debug_v1_info", returnStdout: true ).trim() assert rpcResp : 'Could not get node address from RPC API!' return readJSON(text: rpcResp)['result']['listenAddresses'][0] } /* Helper that prevents saving of parameters in PR jobs. */ def String forcePRDefaults(String previousValue, String defaultValue) { if (utils.isPRBuild()) { return defaultValue } return previousValue ?: defaultValue }