I am trying for a lot of time to get the current branch name in MultibranchPipeline Job inside an Active Choice Reactive Reference Parameter Formatted HTML parameter script block
我花了很多时间在Active Choice反应引用参数格式化的HTML参数脚本块中获取多分支管道作业中的当前分支名称
[
$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
name: 'TestParam',
omitValueField: true,
description: 'Test.',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: '''
return """
<p>FallbackScript. Error in main script</p>
"""
'''
],
script: [
classpath: [],
sandbox: false,
script: '''
String branchName = env.BRANCH_NAME
return """
<p>${branchName}</p>
"""
'''
]
]
]
The thing is that, I believe, the BRANCH_NAME
param is injected after you press the Build
button.
问题是,我相信,BRANCH_NAME参数是在您按下Build按钮之后注入的。
I've tried a lot of things, and I mean, A LOT, still I didn't manage to find a way. The scm
variable doesn't exist as well, I tried to find something with the jenkins.model.Jenkins.instance
but no luck.
我试了很多方法,我是说,很多,但我还是没能找到办法。SCM变量也不存在,我试着用jenkins.mod.Jenkins.inst.查找一些东西,但没有成功。
Is it possible? I would love to ask this question on their Github repo, but issues are not allowed to be opened. Also to open an issue on Jenkins you need a Jira account or something. SO is the only place.
有可能吗?我很想在他们的Github回购上问这个问题,但问题不允许公开。此外,要在Jenkins上打开一期,你需要一个Jira账户或其他什么东西。唯一的地方也是如此。
更多回答
Thanks to Michael's answer, I managed to find a way to make this work. There are a lot more to it than meets the eye, but I will get through all details. I also answered this question here.
多亏了迈克尔的回答,我设法找到了一种方法来实现这一点。这件事比表面看起来要多得多,但我会把所有细节都讲完的。我在这里也回答了这个问题。
I make the assumption that the reader is familiar with the Active Choices plugin. Also, I played with this in a multibranch pipeline job. You might encounter different behaviours with other kinds of jobs.
我假设读者熟悉Active Choices插件。此外,我在一个多分支管道作业中使用了这一点。在其他类型的工作中,你可能会遇到不同的行为。
The parameters sadly don't have access to the environment variables. This is a bit of a limitation which I hope will be fixed/thought of in the future by the plugin's maintainers.
遗憾的是,这些参数无法访问环境变量。这是一个限制,我希望插件的维护人员将来会修复/考虑到这一点。
Some environment variables are only populated at build time, like BRANCH_NAME
. In this case, even if we had access to the env vars we wouldn't have the actual value at hand.
有些环境变量仅在构建时填充,如BRANCH_NAME。在这种情况下,即使我们有权访问env变量,我们手头也不会有实际的值。
To be able to use the env.BRANCH_NAME
we need two reactive parameters.
为了能够使用env.BRANCH_NAME,我们需要两个反应参数。
The plugin has a parameter named FORMATTED_HIDDEN_HTML
. This parameter doesn't get displayed to the user. This is great since we wouldn't want to see in a multibranch pipeline job a parameter with the same name as the branch we are currently on.
该插件有一个名为Formted_Hidden_HTML的参数。此参数不会显示给用户。这很好,因为我们不希望在多分支管道作业中看到与我们当前所在分支同名的参数。
To set this parameter, we can write something like this in a Jenkinsfile.
要设置此参数,我们可以在Jenkinsfile中编写类似以下内容的代码。
[
$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HIDDEN_HTML',
name: 'BranchName',
omitValueField: true,
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: '''
return '<p>error</p>'
'''
],
script: [
classpath: [],
sandbox: true,
script: """
return '<input name="value" value="${env.BRANCH_NAME}" type="text">'
"""
]
]
]
There are a lot of things to note here.
这里有很多事情需要注意。
- The
sandbox
property is set to true
. If you don't do that, you would need to accept the script in the ScriptApproval
menu in Jenkins.
- We use triple-double quotes when we define the
script
property.
script: """
return '<input name="value" value="${env.BRANCH_NAME}" type="text">'
"""
When the job is started for the first time, the BRANCH_NAME
variable is populated. This results in a string interpolation which gets your script property in the following state:
第一次启动作业时,将填充BRANCH_NAME变量。这将导致字符串内插法,该插值法将获得以下状态的脚本属性:
script: """
return '<input name="value" value="myBranchName" type="text">'
"""
If we would've used triple-single quotes, we would get an error like:
如果我们使用三重单引号,我们将得到如下错误:
hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: env for class: WorkflowScript
This gets us back to the fact that we don't have access to the environment variables.
这让我们回到了我们无法访问环境变量的事实。
What to conclude from this? Well, if we use triple-double quotes, first we have a string interpolation, then the script is run.
从这一点可以得出什么结论?嗯,如果我们使用三重双引号,首先我们有一个字符串内插,然后运行脚本。
The HTML element that must be used is input
. This is explained in the docs if you read it carefully. Not only that but also the name
property must be set to value
. This is also explained in the docs.
omitValueField
should be set to true
, or else you will get a trailing comma in your value. E.g.: myBranchName,
Basically, the first time you run the job you get your branch name populated via string interpolation. Only after the second build, you will have the value to use. You will always reference the previous value.
基本上,在第一次运行作业时,您会通过字符串内插法填充分支机构名称。只有在第二次构建之后,您才会拥有要使用的值。您将始终引用先前的值。
After all that, you can reference this parameter in other Active Choices
parameter types via referencedParameters
property.
在此之后,您可以通过引用参数属性在其他Active Choices参数类型中引用此参数。
I desperately needed this because I have a complex use case scenario. I'm making requests to an Azure Container Registry
to get all the tags for a certain image for a certain branch.
我非常需要它,因为我有一个复杂的用例场景。我正在向Azure Container注册表发出请求,以获取某个分支的某个图像的所有标记。
This plugin is great, I'm glad it exists. I would've loved a lot more documentation and examples thoguh.
这个插件很棒,我很高兴它的存在。我会喜欢更多的文档和例子。
Have a look at Groovy's string interpolation.
让我们来看看Groovy的字符串内插。
tl;dr You can access values by using """
and ${variable}
TL;DR您可以使用“”和${Variable}访问值
script: """
return <p>${env.BRANCH_NAME}</p>
"""
You dont need to use 2 DynamicReferenceParameter. Just use this normal one, followed by the other dynamic param.
您不需要使用%2 DynamicReference参数。只需使用这个普通参数,然后使用另一个动态参数。
extendedChoice( defaultValue: "${env.BRANCH_NAME}", name: "branchName", type: 'PT_HIDDEN', value: "${env.BRANCH_NAME}")
TendedChoice(defaultValue:“${env.BRANCH_NAME}”,名称:“分支名称”,类型:‘PT_HIDDEN’,值:“${env.BRANCH_NAME}”)
更多回答
nice to hear that you figured it out!
很高兴听到你想通了!
I know about string interpolation and I used it in my example. Your answer does not work, you have to wrap with quotes the return value. After that, it works, but it comes with a couple of caveats. I don't know if you are familiar with the plugin mentioned. These parameters are reactive and they change or let's say they compute stuff when you press Build with parameters
. Your example works because what it does, at moment t
, you press build, and at moment t + 1
, you will have the value in the script's string. But it is not computed at t
.
我知道字符串内插,并在我的示例中使用了它。您的答案不起作用,您必须用引号将返回值括起来。在那之后,它是有效的,但它伴随着几个警告。我不知道你是否熟悉前面提到的插件。这些参数是反应性的,当您使用参数按下Build时,它们会改变,或者说,它们会进行计算。您的示例之所以有效,是因为在时刻t,您按下了Build,在时刻t+1,脚本的字符串中就有了这个值。但它不是在t处计算的。
Besides that, you would have to approve the script's signature every time you create a new branch because the value will change and you will have <p>foo/bar</p>
or <p>foo/baz</p>
etc. Although your answer works, it isn't helpful in my scenario. I will wait for another solution and if I don't get one, I will accept yours.
除此之外,每次创建一个新分支时,你都必须批准脚本的签名,因为值会改变,你会有foo/bar
或foo/baz
等。我会等待另一个解决方案,如果我没有得到一个,我会接受你的。
Okay I understand. The issue sounds more complex than I thought on first sight.
好的,我明白了。这个问题听起来比我第一眼看到的要复杂得多。
我是一名优秀的程序员,十分优秀!