• 1.0-japan-m9

      In Scope

      • For any node in the railway the developer can click on it and see a list of the steps that had executed for that node
      • Each step has a status (passed, failed or running)
      • Clicking on one of the steps expands the log in place.
      • On successful, aborted, unstable and unknown runs the developer sees all the steps in the log collapsed
      • On failed run the developer sees all the steps in the log collapsed but the failing step is expanded
      • On executing run the developer sees all the steps in the log collapsed but the currently executing step is expanded
      • Not in the mockup: 2px radius on the top and bottom un-expanded steps
      • Don't fetch the whole log into the browser memory ever (break the "download log" feature if needed)
      • Show full log in freestyle cases (no step by step break down) but without eagerly loading the whole multi MB log (should only load last 4K (ping Vivek), as jenkins console does now, with a link to "show full log" that then loads the rest. not test with other then pipeline and multibranch
      • When loading a log (for a step, or whole log for freestyle) and it only loads the last part, offer a link to "Show all" (as Jenkins does now)

      Out of scope:

      • Tailing (UX-73)
      • Download load option
      • Open raw log in new tab (can lazily load from server) in all cases (reasonably formatter, nearly works already but missing newlines)

          [JENKINS-35820] Developer sees the log broken down by step

          Michael Neale added a comment -

          This was as jdumay and I discussed/designed last week. The log can also be downloaded/viewed for the whole job (likely in another tab).

          By segmenting like this, we can also potentially speed up the page load if needed - we can load per flownode if needed.

          Michael Neale added a comment - This was as jdumay and I discussed/designed last week. The log can also be downloaded/viewed for the whole job (likely in another tab). By segmenting like this, we can also potentially speed up the page load if needed - we can load per flownode if needed.

          Michael Neale added a comment -

          vpandey could you take a look at api - and let us know what could be done in the api to provide per step log info?
          Perhaps just having the log for a stage having a prefix for log lines per step is enough for us to collapse it together in the GUI - or else we need a step by step log - need advice please.

          Michael Neale added a comment - vpandey could you take a look at api - and let us know what could be done in the api to provide per step log info? Perhaps just having the log for a stage having a prefix for log lines per step is enough for us to collapse it together in the GUI - or else we need a step by step log - need advice please.

          Michael Neale added a comment -

          jdumay what do you think of a "scroll spy" type of thing (possibly not as initial pass) - as you scroll up or down, it expands the relevant section so you can smoothly navigate: http://www.w3schools.com/bootstrap/bootstrap_scrollspy.asp

          Michael Neale added a comment - jdumay what do you think of a "scroll spy" type of thing (possibly not as initial pass) - as you scroll up or down, it expands the relevant section so you can smoothly navigate: http://www.w3schools.com/bootstrap/bootstrap_scrollspy.asp

          I love the collapse+expand sections.

          Scrollspy is an interesting concept, but I suspect scrollspy with expanding sections could be a bit quirky – especially with short sections at the end. It's more designed to track you in the TOC on long-form content. For this, you'd have to choose a horizontal line in the window view (typically the top of the scroll view) that would expand the content, and then if you have short sections at the end, your scroll may never go down far enough to trigger the expansion of the bottom steps...so your smooth-scroll would stop and then you'd have to click on those bottom sections to open it.

          For scroll spy you could also consider expanding all the content, and then use a TOC-style navigation on the side to click down to the sections. That's more in the original design of scrollspy. That would require pre-fetching all the content though – not sure if that's how its done today, or if you grab content at you expand.

          Spike Washburn added a comment - I love the collapse+expand sections. Scrollspy is an interesting concept, but I suspect scrollspy with expanding sections could be a bit quirky – especially with short sections at the end. It's more designed to track you in the TOC on long-form content. For this, you'd have to choose a horizontal line in the window view (typically the top of the scroll view) that would expand the content, and then if you have short sections at the end, your scroll may never go down far enough to trigger the expansion of the bottom steps...so your smooth-scroll would stop and then you'd have to click on those bottom sections to open it. For scroll spy you could also consider expanding all the content, and then use a TOC-style navigation on the side to click down to the sections. That's more in the original design of scrollspy. That would require pre-fetching all the content though – not sure if that's how its done today, or if you grab content at you expand.

          James Dumay added a comment -

          swashburn great to hear you like that. We are tracking the scroll behaviour for this in the design ticket UX-424. Have you used Google Inbox? We are thinking about something very similar to their "sticky header" behaviour you see in long threads.

          James Dumay added a comment - swashburn great to hear you like that. We are tracking the scroll behaviour for this in the design ticket UX-424 . Have you used Google Inbox? We are thinking about something very similar to their "sticky header" behaviour you see in long threads.

          Sure, that inbox behavior makes sense at the very least.

          Spike Washburn added a comment - Sure, that inbox behavior makes sense at the very least.

          Michael Neale added a comment -

          swashburn yeah - I think the scroll spy won't work here, I kind of liked it with the config page which is long but has tabs, but I don't think it works with the vertical collapsing steps - so can shelve that idea of "scroll spy" for now.

          Michael Neale added a comment - swashburn yeah - I think the scroll spy won't work here, I kind of liked it with the config page which is long but has tabs, but I don't think it works with the vertical collapsing steps - so can shelve that idea of "scroll spy" for now.

          James Dumay added a comment -

          swashburn keep that feedback coming though

          James Dumay added a comment - swashburn keep that feedback coming though

          Michael Neale added a comment - - edited

          Here is a slide deck showing the progression as stop-motion:

          https://docs.google.com/presentation/d/1jz_3mTH4rEldWlrHnm_04kHNtldItDhMXW2l3Ehqjio/edit#slide=id.g140c50d20d_0_0
          (you will have to imagine meaningful logs loading via progressiveText).

          However this is covered in UX-73 and not in scope of this ticket.

          Michael Neale added a comment - - edited Here is a slide deck showing the progression as stop-motion: https://docs.google.com/presentation/d/1jz_3mTH4rEldWlrHnm_04kHNtldItDhMXW2l3Ehqjio/edit#slide=id.g140c50d20d_0_0 (you will have to imagine meaningful logs loading via progressiveText). However this is covered in UX-73 and not in scope of this ticket.

          Sam Van Oort added a comment -

          This is grand. I love this accordian-style representation and the way it makes it easy to spot failures and see steps.

          Sam Van Oort added a comment - This is grand. I love this accordian-style representation and the way it makes it easy to spot failures and see steps.

          James Dumay added a comment -

          svanoort boom! Glad you love it

          James Dumay added a comment - svanoort boom! Glad you love it

          Sam Van Oort added a comment -

          jdumay It's a solid delighter for anyone who's had to look for the failure cause in parallel branches of a flow graph, and I do that pretty often. Plus it looks really slick in the mockups.

          Sam Van Oort added a comment - jdumay It's a solid delighter for anyone who's had to look for the failure cause in parallel branches of a flow graph, and I do that pretty often. Plus it looks really slick in the mockups.

          Thorsten Scherler added a comment - - edited

          to be able to use ?start=xxx we need to get the X-TEXT response attribute to calculate backwards to e.g. start=X-TEXT-200. -> UX-504

          Thorsten Scherler added a comment - - edited to be able to use ?start=xxx we need to get the X-TEXT response attribute to calculate backwards to e.g. start=X-TEXT-200. -> UX-504

          Thorsten Scherler added a comment - - edited

          mneale jdumay it states: On failed run the developer sees all the steps in the log collapsed but the failing step is expanded

          what happens if multiple steps fail? Should be the first visible or all?

          Thorsten Scherler added a comment - - edited mneale jdumay it states: On failed run the developer sees all the steps in the log collapsed but the failing step is expanded what happens if multiple steps fail? Should be the first visible or all?

          Thorsten Scherler added a comment - - edited

          There is IMO a problem with the response the REST server sends for running jobs, I recorded the following on a pipeline that has finished the first stage and was running the second:

          export const firstFinishedSecondRunning = [
            {
              "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl",
              "displayName": "Stage 1",
              "durationInMillis": 10264,
              "edges": [
                {
                  "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl",
                  "id": "12"
                }
              ],
              "id": "5",
              "result": "SUCCESS",
              "startTime": "2016-05-25T13:47:40.534+0200",
              "state": "FINISHED"
            },
            {
              "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl",
              "displayName": "Stage 2",
              "durationInMillis": 7271,
              "edges": [
                {
                  "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl",
                  "id": "16"
                },
                {
                  "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl",
                  "id": "17"
                },
                {
                  "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl",
                  "id": "18"
                }
              ],
              "id": "12",
              "result": "UNKNOWN",
              "startTime": "2016-05-25T13:47:50.798+0200",
              "state": "RUNNING"
            },
            {
              "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl",
              "displayName": "firstBranch",
              "durationInMillis": 7269,
              "edges": [],
              "id": "16",
              "result": "SUCCESS",
              "startTime": "2016-05-25T13:47:50.800+0200",
              "state": "FINISHED"
            },
            {
              "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl",
              "displayName": "secondBranch",
              "durationInMillis": 7268,
              "edges": [],
              "id": "17",
              "result": "SUCCESS",
              "startTime": "2016-05-25T13:47:50.801+0200",
              "state": "FINISHED"
            },
            {
              "_class": "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl",
              "displayName": "thirdBranch",
              "durationInMillis": 7267,
              "edges": [],
              "id": "18",
              "result": "SUCCESS",
              "startTime": "2016-05-25T13:47:50.802+0200",
              "state": "FINISHED"
            }
          ]
          

          As you can see 16-18 are edge jobs and since 12 is currently running they should not have yet a result and the state should be RUNNING. May be related to https://cloudbees.atlassian.net/browse/UX-505?focusedCommentId=37907&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-37907.

          The real end result had been

          Thorsten Scherler added a comment - - edited There is IMO a problem with the response the REST server sends for running jobs, I recorded the following on a pipeline that has finished the first stage and was running the second: export const firstFinishedSecondRunning = [ { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl" , "displayName" : "Stage 1" , "durationInMillis" : 10264, "edges" : [ { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl" , "id" : "12" } ], "id" : "5" , "result" : "SUCCESS" , "startTime" : "2016-05-25T13:47:40.534+0200" , "state" : "FINISHED" }, { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl" , "displayName" : "Stage 2" , "durationInMillis" : 7271, "edges" : [ { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl" , "id" : "16" }, { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl" , "id" : "17" }, { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl" , "id" : "18" } ], "id" : "12" , "result" : "UNKNOWN" , "startTime" : "2016-05-25T13:47:50.798+0200" , "state" : "RUNNING" }, { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl" , "displayName" : "firstBranch" , "durationInMillis" : 7269, "edges" : [], "id" : "16" , "result" : "SUCCESS" , "startTime" : "2016-05-25T13:47:50.800+0200" , "state" : "FINISHED" }, { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl" , "displayName" : "secondBranch" , "durationInMillis" : 7268, "edges" : [], "id" : "17" , "result" : "SUCCESS" , "startTime" : "2016-05-25T13:47:50.801+0200" , "state" : "FINISHED" }, { "_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl" , "displayName" : "thirdBranch" , "durationInMillis" : 7267, "edges" : [], "id" : "18" , "result" : "SUCCESS" , "startTime" : "2016-05-25T13:47:50.802+0200" , "state" : "FINISHED" } ] As you can see 16-18 are edge jobs and since 12 is currently running they should not have yet a result and the state should be RUNNING. May be related to https://cloudbees.atlassian.net/browse/UX-505?focusedCommentId=37907&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-37907 . The real end result had been

          jdumay an observation regarding the status symbols in front of the node log, we are introducing here a new set of status symbols, wouldn't it be better to reuse the ones from the activity view. This would IMO enhance the recognisability of the this statuses. I understand you are using the same as in the modalHeader, if we stay with that we should extract a new component from the modalHeader code generating the symbols and reuse them in the logNodes.

          Thorsten Scherler added a comment - jdumay an observation regarding the status symbols in front of the node log, we are introducing here a new set of status symbols, wouldn't it be better to reuse the ones from the activity view. This would IMO enhance the recognisability of the this statuses. I understand you are using the same as in the modalHeader, if we stay with that we should extract a new component from the modalHeader code generating the symbols and reuse them in the logNodes.

          Thorsten Scherler added a comment - - edited

          [^screencast_00002.mp4] IMO if a job is failed and the last stage have not run it should not rotate, it will not be run never.

          export const runNodesFail = [{
              '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl',
              displayName: 'Stage 1',
              durationInMillis: 10263,
              edges: [{
                  '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl',
                  id: '12'
              }],
              id: '5',
              result: 'SUCCESS',
              startTime: '2016-05-24T13:42:07.833+0200',
              state: 'FINISHED'
          }, {
              '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl',
              displayName: 'Stage 2',
              durationInMillis: 22141,
              edges: [{
                  '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl',
                  id: '15'
              }, {
                  '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl',
                  id: '16'
              }],
              id: '12',
              result: 'FAILURE',
              startTime: '2016-05-24T13:42:18.096+0200',
              state: 'FINISHED'
          }, {
              '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl',
              displayName: 'firstBranch',
              durationInMillis: 22074,
              edges: [{
                  '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl',
                  id: '28'
              }],
              id: '15',
              result: 'SUCCESS',
              startTime: '2016-05-24T13:42:18.098+0200',
              state: 'FINISHED'
          }, {
              '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl',
              displayName: 'secondBranch',
              durationInMillis: 22076,
              edges: [{
                  '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl',
                  id: '28'
              }],
              id: '16',
              result: 'FAILURE',
              startTime: '2016-05-24T13:42:18.099+0200',
              state: 'FINISHED'
          }, {
              '_class': 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl',
              displayName: 'deploy',
              durationInMillis: null,
              edges: [],
              id: '28',
              result: null,
              startTime: null,
              state: null
          }];
          

          Thorsten Scherler added a comment - - edited [^screencast_00002.mp4] IMO if a job is failed and the last stage have not run it should not rotate, it will not be run never. export const runNodesFail = [{ '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl' , displayName: 'Stage 1' , durationInMillis: 10263, edges: [{ '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl' , id: '12' }], id: '5' , result: 'SUCCESS' , startTime: '2016-05-24T13:42:07.833+0200' , state: 'FINISHED' }, { '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl' , displayName: 'Stage 2' , durationInMillis: 22141, edges: [{ '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl' , id: '15' }, { '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl' , id: '16' }], id: '12' , result: 'FAILURE' , startTime: '2016-05-24T13:42:18.096+0200' , state: 'FINISHED' }, { '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl' , displayName: 'firstBranch' , durationInMillis: 22074, edges: [{ '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl' , id: '28' }], id: '15' , result: 'SUCCESS' , startTime: '2016-05-24T13:42:18.098+0200' , state: 'FINISHED' }, { '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl' , displayName: 'secondBranch' , durationInMillis: 22076, edges: [{ '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl$EdgeImpl' , id: '28' }], id: '16' , result: 'FAILURE' , startTime: '2016-05-24T13:42:18.099+0200' , state: 'FINISHED' }, { '_class' : 'io.jenkins.blueocean.service.embedded.rest.PipelineNodeImpl' , displayName: 'deploy' , durationInMillis: null , edges: [], id: '28' , result: null , startTime: null , state: null }];

          James Dumay added a comment -

          tscherler yes we are using the ones from the modal header right now. Circle filled with color vs status background color has to do with what the foreground contrast needs to be. If its white, on its own then we can use the circle variant. If we can't, its filled in and we use the modal header variant.

          James Dumay added a comment - tscherler yes we are using the ones from the modal header right now. Circle filled with color vs status background color has to do with what the foreground contrast needs to be. If its white, on its own then we can use the circle variant. If we can't, its filled in and we use the modal header variant.

          Michael Neale added a comment -

          tscherler use finished jobs for now, and then we may have to open other ticket for running states.

          Michael Neale added a comment - tscherler use finished jobs for now, and then we may have to open other ticket for running states.

          James Dumay added a comment -

          tscherler

          On failed run the developer sees all the steps in the log collapsed but the failing step is expanded
          what happens if multiple steps fail? Should be the first visible or all?

          If this is referring to the graph, the first failure in the graph should be visible.

          James Dumay added a comment - tscherler On failed run the developer sees all the steps in the log collapsed but the failing step is expanded what happens if multiple steps fail? Should be the first visible or all? If this is referring to the graph, the first failure in the graph should be visible.

          Michael Neale added a comment -

          FYI I just added an in-scope (jdumay) as the log api is being corrected by vpandey to only load the last 4K - there will be a need for a user to "show all" in cases where there is a lot of back-log they want to view (as is the case in jenkins now).

          Michael Neale added a comment - FYI I just added an in-scope ( jdumay ) as the log api is being corrected by vpandey to only load the last 4K - there will be a need for a user to "show all" in cases where there is a lot of back-log they want to view (as is the case in jenkins now).

          https://github.com/jenkinsci/blueocean-plugin/pull/212/files#diff-ee06b67a788e43a3e9215a1940ab804fR546

          We should simply change that to
          `const logUrl = calculateLogUrl(config) + config.fullLog ? ' ?start=0' : '';`

          Thorsten Scherler added a comment - https://github.com/jenkinsci/blueocean-plugin/pull/212/files#diff-ee06b67a788e43a3e9215a1940ab804fR546 We should simply change that to `const logUrl = calculateLogUrl(config) + config.fullLog ? ' ?start=0' : '';`

          Josh McDonald added a comment -

          Layout-only component:

          Josh McDonald added a comment - Layout-only component:

            tscherler Thorsten Scherler
            jamesdumay James Dumay
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: