Issue
Below line in Jenkinsfile
latestTagSHA1 = sh(returnStdout: true, script: "git rev-parse ${latestTag}^{commit}")
results in script.sh: ^{commit}: not found
error.
Is there a way to escape ^{commit}
part?
I tried to use ^\{commit\}
to no avail.
It's important to note that i want to actually run command
git rev-parse ${latestTag}^{commit}
, for example git rev-parse 2.0.0^{commit}
where latestTag
equals 2.0.0
.
This command returns SHA1 of git tag. For example, for existing tagged commit 850d25580a894befbce6d922bee954c7669cf70c
with tag 1.0
below command will return the SHA1
of the tag:
git rev-parse 1.0^{commit}
850d25580a894befbce6d922bee954c7669cf70c
added full Jenkinsfile
using the failing line:
pipeline {
agent {
node {
label 'some_label'
customWorkspace "workspace/${JOB_NAME}/${params.PROJECT}/${params.REPO_NAME}/${BUILD_NUMBER}/"
}
}
parameters {
string defaultValue: "${REPO_NAME}", name: 'REPO_NAME', trim: true
string defaultValue: "${PROJECT}", name: 'PROJECT', trim: true
string defaultValue: "${SRC_BRANCH_NAME}", name: 'SRC_BRANCH_NAME', trim: true
string defaultValue: "${PR_MERGER_EMAIL}", name: 'PR_MERGER_EMAIL', trim: true
string defaultValue: "${SHA1}", name: 'SHA1', trim: true
}
options {
lock resource: "${params.REPO_NAME}" // lock on repo to avoid concurrent releases on the same repo
}
stages {
stage("package") {
steps {
dir("/tmp/${params.PROJECT}/${params.REPO_NAME}") {
checkout(
[
$class: 'GitSCM',
branches: [[name: 'refs/heads/master']],
extensions: [
[$class: 'LocalBranch', localBranch: "master"]
],
userRemoteConfigs: [[
url: env.GIT_URL, credentialsId: "smth"
]]
]
)
script {
sh "cd /tmp/${params.PROJECT}/${params.REPO_NAME}"
latestTag = sh(returnStdout: true, script: "git describe --tags `git rev-list --tags --max-count=1`")
latestTagSHA1 = sh(returnStdout: true, script: "git rev-parse ${latestTag}^{commit}")
latestSHA1Timestamp = sh(returnStdout: true, script: "git show -s --format='%ct' ${latestTagSHA1}")
currentCommitSHA1Timestamp = sh(returnStdout: true, script: "git show -s --format='%ct' ${params.SHA1}")
if (latestSHA1Timestamp > currentCommitSHA1Timestamp) {
currentBuild.result = 'ABORTED'
error('some')
}
}
}
}
}
}
}
Solution
You don't have to escape anything in line that throws the error. The problem is that the sh
step returns an output with a trailing newline.
returnStdout (optional)
If checked, standard output from the task is returned as the step value as aString
, rather than being printed to the build log. (Standard error, if any, will still be printed to the log.) You will often want to call.trim()
on the result to strip off a trailing newline.
Source: https://www.jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
That is why what Jenkins is trying to execute in your case is:
git rev-parse 1.0.0
^{commit}
instead of
git rev-parse 1.0.0^{commit}
The solution to this problem is simple: when you return the output of the sh
step, call trim()
in the end to remove a trailing newline.
latestTag = sh(returnStdout: true, script: "git describe --tags `git rev-list --tags --max-count=1`").trim()
Keep in mind that you will have to trim the output of all variables that are later use as a part of the next command.
Answered By - Szymon Stepniak
Answer Checked By - Katrina (JavaFixing Volunteer)