英文:
MissingMethodException: No signature of method: p.call() when configuring Jenkins Pipeline script from SCM that targets Scripted Pipeline Jenkinsfile
问题
I have translated the requested content:
我在Jenkins中编写了一个Scripted Pipeline,在选择“Pipeline script”选项并将文本直接粘贴到作业中时,它可以正确执行。由于我们的某些阶段名称是动态生成的,声明性Pipeline仅允许使用字符串文字而不是插入字符串,因此我们需要使用Scripted Pipeline:
https://issues.jenkins.io/browse/JENKINS-43820
我想将这个Scripted Pipeline存储在我们的代码库中,作为一个Jenkinsfile,因为它将被多个作业使用,我希望将来的更改对所有使用该脚本的作业生效(而不是手动复制和粘贴更改到每个使用该脚本的作业中)。
在Jenkins文档中,它说Jenkinsfile既可以是声明性的也可以是Scripted的:
然而,当我将“Pipeline script from SCM”定位到我的Scripted Pipeline Jenkinsfile时,我收到以下错误消息:
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: pipeline.call() is applicable for argument types: () values: []
这暗示它期望一个声明性Pipeline而不是Scripted Pipeline:
哪种配置将允许从SCM使用Scripted Pipeline Jenkinsfile?
我需要在Jenkinsfile本身添加什么吗?
为了保护隐私,我已经简化了我们的Scripted Pipeline Jenkinsfile,但核心组件还在那里(动态阶段名称通常包装在each循环中,以更好地利用这个功能):
String service
node("master") {
stage("Clean Workspace") {
deleteDir()
}
stage("Get Service From Job Build") {
service = getServiceFromJobName env.JOB_NAME.toString()
}
stage("Checkout '$service'") {
checkoutRepo service, "[GIT地址在这里]/${repo}.git"
}
}
private def checkoutRepo(String repo, String branch) {
checkout([
$class : "GitSCM",
branches : [[name: branch]],
doGenerateSubmoduleConfigurations: false,
extensions : [[$class: "WipeWorkspace"]],
submoduleCfg : [],
userRemoteConfigs : [[credentialsId: [CREDS在这里],
url : "[GIT地址在这里]/${repo}.git"
]]
])
}
private static String getServiceFromJobName(String jobName) {
String job = jobName.tokenize("/").pop()
job.replace(" Service", "")
}
还是Jenkins中有一些我不知道的配置?
为了保护隐私,我已经删除了我们的git详细信息,但这是我们的Jenkins Pipeline script from SCM配置:
Jenkins Pipeline script from SCM configuration
英文:
I have written a Scripted Pipeline in Jenkins that executes correctly when I choose the "Pipeline script" option and paste the text directly into the Job. We need to use a Scripted Pipeline as some of our Stage names are dynamically generated and Declarative Pipelines only allow for string literals and not interpolated strings:
https://issues.jenkins.io/browse/JENKINS-43820
I would like to store this Scripted Pipeline in our repository as a Jenkinsfile as it will be used by multiple Jobs and I would like any future changes to be made effective in all Jobs (instead of having to copy and paste the changes manually into every Job that uses the script).
In the Jenkins docs, it says that a Jenkinsfile can be both Declarative and Scripted:
However, when I target the "Pipeline script from SCM" at my Scripted Pipeline Jenkinsfile I get the following error message:
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: pipeline.call() is applicable for argument types: () values: []
Which implies that it is expecting a Declarative Pipeline and not a Scripted Pipeline:
What configuration will enable a Scripted Pipeline Jenkinsfile from SCM?
Is there something I need to add to the Jenkinsfile itself?
I have simplified our Scripted Pipeline Jenkinsfile below for privacy but the core components are there (the dynamic stage name is usually wrapped in an each-loop to better utilise this functionality):
String service
node("master") {
stage("Clean Workspace") {
deleteDir()
}
stage("Get Service From Job Build") {
service = getServiceFromJobName env.JOB_NAME.toString()
}
stage("Checkout '$service'") {
checkoutRepo service, "master"
}
}
private def checkoutRepo(String repo, String branch) {
checkout([
$class : "GitSCM",
branches : [[name: branch]],
doGenerateSubmoduleConfigurations: false,
extensions : [[$class: "WipeWorkspace"]],
submoduleCfg : [],
userRemoteConfigs : [[credentialsId: [CREDS GO HERE],
url : "[GIT GOES HERE]/${repo}.git"
]]
])
}
private static String getServiceFromJobName(String jobName) {
String job = jobName.tokenize("/").pop()
job.replace(" Service", "")
}
Or is there something in Jenkins to configure that I am unaware of?
I have removed our git details for privacy but this is our Jenkins Pipeline script from SCM configuration:
答案1
得分: 0
我找到了一个解决方法,通过在“Scripts”部分的静态命名阶段中嵌套我的脚本管道和动态阶段名称的声明性管道来解决此问题:
String service
def call() {
pipeline {
agent any
stages {
stage("Clean Workspace") {
steps {
deleteDir()
}
}
stage("Get Service From Job Build") {
steps {
script {
service = getServiceFromJobName env.JOB_NAME.toString()
stage("Checkout '$service'") {
checkoutRepo service, "master"
}
}
}
}
}
}
}
private def checkoutRepo(String repo, String branch) {
checkout([
$class : "GitSCM",
branches : [[name: branch]],
doGenerateSubmoduleConfigurations: false,
extensions : [[$class: "WipeWorkspace"]],
submoduleCfg : [],
userRemoteConfigs : [[credentialsId: [CREDS GO HERE],
url : "[GIT GOES HERE]/${repo}.git"
]]
])
}
private static String getServiceFromJobName(String jobName) {
String job = jobName.tokenize("/").pop()
job.replace(" Service", "")
}
Credit goes here:
https://issues.jenkins.io/browse/JENKINS-61280
英文:
I found a fix for this issue by nesting my Scripted Pipeline and Dynamic Stage Names within a Declarative Pipeline in the Scripts section of a Static-Named Stage:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
String service
def call() {
pipeline {
agent any
stages {
stage("Clean Workspace") {
steps {
deleteDir()
}
}
stage("Get Service From Job Build") {
steps {
script {
service = getServiceFromJobName env.JOB_NAME.toString()
stage("Checkout '$service'") {
checkoutRepo service, "master"
}
}
}
}
}
}
}
private def checkoutRepo(String repo, String branch) {
checkout([
$class : "GitSCM",
branches : [[name: branch]],
doGenerateSubmoduleConfigurations: false,
extensions : [[$class: "WipeWorkspace"]],
submoduleCfg : [],
userRemoteConfigs : [[credentialsId: [CREDS GO HERE],
url : "[GIT GOES HERE]/${repo}.git"
]]
])
}
private static String getServiceFromJobName(String jobName) {
String job = jobName.tokenize("/").pop()
job.replace(" Service", "")
}
<!-- end snippet -->
Credit goes here:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论