Getting Error while Passing variables extracted from shell in Jenkinsfile - jenkins-pipeline

I am setting up Jenkins pipeline, but getting an error while Passing variables extracted from the shell in the environment
pipeline {
agent any
environment {
PHP_CHANGE_SET = sh (script: "git diff-tree --no-commit-id --name-only -r HEAD | grep '.php'",returnStdout: true).trim()
}
I am getting mentioned ERROR
[Pipeline] { (Declarative: Post Actions)
[Pipeline] sh
Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
Error when executing failure post condition:
org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing
at org.jenkinsci.plugins.workflow.steps.StepDescriptor.checkContextAvailability(StepDescriptor.java:260)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:262)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:178)
at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
I need PHP files name only which are in commit and store in variable

As mentioned in the comment, you cannot use it outside node block. If you really need to do this and this is the first thing you want for your job(A), what you can do is make another job (B) and there run this command in the directory you want and then trigger this job(A). You can have "PHP_CHANGE_SET" as a parameter which you can pass from job B.

Related

Jenkins groovy scripted pipeline variables not substituting correctly

I'm running a very simple pipeline to create maven projects, the pipeline is to run a single maven install command.
The trouble is substituting variables into the one-liner. I've tried various different things but stuck in a strange place. Take example pipeline below:
node {
stage('Set Vars') {
GIT_HASH = sh (script: "git log -n 1 --pretty=format:'%H'" , returnStdout: true)
echo "git hash is >>>>>>>> $GIT_HASH"
BUILD_NUM="${env.BUILD_NUMBER}"
echo "build no is >>>>>>>> ${BUILD_NUM}"
}
stage('Build Project') {
sh "mvn clean install -PrunInstallPackage -Duser=admin -Dpass=guessing -Dip=200.0.0.1 -Dport=4444 -Dhash=${GIT_HASH} -Dbuildnumber=${BUILD_NUM}"
}
}
I would expect to see the variables substitued in the mvn install command, this does not seem to work this way though.
This build results in:
sh "mvn clean install -PrunInstallPackage -Duser=admin -Dpass=guessing -Dip=200.0.0.1 -Dport=4444 -Dhash=${GIT_HASH}
Both echo commands print out correct output.
Why does the last command get cut off after the first variable substitution?
Also, for some unknown reason, I cannot substitute -Dbuildnumber=${env.BUILD_NUMBER}" directly into the maven command. Seems like something that a user should be able to do. What am I missing here?
Many thanks in advance
I am trying to remember how I solved same issues in the past..
Problem 1
You are using the GIT_HASH variable across two stages, so you have to declare it global to share it across them:
// Global variables declaration
GIT_HASH = null
// Pipeline code
node {
stage('Set Vars') {
GIT_HASH = sh (script: "git log -n 1 --pretty=format:'%H'" , returnStdout: true)
echo "git hash is >>>>>>>> $GIT_HASH"
BUILD_NUM="${env.BUILD_NUMBER}"
echo "build no is >>>>>>>> ${BUILD_NUM}"
}
stage('Build Project') {
sh "mvn clean install -PrunInstallPackage -Duser=admin -Dpass=guessing -Dip=200.0.0.1 -Dport=4444 -Dhash=${GIT_HASH} -Dbuildnumber=${BUILD_NUM}"
}
}
Problem 2
env.BUILD_NUMBER is a Groovy statement, instead mvn gets executed inside a shell instance by the sh command.
For that reason I suggest you to use the BUILD_NUM variable way.

setting variable in jenkinsfile from git log command

I need to run following command in my jenkinsfile
steps
{
echo "Get source branch name in pull request"
script {
Def sourceBranchString= bat "git log --name-status HEAD^..HEAD | findstr 'from'"
echo ${sourceBranchString}
def sourceBranch = powershell "bin\\DeploymentUtils\\ReadPullRequestSourceBranch.ps1 ${sourceBranchString}"
echo $sourceBranch
}
}
First i need to set the variable sourceBranchString with the outputput from
bat "git log --name-status HEAD^..HEAD | findstr 'from'"
It seems to ignore the ^ in the git command, i have tried to escape it with \ but then it fails.
Then i want to call my powershell script with the sourceBranchString variable as
input parameter.
It errors out in the pipeline without any error message. I think im not getting the git command executed.
And im not shure i am using the right syntax for initialize the variable.
Can anybody help

Jenkinsfile not executing entire shell script

I have the following in a Jenkinsfile as a discrete stage:
stage("Check if Postman scripts are already cloned, delete") {
steps {
sh "[ -d postman-scripts ] && rm -rf postman-scripts && echo 'Directory cleared.'"
}
}
However when I look at my Jenkins pipeline it looks like it fails and doesn't run the entire script:
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Check if Postman scripts are already cloned, delete)
[Pipeline] sh
+ '[' -d postman-scripts ']'
[Pipeline] }
Is that because it's not finding the postman-scripts directory, so it's not executing the rest of the script? And is that being counted as a build failure? It skips all following stages, so logically I think it's doing that.
Also any help with the bash scripting would be nice, I'm not entirely sure how I can string this all together on one line to do what I want (IF directory exists, remove directory. Otherwise do nothing).
Your shell test condition [ -d postman-scripts ] will FAIL if the directory does not exist. That is a failure like any other command, so it exits. #jordanm is correct, using -f will return success even if nothing exists to remove, so your next step will continue. Exception if unable to remove files because of a system lock or similar, which is probably a good thing,

Terminate a buildspec early based on Condition, specifically on a git tag

I'd like to run my build pipeline only when my repo is tagged with certain specific release tags. I can get the tag value from the CODEBUILD_WEBHOOK_TRIGGER environment variable and I can conditionally execute code in my BUILD phase with some bash kung fu :
build:
commands:
- echo ${CODEBUILD_WEBHOOK_TRIGGER##*/}
- |
if expr "${CODEBUILD_WEBHOOK_TRIGGER}" : '^tag/30' >/dev/null; then
git add *
git commit -am "System commit"
git push
git tag ${CODEBUILD_WEBHOOK_TRIGGER##*/}
git push origin ${CODEBUILD_WEBHOOK_TRIGGER##*/}
echo Pushed the repo
fi
Works fine, I only push when a tag looks a certain way.
Putting aside the brittleness of the above, what I really want to do is to terminate the entire build process in the INSTALL phase if my CODEBUILD_WEBHOOK_TRIGGER variable doesn't have a specific prefix. I'd like to skip all subsequent steps and exit the pipeline without error.
Is there a way to do this? It would be nice to minimize the resources I'm using.
It worked for me to use the aws-cli command for stopping the build, using the provided CodeBuild environment variable ${CODEBUILD_BUILD_ID}:
- aws codebuild stop-build --id ${CODEBUILD_BUILD_ID}
For instance:
- |
if expr "${CODEBUILD_WEBHOOK_TRIGGER}" : '^tag/30' >/dev/null; then
. . .
else
aws codebuild stop-build --id ${CODEBUILD_BUILD_ID}
fi
CodeBuild natively supports tag filtering now. Documentation # https://docs.aws.amazon.com/codebuild/latest/userguide/sample-github-pull-request.html#sample-github-pull-request-filter-webhook-events.
Answering my own question, It turns out you can do this by specifying a branch filter in the source set up. The regular expression appears to match anything that comes back from the webhook:
^tag/30
That works for my tag pattern.
The question stands. I can still imagine use cases where you want to short-circuit the execution of the build pipeline for some other reason.

How to take the result of a precious build step in Jenkins with Groovy?

Is there an example script of taking the previous build step's return code? I would like to know how to do this with Groovy. The previous build step is running an SSH command remotely and returns a specific return code. How can I read this return code in the next build step with Groovy?
If you go to the pipeline snippet generator from a pipeline job in the Jenkins UI (click on 'pipeline syntax' on the left) it will give you the syntax of each step like "sh". For a shell command you can do it like this example:
pipeline {
// Assumes you have Linux agents..
agent any
stages{
stage('Test') {
steps {
script {
def result = sh returnStatus: true, script: 'ls -a'
echo "Return code of shell script: ${result}"
}
}
}
}
}
I don't know if there is any way of getting it for the previous step, if you did not get the result like this for every step though.
In case of failure, when the returnStatus is explicitly requested like this, an exception is not thrown so you will need to handle the return status and fail the job explicitly with error('message..') if that is what is required.

Resources