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

Regression: Initial stage run does not show graph

    XMLWordPrintable

Details

    • indian, arctic, tasman

    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

          jamesdumay James Dumay added a comment - - edited

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

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

          jamesdumay 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. tscherler please confirm if my evaluation is correct.

          vivek Vivek Pandey added a comment - jamesdumay 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. tscherler please confirm if my evaluation is correct.

          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.

          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.
          jamesdumay James Dumay added a comment -

          Thanks tscherler!

          jamesdumay James Dumay added a comment - Thanks tscherler !

          jamesdumay 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)
          
          
          tscherler Thorsten Scherler added a comment - jamesdumay 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)

          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

          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

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

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

          The problem is that the first answer for nodes is empty

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

          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

          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
          jamesdumay James Dumay added a comment -

          tscherler thanks mate. Perhaps this is related to a few changes vivek made when we adopted bismuth?

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

          jamesdumay 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;
              }
          
          vivek Vivek Pandey added a comment - - edited jamesdumay 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; }
          michaelneale Michael Neale added a comment -

          Thanks tscherler, I think perhaps tfennelly might be able to tackle this later this week?

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

          michaelneale Michael Neale added a comment - Thanks tscherler , I think perhaps tfennelly might be able to tackle this later this week? Vivek is out for thanksgiving - tfennelly able to take a look?
          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.

          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.
          jamesdumay James Dumay added a comment -

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

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

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

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

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

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

          People

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

            Dates

              Created:
              Updated:
              Resolved: