Q: rename a variable without breaking compatibility in the declarative pipeline

39 views
Skip to first unread message

Victor Martinez

unread,
Dec 10, 2019, 2:44:59 PM12/10/19
to Jenkins Developers
Hi there,

I thought the readResolve might be the way to go but apparently I missed something and then there are no backward compatible for the when changeset and likely the same for the when branch in the declarative pipeline syntax. See the comment in https://issues.jenkins-ci.org/browse/JENKINS-60217?focusedCommentId=381168&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-381168 as it did report a breaking change.

I'd like to ask you what are the bits and pieces I missed and some suggestions to validate this somehow automatically with some testing.

Thanks

Robert Sandell

unread,
Dec 11, 2019, 10:09:49 AM12/11/19
to Jenkins Developer List
Ah yes, that's gonna be a tricky one.

The problem is that the databound constructor no longer has a parameter named "glob". changeset "something*" should still work fine I guess, but since there is no databound constructor with that parameter or a databound setter with the name setGlob it fails. But just adding a @DataboundSetter setGlob(String glob) {pattern = glob;} won't solve it either since there is now another mandatory parameter named "pattern" that must be passed. And removing the databound constructor will break the changeset "something*" calls.

Maybe there is something in the descriptor that can be overridden to manually handle the various scenarios, like overriding configure or newInstance but I don't remember if that is possible on the top of my head.

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/6cd3a4d5-8b36-4fd3-91e2-b0629d0f6856%40googlegroups.com.


--
Robert Sandell
Software Engineer
CloudBees, Inc.
CloudBees-Logo.png
Twitter: robert_sandell

Jesse Glick

unread,
Dec 11, 2019, 1:24:36 PM12/11/19
to Jenkins Dev
On Wed, Dec 11, 2019 at 10:09 AM Robert Sandell <rsan...@cloudbees.com> wrote:
> Maybe there is something in the descriptor that can be overridden to manually handle the various scenarios, like overriding configure or newInstance

https://javadoc.jenkins.io/plugin/structs/org/jenkinsci/plugins/structs/describable/CustomDescribableModel.html

Victor Martinez

unread,
Dec 11, 2019, 5:12:32 PM12/11/19
to Jenkins Developers
Thanks for the details, I managed to test the CustomDescribableModel within the pipeline-model-definition plugin and it seems the customInstantiate happens after the transformToRuntimeAST, in other words, I'm able to manipulate the content of the parameters but I cannot manipulate and infer the deprecated parameter as the new parameter since there is a MultipleCompilationErrorsException :_(

As an example:

 "value" is deprecated and 'pattern' is the new parameter for the hypothetical case of changing the `environment when` condition in  the declarative pipeline definition.

Then the below implementation of the customInstantiate doesn't work when using environment name: 'FOO', pattern: 'BAR'

 private final String name;
 @Deprecated
 private transient String value;
private String pattern;

 @DataBoundConstructor
 public EnvironmentConditional(String name, String pattern) {
   this.name= name;
   this.pattern = pattern;
 }

  ...

  protected Object readResolve() throws IOException {
   if (this.value != null) {
     this.pattern = this.value;
   }
   return this;
 }

 @Extension
 @Symbol("environment")
 public static class DescriptorImpl extends DeclarativeStageConditionalDescriptor<EnvironmentConditional> {
   
   ...

   @Override
   public Expression transformToRuntimeAST(@CheckForNull ModelASTWhenContent original) {
     return ASTParserUtils.transformWhenContentToRuntimeAST(original);
   }

   @Override
   public Map<String, Object> customInstantiate(Map<String, Object> arguments) {
     Map<String, Object> r = new HashMap<>(arguments);
     Object value = r.get("value");
     if (value instanceof String) {
        r.put("pattern", ((String) value));
     }
     return r;
   }
 }




org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 90: Invalid parameter "value", did you mean "name"? @ line 90, column 42.
        environment name: "FOO", value: "BA
                                 ^
1 error

at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:133)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:126)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:561)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:522)
at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:320)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:429)
Finished: FAILURE


Most likelly It's something else that I'm missing though. Although the few examples I've just found for the customInstantiate where about to manipulate the content or remove some of the parameters. 

Any clues what I'm missing?

Thanks again


Jesse Glick

unread,
Dec 12, 2019, 9:11:59 AM12/12/19
to Jenkins Dev
On Wed, Dec 11, 2019 at 5:12 PM Victor Martinez
<victormar...@gmail.com> wrote:
> I managed to test the CustomDescribableModel within the pipeline-model-definition plugin and it seems the customInstantiate happens after the transformToRuntimeAST

Sounds like a feature request for Declarative.

Victor Martinez

unread,
Dec 13, 2019, 9:46:13 AM12/13/19
to Jenkins Developers
Sure, thanks for all the information. I've raise an issue to track this conversation:
https://issues.jenkins-ci.org/browse/JENKINS-60466

Cheers
Reply all
Reply to author
Forward
0 new messages