Jenkins - translate withCredentials into declarative style syntax - jenkins

I have a jenkins pipeline which is written using a scripted syntax and I need to make this into a new pipeline using a declarative style.
This is my fist project with jenkins and I am stuck at how to translate the withCredentials syntax in declarative jenkins.
The original(scripted) pipeline looks something like this:
stage('stage1') {
steps {
script {
withCredentials([usernamePassword(credentialsId: CredentialsAWS, passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) {
parallel (
something: {
sh 'some commands where there is no reference to the above credentials'
}
)
}
}
}
}
So far, I have set the credentials in question as an environment variable but since in the original pipeline these are not referenced in the command but they just wrap around the command as 'withCredentials', I am not sure how to achieve the same result. Any idea how to do this?

First of all take a look at official documentation
For your case pipeline will look like:
pipeline {
agent any
environment {
YOUR_CRED = credentials('CredentialsAWS')
}
stages {
stage('Call username and password from YOUR_CRED') {
steps {
echo "To call username use ${YOUR_CRED_USR}"
echo "To call password use ${YOUR_CRED_PSW}"
}
}
}
}

Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
parameters {
string(name: 'STATEMENT', defaultValue: 'hello; ls /', description: 'What should I say?')
}
stages {
stage('Example') {
steps {
/* CORRECT */
sh('echo ${STATEMENT}')
}
}
}
}
visit here

Related

Execute step or script outside of the Jenkins agent in Declarative Jenkinsfile

Is there a way to execute step outside of the Jenkins agent?
Suppose that I have following structure of Jenkinsfile:
pipeline {
agent none
stages {
stage('Example Stage') {
agent { someAgent }
steps {
run something ...
input ...
}
}
}
}
I would like to execute input outside of an agent to not block it for hours (timeout is not the answer ;))
One of the possible solutions is to execute the logic in separate stages but i'm trying to avoid creating additional ones.
You could use node instead of agent:
pipeline {
agent none
stages {
stage('Example Stage') {
steps {
node( someAgent ) {
run something ...
}
// outside of any agent
input ...
}
}
}
}

How to get Jenkins credentials variable in all stages of my Jenkins Declarative Pipeline

