Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
9f340a5
Refactor logic for determining deployment environments and deployment…
mazhelez Oct 1, 2025
6c30380
Define $envName
mazhelez Oct 1, 2025
eba5267
Fix output names in CICD
mazhelez Oct 1, 2025
22c71c1
Fix tests for DetermineDeploymentEnvironments action
mazhelez Oct 2, 2025
fff2b22
Fix failing tests
mazhelez Oct 2, 2025
7ca7504
Fix PP tests
mazhelez Oct 2, 2025
3f06a03
Fix Deploy action README
mazhelez Oct 2, 2025
f6ea3f5
Merge branch 'main' into mazhelez/env-deployment-settings
mazhelez Oct 6, 2025
53a9959
Moving GetGithubEnvironments to AL-Go-Helper
spetersenms Oct 21, 2025
7086581
Handling DeployTo settings in ReadSettings.
spetersenms Oct 21, 2025
07e557b
Duplicating GetGitHubEnvironments function in both settings and deter…
spetersenms Oct 21, 2025
6d70703
Using contains instead of ContainsKey
spetersenms Oct 21, 2025
27a2435
Error handling
spetersenms Oct 21, 2025
3b59061
Helpful comment
spetersenms Oct 22, 2025
35e3a10
commenting out old solution to test new one
spetersenms Oct 22, 2025
26d3bb6
Adding environmentName param to GetArtifactsForDeployment action and …
spetersenms Oct 22, 2025
bf8d0cd
Corrected syntax
spetersenms Oct 22, 2025
2cc302c
Corrected syntax
spetersenms Oct 22, 2025
70eb24a
Cleanup
spetersenms Oct 22, 2025
6fb3915
Fixing tests
spetersenms Oct 22, 2025
b4bc562
test
spetersenms Oct 22, 2025
7ed8bea
Syntax fix
spetersenms Oct 22, 2025
a15b1fe
Converting settings object to hashtable
spetersenms Oct 22, 2025
2c623cc
Replicating changes in AppSource
spetersenms Oct 23, 2025
997ac61
pre-commit
spetersenms Oct 23, 2025
875d9ed
Merge branch 'main' into refactor
spetersenms Oct 23, 2025
5bfefa6
Additional debugging
spetersenms Oct 27, 2025
e3838a2
Handle build modes in reference documentation
spetersenms Oct 27, 2025
df96b60
cleanup
spetersenms Oct 27, 2025
5f9ed09
More testing.
spetersenms Oct 27, 2025
9bac73b
Syntax fix.
spetersenms Oct 27, 2025
ca5a850
Pre-commit and test fix
spetersenms Oct 28, 2025
e15ac8c
Moved GetGithubEnvironments to separate action.
spetersenms Oct 28, 2025
72c639d
Importing helpers
spetersenms Oct 28, 2025
ebdcee1
Debug
spetersenms Oct 28, 2025
6ed6a09
Using env instead of output
spetersenms Oct 28, 2025
5767d56
Cleanup tests
spetersenms Oct 29, 2025
91cb90d
Replicating action changes in both templates
spetersenms Oct 29, 2025
eda8044
Fix read settings test.
spetersenms Oct 29, 2025
56c6ce3
Changed githubEnvironmentsJson input to non required and added error …
spetersenms Oct 29, 2025
3f3da07
Aligned readme, yaml and script.
spetersenms Oct 29, 2025
ab86579
More tests.
spetersenms Oct 29, 2025
91ae068
Merge branch 'main' into refactor
spetersenms Oct 29, 2025
e824253
Fixed output name
spetersenms Oct 29, 2025
7b602a8
Merge branch 'refactor' of github.com:spetersenms/AL-Go into refactor
spetersenms Oct 29, 2025
cb83cd6
Merge branch 'main' into refactor
spetersenms Nov 12, 2025
e93967b
Merge branch 'main' into refactor
spetersenms Nov 18, 2025
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
87 changes: 86 additions & 1 deletion Actions/.Modules/ReadSettings.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ function ReadSettings {
[string] $repoSettingsVariableValue = "$ENV:ALGoRepoSettings",
[string] $environmentSettingsVariableValue = "$ENV:ALGoEnvSettings",
[string] $environmentName = "$ENV:ALGoEnvName",
[string] $customSettings = ""
[string] $customSettings = "",
[string] $githubEnvironmentsJson = ""
)

