tcplugins / tcWebHooks

WebHooks plugin for Teamcity. Supports many build states and payload formats.
https://netwolfuk.wordpress.com/category/teamcity/tcplugins/tcwebhooks/
157 stars 30 forks source link

Calculate Time To Restore #217

Closed Super8film87 closed 1 year ago

Super8film87 commented 1 year ago

Description I'm facing challenges in calculating the Time To Restore duration. So my basic idea was to calculate this directly inside template based on the time duration between broken - fixed build. Didn't find any possibility

Thank you in advance for your assistance!

netwolfuk commented 1 year ago

I'm guessing you want to find the first build failure for the current build assuming it is failed and not broken (since that would imply the previous build was successful).

I'm not at the computer, but I'll have a think about it. If the previous SFinishedBuild is available in the payload (I don't think it is) you could access that time, but there is no guarantee that that was the first failure.

I imagine a helper tool (like the one you found for dates) that gave access to the build history some how would be a useful feature. I'll take some time to look at it over the weekend.

Super8film87 commented 1 year ago

I'm guessing you want to find the first build failure for the current build assuming it is failed and not broken (since that would imply the previous build was successful).

So in the template we can use "buildResultDelta" which use "broken", "fixed" & "unchanged". But I do not find where is data is coming from. So a broken build is the first failure after a successful build (state change). So I'm really interested into the state change.

I didnt found any entry so thats the reason why I asked :D Thx for your support

netwolfuk commented 1 year ago

Yeah. That value is calculated against the previous build, and only the result is available.

And even if it was available, it would refer to the previous build, which might not have been the first time the build failed. I'm presuming you want to know the total time from first failure to resolution.

Super8film87 commented 1 year ago

ah ok - got it. so we would need a attribute with the date. Ok sounds like this would be not possible :D

netwolfuk commented 1 year ago

I just need to write a velocity tool that exposes a method to fetch the first failed build.

That's fairly simple to do. Which version of tcWebHooks are you using? 1.2 or 2.0?

netwolfuk commented 1 year ago

I've figured out how to accomplish something similar to what I think you want from velocity. No code change required in the plugin.

I have defined a macro named getFirstFailedBuild. If finds the first failed build and assumes the current build is failed. You probably want this to run on "fixed", so you might want to call it with $build.getPreviousFinished().

It simply gets the previous build from the current build and saves it as a variable. Then loops around getting the next previous build each time until it find a successful one. If our previous build was successful, then our current build in the loop must be the last failed one.

## Define macro called "getFirstFailedBuild"
#macro( getFirstFailedBuild $myBuild)
  #set ($currentBuild = $myBuild)
  #set ($previousBuild = $myBuild.getPreviousFinished())
  #set ($keepLooping = true)
  #foreach($unused in [1..50]) ## only loop 50 times in case there are hundreds of failures
    #if ($keepLooping)
      #if ($previousBuild) ## Null check 
        #if ($previousBuild.getStatusDescriptor().isSuccessful())
          #set ($keepLooping = false) ## Our $previousBuild isSuccessful, so the $currentBuild is the first failure
          "$currentBuild.buildNumber :: $currentBuild.getStatusDescriptor().isSuccessful()" ## Output something when we find our first failure
        #end
      #else
         #set ($keepLooping = false)
         "unknown" ## text to display if getPreviousFinished returns null
      #end
      #set ($currentBuild = $previousBuild) ## set vars for next iteration
      #set ($previousBuild = $previousBuild.getPreviousFinished()) ## set vars for next iteration
    #end ## close $keepLooping
  #end
#end

#set($queueDuration = (${build.StartDate.Time} - ${build.QueuedDate.Time}) /1000)
#set($buildDuration = (${build.FinishDate.Time} - ${build.StartDate.Time}) /1000)
{ 
    "queueTime" : "$queueDuration seconds",
    "buildTime" : "$buildDuration seconds",
    "firstFailed" : #getFirstFailedBuild($build)
}

This is what I get. My build 305 was a broken build. Builds 302 to 305 all failed, so the first failed build was 302

image

Note: The javadoc for getPreviousFinished says:

returns previous finished build (ordered by changes). If this build is personal, this method can return previous personal build, otherwise only regular builds are returned.

From my testing, it appears to only return builds on the same branch.

netwolfuk commented 1 year ago

I'll close this. Feel free to message back if you need further help.