How do I get Jenkins credentials variable i.e "mysqlpassword" accessible to all stages of my Jenkins Declarative Pipeline?
The below code snippet works fine and prints my credentials.
node {
stage('Getting Database Credentials') {
withCredentials([usernamePassword(credentialsId: 'mysql_creds', passwordVariable: 'mysqlpassword', usernameVariable: 'mysqlusername')])
{
creds = "\nUsername: ${mysqlusername}\nPassword: ${mysqlpassword}\n"
}
println creds
}
}
How can I incorporate the above code in my current pipeline so that mysqlusername & mysqlpassword variables are accessible to all stages across the pipeline script i.e globally.
My pipeline script layout looks like below:
pipeline { //indicate the job is written in Declarative Pipeline
agent { label 'Prod_Slave' }
environment {
STAGE_2_EXECUTED = "0"
}
stages {
stage ("First Stage") {
steps {
echo "First called in pipeline"
script {
echo "Inside script of First stage"
}
}
} // end of first stage
stage ("Second Stage") {
steps {
echo "Second stage called in pipeline"
script {
echo "Inside script of Second stage"
}
}
} // end of second stage
} //end of stages
} // end of pipeline
I m on the latest version of Jenkins.
Requesting solutions. Thank you.
You can do something like this. Here, you define you variables under environment { } and use it throughout your stages.
pipeline {
agent any
environment {
// More detail:
// https://jenkins.io/doc/book/pipeline/jenkinsfile/#usernames-and-passwords
MYSQL_CRED = credentials('mysql_creds')
}
stages {
stage('Run Some Command') {
steps{
echo "Running some command"
sh '<some-command> -u $MYSQL_CRED_USR -p $MYSQL_CRED_PSW'
}
}
}
Variables defined under environments are global to all the stages so can be used in the whole jenkinsfile.
More information about credentials() in official documentation.

Equivalent block to environment in scripted pipeline with Jenkins

I have the following pipeline:
pipeline {
agent any
environment {
branch = 'master'
scmUrl = 'ssh://git#myrepo.git'
serverPort = '22'
}
stages {
stage('Stage 1') {
steps {
sh '/var/jenkins_home/contarpalabras.sh'
}
}
}
}
I want to change the pipeline to "scripted pipeline" in order to use try / catch blocks and have better error management. However i did not find how the equivalent to environment block in official documentation.
You can use the withEnv block like:
node {
withEnv(['DISABLE_AUTH=true',
'DB_ENGINE=sqlite']) {
stage('Build') {
sh 'printenv'
}
}
}
This info is also in the official documentation : https://jenkins.io/doc/pipeline/tour/environment/#

Declarative Jenkins Pipeline; How to declare a variable and use it in script or mail notification?

(update below)
I have a declarative pipeline job which can take an argument VERSION.
pipeline {
parameters {
string(name: VERSION, defaultValue: '')
}
// ...
}
If no VERSION is given, like when Gitlab send a hook to this job, I want to compute it from git, so I do something like this
stages {
stage('Prepare') {
steps {
// ...
if (! env.VERSION) {
VERSION = sh(script: "git describe", returnStdout: true).trim()
}
}
}
}
Now I want to "inject" this variable to
my build script. It needs to find "VERSION" in the environment variables
to the jenkins mail notificator. And get it to retreive ${VERSION} in subject or body text
I tried changing above code with
stages {
stage('Prepare') {
steps {
// ...
if (! env.VERSION) {
env.VERSION = sh(script: "git describe", returnStdout: true).trim()
}
}
}
}
Got this error groovy.lang.MissingPropertyException: No such property: VERSION for class: groovy.lang.Binding
I then tried to add a "environment" step below
environment {
VERSION = ${VERSION}
}
but it didn't solve my problem.
I'm looking for any help to solve it.
UPDATE
I now have a working pipeline which looks like
pipeline {
agent any
parameters {
string(name: 'VERSION', defaultValue: '')
}
environment {
def VERSION = "${params.VERSION}"
}
stages {
stage('Prepare & Checkout') {
steps {
script {
if (! env.VERSION) {
VERSION = sh(script: "date", returnStdout: true).trim()
}
echo "** version: ${VERSION} **"
}
}
}
stage('Build') {
steps {
// sh "./build.sh"
echo "** version2: ${VERSION} **"
}
}
} // stages
post {
always {
mail to: 'foo#example.com',
subject: "SUCCESS: ${VERSION}",
body: """<html><body><p>SUCCESS</p></body></html>""",
mimeType: 'text/html',
charset: 'UTF-8'
deleteDir()
}
}
} // pipeline
I needed to add the "environment" step to be able to get $VERSION in all Stages (not only in the one it is manipulated).
I still need to find a way to inject this $VERSION variable in the environment variables, so that my build script can find it.
If you want to inject the variable in the environment so that you can use it later, you could define another variable that is equal to env.VERSION or the output of the shell scrip. Then use that variable in your pipeline eg:
pipeline {
parameters {
string(name: VERSION, defaultValue: '')
}
def version = env.VERSION
stages {
stage('Prepare') {
steps {
// ...
if (!version) {
version = sh(script: "git describe", returnStdout: true).trim()
}
}
}
mail subject: "$version build succeeded", ...
}
If you want other jobs to be able to access the value of VERSION after the build is run, you can write it in a file and archive it.
Edit:
In order for your script to be able to use the version variable, you can either make your script take version as a parameter or you can use the withEnv step.
Assuming you are using Parametrized pipelines, you should call variable as ${params.parameterName}
Although parameters are available in env they currently are created before the first time the pipeline is run, therefore you should access them via params:
In your case:
${params.VERSION}

Cannot define variable in pipeline stage

I'm trying to create a declarative Jenkins pipeline script but having issues with simple variable declaration.
Here is my script:
pipeline {
agent none
stages {
stage("first") {
def foo = "foo" // fails with "WorkflowScript: 5: Expected a step # line 5, column 13."
sh "echo ${foo}"
}
}
}
However, I get this error:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 5: Expected a step # line 5, column 13.
def foo = "foo"
^
I'm on Jenkins 2.7.4 and Pipeline 2.4.
The Declarative model for Jenkins Pipelines has a restricted subset of syntax that it allows in the stage blocks - see the syntax guide for more info. You can bypass that restriction by wrapping your steps in a script { ... } block, but as a result, you'll lose validation of syntax, parameters, etc within the script block.
I think error is not coming from the specified line but from the first 3 lines. Try this instead :
node {
stage("first") {
def foo = "foo"
sh "echo ${foo}"
}
}
I think you had some extra lines that are not valid...
From declaractive pipeline model documentation, it seems that you have to use an environment declaration block to declare your variables, e.g.:
pipeline {
environment {
FOO = "foo"
}
agent none
stages {
stage("first") {
sh "echo ${FOO}"
}
}
}
Agree with #Pom12, #abayer. To complete the answer you need to add script block
Try something like this:
pipeline {
agent any
environment {
ENV_NAME = "${env.BRANCH_NAME}"
}
// ----------------
stages {
stage('Build Container') {
steps {
echo 'Building Container..'
script {
if (ENVIRONMENT_NAME == 'development') {
ENV_NAME = 'Development'
} else if (ENVIRONMENT_NAME == 'release') {
ENV_NAME = 'Production'
}
}
echo 'Building Branch: ' + env.BRANCH_NAME
echo 'Build Number: ' + env.BUILD_NUMBER
echo 'Building Environment: ' + ENV_NAME
echo "Running your service with environemnt ${ENV_NAME} now"
}
}
}
}
In Jenkins 2.138.3 there are two different types of pipelines.
Declarative and Scripted pipelines.
"Declarative pipelines is a new extension of the pipeline DSL (it is basically a pipeline script with only one step, a pipeline step with arguments (called directives), these directives should follow a specific syntax. The point of this new format is that it is more strict and therefore should be easier for those new to pipelines, allow for graphical editing and much more.
scripted pipelines is the fallback for advanced requirements."
jenkins pipeline: agent vs node?
Here is an example of using environment and global variables in a Declarative Pipeline. From what I can tell enviroment are static after they are set.
def browser = 'Unknown'
pipeline {
agent any
environment {
//Use Pipeline Utility Steps plugin to read information from pom.xml into env variables
IMAGE = readMavenPom().getArtifactId()
VERSION = readMavenPom().getVersion()
}
stages {
stage('Example') {
steps {
script {
browser = sh(returnStdout: true, script: 'echo Chrome')
}
}
}
stage('SNAPSHOT') {
when {
expression {
return !env.JOB_NAME.equals("PROD") && !env.VERSION.contains("RELEASE")
}
}
steps {
echo "SNAPSHOT"
echo "${browser}"
}
}
stage('RELEASE') {
when {
expression {
return !env.JOB_NAME.equals("TEST") && !env.VERSION.contains("RELEASE")
}
}
steps {
echo "RELEASE"
echo "${browser}"
}
}
}//end of stages
}//end of pipeline
You are using a Declarative Pipeline which requires a script-step to execute Groovy code. This is a huge difference compared to the Scripted Pipeline where this is not necessary.
The official documentation says the following:
The script step takes a block of Scripted Pipeline and executes that
in the Declarative Pipeline.
pipeline {
agent none
stages {
stage("first") {
script {
def foo = "foo"
sh "echo ${foo}"
}
}
}
}
you can define the variable global , but when using this variable must to write in script block .
def foo="foo"
pipeline {
agent none
stages {
stage("first") {
script{
sh "echo ${foo}"
}
}
}
}
Try this declarative pipeline, its working
pipeline {
agent any
stages {
stage("first") {
steps{
script {
def foo = "foo"
sh "echo ${foo}"
}
}
}
}
}

Resources