How to select multiple JDK version in declarative pipeline Jenkins - jenkins

I want to use different JDK versions for different stages in Jenkins declarative pipeline. In the first stage I am using Java 8. In the second stage i am using Java 6. How to select multiple JDK version in declarative pipeline in Jenkins?
pipeline {
agent any
tools {
jdk 'jdk_1.8.0_151'
jdk 'jdk_1.6.0_45'
}
stages {
stage('java 8') {
steps {
sh 'java -version'
sh 'javac -version'
}
}
stage('java 6') {
steps {
sh 'java -version'
sh 'javac -version'
}
}
}
}

you can add a tools section for each stage.
pipeline {
agent any
stages {
stage ("first") {
tools {
jdk "jdk-1.8.101"
}
steps {
sh 'java -version'
}
}
stage("second"){
tools {
jdk "jdk-1.8.152"
}
steps{
sh 'java -version'
}
}
}
}

From the Pipeline tools directive:
tools: A section defining tools to auto-install and put on the PATH.
The tool name must be pre-configured in Jenkins under
Manage Jenkins → Global Tool Configuration.
From the pipeline-examples and cloudbess example:
pipeline {
agent any
tools {
jdk 'jdk_1.8.0_151'
}
stages {
stage('jdk 8') {
steps {
sh 'java -version'
sh 'javac -version'
}
}
stage('jdk 6') {
steps {
withEnv(["JAVA_HOME=${tool 'openjdk_1.6.0_45'}", "PATH=${tool 'openjdk_1.6.0_45'}/bin:${env.PATH}"]) {
sh 'java -version'
sh 'javac -version'
}
}
}
stage('global jdk') {
steps {
sh 'java -version'
sh 'javac -version'
}
}
}
}

I would recommend you to use different docker images for each stage if you want to have different JDK versions. You can achieve using the docker hub openjdk images with the correct tag.
https://hub.docker.com/r/library/openjdk/
https://hub.docker.com/r/library/openjdk/tags/
Something like that:
pipeline {
agent none
stages {
stage('openjdk:7-jdk') {
agent {
docker { image 'jdk7_image' }
}
steps {
sh 'java -version'
}
}
stage('java8') {
agent {
docker { image 'openjdk:8-jdk' }
}
steps {
sh 'java -version'
}
}
}
}

Related

How to add a jmeter build step to jenkins pipeline when using jmeter maven plugin

