//---------------------------------------------------------------------------------------------------------------------------------------------------- // Parameters //---------------------------------------------------------------------------------------------------------------------------------------------------- // set start time for nightly build on master branch String cron_string = env.BRANCH_NAME == 'master' ? '0 19 * * *' : '' // agent specific parameters - tailor for Your project! def agentBuild = 'ITTOR47YBS08' def agentBuildPathToolsGeneric = 'D:\\ALGitRepo\\ToolsGeneric' def agentSmokeTest = 'RT HQGIF Smoke test agent' def agentSmokeTestPathToolsGeneric = 'C:\\ALGitRepo\\ToolsGeneric' def agentBuildLinux = 'itoskabsp004-Linux' // project specific parameters - tailor for Your project! def artifactoryProjectName = 'ALGEN' def artifactoryBrowserUrl = 'https://hub.marelli.com/artifactory/webapp/#/artifacts/browse/tree/General' def projectRepoName = 'Cln1' def softwareLabelDefault = 'Z03_IN005_SWAP_XXXX.XXXX.XX' def swttnrDefault = '0000000000' def pathToCFGID = 'Src\\Src_AL\\Cust\\In\\In005\\App\\ALUnit\\CfgId' def remoteRepoUrl = 'ssh://p_al_user_agent_1@hub.marelli.com:7996/algen/cln1.git' def remoteRepository = 'https://hub.marelli.com/bitbucket/scm/algen/cln1.git' def buildOutputBin = 'Z03In005_App_default' // assembled artifactory url def artifactoryBasePath = "${artifactoryProjectName}/${projectRepoName}/application" def artifactoryBrowserUrlProject = "${artifactoryBrowserUrl}/${artifactoryBasePath}" //---------------------------------------------------------------------------------------------------------------------------------------------------- // Function to stop older builds (of the same branch/PR) if a newer one is in the queue already // Source: https://issues.jenkins.io/browse/JENKINS-43353?focusedCommentId=376915&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-376915 //---------------------------------------------------------------------------------------------------------------------------------------------------- @NonCPS def cancelPreviousBuilds() { // Check for other instances of this particular build, cancel any that are older than the current one def jobName = env.JOB_NAME def currentBuildNumber = env.BUILD_NUMBER.toInteger() def currentJob = Jenkins.instance.getItemByFullName(jobName) // Loop through all instances of this particular job/branch for (def build : currentJob.builds) { if (build.isBuilding() && (build.number.toInteger() < currentBuildNumber)) { echo "Older build still queued. Sending kill signal to build number: ${build.number}" build.doStop() } } } //---------------------------------------------------------------------------------------------------------------------------------------------------- // Pipeline itself //---------------------------------------------------------------------------------------------------------------------------------------------------- pipeline { agent none options { timestamps () skipDefaultCheckout() } triggers { cron(cron_string) } stages { stage('Init') { agent { label 'master' } steps { script { cancelPreviousBuilds() } } } stage("Prepare Variables") { agent { label 'master' } steps{ echo "Prepare Variables" echo "On Node: ${NODE_NAME}" echo "Initially prepare build variables" script { def tmpUserInput def userInputSWLabel = "NotSet" def userInputSWTTNR = "NotSet" // env._DATE def tmpTimestamp = env.BUILD_TIMESTAMP // BUILD_TIMESTAMP=2020-12-01 10:51:50 CET env._DATE = tmpTimestamp.substring(0,10) echo "env._DATE: ${_DATE}" // env._BUILDNO def tmpBuildNo = env.BUILD_NUMBER env._BUILDNO = tmpBuildNo.padLeft(8, '0') echo "env._BUILDNO: ${_BUILDNO}" // env._PROJ_REPO_BRANCHNAME env._PROJ_REPO_BRANCHNAME = env.BRANCH_NAME echo "env._PROJ_REPO_BRANCHNAME: ${_PROJ_REPO_BRANCHNAME}" env._PROJ_REPO_BRANCHNAME_NO_SLASH = env._PROJ_REPO_BRANCHNAME.replaceAll( '/', '-' ) echo "_PROJ_REPO_BRANCHNAME_NO_SLASH: ${_PROJ_REPO_BRANCHNAME_NO_SLASH}" // env._PLANNAME, env._USERINPUTSWLABEL, env._USERINPUTSWTTNR env._PLANNAME = 'NotSet' env._USERINPUTSWLABEL = 'NotSet' env._USERINPUTSWTTNR = 'NotSet' env._BUILDOUTPUTBIN = "${buildOutputBin}" // nightly-build if (env.BRANCH_NAME == 'master') { env._PLANNAME = 'nightly-build' env._ARTIFACTORY_URL = "${artifactoryBasePath}/${_PLANNAME}/${BRANCH_NAME}/${_DATE}-${_BUILDNO}" env._ARTIFACTORY_URL_LATEST = "${artifactoryBasePath}/${_PLANNAME}/${BRANCH_NAME}/0000-00-00-latest" env._ARTIFACTORY_URL_BROWSER = "${artifactoryBrowserUrlProject}/${_PLANNAME}/${BRANCH_NAME}/${_DATE}-${_BUILDNO}" } // integration-build if (env.BRANCH_NAME ==~ /PR-.*/ || env.BRANCH_NAME ==~ /feature.*/ || env.BRANCH_NAME ==~ /bugfix.*/) { env._PLANNAME = 'integration-build' env._ARTIFACTORY_URL = "${artifactoryBasePath}/${_PLANNAME}/${BRANCH_NAME}/${_DATE}-${_BUILDNO}" env._ARTIFACTORY_URL_BROWSER = "${artifactoryBrowserUrlProject}/${_PLANNAME}/${BRANCH_NAME}/${_DATE}-${_BUILDNO}" } // release-candidate-build if (env.BRANCH_NAME ==~ /release.*/) { env._PLANNAME = 'release-candidate-build' // Read input label def userInput timeout(time: 30, unit: "MINUTES") { tmpUserInput = input(id: 'userInput', message: 'SW logistic data:', parameters: [ [$class: 'TextParameterDefinition', defaultValue: '${softwareLabelDefault}', description: 'SWLabel', name: 'swlabel'], [$class: 'TextParameterDefinition', defaultValue: '${swttnrDefault}', description: 'SWTTNR', name: 'swttnr'] ]) } env._USERINPUTSWLABEL = tmpUserInput['swlabel'] env._USERINPUTSWTTNR = tmpUserInput['swttnr'] echo ("userInputSWLabel: "+env._USERINPUTSWLABEL) echo ("userInputSWTTNR: "+env._USERINPUTSWTTNR) env._ARTIFACTORY_URL = "${artifactoryBasePath}/${_PLANNAME}/${_DATE}-${_USERINPUTSWLABEL}" env._ARTIFACTORY_URL_BROWSER = "${artifactoryBrowserUrlProject}/${_PLANNAME}/${_DATE}-${_USERINPUTSWLABEL}" } echo "env._PLANNAME: ${_PLANNAME}" // env._ARTIFACTORY_URL, env._ARTIFACTORY_URL_BROWSER echo "env._BUILDOUTPUTBIN: ${env._BUILDOUTPUTBIN}" echo "env._ARTIFACTORY_URL: ${env._ARTIFACTORY_URL}" echo "env._ARTIFACTORY_URL_LATEST: ${env._ARTIFACTORY_URL_LATEST}" echo "env._ARTIFACTORY_URL_BROWSER: ${env._ARTIFACTORY_URL_BROWSER}" } } } stage('Pull ToolsGeneric') { agent {label "${agentBuild}"} steps { lock("${NODE_NAME}LockToolsGenericPull") { echo 'Pull ToolsGeneric' echo "On Node: ${NODE_NAME}" bat """ cd ${agentBuildPathToolsGeneric} git pull """ } } } stage('Checkout project repository') { parallel { stage('Checkout project repo on Windows (default)') { agent {label "${agentBuild}"} steps { checkout([ $class: 'GitSCM', branches: scm.branches, extensions: scm.extensions + [[$class: 'GitLFSPull'], [$class: 'CheckoutOption', timeout: 45], [$class: 'CloneOption', timeout: 45, noTags: false, reference: 'D:/ALGitRepoMirror/cln1.git', shallow: false], [$class: 'SubmoduleOption', disableSubmodules: false, parentCredentials: true, recursiveSubmodules: true, reference: '', timeout: 45, trackingSubmodules: false]], userRemoteConfigs: scm.userRemoteConfigs ]) } } stage('Checkout project repo on Linux') { agent {label "${agentBuildLinux}"} steps { checkout([ $class: 'GitSCM', branches: scm.branches, extensions: scm.extensions + [[$class: 'GitLFSPull'], [$class: 'CheckoutOption', timeout: 45], [$class: 'CloneOption', timeout: 45, noTags: false, shallow: false], [$class: 'SubmoduleOption', disableSubmodules: false, parentCredentials: true, recursiveSubmodules: true, reference: '', timeout: 45, trackingSubmodules: false]], userRemoteConfigs: scm.userRemoteConfigs ]) } } } } stage('Delete user settings') { agent {label "${agentBuild}"} steps { echo 'Delete user settings!' echo "On Node: ${NODE_NAME}" bat """ echo Actual working directory: cd del Build\\Make\\Make_005_UserSettings.gmk """ } } stage('Create BuildInfo.txt file') { agent {label "${agentBuild}"} steps { echo 'Create BuildInfo.txt file!' echo "On Node: ${NODE_NAME}" bat """ echo Actual working directory: cd REM Saved in BuildInfo.txt SET PROJECTBranchName = NotSet SET PROJECTCommitHash = NotSet SET ToolsGenericBranchName = NotSet SET ToolsGenericCommitHash = NotSet REM get PROJECT repository information git symbolic-ref -q --short HEAD > temp.txt set /p PROJECTBranchName= temp.txt set /p PROJECTCommitHash= temp.txt set /p ToolsGenericBranchName= temp.txt set /p ToolsGenericCommitHash= BuildInfo.txt """ } } stage('integration-build') { parallel { stage ('integration-build on Linux') { agent {label "${agentBuildLinux}"} when { expression {env._PLANNAME == 'integration-build'} } steps { sh ''' echo "build/run one unit test" echo cd Build/VS echo ../Make/make.sh W00 Gen_Gen UNIX_GCC CUnit GCOV X64 In005 Test Mt_ApplBenchmark NonKey rebuild cat ../Bin/W00In005_Test_Mt_ApplBenchmark/W00In005_Test_Mt_ApplBenchmark_ExecutionResult.txt echo "verify unit test result" echo cat ../Bin/W00In005_Test_Mt_ApplBenchmark/W00In005_Test_Mt_ApplBenchmark_ExecutionResult.txt | grep 'number_of_failed_asserts' | awk '{print($2 == "0")}' | grep '1' ''' } } stage ('integration-build on Windows (default)') { agent {label "${agentBuild}"} when { expression {env._PLANNAME == 'integration-build'} } steps { bat """ cd ${env.WORKSPACE}\\CI\\Support set PATH_TOOLSGENERIC=${agentBuildPathToolsGeneric} set PROJECTNAME_AXIVION=CLN1-${env._PROJ_REPO_BRANCHNAME_NO_SLASH} call 00_integration.bat echo ErrorLevel: %ERRORLEVEL% if %ERRORLEVEL% EQU 0 ( echo 00_integration.bat Success, ErrorLevel is: %ERRORLEVEL% ) else ( echo 00_integration.bat Failure, ErrorLevel is: %ERRORLEVEL% exit /b %errorlevel% ) """ } post { always { echo "Deploy to Artifactory on Node: ${NODE_NAME}" rtUpload ( serverId: 'artifactory-al-prod', specPath: '${WORKSPACE}/CI/ArtifactorySpecs/integration-build/1-AP-deploy-app-mt-it.txt' ) script { currentBuild.description = """Link to Artifactory""" } echo '30_eval_app_build.bat' bat """ cd ${env.WORKSPACE}\\CI\\Support set PATH_TOOLSGENERIC=${agentBuildPathToolsGeneric} call 30_eval_app_build.bat echo ErrorLevel: %ERRORLEVEL% if %ERRORLEVEL% EQU 0 ( echo 30_eval_app_build.bat Success, ErrorLevel is: %ERRORLEVEL% exit /b %ERRORLEVEL% ) else ( echo 30_eval_app_build.bat Failure, ErrorLevel is: %ERRORLEVEL% exit /b %ERRORLEVEL% ) """ } } } } } stage('nightly-build') { parallel { stage ('nightly-build on Linux') { agent {label "${agentBuildLinux}"} when { expression {env._PLANNAME == 'nightly-build'} } steps { echo "not implemented yet" } } stage('nightly-build on Windows (default)') { agent {label "${agentBuild}"} when { expression {env._PLANNAME == 'nightly-build'} } steps { bat """ cd ${env.WORKSPACE}\\CI\\Support set PATH_TOOLSGENERIC=${agentBuildPathToolsGeneric} set PROJECTNAME_AXIVION=CLN1-${env._PROJ_REPO_BRANCHNAME_NO_SLASH} call 00_integration.bat echo ErrorLevel: %ERRORLEVEL% if %ERRORLEVEL% EQU 0 ( echo 00_integration.bat Success, ErrorLevel is: %ERRORLEVEL% ) else ( echo 00_integration.bat Failure, ErrorLevel is: %ERRORLEVEL% exit /b %errorlevel% ) """ } post { always { echo "Deploy to Artifactory on Node: ${NODE_NAME}" rtUpload ( serverId: 'artifactory-al-prod', specPath: '${WORKSPACE}/CI/ArtifactorySpecs/nightly-build/1-AP-deploy-app-mt-it.txt' ) script { currentBuild.description = """Link to Artifactory""" } rtUpload ( serverId: 'artifactory-al-prod', specPath: '${WORKSPACE}/CI/ArtifactorySpecs/nightly-build/1-AP-deploy-app-mt-it-latest.txt' ) echo '30_eval_app_build.bat' bat """ cd ${env.WORKSPACE}\\CI\\Support set PATH_TOOLSGENERIC=${agentBuildPathToolsGeneric} call 30_eval_app_build.bat echo ErrorLevel: %ERRORLEVEL% if %ERRORLEVEL% EQU 0 ( echo 30_eval_app_build.bat Success, ErrorLevel is: %ERRORLEVEL% exit /b %ERRORLEVEL% ) else ( echo 30_eval_app_build.bat Failure, ErrorLevel is: %ERRORLEVEL% exit /b %ERRORLEVEL% ) """ } } } } } stage('release-candidate-build') { parallel { stage ('release-candidate-build on Linux') { agent {label "${agentBuildLinux}"} when { expression {env._PLANNAME == 'release-candidate-build'} } steps { echo "not implemented yet" } } stage ('release-candidate-build on Windows (default)') { agent {label "${agentBuild}"} when { expression {env._PLANNAME == 'release-candidate-build'} } steps { bat """ git status git stash git checkout ${env.BRANCH_NAME} git stash apply git status git config --list git remote add central ${remoteRepoUrl} echo set configurations git config --global user.email "" git config --global user.name "Jenkins Agent" git fetch central echo create and push tag git tag -a ${env._USERINPUTSWLABEL} -m "Created by Jenkins Agent" git push central --tags git status """ bat """ REM Tailor: adapt path to CfgId folder of Your project cd ${pathToCFGID} echo "${env._USERINPUTSWLABEL}" > CFGID_CfgInfoVersion.txt.h echo "${env.userInputSWTTNR}" > CfgId_CfgInfoPartNo.txt.h """ bat """ cd CI\\Support set PATH_TOOLSGENERIC=${agentBuildPathToolsGeneric} set PROJECTNAME_AXIVION=CLN1-${env._PROJ_REPO_BRANCHNAME_NO_SLASH} call 00_integration.bat echo ErrorLevel: %ERRORLEVEL% if %ERRORLEVEL% EQU 0 ( echo 00_integration.bat Success, ErrorLevel is: %ERRORLEVEL% ) else ( echo 00_integration.bat Failure, ErrorLevel is: %ERRORLEVEL% exit /b %errorlevel% ) """ } post { always { echo "Deploy to Artifactory on Node: ${NODE_NAME}" rtUpload ( serverId: 'artifactory-al-prod', specPath: '${WORKSPACE}/CI/ArtifactorySpecs/release-candidate-build/1-AP-deploy-app-mt-it.txt' ) script { currentBuild.description = """Link to Artifactory
${env._USERINPUTSWLABEL} ${env.userInputSWTTNR}""" } echo '30_eval_app_build.bat' bat """ cd CI\\Support set PATH_TOOLSGENERIC=${agentBuildPathToolsGeneric} call 30_eval_app_build.bat echo ErrorLevel: %ERRORLEVEL% if %ERRORLEVEL% EQU 0 ( echo 30_eval_app_build.bat Success, ErrorLevel is: %ERRORLEVEL% exit /b %ERRORLEVEL% ) else ( echo 30_eval_app_build.bat Failure, ErrorLevel is: %ERRORLEVEL% exit /b %ERRORLEVEL% ) """ } } } } } } post { always { node( "${agentBuild}" ) { echo 'One way or another, execution has finished' cleanWs() emailext ( body: """

Build status: ${currentBuild.result}.


Jenkins build output: ${env.JOB_NAME} ${env._PLANNAME}#${env.BUILD_NUMBER}


Link to Artifactory: ${env._ARTIFACTORY_URL_BROWSER}""", mimeType: "text/html", to: "mark.strecker@marelli.com, ${env.CHANGE_AUTHOR_EMAIL}", subject: "ALJenkins: ${env.JOB_NAME} - ${env._PLANNAME} - #${env.BUILD_NUMBER} - ${currentBuild.result}" ) } } success { echo 'I succeeded!' } unstable { echo 'I am unstable :/' } failure { echo 'I failed :(' } changed { echo 'Things were different before...' } } }