# If the build is triggered by a pull request the refname will be the merge branch. To apply conditional settings we need to use the base branch
Expand Down Expand Up @@ -549,6 +550,74 @@ function ReadSettings {
$settings.projectName = $project # Default to project path as project name
}

# Environments can come from three places: GitHub repo environments, settings.environments and the environmentName input of the PublishToEnvironment action
if ($githubEnvironmentsJson) {
$ghEnvironments = $githubEnvironmentsJson | ConvertFrom-Json
} else {
$ghEnvironments = @()
}

# $ghEnvironments = @(GetGitHubEnvironments)
$environments = @($ghEnvironments | ForEach-Object { $_.name }) + @($settings.environments) + @($environmentName) | Select-Object -unique | Where-Object { $_ -ne "" }

if ($environments) {
OutputDebug "$($environments.Count) Environment(s) defined: $($environments -join ', ')"
foreach ($environmentName in $environments) {
$envName = $environmentName.Split(' ')[0]
# Default deployment settings
$deploymentSettings = @{
"EnvironmentType" = "SaaS"
"EnvironmentName" = $envName
"Branches" = @()
"Projects" = @('*')
"DependencyInstallMode" = "install" # ignore, install, upgrade or forceUpgrade
"includeTestAppsInSandboxEnvironment" = $false
"excludeAppIds" = @()
"Scope" = $null
"SyncMode" = $null
"buildMode" = $null
"continuousDeployment" = $null
"runs-on" = $settings."runs-on"
"shell" = $settings."shell"
"companyId" = ''
"ppEnvironmentUrl" = ''
}
$settingsName = "DeployTo$envName"
if ($settings.Contains($settingsName)) {
# If a DeployTo<environmentName> setting exists - use values from this (over the defaults)
Write-Host "Using custom settings for environment $environmentName"
$deployTo = $settings."$settingsName"
$keys = @($deployTo.Keys)
foreach($key in $keys) {
if ($deploymentSettings.Contains($key)) {
if ($null -ne $deploymentSettings."$key" -and $null -ne $deployTo."$key" -and $deploymentSettings."$key".GetType().Name -ne $deployTo."$key".GetType().Name) {
if ($key -eq "runs-on" -and $deployTo."$key" -is [Object[]]) {
# Support setting runs-on as an array in settings to not break old settings
# See https://github.com/microsoft/AL-Go/issues/1182
$deployTo."$key" = $deployTo."$key" -join ','
}
else {
OutputWarning -message "The property $key in $settingsName is expected to be of type $($deploymentSettings."$key".GetType().Name)"
}
}
$deploymentSettings."$key" = $deployTo."$key"
}
}
if ($deploymentSettings."shell" -ne 'pwsh' -and $deploymentSettings."shell" -ne 'powershell') {
throw "The shell setting in $settingsName must be either 'pwsh' or 'powershell'"
}
if ($deploymentSettings."runs-on" -like "*ubuntu-*" -and $deploymentSettings."shell" -eq "powershell") {
Write-Host "Switching deployment shell to pwsh for ubuntu"
$deploymentSettings."shell" = "pwsh"
}
}
OutputDebug -message "Deployment settings for environment $($envName): $($deploymentSettings | ConvertTo-Json -Depth 5 -Compress)"
$settings."$settingsName" = $deploymentSettings
}
} else {
OutputDebug "No environments defined"
}

$settings | ValidateSettings

$settings
Expand Down Expand Up @@ -608,5 +677,21 @@ function SanitizeWorkflowName {
return $workflowName.Trim().Split([System.IO.Path]::getInvalidFileNameChars()) -join ""
}

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)
}
catch {
$ghEnvironments = @()
Write-Host "Failed to get environments from GitHub API - Environments are not supported in this repository"
}
$ghEnvironments
}

Export-ModuleMember -Function ReadSettings
Export-ModuleMember -Variable ALGoFolderName, ALGoSettingsFile, RepoSettingsFile, CustomTemplateRepoSettingsFile, CustomTemplateProjectSettingsFile
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,33 @@ $excludeProjects = $settings.alDoc.excludeProjects
$maxReleases = $settings.alDoc.maxReleases
$artifactsFolder = Join-Path $ENV:GITHUB_WORKSPACE ".artifacts"
$artifactsFolderCreated = $false
$buildModePrefixes = @()
if ($settings.PSObject.Properties.Name -contains "buildModes") {
$buildModes = $settings.buildModes
foreach($buildMode in $buildModes) {
if ($buildMode -eq 'default') {
$buildMode = ''
}
if (-not ($buildModePrefixes -contains $buildMode)) {
$buildModePrefixes += $buildMode
}
}
}
if ($buildModePrefixes.Count -eq 0) {
$buildModePrefixes += ''
}
Write-Host $buildModePrefixes
if (!(Test-Path $artifactsFolder)) {
New-Item $artifactsFolder -ItemType Directory | Out-Null
$artifactsFolderCreated = $true
}
if ($artifacts -ne ".artifacts") {
Write-Host "::group::Downloading artifacts"
$allArtifacts = @(GetArtifacts -token $token -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY -mask "Apps" -projects '*' -Version $artifacts -branch $ENV:GITHUB_REF_NAME)
$allArtifacts = @()
$buildModePrefixes | ForEach-Object {
$allArtifacts += @(GetArtifacts -token $token -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY -mask "$($_)Apps" -projects '*' -Version $artifacts -branch $ENV:GITHUB_REF_NAME)
}
# $allArtifacts = @(GetArtifacts -token $token -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY -mask "Apps" -projects '*' -Version $artifacts -branch $ENV:GITHUB_REF_NAME)
if ($allArtifacts) {
$allArtifacts | ForEach-Object {
$filename = DownloadArtifact -token $token -artifact $_ -path $artifactsFolder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ function ModifyBuildWorkflows {
# Modify Deliver and Deploy steps depending on build jobs
if ($deploy) {
$deploy.Replace('needs:', "needs: [ $($needs -join ', ') ]")
$deploy.Replace('if:', "if: (!cancelled())$ifpart && needs.Initialization.outputs.environmentCount > 0")
$deploy.Replace('if:', "if: (!cancelled())$ifpart && fromJson(needs.Initialization.outputs.deploymentEnvironmentsJson).environmentCount > 0")
$yaml.Replace('jobs:/Deploy:/', $deploy.content)
$postProcessNeeds += @('Deploy')
}
Expand Down
40 changes: 7 additions & 33 deletions Actions/Deploy/Deploy.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ Param(
[Parameter(HelpMessage = "Type of deployment (CD or Publish)", Mandatory = $false)]
[ValidateSet('CD','Publish')]
[string] $type = "CD",
[Parameter(HelpMessage = "The settings for all Deployment Environments", Mandatory = $true)]
[string] $deploymentEnvironmentsJson,
[Parameter(HelpMessage = "Artifacts version. Used to check if this is a deployment from a PR", Mandatory = $false)]
[string] $artifactsVersion = ''
)
Expand All @@ -18,41 +16,17 @@ Import-Module (Join-Path -Path $PSScriptRoot "Deploy.psm1")
. (Join-Path -Path $PSScriptRoot -ChildPath "..\AL-Go-Helper.ps1" -Resolve)
DownloadAndImportBcContainerHelper

$deploymentEnvironments = $deploymentEnvironmentsJson | ConvertFrom-Json | ConvertTo-HashTable -recurse
$deploymentSettings = $deploymentEnvironments."$environmentName"

$envName = $environmentName.Split(' ')[0]

$secrets = $env:Secrets | ConvertFrom-Json
$settings = $env:Settings | ConvertFrom-Json | ConvertTo-HashTable -recurse

# Check DeployTo<environmentName> setting (it could have been added in the environment-specific settings)
$settingsName = "DeployTo$envName"
if ($settings.ContainsKey($settingsName)) {
# If a DeployTo<environmentName> setting exists - use values from this (over the defaults)
Write-Host "Setting $settingsName"
$deployTo = $settings."$settingsName"
$keys = @($deployTo.Keys)
foreach($key in $keys) {
if ($deploymentSettings.ContainsKey($key)) {
if ($null -ne $deploymentSettings."$key" -and $null -ne $deployTo."$key" -and $deploymentSettings."$key".GetType().Name -ne $deployTo."$key".GetType().Name) {
if ($key -eq "runs-on" -and $deployTo."$key" -is [Object[]]) {
# Support setting runs-on as an array in settings to not break old settings
# See https://github.com/microsoft/AL-Go/issues/1182
$deployTo."$key" = $deployTo."$key" -join ','
}
else {
Write-Host "::WARNING::The property $key in $settingsName is expected to be of type $($deploymentSettings."$key".GetType().Name)"
}
}
Write-Host "Property $key = $($deployTo."$key")"
$deploymentSettings."$key" = $deployTo."$key"
}
else {
$deploymentSettings += @{
"$key" = $deployTo."$key"
}
}
}
$settingsName = "deployTo$($envName)"
if($settings.Keys -contains $settingsName) {
$deploymentSettings = ($settings."$settingsName") | ConvertTo-HashTable -recurse
OutputDebug -message "Using deployment settings: $($deploymentSettings | ConvertTo-Json -Depth 10)"
} else {
OutputError -message "No deployment settings found for environment $envName"
}

$authContext = $null
Expand Down
1 change: 0 additions & 1 deletion Actions/Deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Deploy Apps to online environment
| environmentName | Yes | Name of environment to deploy to |
| artifactsFolder | Yes | Path to the downloaded artifacts to deploy | |
| type | | Type of delivery (CD or Release) | CD |
| deploymentEnvironmentsJson | Yes | The settings for all Deployment Environments | |

## OUTPUT

Expand Down
6 changes: 1 addition & 5 deletions Actions/Deploy/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ inputs:
description: Type of deployment (CD or Publish)
required: false
default: 'CD'
deploymentEnvironmentsJson:
description: The settings for all Deployment Environments
required: true
artifactsVersion:
description: Artifacts version. Used to check if this is a deployment from a PR
required: false
Expand All @@ -41,11 +38,10 @@ runs:
_environmentName: ${{ inputs.environmentName }}
_artifactsFolder: ${{ inputs.artifactsFolder }}
_type: ${{ inputs.type }}
_deploymentEnvironmentsJson: ${{ inputs.deploymentEnvironmentsJson }}
_artifactsVersion: ${{ inputs.artifactsVersion }}
run: |
${{ github.action_path }}/../Invoke-AlGoAction.ps1 -ActionName "Deploy" -Action {
${{ github.action_path }}/Deploy.ps1 -token $ENV:_token -environmentName $ENV:_environmentName -artifactsFolder $ENV:_artifactsFolder -type $ENV:_type -deploymentEnvironmentsJson $ENV:_deploymentEnvironmentsJson -artifactsVersion $ENV:_artifactsVersion
${{ github.action_path }}/Deploy.ps1 -token $ENV:_token -environmentName $ENV:_environmentName -artifactsFolder $ENV:_artifactsFolder -type $ENV:_type -artifactsVersion $ENV:_artifactsVersion
}
branding:
icon: terminal
Expand Down
1 change: 0 additions & 1 deletion Actions/DeployPowerPlatform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Deploy the Power Platform solution from the artifacts folder
| environmentName | Yes | Name of environment to deploy to |
| artifactsFolder | | Path to the downloaded artifacts to deploy (when deploying from a build) | |
| solutionFolder | | Path to the unpacked solutions to deploy (when deploying from branch) | |
| deploymentEnvironmentsJson | Yes | The settings for all Deployment Environments | |

Either artifactsFolder or solutionFolder needs to be specified

Expand Down
9 changes: 5 additions & 4 deletions Actions/DeployPowerPlatform/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ inputs:
description: Path to the unpacked solution to deploy (when deploying from branch)
required: false
default: ''
deploymentEnvironmentsJson:
description: The settings for all Deployment Environments
required: true
runs:
using: composite
steps:
Expand All @@ -42,12 +39,16 @@ runs:
ref: ${{ env.actionsRef }}
path: ${{ env.actionsPath }}

- name: Read settings
uses: ./_AL-Go/Actions/ReadSettings@main
with:
shell: ${{ matrix.shell }}

- name: Parse DeployToSettings and AuthContext
id: ReadPowerPlatformSettings
uses: ./_AL-Go/Actions/ReadPowerPlatformSettings
with:
shell: ${{ inputs.shell }}
deploymentEnvironmentsJson: ${{ inputs.deploymentEnvironmentsJson }}
environmentName: ${{ inputs.environmentName }}

- name: Determine Power Platform solution location
Expand Down
Loading
Loading