Jenkinsfile groovy unable to use arguments in method - jenkins

How do I call a method with arguments from a Jenkinsfile.
def upload_nightly_build(local_filename, remote_filename)
{
sh 'curl --output $local_filename http://someserver:8000/firmware/$remote_filename'
sh 'curl -F upload_file=#$local_filename http://someserver:8000/frontend/file_upload_handler'
sh 'rm $local_filename'
}
pipeline
{
agent
{
dockerfile
{
dir 'dockerfiles'
filename 'Dockerfile-integration.tests'
}
}
stages
{
stage('upload binaries')
{
steps
{
dir ("firmware")
{
upload_nightly_build('iobox-1024-nightly.bin', 'iobox-1024.bin')
}
}
}
}
}
Tried so far
encapsulate usage of arguments in method with braces
define arguments as String
define arguments with def
used named arguments using Map
Whatever I try, in Jenkins console output I will always see
+ curl --output http://someserver:8000/firmware/
curl: no URL specified!

Sigh... found it myself eventually..
sh "curl --output $local_filename http://someserver:8000/firmware/$remote_filename"
Double quote the sh argument... I should've known...

Related

Jenkins script how to compare two string variables

def pname = "netstat -ntlp|grep 8080|awk '{printf \$7}'|cut -d/ -f2"
sh "echo $pname" \ java
if ("java".equals(pname)) { sh "echo 1111" }
The process corresponding to port 8080 is a java process, and the 2nd line print "java". But the body of the if statement just doesn't execute.
You seem to be not executing the command correctly. Please refer to the following sample. Please note the returnStdout: true to return output of the command.
pipeline {
agent any
stages {
stage('Test') {
steps {
script {
def pname = sh(returnStdout: true, script: "netstat -ntlp|grep 8080|awk '{printf \$7}'|cut -d/ -f2").trim()
if (pname == "java") {
echo "echo 1111"
}
}
}
}
}
}
try
"==" for equal
or you can read doc.
https://groovy-lang.org/operators.html#_relational_operators

Jenkinsfile post always directive with multiple steps

