-
Bug
-
Resolution: Unresolved
-
Major
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements.
This works fine e.g. for the archiveArtifacts publisher.
However when one invokes the promotion call twice like this:
job.with { properties{ promotions { promotion { name "First promotion" //... } } } } job.with { properties{ promotions { promotion { name "Second promotion" //... } } } }
The result is:
- if one views the web ui confiuguration form only the "Second promotion" is displayed
- if one views the Promotion Status (buildUrl/promotion/) for the build or for the whole job only the "First promotion" is displayed
- there are two "Promotion Status" links in the job sidebar and two badges (or how you call that) on the job status page
- there is only a single "Promotion Status" link and badge on the build status page
[JENKINS-43340] Invoking properties / promotions / promotion twice results in inconsistent configuration
Description |
Original:
Changing a {{textParam}} to \{\{validatingStringParameterDefinition}} like this: {code:java} manual('engineering') { parameters{ - textParam 'SOURCE' + validatingStringParameterDefinition { + name 'SOURCE' + regex '^[0-9]+$' + defaultValue '' + failedValidationMessage '' + description 'Commit to be merged into integration branch' + } } } {code} results in: {code:java} java.lang.ClassCastException: java.lang.String cannot be cast to groovy.util.Node at hudson.plugins.promoted_builds.integrations.jobdsl.ManualConditionConverter.convertNode(ManualConditionConverter.java:63) at hudson.plugins.promoted_builds.integrations.jobdsl.ManualConditionConverter.marshal(ManualConditionConverter.java:48) at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69) at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58) at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43) at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88) at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64) at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:74) at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69) at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58) at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43) at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88) at hudson.plugins.promoted_builds.integrations.jobdsl.JobDslPromotionProcessConverter.marshal(JobDslPromotionProcessConverter.java:73) at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69) at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58) at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43) at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82) at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37) at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026) at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015) at com.thoughtworks.xstream.XStream.toXML(XStream.java:988) at com.thoughtworks.xstream.XStream.toXML(XStream.java:975) at hudson.plugins.promoted_builds.integrations.jobdsl.PromotionsExtensionPoint.notifyItemCreated(PromotionsExtensionPoint.java:78) at hudson.plugins.promoted_builds.integrations.jobdsl.PromotionsExtensionPoint.notifyItemUpdated(PromotionsExtensionPoint.java:136) at javaposse.jobdsl.plugin.JenkinsJobManagement.notifyItemUpdated(JenkinsJobManagement.java:575) at javaposse.jobdsl.plugin.JenkinsJobManagement.updateExistingItem(JenkinsJobManagement.java:501) at javaposse.jobdsl.plugin.JenkinsJobManagement.createOrUpdateConfig(JenkinsJobManagement.java:149) at javaposse.jobdsl.dsl.JobManagement$createOrUpdateConfig$10.call(Unknown Source) at javaposse.jobdsl.plugin.InterruptibleJobManagement.createOrUpdateConfig(InterruptibleJobManagement.groovy:37) at javaposse.jobdsl.dsl.JobManagement$createOrUpdateConfig$10.call(Unknown Source) at javaposse.jobdsl.dsl.AbstractDslScriptLoader$_extractGeneratedJobs_closure4.doCall(AbstractDslScriptLoader.groovy:187) at sun.reflect.GeneratedMethodAccessor9651.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024) at groovy.lang.Closure.call(Closure.java:414) at groovy.lang.Closure.call(Closure.java:430) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2030) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2015) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2056) at org.codehaus.groovy.runtime.dgm$162.invoke(Unknown Source) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedJobs(AbstractDslScriptLoader.groovy:180) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210) at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:174) at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedItems(AbstractDslScriptLoader.groovy:167) at javaposse.jobdsl.plugin.JenkinsDslScriptLoader.extractGeneratedItems(JenkinsDslScriptLoader.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182) at javaposse.jobdsl.dsl.AbstractDslScriptLoader$_runScripts_closure1.doCall(AbstractDslScriptLoader.groovy:60) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024) at groovy.lang.Closure.call(Closure.java:414) at groovy.lang.Closure.call(Closure.java:430) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2030) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2015) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2068) at org.codehaus.groovy.runtime.dgm$164.invoke(Unknown Source) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts(AbstractDslScriptLoader.groovy:45) at javaposse.jobdsl.plugin.ExecuteDslScripts.perform(ExecuteDslScripts.java:251) at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:78) at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20) at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:779) at hudson.model.Build$BuildExecution.build(Build.java:206) at hudson.model.Build$BuildExecution.doRun(Build.java:163) at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534) at hudson.model.Run.execute(Run.java:1728) at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43) at hudson.model.ResourceController.execute(ResourceController.java:98) at hudson.model.Executor.run(Executor.java:405) ERROR: java.lang.String cannot be cast to groovy.util.Node{code} |
New:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar |
Attachment | New: snap.png [ 36866 ] |
Description |
Original:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar |
New:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar !snap.png! |
Description |
Original:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar !snap.png! |
New:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar !snap.png|thumbnail! |
Description |
Original:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar !snap.png|thumbnail! |
New:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) for the build or for the whole job only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar and two badges (or how you call that) on the job status page !snap.png|thumbnail! - there is only a single "Promotion Status" link and badge on the build status page |
Description |
Original:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) for the build or for the whole job only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar and two badges (or how you call that) on the job status page !snap.png|thumbnail! - there is only a single "Promotion Status" link and badge on the build status page |
New:
When creating jobs via DSL we run them though a chain of decorators, relying heavily on the intelligent append/replace behavior of dsl elements. This works fine e.g. for the archiveArtifacts publisher. However when one invokes the {{promotion}} call twice like this: {code:java} job.with { properties{ promotions { promotion { name "First promotion" //... } } } } job.with { properties{ promotions { promotion { name "Second promotion" //... } } } } {code} The result is: - if one views the web ui confiuguration form only the "Second promotion" is displayed - if one views the Promotion Status ({{buildUrl/promotion/}}) for the build or for the whole job only the "First promotion" is displayed - there are two "Promotion Status" links in the job sidebar and two badges (or how you call that) on the job status page !snap.png|thumbnail! - there is only a single "Promotion Status" link and badge on the build status page |
Assignee | Original: Oleg Nenashev [ oleg_nenashev ] |
Epic Link | New: JENKINS-44837 [ 182897 ] |
Merging the above code into a single promotions invocation fixes it:
it's not that easy in our real setup though as the promotions are added by different parts of our code