I have two stages on jenkins pipeline, and it is expecting to add steps in execute jmeter stage
Could someone help to resolve this....
I got below error:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 339: Expected one of "steps", "stages", or "parallel" for stage "Execute Jmeter" # line 339, column 9.
stage('Execute Jmeter') {
Below is the code snippet of jenkins pipeline:
pipeline {
agent {
label 'qatest'
}
tools {
maven 'Maven'
jdk 'JDK8'
}
environment {
VIRTUOSO_URL = 'qa.myapp.com'
}
stages {
stage('BUILD') {
steps {
sh 'mvn clean verify'
}
}
stage('Execute Jmeter') {
post{
always{
dir("scenarioLoadTests/target/jmeter/results/"){
sh 'pwd'
sh 'mv *myapp_UserLoginAndLogout.csv UserLoginAndLogout.csv '
sh 'mv *myapp_myappPortfolioScenario.csv myappPortfolioScenario.csv '
sh 'mv *myapp_myappDesign.csv myappDesign.csv '
perfReport '*.csv'
}
}
}
}
}
}
Shouldn't you use script blocks like:
pipeline {
agent {
label 'qatest'
}
tools {
maven 'Maven'
jdk 'JDK8'
}
environment {
VIRTUOSO_URL = 'qa.myapp.com'
}
stages {
stage('BUILD') {
steps {
script { // <----------------- here
sh 'mvn clean verify'
}
}
}
stage('Execute Jmeter') {
post {
always {
dir('scenarioLoadTests/target/jmeter/results/') {
script { <-------------------------------------- and here
sh 'pwd'
sh 'mv *myapp_UserLoginAndLogout.csv UserLoginAndLogout.csv '
sh 'mv *myapp_myappPortfolioScenario.csv myappPortfolioScenario.csv '
sh 'mv *myapp_myappDesign.csv myappDesign.csv '
perfReport '*.csv'
}
}
}
}
}
}
}
More information:
Pipeline Maven Integration
Running a JMeter Test via Jenkins Pipeline - A Tutorial

Jenkins declarative pipeline can't find some scripts

I have written a Jenkins pipeline where the relevant parts looks as follows:
pipeline {
agent {
dockerfile true
}
triggers {
pollSCM('H 1 * * 1-5')
}
options {
buildDiscarder(logRotator(artifactNumToKeepStr: "${NUMBER_OF_ARTIFACTS_TO_KEEP}"))
disableConcurrentBuilds()
timeout(time: 60, unit: 'MINUTES')
timestamps()
}
stages {
stage('Metadata') {
steps {
script {
sh 'java -version'
}
script {
sh './mvnw -v'
}
}
}
stage('Build') {
steps {
script {
sh './mvnw --batch-mode clean install'
}
}
}
stage('Archive artifacts (develop/master)') {
when {
anyOf {
branch 'master'
branch 'develop'
}
}
steps {
script {
sh './package.sh'
}
archive '**/target/*.jar'
archiveArtifacts artifacts: '*.deb'
}
}
}
post {
always {
deleteDir()
}
failure {
sendNotifications currentBuild.result
}
unstable {
sendNotifications currentBuild.result
}
}
}
And my Dockerfile:
FROM alpine
RUN apk add --no-cache dpkg openjdk8
All scripts run fine, except package.sh where I get the following log in the output:
07:47:25 [chx-sync_-sync_master-A2F53LY4I2X54TLDEU2Z2PXI423NI6FODHQDS7CRIKCCNDF5UGOA] Running shell script
07:47:25 + ./package.sh
07:47:25 /home/jenkins/jenkins/workspace/chx-sync_-sync_master-A2F53LY4I2X54TLDEU2Z2PXI423NI6FODHQDS7CRIKCCNDF5UGOA#tmp/durable-dbcb4143/script.sh: line 1: ./package.sh: not found
I can't figure out why all scripts except this one would work. They are all located in the root of the project in Git. Is there some command in my pipeline that would change the working directory, or what is going on here?
EDIT:
I'm guessing the shebang in package.sh might be relevant? It is #!/bin/bash.
I got the answer from this answer on SO. I simply changed the using #!/bin/sh and it is working.

Reuse agent (docker container) in Jenkins between multiple stages

I have a pipeline with multiple stages, and I want to reuse a docker container between only "n" number of stages, rather than all of them:
pipeline {
agent none
stages {
stage('Install deps') {
agent {
docker { image 'node:10-alpine' }
}
steps {
sh 'npm install'
}
}
stage('Build, test, lint, etc') {
agent {
docker { image 'node:10-alpine' }
}
parallel {
stage('Build') {
agent {
docker { image 'node:10-alpine' }
}
// This fails because it runs in a new container, and the node_modules created during the first installation are gone at this point
// How do I reuse the same container created in the install dep step?
steps {
sh 'npm run build'
}
}
stage('Test') {
agent {
docker { image 'node:10-alpine' }
}
steps {
sh 'npm run test'
}
}
}
}
// Later on, there is a deployment stage which MUST deploy using a specific node,
// which is why "agent: none" is used in the first place
}
}
See reuseNode option for Jenkins Pipeline docker agent:
https://jenkins.io/doc/book/pipeline/syntax/#agent
pipeline {
agent any
stages {
stage('NPM install') {
agent {
docker {
/*
* Reuse the workspace on the agent defined at top-level of
* Pipeline, but run inside a container.
*/
reuseNode true
image 'node:12.16.1'
}
}
environment {
/*
* Change HOME, because default is usually root dir, and
* Jenkins user may not have write permissions in that dir.
*/
HOME = "${WORKSPACE}"
}
steps {
sh 'env | sort'
sh 'npm install'
}
}
}
}
You can use scripted pipelines, where you can put multiple stage steps inside a docker step, e.g.
node {
checkout scm
docker.image('node:10-alpine').inside {
stage('Build') {
sh 'npm run build'
}
stage('Test') {
sh 'npm run test'
}
}
}
(code untested)
For Declarative pipeline, one solution can be to use Dockerfile in the root of the project. For e.g.
Dockerfile
FROM node:10-alpine
// Further Instructions
Jenkinsfile
pipeline{
agent {
dockerfile true
}
stage('Build') {
steps{
sh 'npm run build'
}
}
stage('Test') {
steps{
sh 'npm run test'
}
}
}

Creating Jenkins Pipeline inside Job DSL script

I can create pipelines by putting the following code into "Jenkinsfile" in my repository(called repo1) and creating a new item, through Jenkins GUI, to poll the repository.
pipeline {
agent {
docker {
image 'maven:3-alpine'
args '-v /root/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
}
}
}
stage('Deploy') {
steps {
sh 'echo \'uploading artifacts to some repositories\''
}
}
}
}
But I have a case where I am not allowed create new items through Jenkins GUI but have a pre-defined job which reads JobDSL files in a repository I provide. So, I need to create the same pipeline through JobDSL but I cannot find the corresponding syntax for all the things, for instance, I couldn't find 'agent' DSL command.
Here is a job DSL code I was trying to change.
pipelineJob('the-same-pipeline') {
definition {
cps {
sandbox()
script("""
node {
stage('prepare') {
steps {
sh '''echo 'hello''''
}
}
}
""".stripIndent())
}
}
}
For instance, I could not find 'agent' command. Is it really possible to have the exact pipeline by using job DSL?
I found a way to create the pipeline item through jobDSL. So, the following jobDSL is creating another item which is just a pipeline.
pipelineJob('my-actual-pipeline') {
definition {
cpsScmFlowDefinition {
scm {
gitSCM {
userRemoteConfigs {
userRemoteConfig {
credentialsId('')
name('')
refspec('')
url('https://github.com/muatik/jenkins-as-code-example')
}
}
branches {
branchSpec {
name('*/master')
}
}
browser {
gitWeb {
repoUrl('')
}
}
gitTool('')
doGenerateSubmoduleConfigurations(false)
}
}
scriptPath('Jenkinsfile')
lightweight(true)
}
}
}
You can find the Jenkinsfile and my test repo here: https://github.com/muatik/jenkins-as-code-example

