diff --git a/Actions/.Modules/WorkflowPostProcessHelper.psm1 b/Actions/.Modules/WorkflowPostProcessHelper.psm1 new file mode 100644 index 000000000..1d192260d --- /dev/null +++ b/Actions/.Modules/WorkflowPostProcessHelper.psm1 @@ -0,0 +1,47 @@ +<# +.SYNOPSIS +Helper functions for WorkflowPostProcess action + +.DESCRIPTION +Contains utility functions used by the WorkflowPostProcess action and its tests +#> + +<# +.SYNOPSIS +Calculate the duration of a workflow from a start time + +.DESCRIPTION +Calculates the duration in seconds from the provided start time to the current UTC time. +Handles both DateTime objects and string representations in any date format that can be parsed by the invariant culture (e.g., ISO 8601 or other culture-independent formats). + +.PARAMETER StartTime +The workflow start time as either a DateTime object or a string in any date format that can be parsed by the invariant culture (such as ISO 8601 or other culture-independent formats) + +.PARAMETER EndTime +(Optional) The end time as a DateTime object. Defaults to the current UTC time. + +.EXAMPLE +$duration = GetWorkflowDuration -StartTime "2025-12-12T10:00:00.0000000Z" -EndTime ([DateTime]::UtcNow) + +.EXAMPLE +$duration = GetWorkflowDuration -StartTime ([DateTime]::UtcNow) +#> +function GetWorkflowDuration { + Param( + [Parameter(Mandatory = $true)] + $StartTime, + [Parameter(Mandatory = $false)] + $EndTime = [DateTime]::UtcNow + ) + + if ($StartTime -is [DateTime]) { + $workflowStartTime = $StartTime.ToUniversalTime() + } else { + $workflowStartTime = [DateTime]::Parse($StartTime, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::AdjustToUniversal) + } + + $workflowDuration = $EndTime.ToUniversalTime().Subtract($workflowStartTime).TotalSeconds + return $workflowDuration +} + +Export-ModuleMember -Function GetWorkflowDuration diff --git a/Actions/WorkflowInitialize/WorkflowInitialize.ps1 b/Actions/WorkflowInitialize/WorkflowInitialize.ps1 index 5629ea421..9413e24ef 100644 --- a/Actions/WorkflowInitialize/WorkflowInitialize.ps1 +++ b/Actions/WorkflowInitialize/WorkflowInitialize.ps1 @@ -30,8 +30,9 @@ TestALGoRepository TestRunnerPrerequisites # Create a json object that contains an entry for the workflowstarttime +# Use ISO 8601 format for locale-agnostic serialization $scopeJson = @{ - "workflowStartTime" = [DateTime]::UtcNow + "workflowStartTime" = [DateTime]::UtcNow.ToString("o") } | ConvertTo-Json -Compress Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "telemetryScopeJson=$scopeJson" diff --git a/Actions/WorkflowPostProcess/WorkflowPostProcess.ps1 b/Actions/WorkflowPostProcess/WorkflowPostProcess.ps1 index 9928ce944..eb1eb8bb4 100644 --- a/Actions/WorkflowPostProcess/WorkflowPostProcess.ps1 +++ b/Actions/WorkflowPostProcess/WorkflowPostProcess.ps1 @@ -68,8 +68,9 @@ function LogWorkflowEnd($TelemetryScopeJson, $JobContext, $AlGoVersion) { # Calculate the workflow duration using the github api if ($telemetryScope -and ($null -ne $telemetryScope.workflowStartTime)) { Write-Host "Calculating workflow duration..." - $workflowTiming= [DateTime]::UtcNow.Subtract([DateTime]::Parse($telemetryScope.workflowStartTime)).TotalSeconds - Add-TelemetryProperty -Hashtable $AdditionalData -Key 'WorkflowDuration' -Value $workflowTiming + + $workflowDuration = GetWorkflowDuration -StartTime $telemetryScope.workflowStartTime + Add-TelemetryProperty -Hashtable $AdditionalData -Key 'WorkflowDuration' -Value $workflowDuration } # Log additional telemetry from AL-Go settings @@ -102,6 +103,7 @@ function LogWorkflowEnd($TelemetryScopeJson, $JobContext, $AlGoVersion) { } Import-Module (Join-Path -Path $PSScriptRoot -ChildPath "..\TelemetryHelper.psm1" -Resolve) +Import-Module (Join-Path -Path $PSScriptRoot -ChildPath "..\.Modules\WorkflowPostProcessHelper.psm1" -Resolve) try { LogWorkflowEnd -TelemetryScopeJson $telemetryScopeJson -JobContext $currentJobContext -AlGoVersion (GetAlGoVersion -ActionsRepo $actionsRepo -ActionRef $actionsRef) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3c7cd0000..c25448982 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,5 +1,6 @@ ### Issues +- Issue 2045 DateTime parsing fails on non-US locale runners in WorkflowPostProcess.ps1 - Issue 2055 When using versioningStrategy 3+16, you get an error when building - AL-Go repositories with large amounts of projects may run into issues with too large environment variables diff --git a/Tests/WorkflowPostProcess.Test.ps1 b/Tests/WorkflowPostProcess.Test.ps1 index dbcc2c104..36fea65a2 100644 --- a/Tests/WorkflowPostProcess.Test.ps1 +++ b/Tests/WorkflowPostProcess.Test.ps1 @@ -1,5 +1,6 @@ Get-Module TestActionsHelper | Remove-Module -Force Import-Module (Join-Path $PSScriptRoot 'TestActionsHelper.psm1') +Import-Module (Join-Path $PSScriptRoot '..\Actions\.Modules\WorkflowPostProcessHelper.psm1') $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 Describe "WorkflowPostProcess Action Tests" { @@ -25,4 +26,24 @@ Describe "WorkflowPostProcess Action Tests" { # Call action + It 'GetWorkflowDuration handles different culture formats correctly' { + $endTimeUTC = [DateTime]::Parse("2025-12-12T10:00:01.0000000Z") + + # Test UTC start time + $workflowDuration = GetWorkflowDuration -StartTime "2025-12-12T10:00:00.0000000Z" -EndTime $endTimeUTC + $workflowDuration | Should -Be 1 + + # Test en-US culture format + $workflowDuration = GetWorkflowDuration -StartTime "12/12/2025 10:00:00 AM" -EndTime $endTimeUTC + $workflowDuration | Should -Be 1 + + # Test de-DE culture format + $workflowDuration = GetWorkflowDuration -StartTime "12.12.2025 10:00:00" -EndTime $endTimeUTC + $workflowDuration | Should -Be 1 + + # Test da-DK culture format + $workflowDuration = GetWorkflowDuration -StartTime "12-12-2025 10:00:00" -EndTime $endTimeUTC + $workflowDuration | Should -Be 1 + } + }