From bf7ff5362bdb5c498ab037a4be1cd9f3402feac1 Mon Sep 17 00:00:00 2001 From: Stefan Maron Date: Wed, 18 Mar 2026 12:21:59 +0100 Subject: [PATCH 1/4] Document global continuousDeployment setting Add documentation for the new top-level `continuousDeployment` setting that provides a global default for all environments, overridable per environment via DeployTo.ContinuousDeployment. --- Scenarios/settings.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Scenarios/settings.md b/Scenarios/settings.md index c11a181aa..ed00399e1 100644 --- a/Scenarios/settings.md +++ b/Scenarios/settings.md @@ -131,6 +131,7 @@ The repository settings are only read from the repository settings file (.github | enableTaskScheduler | Setting enableTaskScheduler to true in your project setting file, causes the build container to be created with the Task Scheduler running. | false | | useCompilerFolder | Setting useCompilerFolder to true causes your pipelines to use containerless compiling. Unless you also set **doNotPublishApps** to true, setting useCompilerFolder to true won't give you any performance advantage, since AL-Go for GitHub will still need to create a container in order to publish and test the apps. In the future, publishing and testing will be split from building and there will be other options for getting an instance of Business Central for publishing and testing. **Note** when using UseCompilerFolder you need to sign apps using the new signing mechanism described [here](../Scenarios/Codesigning.md). | false | | excludeEnvironments | excludeEnvironments can be an array of GitHub Environments, which should be excluded from the list of environments considered for deployment. github-pages is automatically added to this array and cannot be used as environment for deployment of AL-Go for GitHub projects. | [ ] | +| continuousDeployment | Global default for continuous deployment. When set, this overrides the per-environment default (which is based on environment name conventions), but is itself overridden by any per-environment **DeployTo\.ContinuousDeployment** setting. Set to **false** to disable automatic CD for all environments globally — for example in an organization settings variable — while still allowing manual deployment via the **Publish To Environment** workflow. Per-environment settings can then opt back in by setting `DeployTo: { continuousDeployment: true }`. | (not set — falls back to per-environment name convention) | | trustMicrosoftNuGetFeeds | Unless this setting is set to false, AL-Go for GitHub will trust the NuGet feeds provided by Microsoft. The feeds provided by Microsoft contains all Microsoft apps, all Microsoft symbols and symbols for all AppSource apps. | true | | trustedNuGetFeeds | trustedNuGetFeeds can be an array of NuGet feed specifications, which AL-Go for GitHub will use for dependency resolution. Every feed specification must include a URL property and can optionally include a few other properties:
**url** = The URL of the feed (examples: https://pkgs.dev.azure.com/myorg/apps/\_packaging/myrepo/nuget/v3/index.json or https://nuget.pkg.github.com/mygithuborg/index.json").
**authTokenSecret** = If the NuGet feed specified by URL is private, the authTokenSecret must be the name of a secret containing the authentication token with permissions to search and read packages from the NuGet feed.
**patterns** = AL-Go for GitHub will only trust packages, where the ID matches this pattern. Default is all packages (\*).
**fingerprints** = If specified, AL-Go for GitHub will only trust packages signed with a certificate with a fingerprint matching one of the fingerprints in this array. | [ ] | | nuGetFeedSelectMode | Determines the select mode when finding Business Central app packages from NuGet feeds, based on the dependency version specified in app.json. Options are:
- `Earliest` for earliest version of the package
- `EarliestMatching` for earliest version of the package also compatible with the Business Central version used
- `Exact` for the exact version of the package
- `Latest` for the latest version of the package
- `LatestMatching` for the latest version of the package also compatible with the Business Central version used. | LatestMatching | From b33f3da35fdcac33019ee5dc7ea25d05fe0f7cf3 Mon Sep 17 00:00:00 2001 From: Stefan Maron Date: Wed, 18 Mar 2026 13:20:29 +0100 Subject: [PATCH 2/4] Add global continuousDeployment setting Allow users to set a global `continuousDeployment` default at the repository or organization settings level, rather than requiring per-environment `DeployTo.ContinuousDeployment` entries for every environment. The new top-level `continuousDeployment` setting acts as a fallback: it is applied to an environment only when no per-environment setting is present. Per-environment DeployTo.ContinuousDeployment still takes precedence, preserving full backwards compatibility. Setting `continuousDeployment: false` in an organization settings variable (ALGoOrgSettings) disables automatic CD across all repos and all environments, while leaving the manual Publish To Environment workflow unaffected (it uses type 'Publish', which ignores this flag). The schema allows boolean and null to match the runtime semantics, where null means "unset - fall back to name-based convention". --- Actions/.Modules/ReadSettings.psm1 | 1 + Actions/.Modules/settings.schema.json | 4 ++ .../DetermineDeploymentEnvironments.ps1 | 5 ++ .../DetermineDeploymentEnvironments.Test.ps1 | 66 +++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/Actions/.Modules/ReadSettings.psm1 b/Actions/.Modules/ReadSettings.psm1 index d8ea49ff3..cd8c99745 100644 --- a/Actions/.Modules/ReadSettings.psm1 +++ b/Actions/.Modules/ReadSettings.psm1 @@ -220,6 +220,7 @@ function GetDefaultSettings } "fullBuildPatterns" = @() "excludeEnvironments" = @() + "continuousDeployment" = $null "alDoc" = [ordered]@{ "continuousDeployment" = $false "deployToGitHubPages" = $true diff --git a/Actions/.Modules/settings.schema.json b/Actions/.Modules/settings.schema.json index 419fdac01..287731f61 100644 --- a/Actions/.Modules/settings.schema.json +++ b/Actions/.Modules/settings.schema.json @@ -561,6 +561,10 @@ }, "description": "An array of environments to be excluded from the build. See https://aka.ms/ALGoSettings#excludeenvironments" }, + "continuousDeployment": { + "type": ["boolean", "null"], + "description": "Global default for continuous deployment. When set to false, disables automatic CD for all environments (overrides the name-based default, but not per-environment DeployTo.ContinuousDeployment). Set to null or omit to fall back to per-environment name conventions. See https://aka.ms/ALGoSettings#continuousdeployment" + }, "alDoc": { "type": "object", "properties": { diff --git a/Actions/DetermineDeploymentEnvironments/DetermineDeploymentEnvironments.ps1 b/Actions/DetermineDeploymentEnvironments/DetermineDeploymentEnvironments.ps1 index 6fc16f99e..462ae7f18 100644 --- a/Actions/DetermineDeploymentEnvironments/DetermineDeploymentEnvironments.ps1 +++ b/Actions/DetermineDeploymentEnvironments/DetermineDeploymentEnvironments.ps1 @@ -218,6 +218,11 @@ else { $ghEnvironment = $ghEnvironments | Where-Object { $_.name -eq $environmentName } $deploymentSettings.BranchesFromPolicy = @(Get-BranchesFromPolicy -ghEnvironment $ghEnvironment) + # If continuousDeployment is not set per-environment, check for a global continuousDeployment setting + if ($null -eq $deploymentSettings.continuousDeployment -and $null -ne $settings.continuousDeployment) { + $deploymentSettings.continuousDeployment = $settings.continuousDeployment + } + # Include Environment if: # - Type is not Continous Deployment # - Environment is setup for Continuous Deployment (in settings) diff --git a/Tests/DetermineDeploymentEnvironments.Test.ps1 b/Tests/DetermineDeploymentEnvironments.Test.ps1 index 6b90ef76a..5fc6ac52e 100644 --- a/Tests/DetermineDeploymentEnvironments.Test.ps1 +++ b/Tests/DetermineDeploymentEnvironments.Test.ps1 @@ -331,4 +331,70 @@ Describe "DetermineDeploymentEnvironments Action Test" { $EnvironmentCount | Should -Be 0 $UnknownEnvironment | Should -Be 0 } + + # Global continuousDeployment: false disables CD for all environments + It 'Test calling action directly - Global continuousDeployment=false disables CD for all environments' { + Mock InvokeWebRequest -ParameterFilter { $uri -like '*/environments' } -MockWith { + return @{"Content" = (ConvertTo-Json -Compress -Depth 99 -InputObject @{ "environments" = @( @{ "name" = "test"; "protection_rules" = @() }, @{ "name" = "another"; "protection_rules" = @() } ) })} + } + + # Global continuousDeployment=false - no environments should be included in CD + $settings = @{ "type" = "PTE"; "runs-on" = "ubuntu-latest"; "shell" = "pwsh"; "environments" = @(); "excludeEnvironments" = @( 'github-pages' ); "continuousDeployment" = $false; "alDoc" = @{ "continuousDeployment" = $false; "deployToGitHubPages" = $false } } + $env:Settings = $settings | ConvertTo-Json -Compress + . (Join-Path $scriptRoot $scriptName) -getEnvironments '*' -type 'CD' + PassGeneratedOutput + $EnvironmentCount | Should -Be 0 + } + + # Global continuousDeployment: false does not affect Publish + It 'Test calling action directly - Global continuousDeployment=false does not affect Publish' { + Mock InvokeWebRequest -ParameterFilter { $uri -like '*/environments' } -MockWith { + return @{"Content" = (ConvertTo-Json -Compress -Depth 99 -InputObject @{ "environments" = @( @{ "name" = "test"; "protection_rules" = @() }, @{ "name" = "another"; "protection_rules" = @() } ) })} + } + + # Global continuousDeployment=false - Publish should still include all environments + $settings = @{ "type" = "PTE"; "runs-on" = "ubuntu-latest"; "shell" = "pwsh"; "environments" = @(); "excludeEnvironments" = @( 'github-pages' ); "continuousDeployment" = $false; "alDoc" = @{ "continuousDeployment" = $false; "deployToGitHubPages" = $false } } + $env:Settings = $settings | ConvertTo-Json -Compress + . (Join-Path $scriptRoot $scriptName) -getEnvironments 'test' -type 'Publish' + PassGeneratedOutput + $EnvironmentCount | Should -Be 1 + ($EnvironmentsMatrixJson | ConvertFrom-Json | ConvertTo-HashTable -recurse).matrix.include.environment | Should -Contain "test" + } + + # Per-environment setting overrides global continuousDeployment + It 'Test calling action directly - Per-environment continuousDeployment overrides global setting' { + Mock InvokeWebRequest -ParameterFilter { $uri -like '*/environments' } -MockWith { + return @{"Content" = (ConvertTo-Json -Compress -Depth 99 -InputObject @{ "environments" = @( @{ "name" = "test"; "protection_rules" = @() }, @{ "name" = "another"; "protection_rules" = @() } ) })} + } + + # Global=false but test environment opts back in with per-env setting + $settings = @{ + "type" = "PTE"; "runs-on" = "ubuntu-latest"; "shell" = "pwsh"; "environments" = @(); "excludeEnvironments" = @( 'github-pages' ) + "continuousDeployment" = $false + "DeployToTest" = @{ "continuousDeployment" = $true } + "alDoc" = @{ "continuousDeployment" = $false; "deployToGitHubPages" = $false } + } + $env:Settings = $settings | ConvertTo-Json -Compress -Depth 5 + . (Join-Path $scriptRoot $scriptName) -getEnvironments '*' -type 'CD' + PassGeneratedOutput + $EnvironmentCount | Should -Be 1 + ($EnvironmentsMatrixJson | ConvertFrom-Json | ConvertTo-HashTable -recurse).matrix.include.environment | Should -Contain "test" + ($EnvironmentsMatrixJson | ConvertFrom-Json | ConvertTo-HashTable -recurse).matrix.include.environment | Should -Not -Contain "another" + } + + # No global setting - existing name-based default behaviour is preserved + It 'Test calling action directly - No global continuousDeployment preserves existing name-based default' { + Mock InvokeWebRequest -ParameterFilter { $uri -like '*/environments' } -MockWith { + return @{"Content" = (ConvertTo-Json -Compress -Depth 99 -InputObject @{ "environments" = @( @{ "name" = "test (PROD)"; "protection_rules" = @() }, @{ "name" = "another"; "protection_rules" = @() } ) })} + } + + # No global continuousDeployment - PROD-tagged environment excluded, non-PROD included (existing behaviour) + $settings = @{ "type" = "PTE"; "runs-on" = "ubuntu-latest"; "shell" = "pwsh"; "environments" = @(); "excludeEnvironments" = @( 'github-pages' ); "alDoc" = @{ "continuousDeployment" = $false; "deployToGitHubPages" = $false } } + $env:Settings = $settings | ConvertTo-Json -Compress + . (Join-Path $scriptRoot $scriptName) -getEnvironments '*' -type 'CD' + PassGeneratedOutput + $EnvironmentCount | Should -Be 1 + ($EnvironmentsMatrixJson | ConvertFrom-Json | ConvertTo-HashTable -recurse).matrix.include.environment | Should -Contain "another" + ($EnvironmentsMatrixJson | ConvertFrom-Json | ConvertTo-HashTable -recurse).matrix.include.environment | Should -Not -Contain "test (PROD)" + } } From f1078f71b591a0445b42dfe821f17d17e3b505da Mon Sep 17 00:00:00 2001 From: Stefan Maron Date: Wed, 18 Mar 2026 13:33:37 +0100 Subject: [PATCH 3/4] Fix docs casing consistency: use PascalCase ContinuousDeployment to match existing DeployTo property docs --- Scenarios/settings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scenarios/settings.md b/Scenarios/settings.md index ed00399e1..a2982972a 100644 --- a/Scenarios/settings.md +++ b/Scenarios/settings.md @@ -131,7 +131,7 @@ The repository settings are only read from the repository settings file (.github | enableTaskScheduler | Setting enableTaskScheduler to true in your project setting file, causes the build container to be created with the Task Scheduler running. | false | | useCompilerFolder | Setting useCompilerFolder to true causes your pipelines to use containerless compiling. Unless you also set **doNotPublishApps** to true, setting useCompilerFolder to true won't give you any performance advantage, since AL-Go for GitHub will still need to create a container in order to publish and test the apps. In the future, publishing and testing will be split from building and there will be other options for getting an instance of Business Central for publishing and testing. **Note** when using UseCompilerFolder you need to sign apps using the new signing mechanism described [here](../Scenarios/Codesigning.md). | false | | excludeEnvironments | excludeEnvironments can be an array of GitHub Environments, which should be excluded from the list of environments considered for deployment. github-pages is automatically added to this array and cannot be used as environment for deployment of AL-Go for GitHub projects. | [ ] | -| continuousDeployment | Global default for continuous deployment. When set, this overrides the per-environment default (which is based on environment name conventions), but is itself overridden by any per-environment **DeployTo\.ContinuousDeployment** setting. Set to **false** to disable automatic CD for all environments globally — for example in an organization settings variable — while still allowing manual deployment via the **Publish To Environment** workflow. Per-environment settings can then opt back in by setting `DeployTo: { continuousDeployment: true }`. | (not set — falls back to per-environment name convention) | +| continuousDeployment | Global default for continuous deployment. When set, this overrides the per-environment default (which is based on environment name conventions), but is itself overridden by any per-environment **DeployTo\** setting with **ContinuousDeployment** specified. Set to **false** to disable automatic CD for all environments globally — for example in an organization settings variable — while still allowing manual deployment via the **Publish To Environment** workflow. Per-environment settings can then opt back in by setting **DeployTo\** with **ContinuousDeployment** = true. | (not set — falls back to per-environment name convention) | | trustMicrosoftNuGetFeeds | Unless this setting is set to false, AL-Go for GitHub will trust the NuGet feeds provided by Microsoft. The feeds provided by Microsoft contains all Microsoft apps, all Microsoft symbols and symbols for all AppSource apps. | true | | trustedNuGetFeeds | trustedNuGetFeeds can be an array of NuGet feed specifications, which AL-Go for GitHub will use for dependency resolution. Every feed specification must include a URL property and can optionally include a few other properties:
**url** = The URL of the feed (examples: https://pkgs.dev.azure.com/myorg/apps/\_packaging/myrepo/nuget/v3/index.json or https://nuget.pkg.github.com/mygithuborg/index.json").
**authTokenSecret** = If the NuGet feed specified by URL is private, the authTokenSecret must be the name of a secret containing the authentication token with permissions to search and read packages from the NuGet feed.
**patterns** = AL-Go for GitHub will only trust packages, where the ID matches this pattern. Default is all packages (\*).
**fingerprints** = If specified, AL-Go for GitHub will only trust packages signed with a certificate with a fingerprint matching one of the fingerprints in this array. | [ ] | | nuGetFeedSelectMode | Determines the select mode when finding Business Central app packages from NuGet feeds, based on the dependency version specified in app.json. Options are:
- `Earliest` for earliest version of the package
- `EarliestMatching` for earliest version of the package also compatible with the Business Central version used
- `Exact` for the exact version of the package
- `Latest` for the latest version of the package
- `LatestMatching` for the latest version of the package also compatible with the Business Central version used. | LatestMatching | From 70ad848a3af65e30b9df477b7c9e8b9f936318ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Maro=C5=84?= Date: Fri, 8 May 2026 11:23:29 +0200 Subject: [PATCH 4/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- Actions/.Modules/settings.schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Actions/.Modules/settings.schema.json b/Actions/.Modules/settings.schema.json index 287731f61..ffd60c4de 100644 --- a/Actions/.Modules/settings.schema.json +++ b/Actions/.Modules/settings.schema.json @@ -562,8 +562,8 @@ "description": "An array of environments to be excluded from the build. See https://aka.ms/ALGoSettings#excludeenvironments" }, "continuousDeployment": { - "type": ["boolean", "null"], - "description": "Global default for continuous deployment. When set to false, disables automatic CD for all environments (overrides the name-based default, but not per-environment DeployTo.ContinuousDeployment). Set to null or omit to fall back to per-environment name conventions. See https://aka.ms/ALGoSettings#continuousdeployment" + "type": "boolean", + "description": "Global default for continuous deployment. When set to false, disables automatic CD for all environments (overrides the name-based default, but not per-environment DeployTo.ContinuousDeployment). Omit to fall back to per-environment name conventions. See https://aka.ms/ALGoSettings#continuousdeployment" }, "alDoc": { "type": "object",