Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-39229

Regression: Initial stage run does not show graph

    Details

    • Sprint:
      indian, arctic, tasman
    • Similar Issues:

      Description

      I saw something strange while testing blue ocean on b10

      Here's the pipeline:

      node {
        checkout scm
        stage ('Build1') {
            sh 'ping -c 10 www.apple.com'
        }
        stage ('Build2') {
            sh 'ping -c 10 www.apple.com'
        }
        stage ('Build3') {
            sh 'ping -c 10 www.apple.com'
        }
        stage ('Build4') {
            sh 'ping -c 10 www.apple.com'
        }
        stage ('Build5') {
            sh 'ping -c 10 www.apple.com'
        }
      }
      

      This is what the initial build looks like:

      Ideally we should have a regression test for this problem.

        Attachments

          Activity

          Hide
          jamesdumay James Dumay added a comment - - edited

          Vivek Pandey please take a look when you get the chance. Not sure if this is a frontend or backend issue.

          Show
          jamesdumay James Dumay added a comment - - edited Vivek Pandey please take a look when you get the chance. Not sure if this is a frontend or backend issue.
          Hide
          vivek Vivek Pandey added a comment -

          James Dumay backend API is returning DAG. it might have something to do with UI reacting to SSE and there is some bug in SSE where it deals with blocked scope stages. I tried the same script modified as legacy (non blocked scope) and it appears fine. Brief look at JS code tells me, DAG is drawn using SSE events and not by fetching DAG from node API. Thorsten Scherler please confirm if my evaluation is correct.

          Show
          vivek Vivek Pandey added a comment - James Dumay backend API is returning DAG. it might have something to do with UI reacting to SSE and there is some bug in SSE where it deals with blocked scope stages. I tried the same script modified as legacy (non blocked scope) and it appears fine. Brief look at JS code tells me, DAG is drawn using SSE events and not by fetching DAG from node API. Thorsten Scherler please confirm if my evaluation is correct.
          Hide
          tscherler Thorsten Scherler added a comment -

          I will have a look but that appeared to be caused that the initial response is not conform to what we had before. I remember a ticket with parallel where the first run did weird things, since the initial response has changed.

          { (hasResultsForSteps || isPipelineQueued) && nodes && nodes[nodeKey] && !this.mergedConfig.forceLogView && <Extensions.Renderer

          That is the code calling it. Since I used that extensionpoint in my presentation I know it works which remind me, that there had been a change on the PipelineRunGraph, which may be related.

          ...will investigate.

          Show
          tscherler Thorsten Scherler added a comment - I will have a look but that appeared to be caused that the initial response is not conform to what we had before. I remember a ticket with parallel where the first run did weird things, since the initial response has changed. { (hasResultsForSteps || isPipelineQueued) && nodes && nodes [nodeKey] && !this.mergedConfig.forceLogView && <Extensions.Renderer That is the code calling it. Since I used that extensionpoint in my presentation I know it works which remind me, that there had been a change on the PipelineRunGraph, which may be related. ...will investigate.
          Hide
          jamesdumay James Dumay added a comment -
          Show
          jamesdumay James Dumay added a comment - Thanks Thorsten Scherler !
          Hide
          tscherler Thorsten Scherler added a comment -

          James Dumay The pipeline you have posted is throwing an exception in my system:

          Started by user Thorsten Scherler
          2 	[Pipeline] node
          3 	Running on master in /home/thorsten/opt/src/cloudbees/blueocean-plugin/blueocean/work/workspace/JENKINS-39229_Regression_Initial_stage_run_does_not_show_graph
          4 	[Pipeline] {
          5 	[Pipeline] }
          6 	[Pipeline] // node
          7 	[Pipeline] End of Pipeline
          8 	java.lang.IllegalStateException: inappropriate context
          9 		at org.jenkinsci.plugins.workflow.multibranch.SCMVar.getValue(SCMVar.java:78)
          10 		at org.jenkinsci.plugins.workflow.multibranch.SCMVar.getValue(SCMVar.java:56)
          11 		at org.jenkinsci.plugins.workflow.cps.CpsScript.getProperty(CpsScript.java:128)
          12 		at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:172)
          13 		at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
          14 		at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:243)
          15 		at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:52)
          16 		at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:308)
          
          
          Show
          tscherler Thorsten Scherler added a comment - James Dumay The pipeline you have posted is throwing an exception in my system: Started by user Thorsten Scherler 2 [Pipeline] node 3 Running on master in /home/thorsten/opt/src/cloudbees/blueocean-plugin/blueocean/work/workspace/JENKINS-39229_Regression_Initial_stage_run_does_not_show_graph 4 [Pipeline] { 5 [Pipeline] } 6 [Pipeline] // node 7 [Pipeline] End of Pipeline 8 java.lang.IllegalStateException: inappropriate context 9 at org.jenkinsci.plugins.workflow.multibranch.SCMVar.getValue(SCMVar.java:78) 10 at org.jenkinsci.plugins.workflow.multibranch.SCMVar.getValue(SCMVar.java:56) 11 at org.jenkinsci.plugins.workflow.cps.CpsScript.getProperty(CpsScript.java:128) 12 at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:172) 13 at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456) 14 at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:243) 15 at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:52) 16 at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:308)
          Hide
          tscherler Thorsten Scherler added a comment -

          Removing the checkout line and replacing it with echo in a normal pipeline works.

          I will now try as multibranch since the script makes only sense as multibranch

          Show
          tscherler Thorsten Scherler added a comment - Removing the checkout line and replacing it with echo in a normal pipeline works. I will now try as multibranch since the script makes only sense as multibranch
          Hide
          tscherler Thorsten Scherler added a comment -

          Yes I can reproduce it with git@github.com:scherler/multiKultiBranch.git

          Show
          tscherler Thorsten Scherler added a comment - Yes I can reproduce it with git@github.com:scherler/multiKultiBranch.git
          Hide
          tscherler Thorsten Scherler added a comment -

          The problem is that the first answer for nodes is empty

          Show
          tscherler Thorsten Scherler added a comment - The problem is that the first answer for nodes is empty
          Hide
          tscherler Thorsten Scherler added a comment -

          I located the problematic part and I am surprised that Karaoke is still working.

          src/main/java/io/jenkins/blueocean/events/PipelineEventListener.java around line 155

          It seems that currentStageName is now always null (not have been like that before)

          in src/main/js/components/RunDetailsPipeline.jsx we are using event.pipeline_step_stage_id to determine whether to fetchNodes or fetchSteps. However that is not set anymore.

          Will need to debug PipelineEventListener why the currentStageName now is always null

          Show
          tscherler Thorsten Scherler added a comment - I located the problematic part and I am surprised that Karaoke is still working. src/main/java/io/jenkins/blueocean/events/PipelineEventListener.java around line 155 It seems that currentStageName is now always null (not have been like that before) in src/main/js/components/RunDetailsPipeline.jsx we are using event.pipeline_step_stage_id to determine whether to fetchNodes or fetchSteps. However that is not set anymore. Will need to debug PipelineEventListener why the currentStageName now is always null
          Hide
          jamesdumay James Dumay added a comment -

          Thorsten Scherler thanks mate. Perhaps this is related to a few changes Vivek Pandey made when we adopted bismuth?

          Show
          jamesdumay James Dumay added a comment - Thorsten Scherler thanks mate. Perhaps this is related to a few changes Vivek Pandey made when we adopted bismuth?
          Hide
          vivek Vivek Pandey added a comment - - edited

          James Dumay Nothing to do with bismuth. Its just that SSE code is not aware of block scoped stages. SSE code should use PipelineNodeUtil to determine whether given node is stage or not or to get stage name etc. Current SSE code relies on StageAction, that was for non-block scoped stage, so won't work for blocked scoped stage.

          To keep SSE pipeline related code and /nodes API in sync, I suggest it uses whats implemented in /nodes. For example code something like following is all it needs. I can make it more general purpose if needed. Otherwise there is always going to be duplication in some form and things can get out of sync. For example handling of synthetic stage, SSE might treat as normal stage and fire event where as such stages won't appear in the DAG returned by /nodes API.

          NodeGraphBuilder graphBuilder graphBuilder = NodeGraphBuilder.NodeGraphBuilderFactory.getInstance(workflowRun);
          
          public List<FlowNode> getStages(NodeGraphBuilder builder){
                  List<FlowNode> nodes = new ArrayList<>();
                  for(FlowNodeWrapper node: builder.getPipelineNodes()){
                      if(node.type == FlowNodeWrapper.NodeType.STAGE){
                          nodes.add(node.getNode());
                      }
                  }
          
                  return nodes;
              }
              public List<FlowNode> getStagesAndParallels(NodeGraphBuilder builder){
                  List<FlowNode> nodes = new ArrayList<>();
                  for(FlowNodeWrapper node: builder.getPipelineNodes()){
                      if(node.type == FlowNodeWrapper.NodeType.STAGE || node.type == FlowNodeWrapper.NodeType.PARALLEL){
                          nodes.add(node.getNode());
                      }
                  }
          
                  return nodes;
              }
          
              public List<FlowNode> getParallels(NodeGraphBuilder builder){
                  List<FlowNode> nodes = new ArrayList<>();
                  for(FlowNodeWrapper node: builder.getPipelineNodes()){
                      if(node.type == FlowNodeWrapper.NodeType.PARALLEL){
                          nodes.add(node.getNode());
                      }
                  }
          
                  return nodes;
              }
          
          Show
          vivek Vivek Pandey added a comment - - edited James Dumay Nothing to do with bismuth. Its just that SSE code is not aware of block scoped stages. SSE code should use PipelineNodeUtil to determine whether given node is stage or not or to get stage name etc. Current SSE code relies on StageAction, that was for non-block scoped stage, so won't work for blocked scoped stage. To keep SSE pipeline related code and /nodes API in sync, I suggest it uses whats implemented in /nodes. For example code something like following is all it needs. I can make it more general purpose if needed. Otherwise there is always going to be duplication in some form and things can get out of sync. For example handling of synthetic stage, SSE might treat as normal stage and fire event where as such stages won't appear in the DAG returned by /nodes API. NodeGraphBuilder graphBuilder graphBuilder = NodeGraphBuilder.NodeGraphBuilderFactory.getInstance(workflowRun); public List<FlowNode> getStages(NodeGraphBuilder builder){ List<FlowNode> nodes = new ArrayList<>(); for (FlowNodeWrapper node: builder.getPipelineNodes()){ if (node.type == FlowNodeWrapper.NodeType.STAGE){ nodes.add(node.getNode()); } } return nodes; } public List<FlowNode> getStagesAndParallels(NodeGraphBuilder builder){ List<FlowNode> nodes = new ArrayList<>(); for (FlowNodeWrapper node: builder.getPipelineNodes()){ if (node.type == FlowNodeWrapper.NodeType.STAGE || node.type == FlowNodeWrapper.NodeType.PARALLEL){ nodes.add(node.getNode()); } } return nodes; } public List<FlowNode> getParallels(NodeGraphBuilder builder){ List<FlowNode> nodes = new ArrayList<>(); for (FlowNodeWrapper node: builder.getPipelineNodes()){ if (node.type == FlowNodeWrapper.NodeType.PARALLEL){ nodes.add(node.getNode()); } } return nodes; }
          Hide
          michaelneale Michael Neale added a comment -

          Thanks Thorsten Scherler, I think perhaps Tom FENNELLY might be able to tackle this later this week?

          Vivek is out for thanksgiving - Tom FENNELLY able to take a look?

          Show
          michaelneale Michael Neale added a comment - Thanks Thorsten Scherler , I think perhaps Tom FENNELLY might be able to tackle this later this week? Vivek is out for thanksgiving - Tom FENNELLY able to take a look?
          Hide
          michaelneale Michael Neale added a comment - - edited

          I can't consistently reproduce this - can anyone else?

          EDIT: got it, needs to have something happen before a stage opens :

          node {
            sh 'ping -c 10 www.apple.com'
            stage ('Build1') {
                sh 'ping -c 10 www.apple.com'
            }
            stage ('Build2') {
                sh 'ping -c 10 www.apple.com'
            }
            stage ('Build3') {
                sh 'ping -c 10 www.apple.com'
            }
            stage ('Build4') {
                sh 'ping -c 10 www.apple.com'
            }
            stage ('Build5') {
                sh 'ping -c 10 www.apple.com'
            }
          }
          

          checkout scm will also do that - is timing sensitive.

          Show
          michaelneale Michael Neale added a comment - - edited I can't consistently reproduce this - can anyone else? EDIT: got it, needs to have something happen before a stage opens : node { sh 'ping -c 10 www.apple.com' stage ('Build1') { sh 'ping -c 10 www.apple.com' } stage ('Build2') { sh 'ping -c 10 www.apple.com' } stage ('Build3') { sh 'ping -c 10 www.apple.com' } stage ('Build4') { sh 'ping -c 10 www.apple.com' } stage ('Build5') { sh 'ping -c 10 www.apple.com' } } checkout scm will also do that - is timing sensitive.
          Hide
          jamesdumay James Dumay added a comment -

          Nice one Michael Neale. Not sure why my example didn't work... scratches head

          Show
          jamesdumay James Dumay added a comment - Nice one Michael Neale . Not sure why my example didn't work... scratches head
          Hide
          michaelneale Michael Neale added a comment -

          I tried and this seems too timing sensitive to be able to pick up with the ATH

          Show
          michaelneale Michael Neale added a comment - I tried and this seems too timing sensitive to be able to pick up with the ATH
          Hide
          tscherler Thorsten Scherler added a comment -

          Michael Neale yeah you are right I was able to reproduce it only once before. I will try your scripts now.

          Show
          tscherler Thorsten Scherler added a comment - Michael Neale yeah you are right I was able to reproduce it only once before. I will try your scripts now.

            People

            • Assignee:
              tscherler Thorsten Scherler
              Reporter:
              jamesdumay James Dumay
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: