Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
de9d2ca
Add separate RunTests action gated by useSeparateTestAction
spetersenms Aug 6, 2026
6550465
Documentation cleanup and skip action when relevant.
spetersenms Aug 6, 2026
d375a8b
Merge branch 'main' into spetersen/separateTestAction
spetersenms Aug 7, 2026
cd2c03a
Fix failing tests
spetersenms Aug 7, 2026
d3b320f
Merge branch 'main' into spetersen/separateTestAction
spetersenms Aug 7, 2026
b015e22
Use AlTool as the default test runner in the RunTests action
spetersenms Aug 7, 2026
3ab5c81
Remove unsupported altool --testplan batching from RunTests
spetersenms Aug 10, 2026
262babf
Handle array in PS5
spetersenms Aug 10, 2026
12f6088
respect additionalCountries setting and disabledTests
spetersenms Aug 17, 2026
c9c3fbd
Run AlTool as native command to correctly handle terminating errors.
spetersenms Aug 17, 2026
a37d187
Filter out BCPT tests.
spetersenms Aug 17, 2026
07af75e
Re-run only missing results.
spetersenms Aug 17, 2026
46c8b8c
Copy TestResults.xml to artifacts folder.
spetersenms Aug 17, 2026
4d3ae9a
Export event logs from container.
spetersenms Aug 19, 2026
2f2f009
Cleanup documentation
spetersenms Aug 19, 2026
3885bca
Use AlTool batching feature and cleanup implementation.
spetersenms Aug 19, 2026
499eb15
Pre install Altool before Al test runner is invoked. Simplify test va…
spetersenms Aug 20, 2026
cd26ae8
Additional error handling and function documentation.
spetersenms Aug 20, 2026
85dbd27
Simplified Invoke-AlNativeCommand
spetersenms Aug 21, 2026
dcf9461
Simplified AlTool output parsing.
spetersenms Aug 21, 2026
5e6300b
Simplified parse check
spetersenms Aug 21, 2026
e64e58d
Write warning on eventlog capture failure instead of throwing
spetersenms Aug 24, 2026
5bf9179
Return App Path, Id and Name from Get-TestAppsToRun function.
spetersenms Aug 24, 2026
515c8fa
Cleanup of old snippets, gates and unused params
spetersenms Aug 25, 2026
723d846
Removed RunPipelineTests
spetersenms Aug 25, 2026
3d169c2
Merge branch 'main' into spetersen/separateTestAction
spetersenms Aug 25, 2026
cdb9641
Settings schema default value added. Installing AlTool to user folder…
spetersenms Aug 25, 2026
656791c
Merge branch 'spetersen-microsoft-resolve-test-action-merge' into spe…
spetersenms Aug 25, 2026
36ee6b9
Merge main
spetersenms Aug 25, 2026
55141fb
Remove New-AlToolProject as it is no longer required.
spetersenms Aug 25, 2026
c1c775f
Parse codeunits as Ints
spetersenms Aug 25, 2026
b733a94
Support test types
spetersenms Aug 25, 2026
da8f233
Merge branch 'main' into spetersen/separateTestAction
spetersenms Aug 27, 2026
f3e0106
Merge branch 'main' into spetersen/separateTestAction
spetersenms Aug 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Actions/.Modules/ReadSettings.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ function GetDefaultSettings
"doNotBuildTests" = $false
"doNotPerformUpgrade" = $false
"doNotRunTests" = $false
"useSeparateTestAction" = $false
"testType" = ""
"doNotRunBcptTests" = $false
"doNotRunPageScriptingTests" = $false
"doNotPublishApps" = $false
Expand Down
10 changes: 10 additions & 0 deletions Actions/.Modules/settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,16 @@
"doNotRunTests": {
"type": "boolean"
},
"useSeparateTestAction": {
"type": "boolean",
"default": false,
"description": "PREVIEW: When set to true, normal tests (testFolders) run in a separate RunTests action against the build container kept alive by RunPipeline. Builds with additionalCountries continue to run normal tests inside RunPipeline so every country is tested. See https://aka.ms/ALGoSettings#useSeparateTestAction"
},
"testType": {
"type": "string",
"default": "",
"description": "Optional test type used by the separate RunTests action. The built-in AlTool runner supports UnitTest, IntegrationTest, and Uncategorized; blank runs all test types. Custom RunTestsInBcContainer overrides may interpret other values. See https://aka.ms/ALGoSettings#testType"
},
"doNotRunBcptTests": {
"type": "boolean"
},
Expand Down
7 changes: 5 additions & 2 deletions Actions/AnalyzeTests/TestResultAnalyzer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,14 @@ function GetTestResultSummaryMD {
$suiteFailureNode = [FailureNode]::new($false)
$suiteFailureNode.summaryDetails = "$($suite.name), $($suite.tests) tests, $($suite.failures) failed, $($suite.skipped) skipped, $($suite.time) seconds"
foreach($testcase in $suite.testcase) {
if ($testcase.ChildNodes.Count -gt 0) {
$failureNodes = @($testcase.ChildNodes | Where-Object {
$_.NodeType -eq [System.Xml.XmlNodeType]::Element -and $_.LocalName -eq 'failure'
})
if ($failureNodes.Count -gt 0) {
Write-Host " - $($testcase.name), Failure, $($testcase.time) seconds"
$testCaseFailureNode = [FailureNode]::new($false)
$testCaseFailureNode.summaryDetails = "$($testcase.name), Failure"
foreach($failure in $testcase.ChildNodes) {
foreach($failure in $failureNodes) {
Write-Host " - Error: $($failure.message)"
Write-Host " Stacktrace:"
Write-Host " $($failure.InnerText.Trim().Replace("`n","`n "))"
Expand Down
2 changes: 2 additions & 0 deletions Actions/RunPipeline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Run pipeline in AL-Go repository
| Name | Description |
| :-- | :-- |
| containerName | Container name of a container used during build |
| containerCredential | Masked, base64-encoded JSON credential for reconnecting to a container kept alive for the RunTests action |
| runTestsInSeparateAction | True only when RunPipeline kept a single local build container alive for the RunTests action |

## OUTPUT variables

Expand Down
39 changes: 39 additions & 0 deletions Actions/RunPipeline/RunPipeline.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ Param(
[string] $previousAppsPath = ''
)

function New-KeepAliveContainerCredential {
Comment thread
spetersenms marked this conversation as resolved.
<#
.SYNOPSIS
Creates a credential for a build container kept alive for the RunTests action.
.DESCRIPTION
Returns a random administrator credential so the RunTests action can reconnect to the
container after RunPipeline completes.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'A container password must be generated as plain text to build a reusable credential')]
param()
$password = "Pass!$([GUID]::NewGuid().ToString())"
return (New-Object pscredential 'admin', (ConvertTo-SecureString -String $password -AsPlainText -Force))
}

$containerBaseFolder = $null
$projectPath = $null

Expand Down Expand Up @@ -473,6 +487,30 @@ try {
$runAlPipelineParams["preprocessorsymbols"] = $settings.preprocessorSymbols
$runAlPipelineParams["features"] = $settings.features

# The separate action needs one local container that remains alive after RunPipeline. Multi-country
# builds keep normal tests here because Run-AlPipeline creates and tests a container per country.
$runTestsInSeparateAction = $settings.useSeparateTestAction -and -not $settings.doNotRunTests -and -not $settings.doNotPublishApps -and @($additionalCountries).Count -eq 0
Add-Content -Encoding UTF8 -Path $env:GITHUB_ENV -Value "runTestsInSeparateAction=$runTestsInSeparateAction"

if ($runTestsInSeparateAction) {
Write-Host "useSeparateTestAction is enabled: skipping normal test execution in RunPipeline and keeping the container alive for the RunTests action"
$runAlPipelineParams["doNotRunTests"] = $true

# Surface a reusable credential so RunTests can reconnect to the kept-alive container.
$containerCredential = New-KeepAliveContainerCredential
$runAlPipelineParams["credential"] = $containerCredential

$containerCredentialPassword = $containerCredential.GetNetworkCredential().Password
$containerCredentialJson = @{ "username" = $containerCredential.UserName; "password" = $containerCredentialPassword } | ConvertTo-Json -Compress
$containerCredentialBase64 = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($containerCredentialJson))
Write-Host "::add-mask::$containerCredentialPassword"
Write-Host "::add-mask::$containerCredentialBase64"
Add-Content -Encoding UTF8 -Path $env:GITHUB_ENV -Value "containerCredential=$containerCredentialBase64"
}
elseif ($settings.useSeparateTestAction -and -not $settings.doNotRunTests) {
Write-Host "::Notice::useSeparateTestAction is enabled, but either additionalCountries is configured or no local build container is created. The separate RunTests action will be skipped."
}

Write-Host "Invoke Run-AlPipeline with buildmode $buildMode"
Run-AlPipeline @runAlPipelineParams `
-accept_insiderEula `
Expand Down Expand Up @@ -518,6 +556,7 @@ try {
-pageScriptingTestResultsFolder (Join-Path $buildArtifactFolder 'PageScriptingTestResultDetails') `
-CreateRuntimePackages:$CreateRuntimePackages `
-appVersion ($versionNumber.MajorMinorVersion) -appBuild ($versionNumber.BuildNumber) -appRevision ($versionNumber.RevisionNumber) `
-keepContainer:$runTestsInSeparateAction `
-uninstallRemovedApps

if ($containerBaseFolder) {
Expand Down
Loading
Loading