Define a global Ant tool in a Jenkins Declarative Pipeline

I have recently started to write a Jenkins Declarative Pipeline (Jenkinsfile in CVS) with several stages.
I'd like to know if there is way to define Ant only once and then reuse the same command in all stages.
Instead of repeating bat "%ANT_HOME%/bin/ant.bat the_ant_target_to_run", I'd prefer doing this instead: ant clean compile
pipeline {
agent any
stages {
stage("Build") {
steps {
echo "Building application..."
bat "%ANT_HOME%/bin/ant.bat clean compile"
}
}
stage("Unit Tests") {
steps {
echo "Unit tests (JUnit)..."
echo "Mutation tests (pitest)..."
bat "%ANT_HOME%/bin/ant.bat run-unit-tests"
bat "%ANT_HOME%/bin/ant.bat run-mutation-tests"
}
}
stage("Functional Test") {
steps {
echo "Selenium tests..."
}
}
stage("Performance Test") {
steps {
echo "JMeter tests..."
}
}
stage("Quality Analysis") {
steps {
echo "Running SonarQube..."
bat "%ANT_HOME%/bin/ant.bat run-sonarqube-analysis"
}
}
stage("Security Assessment") {
steps {
echo "Pen testing..."
}
}
stage("Approval") {
steps {
input "Is the build OK?"
}
}
stage("Deploy") {
steps {
echo "Deploying to JBoss 7.2..."
}
}
}
post {
always {
junit '/test/reports/*.xml'
}
}
}
you can go to Manage Jenkins section and then Global Tool Configuration
there you can add ant installation.
then in the pipeline add the line:
antHome = tool 'ANT' - the name you gave your ant in the configurations.
after it you can use it as a parameter
Home it helps

Resources