脚本:"git rev-parse ${latestTag}^{commit}" 在 Jenkinsfile 中失败
script: "git rev-parse ${latestTag}^{commit}" fails in Jenkinsfile
Jenkinsfile 中的下一行
latestTagSHA1 = sh(returnStdout: true, script: "git rev-parse ${latestTag}^{commit}")
导致 script.sh: ^{commit}: not found
错误。
有没有办法逃避 ^{commit}
部分?
我试过 ^\{commit\}
没用。
重要的是要注意我实际上想要 运行 命令
git rev-parse ${latestTag}^{commit}
,例如 git rev-parse 2.0.0^{commit}
其中 latestTag
等于 2.0.0
.
此命令 returns git 标签的 SHA1。例如,对于现有的带有标记 1.0
的标记提交 850d25580a894befbce6d922bee954c7669cf70c
,下面的命令将 return 标记的 SHA1
:
git rev-parse 1.0^{commit}
850d25580a894befbce6d922bee954c7669cf70c
使用失败行添加了完整 Jenkinsfile
:
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')
}
}
}
}
}
}
}
你可以尝试:“git rev-parse ${latestTag}”^${commit}”
您需要为要调用的所有变量添加 $
您不必转义任何引发错误的行。问题是 sh
步骤 return 的输出带有尾随换行符。
returnStdout (optional)
If checked, standard output from the task is returned as the step value as a String
, 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
这就是为什么 Jenkins 试图在您的案例中执行的是:
git rev-parse 1.0.0
^{commit}
而不是
git rev-parse 1.0.0^{commit}
这个问题的解决方案很简单:当您 return 输出 sh
步骤时,最后调用 trim()
以删除结尾的换行符。
latestTag = sh(returnStdout: true, script: "git describe --tags `git rev-list --tags --max-count=1`").trim()
请记住,您必须 trim 所有变量的输出,这些变量稍后将用作下一个命令的一部分。
Jenkinsfile 中的下一行
latestTagSHA1 = sh(returnStdout: true, script: "git rev-parse ${latestTag}^{commit}")
导致 script.sh: ^{commit}: not found
错误。
有没有办法逃避 ^{commit}
部分?
我试过 ^\{commit\}
没用。
重要的是要注意我实际上想要 运行 命令
git rev-parse ${latestTag}^{commit}
,例如 git rev-parse 2.0.0^{commit}
其中 latestTag
等于 2.0.0
.
此命令 returns git 标签的 SHA1。例如,对于现有的带有标记 1.0
的标记提交 850d25580a894befbce6d922bee954c7669cf70c
,下面的命令将 return 标记的 SHA1
:
git rev-parse 1.0^{commit}
850d25580a894befbce6d922bee954c7669cf70c
使用失败行添加了完整 Jenkinsfile
:
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')
}
}
}
}
}
}
}
你可以尝试:“git rev-parse ${latestTag}”^${commit}”
您需要为要调用的所有变量添加 $
您不必转义任何引发错误的行。问题是 sh
步骤 return 的输出带有尾随换行符。
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
这就是为什么 Jenkins 试图在您的案例中执行的是:
git rev-parse 1.0.0
^{commit}
而不是
git rev-parse 1.0.0^{commit}
这个问题的解决方案很简单:当您 return 输出 sh
步骤时,最后调用 trim()
以删除结尾的换行符。
latestTag = sh(returnStdout: true, script: "git describe --tags `git rev-list --tags --max-count=1`").trim()
请记住,您必须 trim 所有变量的输出,这些变量稍后将用作下一个命令的一部分。