tcplugins/tcWebHooks

build.FinishDate is empty even build is finished

Super8film87 opened this issue · 5 comments

Expected Behavior

build.FinishDate.Time is available and shows time as number

Current Behavior

It looks like build.FinishDate is not available when webhook is sended
build_finish_time": "${build.FinishDate}"

Steps to Reproduce (for bugs)

  1. Use below snippet
  2. Execute build configuration with pre configured webhook
  3. Received payload contains "build_finish_time": ${build.FinishDate.Time} but not number
  4. If I try using it fromGUI to test I see the right value

Your Environment

  • tcWebHooks Version: 1.2.2
  • TeamCity Version: TeamCity Enterprise 2022.10.4 (build 117134)
  • TeamCity server Operating System:
  • Are you using a WebHook Template?:
    No

Example Configuration (xml)

#set($queueDuration = (${build.StartDate.Time} - ${build.QueuedDate.Time}) )
#set($buildDuration = (${build.FinishDate.Time} - ${build.StartDate.Time}) )
{
"build_start_time": ${build.StartDate.Time}, 
"build_full_name" : "${buildFullName}",
"build_finish_time": ${build.FinishDate.Time}
}

I must've seen this before, because I use "build_finish_time": "${currentTime}", in the elastic template.
currentTime is in the format defined on the template.

Alternatively, you could call now() on one of the Date classes. Eg, Instant.now() or something like that.

I cannot use currentTime to calculate duration - Im trying to get the actual timestamp now as workaround/alternative.

If you create a new DateTime object, it will default to now. Your date utils tool might be able to create one for you. I could try to build an example for you in a few hours when I get home.

It looks like I need to add the dateTool into the velocity context. I'll try to get a new release out this weekend.

New release v1.2.4 which includes the new $dateTool variable.

updated template:

## 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 is isSuccessful, so the $currentBuild is the last failure
          "$currentBuild.buildNumber :: $currentBuild.getStatusDescriptor().isSuccessful()" ## Output something when we find out 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 = ($dateTool.Date.Time - ${build.StartDate.Time}) /1000)
{ 
    "queueTime" : "$queueDuration seconds",
    "buildTime" : "$buildDuration seconds",
    "firstFailed" : #getFirstFailedBuild($build)
    "steps" :[
        #foreach($buildStep in $build.getBuildPromotion().getBuildSettings().getBuildRunners())
        #set($stepDuration = ($build.getStatisticValue("buildStageDuration:buildStep" + $buildStep.getId())) /1000)
        {
            "stepName" : "$buildStep.getName()",
            "buildStepDuration" : "$stepDuration seconds"
        },
        #end
    ]
}