diff --git a/Actions/.Modules/DebugLogHelper.psm1 b/Actions/.Modules/DebugLogHelper.psm1 new file mode 100644 index 000000000..335ac82d0 --- /dev/null +++ b/Actions/.Modules/DebugLogHelper.psm1 @@ -0,0 +1,218 @@ + +if ($env:GITHUB_ACTIONS -eq "true") { + $runningLocal = $false +} else { + $runningLocal = $true +} + +# Colors +$colorCodeRed = '31' +$colorCodeGreen = '32' +$colorCodeYellow = '33' +$colorCodeBlue = '34' +$colorCodeMagenta = '35' +$colorCodeCyan = '36' + +<# + .SYNOPSIS + Writes debug information about the function call and its parameters if extended debug logging is enabled or running locally. + .DESCRIPTION + Writes debug information about the function call and its parameters to the console if extended debug logging is enabled or running locally. + Automatically retrieves the caller's name and arguments from the call stack. +#> +function OutputDebugFunctionCall { + try { + $caller = (Get-PSCallStack)[1] + $callerName = $caller.Command + $callerParameters = $caller.InvocationInfo.BoundParameters + + OutputDebug "Function '$callerName' called with parameters:" + if ($callerParameters.Count -eq 0) { + OutputDebug "None" + } + foreach ($key in $callerParameters.Keys) { + $val = $callerParameters[$key] + OutputDebug "-$($key): $val" + } + } catch { + OutputDebug "Unable to retrieve function information from call stack." + } +} + +<# + .SYNOPSIS + Starts a console log group. + .DESCRIPTION + Starts a console log group. All subsequent log messages will be grouped under this message until OutputGroupEnd is called. + If running locally, it writes a simple message to the console. If running in GitHub Actions, it uses the `::group::` command to create a collapsible group in the log. + .PARAMETER Message + Name/Title of the group. +#> +function OutputGroupStart { + param ( + [Parameter(Mandatory = $true)] + [string] $Message + ) + + if ($runningLocal) { + Write-Host "==== Group start: $Message ====" + } else { + Write-Host "::group::$Message" + } +} + +<# + .SYNOPSIS + Ends a console log group. + .DESCRIPTION + Ends a console log group started with OutputGroupStart. All subsequent log messages will be outside of this group. +#> +function OutputGroupEnd { + if ($runningLocal) { + Write-Host "==== Group end ====" + } else { + Write-Host "::endgroup::" + } +} + +<# + .SYNOPSIS + Writes to console with optional color. + .DESCRIPTION + Writes a message to the console with an optional color. If no color is specified, the message is written in the default console color. + .PARAMETER Message + Message to be written to console. + .PARAMETER Color + Optional color for the message. Valid values are 'Red', 'Green', 'Yellow', 'Blue', 'Magenta', 'Cyan'. +#> +function OutputColor { + param ( + [Parameter(Mandatory = $true)] + [string] $Message, + [Parameter(Mandatory = $false)] + [ValidateSet('Red', 'Green', 'Yellow', 'Blue', 'Magenta', 'Cyan')] + [string] $Color + ) + + if ($Color) { + $colorCode = 0 + switch ($Color) { + 'Red' { $colorCode = $colorCodeRed } + 'Green' { $colorCode = $colorCodeGreen } + 'Yellow' { $colorCode = $colorCodeYellow } + 'Blue' { $colorCode = $colorCodeBlue } + 'Magenta' { $colorCode = $colorCodeMagenta } + 'Cyan' { $colorCode = $colorCodeCyan } + } + # char 27 is the escape character for ANSI codes which works in both PS 5 and 7. + Write-Host "$([char] 27)[${colorCode}m$Message$([char] 27)[0m" + } else { + Write-Host $Message + } +} + +<# + .SYNOPSIS + Write an error message to the console. + .DESCRIPTION + Writes an error message to the console. Throws an exception if running locally, otherwise formats the message for GitHub Actions. + .PARAMETER Message + Message to be written to console. +#> +function OutputError { + Param( + [string] $message + ) + + if ($runningLocal) { + throw $message + } + else { + Write-Host "::Error::$($message.Replace("`r",'').Replace("`n",' '))" + $host.SetShouldExit(1) + } +} + +<# + .SYNOPSIS + Write a warning message to the console. + .DESCRIPTION + Writes a warning message to the console. Uses Write-Warning if running locally, otherwise formats the message for GitHub Actions. + .PARAMETER Message + Message to be written to console. +#> +function OutputWarning { + Param( + [string] $message + ) + + if ($runningLocal) { + Write-Warning $message + } + else { + Write-Host "::Warning::$message" + } +} + +<# + .SYNOPSIS + Write a notice message to the console. + .DESCRIPTION + Writes a notice message to the console. Uses regular Write-Host if running locally, otherwise formats the message for GitHub Actions. + .PARAMETER Message + Message to be written to console. +#> +function OutputNotice { + Param( + [string] $message + ) + + if ($runningLocal) { + Write-Host $message + } + else { + Write-Host "::Notice::$message" + } +} + +<# + .SYNOPSIS + Mask a value in the log. + .DESCRIPTION + Masks a value in the log to prevent sensitive information from being displayed. If running locally, it writes the masked value to the console. + .PARAMETER Value + The value to be masked in the log. +#> +function MaskValueInLog { + Param( + [string] $value + ) + + if (!$runningLocal) { + Write-Host "`r::add-mask::$value" + } +} + +<# + .SYNOPSIS + Write a debug message to the console. + .DESCRIPTION + Writes a debug message to the console. Uses Write-Debug if running locally, otherwise formats the message for GitHub Actions. + .PARAMETER Message + Message to be written to console. +#> +function OutputDebug { + Param( + [string] $message + ) + + if ($runningLocal) { + Write-Debug $message + } + else { + Write-Host "::Debug::[AL-Go]$message" + } +} + +Export-ModuleMember -Function OutputColor, OutputDebugFunctionCall, OutputGroupStart, OutputGroupEnd, OutputError, OutputWarning, OutputNotice, MaskValueInLog, OutputDebug +Export-ModuleMember -Variable debugLoggingEnabled diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index cddbd9ddc..1e5d3a8bc 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -4,6 +4,7 @@ Param( $gitHubHelperPath = Join-Path $PSScriptRoot 'Github-Helper.psm1' $readSettingsModule = Join-Path $PSScriptRoot '.Modules/ReadSettings.psm1' +$debugLoggingModule = Join-Path $PSScriptRoot '.Modules/DebugLogHelper.psm1' if (Test-Path $gitHubHelperPath) { Import-Module $gitHubHelperPath # If we are adding more dependencies here, then localDevEnv and cloudDevEnv needs to be updated @@ -13,6 +14,10 @@ if (Test-Path $readSettingsModule) { Import-Module $readSettingsModule } +if (Test-Path $debugLoggingModule) { + Import-Module $debugLoggingModule +} + $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 $ALGoFolderName = '.AL-Go' @@ -22,7 +27,6 @@ $RepoSettingsFile = Join-Path '.github' 'AL-Go-Settings.json' $defaultCICDPushBranches = @( 'main', 'release/*', 'feature/*' ) [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', 'defaultCICDPullRequestBranches', Justification = 'False positive.')] $defaultCICDPullRequestBranches = @( 'main' ) -$runningLocal = $local.IsPresent $defaultBcContainerHelperVersion = "preview" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step - ex. "https://github.com/organization/navcontainerhelper/archive/refs/heads/branch.zip" $notSecretProperties = @("Scopes","TenantId","BlobName","ContainerName","StorageAccountName","ServerUrl","ppUserName","GitHubAppClientId","EnvironmentName") @@ -183,69 +187,6 @@ function ConvertTo-HashTable() { } } -function OutputError { - Param( - [string] $message - ) - - if ($runningLocal) { - throw $message - } - else { - Write-Host "::Error::$($message.Replace("`r",'').Replace("`n",' '))" - $host.SetShouldExit(1) - } -} - -function OutputWarning { - Param( - [string] $message - ) - - if ($runningLocal) { - Write-Host -ForegroundColor Yellow "WARNING: $message" - } - else { - Write-Host "::Warning::$message" - } -} - -function OutputNotice { - Param( - [string] $message - ) - - if ($runningLocal) { - Write-Host $message - } - else { - Write-Host "::Notice::$message" - } -} - -function MaskValueInLog { - Param( - [string] $value - ) - - if (!$runningLocal) { - Write-Host "`r::add-mask::$value" - } -} - -function OutputDebug { - Param( - [string] $message - ) - - if ($runningLocal) { - Write-Host $message - } - else { - Write-Host "::Debug::$message" - } -} - function GetUniqueFolderName { Param( [string] $baseFolder, diff --git a/Actions/DetermineDeploymentEnvironments/DetermineDeploymentEnvironments.ps1 b/Actions/DetermineDeploymentEnvironments/DetermineDeploymentEnvironments.ps1 index f94f1baee..0a27f9e42 100644 --- a/Actions/DetermineDeploymentEnvironments/DetermineDeploymentEnvironments.ps1 +++ b/Actions/DetermineDeploymentEnvironments/DetermineDeploymentEnvironments.ps1 @@ -5,10 +5,13 @@ [ValidateSet('CD','Publish','All')] [string] $type ) +OutputDebugFunctionCall function IsGitHubPagesAvailable() { + OutputDebugFunctionCall $headers = GetHeaders -token $env:GITHUB_TOKEN $url = "$($ENV:GITHUB_API_URL)/repos/$($ENV:GITHUB_REPOSITORY)/pages" + OutputDebug "Url: $url" try { Write-Host "Requesting GitHub Pages settings from GitHub" $ghPages = (InvokeWebRequest -Headers $headers -Uri $url).Content | ConvertFrom-Json @@ -20,8 +23,10 @@ function IsGitHubPagesAvailable() { } function GetGitHubEnvironments() { + OutputDebugFunctionCall $headers = GetHeaders -token $env:GITHUB_TOKEN $url = "$($ENV:GITHUB_API_URL)/repos/$($ENV:GITHUB_REPOSITORY)/environments" + OutputDebug "Url: $url" try { Write-Host "Requesting environments from GitHub" $ghEnvironments = @(((InvokeWebRequest -Headers $headers -Uri $url).Content | ConvertFrom-Json).environments) @@ -34,6 +39,7 @@ function GetGitHubEnvironments() { } function Get-BranchesFromPolicy($ghEnvironment) { + OutputDebugFunctionCall if ($ghEnvironment) { # Environment is defined in GitHub - check protection rules $headers = GetHeaders -token $env:GITHUB_TOKEN diff --git a/Actions/Invoke-AlGoAction.ps1 b/Actions/Invoke-AlGoAction.ps1 index 70360ac8b..854cf9021 100644 --- a/Actions/Invoke-AlGoAction.ps1 +++ b/Actions/Invoke-AlGoAction.ps1 @@ -14,6 +14,7 @@ $progressPreference = "SilentlyContinue" Set-StrictMode -Version 2.0 Import-Module (Join-Path -Path $PSScriptRoot -ChildPath "TelemetryHelper.psm1" -Resolve) +Import-Module (Join-Path -Path $PSScriptRoot -ChildPath ".Modules/DebugLogHelper.psm1" -Resolve) try { $startTime = Get-Date diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 77d47b039..3a72d9985 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -9,6 +9,10 @@ AL-Go now offers a dataexplorer dashboard to get started with AL-Go telemetry. A - Issue 1722 Check if apps are already installed on a higher version before deploying - Issue 1774 Increment Version Number with +0.1 can increment some version numbers twice +### Additional debug logging functionality + +We have improved how logging is handled in AL-Go, and now make better use of GitHub built-in extended debug logging functionality. Extended debug logging can be enabled when re-running actions by clicking the 'Enable debug logging' checkbox in the pop-up window. This can be done both for jobs that failed and jobs that succeeded, but did not produce the correct result. + ### Add custom jobs to AL-Go workflows It is now possible to add custom jobs to AL-Go workflows. The Custom Job needs to be named `CustomJob` and should be placed after all other jobs in the .yaml file. The order of which jobs are executed is determined by the Needs statements. Your custom job will be executed after all jobs specified in the Needs clause in your job and if you need the job to be executed before other jobs, you should add the job name in the Needs clause of that job. See [https://aka.ms/algosettings#customjobs](https://aka.ms/algosettings#customjobs) for details. diff --git a/Templates/AppSource App/.AL-Go/cloudDevEnv.ps1 b/Templates/AppSource App/.AL-Go/cloudDevEnv.ps1 index a07cdb19a..e4f79e668 100644 --- a/Templates/AppSource App/.AL-Go/cloudDevEnv.ps1 +++ b/Templates/AppSource App/.AL-Go/cloudDevEnv.ps1 @@ -53,12 +53,14 @@ $tmpFolder = Join-Path ([System.IO.Path]::GetTempPath()) "$([Guid]::NewGuid().To New-Item -Path $tmpFolder -ItemType Directory -Force | Out-Null $GitHubHelperPath = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/Github-Helper.psm1' -folder $tmpFolder -notifyAuthenticatedAttempt $ReadSettingsModule = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/.Modules/ReadSettings.psm1' -folder $tmpFolder +$debugLoggingModule = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/.Modules/DebugLogHelper.psm1' -folder $tmpFolder $ALGoHelperPath = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/AL-Go-Helper.ps1' -folder $tmpFolder DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/settings.schema.json' -folder $tmpFolder | Out-Null DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/Packages.json' -folder $tmpFolder | Out-Null Import-Module $GitHubHelperPath Import-Module $ReadSettingsModule +Import-Module $debugLoggingModule . $ALGoHelperPath -local $baseFolder = GetBaseFolder -folder $PSScriptRoot diff --git a/Templates/AppSource App/.AL-Go/localDevEnv.ps1 b/Templates/AppSource App/.AL-Go/localDevEnv.ps1 index 80622d5d0..e89df2b3e 100644 --- a/Templates/AppSource App/.AL-Go/localDevEnv.ps1 +++ b/Templates/AppSource App/.AL-Go/localDevEnv.ps1 @@ -57,12 +57,14 @@ $tmpFolder = Join-Path ([System.IO.Path]::GetTempPath()) "$([Guid]::NewGuid().To New-Item -Path $tmpFolder -ItemType Directory -Force | Out-Null $GitHubHelperPath = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/Github-Helper.psm1' -folder $tmpFolder -notifyAuthenticatedAttempt $ReadSettingsModule = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/.Modules/ReadSettings.psm1' -folder $tmpFolder +$debugLoggingModule = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/.Modules/DebugLogHelper.psm1' -folder $tmpFolder $ALGoHelperPath = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/AL-Go-Helper.ps1' -folder $tmpFolder DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/settings.schema.json' -folder $tmpFolder | Out-Null DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/Packages.json' -folder $tmpFolder | Out-Null Import-Module $GitHubHelperPath Import-Module $ReadSettingsModule +Import-Module $debugLoggingModule . $ALGoHelperPath -local $baseFolder = GetBaseFolder -folder $PSScriptRoot diff --git a/Templates/Per Tenant Extension/.AL-Go/cloudDevEnv.ps1 b/Templates/Per Tenant Extension/.AL-Go/cloudDevEnv.ps1 index a07cdb19a..e4f79e668 100644 --- a/Templates/Per Tenant Extension/.AL-Go/cloudDevEnv.ps1 +++ b/Templates/Per Tenant Extension/.AL-Go/cloudDevEnv.ps1 @@ -53,12 +53,14 @@ $tmpFolder = Join-Path ([System.IO.Path]::GetTempPath()) "$([Guid]::NewGuid().To New-Item -Path $tmpFolder -ItemType Directory -Force | Out-Null $GitHubHelperPath = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/Github-Helper.psm1' -folder $tmpFolder -notifyAuthenticatedAttempt $ReadSettingsModule = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/.Modules/ReadSettings.psm1' -folder $tmpFolder +$debugLoggingModule = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/.Modules/DebugLogHelper.psm1' -folder $tmpFolder $ALGoHelperPath = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/AL-Go-Helper.ps1' -folder $tmpFolder DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/settings.schema.json' -folder $tmpFolder | Out-Null DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/Packages.json' -folder $tmpFolder | Out-Null Import-Module $GitHubHelperPath Import-Module $ReadSettingsModule +Import-Module $debugLoggingModule . $ALGoHelperPath -local $baseFolder = GetBaseFolder -folder $PSScriptRoot diff --git a/Templates/Per Tenant Extension/.AL-Go/localDevEnv.ps1 b/Templates/Per Tenant Extension/.AL-Go/localDevEnv.ps1 index 80622d5d0..e89df2b3e 100644 --- a/Templates/Per Tenant Extension/.AL-Go/localDevEnv.ps1 +++ b/Templates/Per Tenant Extension/.AL-Go/localDevEnv.ps1 @@ -57,12 +57,14 @@ $tmpFolder = Join-Path ([System.IO.Path]::GetTempPath()) "$([Guid]::NewGuid().To New-Item -Path $tmpFolder -ItemType Directory -Force | Out-Null $GitHubHelperPath = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/Github-Helper.psm1' -folder $tmpFolder -notifyAuthenticatedAttempt $ReadSettingsModule = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/.Modules/ReadSettings.psm1' -folder $tmpFolder +$debugLoggingModule = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/.Modules/DebugLogHelper.psm1' -folder $tmpFolder $ALGoHelperPath = DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/AL-Go-Helper.ps1' -folder $tmpFolder DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/settings.schema.json' -folder $tmpFolder | Out-Null DownloadHelperFile -url 'https://raw.githubusercontent.com/microsoft/AL-Go-Actions/main/Packages.json' -folder $tmpFolder | Out-Null Import-Module $GitHubHelperPath Import-Module $ReadSettingsModule +Import-Module $debugLoggingModule . $ALGoHelperPath -local $baseFolder = GetBaseFolder -folder $PSScriptRoot diff --git a/Tests/TestActionsHelper.psm1 b/Tests/TestActionsHelper.psm1 index 76d6f6f28..95bcc85dd 100644 --- a/Tests/TestActionsHelper.psm1 +++ b/Tests/TestActionsHelper.psm1 @@ -2,6 +2,8 @@ $env:GITHUB_OUTPUT = [System.IO.Path]::GetTempFileName() +Import-Module (Join-Path $PSScriptRoot '../Actions/.Modules/DebugLogHelper.psm1') -Global + function iReplace { Param( [string] $string,