Dynamically change build parameters
Hi
For our build jobs we want to have a "configuration parameter" which is a select box:
Question: Is there a way to dynamically chang the entires in this list? Unofortunately I was not able to do that with the AbstractBuildParametersProvider class or with a Implementation of the ParametersPreprocessor interface.
It would be great if someone could point me in the right direction.
Please sign in to leave a comment.
Unfortunately, it is not supported now. What you need is to implement another custom constrol that would be able to check parameter from a
given domain.
There is a chance to implement what you need via closed API. For that in your plugin code on the server
you need to extend
jetbrains.buildServer.controllers.parameters.types.SelectParameterTypeBase class :
public class CustomSelectParameterType extends SelectParameterTypeBase {
public String getParameterType() {
return "custom_select";
}
public String getParameterDescription() {
return "Special Select";
}
protected List<KeyValue> parseItems(@NotNull final ControlDescription context) throws InvalidParametersException {
//return here collection of your keys.
}
}
This class should be registered into spring context of a plugin.
Thanks Eugene!
From where do I get the SelectParameterTypeBase class?
Check web.jar or simply add all classes from <teamcity web all>/WEB-INF/lib
Thanks very much!
I now can create my own "select types".
Nevertheless I want to be able to dynamically add the select list (drop down list) each time a user clicks on the elipse button and then switches to the "Build Configuration" Tab. In other words: I do not know the values in before (Information from the build is needed to create the values).
Is it somehow possible to extend the AbstractBuildParametersProvider and then add a "custom" parameter to the build paramter list. Like:
public Map<String, String> getParameters(@NotNull SBuild build, boolean emulationMode) {
BuildPromotion buildPromotion = build.getBuildPromotion();
SBuildType buildConfig = buildPromotion.getBuildType();
buildConfig.addBuildParameter(new MyCustomSelectParameter(...));
return super.getParameters(build, emulationMode);
}
Of course the MyCustomSelectParameter somehow needs to be of type CustomSelectParameterType.
Any suggestions?
Typed parameters on TeamCtiy are only createable via Parameter class with appropriate ControlDescription.
So to have extra parameters for user, I'd suggest you to
1)
add parameter of type your custom type to build configuration
you may also call addParameter method on SBuildType or SBuildTemplate or SProject, and instance of Parameter
you may create via jetbrains.buildServer.serverSide.parameters.ParameterFactory that is spring bean
2)
in your custom control you may have a logic to generate items
You control is called with jetbrains.buildServer.controllers.parameters.ParameterContext interface.
You may call jetbrains.buildServer.controllers.parameters.ParameterContext#getAdditionalParameter to get
reference to to project, template or build type
You may also need to override renderControl method in your examle with
public ModelAndView renderControl(@NotNull final HttpServletRequest request, final ParameterRenderContext context) throws InvalidParametersException {
final ControlDescription descr = context.getDescription();
ModelAndView mv = new ModelAndView("/parameters/optionsField.jsp");
mv.getModel().put("options", parseItems(descr));
return mv;
}
The more generic approach for you could be to use
jetbrains.buildServer.controllers.parameters.api.ParameterControlProviderAdapter class as base class for
your control. Once you have renderControl above it would be totally OK and fully controllable by your code.
Hi Eugene! As I'm a TeamCity plugin dev newbie I again need your help. ;)
I managed to "update" the custom select type dynamically with the following code (extending the ParameterControlProviderAdapter class)
[...]
@Override
@NotNull
public ModelAndView renderControl(@NotNull HttpServletRequest req, @NotNull ParameterRenderContext context) throws InvalidParametersException {
final ControlDescription descr = context.getDescription();
ModelAndView mv = new ModelAndView("/parameters/optionsField.jsp");
// create dropdown list (just for demo purposes)
List<KeyValue> dropDownList = new ArrayList<KeyValue>();
dropDownList.add(new KeyValue("key 1", "value 1"));
dropDownList.add(new KeyValue("key 2", "value 2"));
dropDownList.add(new KeyValue("key 3", "value 3"));
mv.getModel().put("options", dropDownList);
return mv;
}
[...]
Now TeamCity shows:
1) How can I remove the "Unknown value: " from the dropdown. I guess this shows up because the initial value is <empty> (after adding the parameter to build configuration).
2) I really need help with the ParameterContext#getAdditionalParameter stuff. Can you give me an example how to access a TeamCity system property or how to get reference to the project name/id?
Thanks again!
Hello,
You may fork the .jsp file from TeamCity to provide another logic.
The problem here is that initial control value was "", while you returned another values.
This is an implementation detail of the .jsp file to render extra item for that case
I see. But what exactly do you mean by "fork"?
Also. It would be great if you can help me on my second question. ;)
Sorry, I used Git terminology here. By fork I meant you may copy the .jsp file into your plugin and patch it to work in some other way
In parameters context interface you have a number of constants to access context.
public interface ParameterContext {
....
/**
* Provides a build type if control is rendering with build type
* @since 7.0
*/
AdditionalParameter<SBuildType> BUILD_TYPE = new AdditionalParameter<SBuildType>("BuildType", SBuildType.class);
/**
* Provides a build type template if control is rendering with build type
* @since 7.0
*/
AdditionalParameter<BuildTypeTemplate> BUILD_TEMPLATE = new AdditionalParameter<BuildTypeTemplate>("BuildTypeTemplate", BuildTypeTemplate.class);
/**
* Provides a project if control is rendering with project
* @since 7.0
*/
AdditionalParameter<SProject> PROJECT = new AdditionalParameter<SProject>("Project", SProject.class);
}
So you could use those contants to get type-safe reference to project or build type or template.
Hi, Dominik! So if you resolved this task?
Can you publish full recipe for other users with similar question?
Thanks.