I am wondering if it's possible to use various steps block on inside a post step.
Here's the actual code:
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'bash testing.sh'
}
}
}
post {
always {
steps {
sh 'bash cleaning-procedure-1.sh'
}
steps {
sh 'bash cleaning-procedure-2.sh'
}
steps {
sh 'bash general-cleaning.sh'
}
}
}
}
One of the errors that Jenkins gets:
WorkflowScript: 291: Missing required parameter: "delegate" # line 291, column 13.
step {
Is it possible to create different steps inside a POST - ALWAYS block on Jenkins?
steps blocks are not allowed inside a post directive. If you want to use the sh method, then you can invoke it directly outside of the steps scope:
post {
always {
sh 'bash cleaning-procedure-1.sh'
sh 'bash cleaning-procedure-2.sh'
sh 'bash general-cleaning.sh'
}
}
You can use a script block to have multiple actions, like
post {
always {
script {
junit '**/build/junit.xml'
xunit (tools: [CTest(pattern: '**/build/ctest/**/*.xml')] ...)
}
}
}

How to use Jenkins Pipeline global variable on another stages?

I have defined global variable in Jenkins pipeline
def BUILDNRO = '0'
pipeline { ...
Then i manipulate variable with shell script to enable running builds parallel by using job build number as identifier so we don't mix different docker swarms.
stage('Handle BUILD_NUMBER') {
steps {
script {
BUILDNRO = sh( script: '''#!/bin/bash
Build=`echo ${BUILD_NUMBER} | grep -o '..$'`
# Check if BUILD first character is 0
if [[ $Build:0:1 == "0" ]]; then
# replace BUILD first character from 0 to 5
Build=`echo $Build | sed s/./5/1`
fi
echo $Build
''',returnStdout: true).trim()
}
}
}
i get value out from previos stage and trying to get global variable on next stage
stage('DOCKER: Init docker swarm') {
steps {
echo "BUILDNRO is: ${BUILDNRO}" --> Value is here.
sh '''#!/bin/bash
echo Buildnro is: ${BUILDNRO} --> This is empty.
...
}
}
This will out give global variable empty. why? in previous stage there was value in it.
EDIT 1.
Modified code blocks to reflect current status.
I managed to figure it out. Here is solution how i managed to did it.
BUILDNRO is groovy variable and if wanting to used in bash variable it have to pass using withEnv. BUILD_NUMBER in first stage is bash variable hence it can be used directly script in first stage.
def BUILDNRO = '0'
pipeline {
....
stages {
stage('Handle BUILD_NUMBER') {
steps {
script {
BUILDNRO = sh( script: '''#!/bin/bash
Build=`echo ${BUILD_NUMBER} | grep -o '..$'`
''',returnStdout: true).trim()
}
}
}
stage('DOCKER: Init docker swarm') {
steps {
dir("prose_env/prose_api_dev_env") {
withEnv(["MYNRO=${BUILDNRO}"]) {
sh(returnStdout: false, script: '''#!/bin/bash
echo Buildnro is: ${MYNRO}`
'''.stripIndent())
}
}
}
}
}
}
If you are using single quotes(```) in the shell module, Jenkins treats every variable as a bash variable. The solution is using double quotes(""") but then if you made bash variable you have to escape it. Below an example with working your use case and escaped bash variable
pipeline {
agent any
stages {
stage('Handle BUILD_NUMBER') {
steps {
script {
BUILDNRO = sh(script: 'pwd', returnStdout: true).trim()
echo "BUILDNRO is: ${BUILDNRO}"
}
}
}
stage('DOCKER: Init docker swarm') {
steps {
sh """#!/bin/bash
echo Buildnro is: ${BUILDNRO}
variable=world
echo "hello \${variable}"
sh """
}
}
}
}
output of the second stage:
Buildnro is: /var/lib/jenkins/workspace/stack1
hello world

How catch curl response into variable in Jenkinsfile

I want to curl an URL and capture the response into a variable.
when I curl a command and echo its output I get the correct response as below
sh 'output=`curl https://some-host/some-service/getApi?apikey=someKey`;echo $output;'
I want to catch the same response into a variable and use that response for further operation
Below is my Jenkinsfile
pipeline {
agent {
label "build_2"
}
stages {
stage('Build') {
steps {
checkout scm
sh 'npm install'
}
}
stage('Build-Image') {
steps {
echo '..........................Building Image..........................'
//In below line I am getting Output
//sh 'output=`curl https://some-host/some-service/getApi?apikey=someKey`;echo $output;'
script {
//I want to get the same response here
def response = sh 'curl https://some-host/some-service/getApi?apikey=someKey'
echo '=========================Response===================' + response
}
}
}
}
}
Can you please tell me what changes I need to do in my Jenkinsfile
If you want to return an output from sh step and capture it in the variable you have to change:
def response = sh 'curl https://some-host/some-service/getApi?apikey=someKey'
to:
def response = sh(script: 'curl https://some-host/some-service/getApi?apikey=someKey', returnStdout: true)
Reference: https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script

Jenkins pipeline to SSH into an instance and call a function

How to create a function def test() which does some steps after sshing into an instance
I have something like this:
#!/usr/bin/env groovy
def test() {
cd $testPath
mv test*.txt archiveFiles
sh "someScript.sh"
}
pipeline {
agent java
parameters {
string(
name: 'testPath',
defaultValue: '/home/ubuntu/testFiles',
description: 'file directory'
)
}
stages {
stage(test) {
steps{
script{
sh "ssh ubuntu#IP 'test()'"
}
}
}
}
}
I am trying to ssh into an instance and do the steps in the function test() by calling it
I am getting an error like this:
bash: -c: line 1: syntax error: unexpected end of file
ERROR: script returned exit code 1
We use the SSH plugin as follows:
steps {
timeout(time: 2, unit: 'MINUTES') {
sshagent(credentials: ['local-dev-ssh']) {
sh "ssh -p 8022 -l app ${ENVIRONMENT_HOST_NAME} './run-apps.sh ${SERVICE_NAME} ${DOCKER_IMAGE_TAG_PREFIX}-${env.BUILD_NUMBER}'"
}
}
}

Resources