diff --git a/lib/pom.xml b/lib/pom.xml index 246abc557..02373e438 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -50,7 +50,7 @@ org.codehaus.mojo exec-maven-plugin - 3.1.0 + 3.1.1 generate-sources diff --git a/plugin/pom.xml b/plugin/pom.xml index ae5a4ebd7..54d8890b1 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -54,6 +54,12 @@ import pom + + + org.jenkins-ci.plugins + support-core + 1366.v9d076592655d + @@ -253,7 +259,7 @@ org.testcontainers testcontainers - 1.19.0 + 1.19.3 test diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsFlowExecution.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsFlowExecution.java index ded38b7b0..683eecdf9 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsFlowExecution.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsFlowExecution.java @@ -2020,6 +2020,10 @@ public void autopersist(@NonNull FlowNode n) throws IOException { return "Timing data about recently completed Pipeline builds"; } + @Override public ComponentCategory getCategory() { + return ComponentCategory.BUILDS; + } + @Override public void addContents(Container container) { container.add(new Content("nodes/master/pipeline-timings.txt") { @Override public void writeTo(OutputStream outputStream) throws IOException { @@ -2067,6 +2071,10 @@ public void autopersist(@NonNull FlowNode n) throws IOException { return "List of internal API calls made by Pipeline builds (typically from trusted libraries)"; } + @Override public ComponentCategory getCategory() { + return ComponentCategory.BUILDS; + } + @Override public void addContents(Container container) { container.add(new Content("nodes/master/pipeline-internal-calls.txt") { @Override public void writeTo(OutputStream outputStream) throws IOException { diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsScmFlowDefinition.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsScmFlowDefinition.java index 24cc23a43..d10f3a880 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsScmFlowDefinition.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsScmFlowDefinition.java @@ -46,6 +46,7 @@ import java.io.IOException; import java.io.InterruptedIOException; import java.util.Collection; +import java.util.Collections; import java.util.List; import jenkins.model.Jenkins; import jenkins.scm.api.SCMFileSystem; @@ -85,6 +86,11 @@ public SCM getScm() { return scm; } + @Override + public Collection getSCMs() { + return Collections.singletonList(scm); + } + public String getScriptPath() { return scriptPath; } diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsThreadDumpAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsThreadDumpAction.java index 8fdf86ad3..835f271de 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsThreadDumpAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsThreadDumpAction.java @@ -102,6 +102,10 @@ public CpsThreadDump getThreadDump() { return "Thread dumps of running Pipeline builds"; } + @Override public ComponentCategory getCategory() { + return ComponentCategory.BUILDS; + } + @Override public void addContents(Container container) { container.add(new Content("nodes/master/pipeline-thread-dump.txt") { @Override public void writeTo(OutputStream outputStream) throws IOException { diff --git a/plugin/src/main/js/workflow-editor.js b/plugin/src/main/js/workflow-editor.js index 81da7098c..486d6b0d3 100644 --- a/plugin/src/main/js/workflow-editor.js +++ b/plugin/src/main/js/workflow-editor.js @@ -54,7 +54,7 @@ $(function() { setTheme(editor); if (window.isSystemRespectingTheme) { - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { setTheme(editor) }); } diff --git a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/Snippetizer/handle-prototype.js b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/Snippetizer/handle-prototype.js new file mode 100644 index 000000000..533aef6e0 --- /dev/null +++ b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/Snippetizer/handle-prototype.js @@ -0,0 +1,46 @@ +function handlePrototype(url, crumb) { + buildFormTree(document.forms.config); + // TODO JSON.stringify fails in some circumstances: https://gist.github.com/jglick/70ec4b15c1f628fdf2e9 due to Array.prototype.toJSON + // TODO simplify when Prototype.js is removed + const json = Object.toJSON ? Object.toJSON(JSON.parse(document.forms.config.elements.json.value).prototype) : JSON.stringify(JSON.parse(document.forms.config.elements.json.value).prototype); + if (!json) { + return; // just a separator + } + + const headers = new Headers(); + headers.append("Content-Type", "application/x-www-form-urlencoded"); + headers.append("Jenkins-Crumb", crumb); + + fetch(url, { + method: "POST", + headers: headers, + body: "json=" + encodeURIComponent(json), + + }) + .then(response => { + if (response.ok) { + response.text().then((responseText) => { + document.getElementById('prototypeText').value = responseText; + copybutton = document.querySelector('.jenkins-copy-button'); + copybutton.setAttribute("text", responseText); + copybutton.classList.remove('jenkins-hidden'); + }); + } + }) + .catch(error => { + console.error('Fetch error:', error); + }); +} + + +document.addEventListener('DOMContentLoaded', () => { + + const generatePipelineScript = document.getElementById("generatePipelineScript"); + const url = generatePipelineScript.getAttribute("data-url"); + const crumb = generatePipelineScript.getAttribute("data-crumb"); + generatePipelineScript.onclick = (_) => { + handlePrototype(url, crumb); + return false; + }; + +}); \ No newline at end of file diff --git a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/Snippetizer/index.jelly b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/Snippetizer/index.jelly index 05281e3f8..eeb02d9bd 100644 --- a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/Snippetizer/index.jelly +++ b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/Snippetizer/index.jelly @@ -67,40 +67,14 @@ THE SOFTWARE. - - - - - + + + + diff --git a/plugin/src/test/java/org/jenkinsci/plugins/workflow/cps/CpsFlowExecutionTest.java b/plugin/src/test/java/org/jenkinsci/plugins/workflow/cps/CpsFlowExecutionTest.java index 5bf8be4af..325ec7d83 100644 --- a/plugin/src/test/java/org/jenkinsci/plugins/workflow/cps/CpsFlowExecutionTest.java +++ b/plugin/src/test/java/org/jenkinsci/plugins/workflow/cps/CpsFlowExecutionTest.java @@ -703,6 +703,26 @@ public boolean isAllowed(String groovyResourceUrl) { } } + @Test public void evaluateAfterRestart() throws Throwable { + sessions.then(r -> { + WorkflowJob p = r.createProject(WorkflowJob.class, "p"); + p.setDefinition(new CpsFlowDefinition( + "def x = evaluate('class X {X() {}; def m1() {/OK/}}; new X()')\n" + + "def y = evaluate('class Y {X x; def m2() {/really ${x.m1()}/}}; new Y()')\n" + + "semaphore('wait')\n" + + "y.x = x\n" + + "echo(/received ${y.m2()}/)\n", true)); + WorkflowRun b = p.scheduleBuild2(0).waitForStart(); + SemaphoreStep.waitForStart("wait/1", b); + }); + sessions.then(r -> { + WorkflowJob p = r.jenkins.getItemByFullName("p", WorkflowJob.class); + WorkflowRun b = p.getLastBuild(); + SemaphoreStep.success("wait/1", null); + r.assertLogContains("received really OK", r.assertBuildStatus(Result.SUCCESS, r.waitForCompletion(b))); + }); + } + @Issue({ "JENKINS-45327", "JENKINS-68849" }) @Test public void envActionImplPickle() throws Throwable { sessions.then(r -> { diff --git a/pom.xml b/pom.xml index a81243eaa..a071fbe64 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jenkins-ci.plugins plugin - 4.74 + 4.75 org.jenkins-ci.plugins.workflow