| final boolean buildForMac = true | |
| final boolean runCypressTests = false | |
| final boolean triggerAdapterPackJob = false | |
| final boolean sonarScan = false | |
| final boolean validateXml = true | |
| pipeline | |
| { | |
| agent { node { label 'Build-Farm' | |
| customWorkspace '/mnt/raid/workspaces/zap' } } | |
| options { buildDiscarder(logRotator(artifactNumToKeepStr: '10')) } | |
| stages | |
| { | |
| stage('Git setup') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| checkout scm | |
| } | |
| } | |
| } | |
| stage('Npm clean install') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'uname -a' | |
| sh 'rm -rf dist/' | |
| sh 'npm --version' | |
| sh 'node --version' | |
| sh 'npm ci' | |
| sh 'npm list || true' | |
| } | |
| } | |
| } | |
| stage('Initial checks') { | |
| parallel { | |
| stage('Version stamp') { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run version-stamp' | |
| sh 'npm run version' | |
| sh 'npm rebuild canvas --update-binary' | |
| sh 'npm rebuild libxmljs --update-binary' | |
| } | |
| } | |
| } | |
| stage('Generate Eclipse packaging metadata') { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run package-metadata' | |
| } | |
| } | |
| } | |
| stage('XML validation') | |
| { | |
| when { equals expected: true, actual: validateXml } | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run xml-validate' | |
| } | |
| } | |
| } | |
| stage('License check') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run lic' | |
| } | |
| } | |
| } | |
| stage('Outdated packages report') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm outdated || true' | |
| } | |
| } | |
| } | |
| stage('Generate HTML documentation') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run doc' | |
| } | |
| } | |
| } | |
| } | |
| } | |
| stage('Build SPA layout for unit tests') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run build-spa' | |
| } | |
| } | |
| } | |
| stage('Build backend') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run build-backend' | |
| } | |
| } | |
| } | |
| stage('ESLint execution') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run lint' | |
| } | |
| } | |
| } | |
| stage('Unit test execution') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| withEnv(['ZAP_TEST_TIMEOUT=3600000', 'ZAP_TEMPSTATE=1']) | |
| { | |
| sh 'npm run test:unit' | |
| } | |
| } | |
| } | |
| } | |
| stage('Self check') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'rm -rf ~/.zap' | |
| sh 'npm run self-check' | |
| } | |
| } | |
| } | |
| stage('Test generation') { | |
| parallel { | |
| stage('Test Zigbee generation') { | |
| steps { | |
| script { | |
| sh 'npm run gen' | |
| } | |
| } | |
| } | |
| stage('Test Matter generation') { | |
| steps { | |
| script { | |
| sh 'npm run genmatter' | |
| } | |
| } | |
| } | |
| stage('Test Dotdot generation') { | |
| steps { | |
| script { | |
| sh 'npm run gendotdot' | |
| } | |
| } | |
| } | |
| } | |
| } | |
| stage('Cypress UI tests') | |
| { | |
| when { equals expected: true, actual: runCypressTests } | |
| steps | |
| { | |
| script | |
| { | |
| sh 'rm -rf ~/.zap' | |
| sh 'xvfb-run -a npm run test:e2e-ci' | |
| } | |
| } | |
| } | |
| stage('Run Sonar Scan') | |
| { | |
| when | |
| { | |
| allOf { branch 'silabs'; equals expected: true, actual: sonarScan } | |
| } | |
| steps | |
| { | |
| script | |
| { | |
| gitBranch = "${env.BRANCH_NAME}" | |
| sh '/opt/sonar-scanner-cli/sonar-scanner-4.5.0.2216-linux/bin/sonar-scanner -Dsonar.host.url=https://sonarqube.silabs.net/ -Dsonar.login=e48b8a949e2869afa974414c56b4dc7baeb146e3 -X -Dsonar.branch.name=' + gitBranch | |
| } | |
| } | |
| } | |
| stage('Building node.js artifacts') { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'npm run pkg' | |
| sh 'mv dist/zap-linux dist/zap-cli-linux' | |
| sh 'mv dist/zap-macos dist/zap-cli-macos' | |
| sh 'mv dist/zap-win.exe dist/zap-cli-win.exe' | |
| } | |
| } | |
| } | |
| stage('Building electron artifacts') { | |
| parallel { | |
| stage('Building for Mac') | |
| { | |
| when { equals expected: true, actual: buildForMac } | |
| agent { label 'bgbuild-mac' } | |
| steps | |
| { | |
| script | |
| { | |
| withEnv(['PATH+LOCAL_BIN=/usr/local/bin', | |
| 'PATH+NODE14=/usr/local/opt/node@14/bin', | |
| //'DEBUG=electron-builder', | |
| 'NODE_TLS_REJECT_UNAUTHORIZED=0']) // workaround for a self-signed cert issue on canvas 2.7.0 on mac | |
| { | |
| withCredentials([usernamePassword(credentialsId: 'buildengineer', | |
| usernameVariable: 'SL_USERNAME', | |
| passwordVariable: 'SL_PASSWORD')]) | |
| { | |
| sh 'npm --version' | |
| sh 'node --version' | |
| sh 'npm config set strict-ssl false' | |
| sh 'npm ci' | |
| sh 'npm list || true' | |
| sh 'security unlock-keychain -u "/Library/Keychains/System.keychain"' | |
| sh 'npm run version-stamp' | |
| sh 'npm run build' | |
| sh 'npm run pack:mac:native' | |
| stash includes: 'dist/*mac.zip', name: 'zap_apack_mac' | |
| } | |
| } | |
| } | |
| } | |
| } | |
| stage('Building for Windows / Linux') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'echo "Building for Windows"' | |
| sh 'xvfb-run -a npm run pack:win' | |
| stash includes: 'dist/*win.zip', name: 'zap_apack_win' | |
| sh 'echo "Building for Linux"' | |
| sh 'xvfb-run -a npm run pack:linux' | |
| stash includes: 'dist/*linux.zip', name: 'zap_apack_linux' | |
| } | |
| } | |
| } | |
| } | |
| } | |
| stage('Archiving artifacts') | |
| { | |
| parallel { | |
| stage('Archiving for Windows / Linux') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| def file = sh(script: 'ls dist/*win.zip | head -n 1', returnStdout: true).trim() | |
| sh 'cp ' + file + ' zap_apack_win.zip' | |
| file = sh(script: 'ls dist/*linux.zip | head -n 1', returnStdout: true).trim() | |
| sh 'cp ' + file + ' zap_apack_linux.zip' | |
| archiveArtifacts artifacts:'dist/zap*', fingerprint: true | |
| } | |
| } | |
| } | |
| stage('Archiving for macOS') | |
| { | |
| when { equals expected: true, actual: buildForMac } | |
| agent { label 'bgbuild-mac' } | |
| options { skipDefaultCheckout() } | |
| steps | |
| { | |
| script | |
| { | |
| def file = sh(script: 'ls dist/*mac.zip | head -n 1', returnStdout: true).trim() | |
| sh 'cp ' + file + ' zap_apack_mac.zip' | |
| archiveArtifacts artifacts:'dist/zap*', fingerprint: true | |
| } | |
| } | |
| } | |
| stage('Eclipse packaging metadata') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| archiveArtifacts artifacts:'docs/releasenotes.md', fingerprint: true | |
| archiveArtifacts artifacts:'apack_zap.package', fingerprint: true | |
| } | |
| } | |
| } | |
| } | |
| } | |
| stage('Check artifacts') { | |
| parallel { | |
| stage('Checking Windows exe') | |
| { | |
| agent { label 'windows10' } | |
| options { skipDefaultCheckout() } | |
| steps | |
| { | |
| cleanWs() | |
| dir('test_apack_bin') { | |
| script | |
| { | |
| unstash 'zap_apack_win' | |
| sh 'ls -R' | |
| def file = sh(script: 'ls dist/*win.zip | head -n 1', returnStdout: true).trim() | |
| unzip zipFile: file | |
| String response = bat(script: 'zap.exe --version', returnStdout: true).trim() | |
| echo response | |
| if ( response.indexOf('undefined') == -1) { | |
| response = bat (script: 'zap.exe selfCheck', returnStdout: true).trim() | |
| echo response | |
| if ( response.indexOf('Self-check done') == -1 ) { | |
| error 'Wrong self-check result.' | |
| currentBuild.result = 'FAILURE' | |
| } else { | |
| currentBuild.result = 'SUCCESS' | |
| } | |
| } else { | |
| error 'Undefined version information' | |
| currentBuild.result = 'FAILURE' | |
| } | |
| } | |
| deleteDir() | |
| } | |
| } | |
| } | |
| stage('Checking macOS exe') | |
| { | |
| when { equals expected: true, actual: buildForMac } | |
| agent { label 'bgbuild-mac' } | |
| options { skipDefaultCheckout() } | |
| steps | |
| { | |
| // WORKAROUND: | |
| // Skip testing zap within .zap since zip/unzip within Jenkins is unable to | |
| // maintain the framework symlinks, referenced by ZAP | |
| script | |
| { | |
| // redirect stderr to file to avoid return statusCode failing the pipeline. | |
| // mac binaries would err with "Trace/BPT trap: 5". | |
| // depending on electron/electron-builder version, the error appear/disappear from time to time. | |
| String status = sh(script: './dist/mac/zap.app/Contents/MacOS/zap --version 2&> output.txt', returnStatus: true) | |
| def output = readFile('output.txt').trim() | |
| echo output | |
| if ( output.indexOf('undefined') == -1) { | |
| status = sh (script: './dist/mac/zap.app/Contents/MacOS/zap selfCheck 2&> output.txt', returnStdout: true) | |
| output = readFile('output.txt').trim() | |
| echo output | |
| if ( output.indexOf('Self-check done') == -1 ) { | |
| error 'Wrong self-check result.' | |
| currentBuild.result = 'FAILURE' | |
| } else { | |
| currentBuild.result = 'SUCCESS' | |
| } | |
| } else { | |
| error 'Undefined version information' | |
| currentBuild.result = 'FAILURE' | |
| } | |
| } | |
| } | |
| } | |
| stage('Checking Linux exe') | |
| { | |
| steps | |
| { | |
| dir('test_apack_bin') { | |
| script | |
| { | |
| cleanWs() | |
| unstash 'zap_apack_linux' | |
| sh 'ls -R' | |
| def file = sh(script: 'ls dist/*linux.zip | head -n 1', returnStdout: true).trim() | |
| unzip zipFile: file | |
| sh 'chmod 755 zap' | |
| String response = sh(script: 'xvfb-run -a ./zap --version', returnStdout: true).trim() | |
| echo response | |
| if ( response.indexOf('undefined') == -1) { | |
| response = sh (script: 'xvfb-run -a ./zap selfCheck', returnStdout: true).trim() | |
| echo response | |
| if ( response.indexOf('Self-check done') == -1 ) { | |
| error 'Wrong self-check result.' | |
| currentBuild.result = 'FAILURE' | |
| } else { | |
| currentBuild.result = 'SUCCESS' | |
| } | |
| } else { | |
| error 'Undefined version information' | |
| currentBuild.result = 'FAILURE' | |
| } | |
| } | |
| deleteDir() | |
| } | |
| } | |
| } | |
| } | |
| } | |
| stage('Build status resolution') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| currentBuild.result = 'SUCCESS' | |
| } | |
| } | |
| } | |
| stage('Run Adapter_Pack_ZAP_64 on JNKAUS-16.silabs.com') | |
| { | |
| when | |
| { | |
| allOf { branch 'silabs'; equals expected: true, actual: triggerAdapterPackJob } | |
| } | |
| steps | |
| { | |
| script | |
| { | |
| try { | |
| triggerRemoteJob blockBuildUntilComplete: false, | |
| job: 'https://jnkaus016.silabs.com/job/Adapter_Pack_ZAP_64/', | |
| remoteJenkinsName: 'jnkaus016', | |
| shouldNotFailBuild: false, | |
| useCrumbCache: true, | |
| useJobInfoCache: true | |
| } catch (err) { | |
| currentBuild.result = 'UNSTABLE' | |
| } | |
| } | |
| } | |
| } | |
| stage('Building download-artifact for Mac / Linux / Windows') | |
| { | |
| steps | |
| { | |
| script | |
| { | |
| sh 'echo "Building..."' | |
| sh 'npm run pkg:download-artifact' | |
| archiveArtifacts artifacts:'dist/download-artifact*', fingerprint: true | |
| } | |
| } | |
| } | |
| stage('Workspace clean up') | |
| { | |
| parallel { | |
| stage('Mac') { | |
| when { equals expected: true, actual: buildForMac } | |
| agent { label 'bgbuild-mac' } | |
| options { skipDefaultCheckout() } | |
| steps { cleanWs() } | |
| } | |
| stage('Linux / Windows') { | |
| agent { label 'Build-Farm' } | |
| options { skipDefaultCheckout() } | |
| steps { cleanWs() } | |
| } | |
| } | |
| } | |
| } | |
| post { | |
| always { | |
| script | |
| { | |
| def committers = emailextrecipients([[$class: 'CulpritsRecipientProvider'], | |
| [$class: 'DevelopersRecipientProvider']]) | |
| jobName = "${currentBuild.fullDisplayName}".replace('%2', '/') | |
| if (currentBuild.result == 'SUCCESS') { | |
| slackMessage = ":zap_success: SUCCESS: <${env.RUN_DISPLAY_URL}|" + jobName + '>, changes by: ' + committers | |
| slackColor = 'good' | |
| slackSend (color: slackColor, channel: '#zap', message: slackMessage) | |
| } | |
| else if (currentBuild.result == 'UNSTABLE') { | |
| slackMessage = ":zap_warning: WARNING: <${env.RUN_DISPLAY_URL}|" + jobName + '>, changes by: ' + committers | |
| slackColor = 'warning' | |
| slackSend (color: slackColor, channel: '#zap', message: slackMessage) | |
| } | |
| else | |
| { | |
| slackMessage = ":zap_failure: FAILED: <${env.RUN_DISPLAY_URL}|" + jobName + '>, changes by: ' + committers | |
| slackColor = 'danger' | |
| slackSend (color: slackColor, channel: '#zap', message: slackMessage) | |
| } | |
| } | |
| junit 'junit.xml' | |
| } | |
| } | |
| } |