From 0d19cb336fdda6a560c6ee17dbd6718533abf82d Mon Sep 17 00:00:00 2001 From: freddydk Date: Sat, 16 Dec 2023 09:08:54 +0100 Subject: [PATCH 01/62] no special naming --- Actions/AL-Go-Helper.ps1 | 2 +- Actions/Deliver/Deliver.ps1 | 3 --- Actions/RunPipeline/RunPipeline.ps1 | 6 +++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index 1c284ebc1..9bb0320be 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -18,7 +18,7 @@ $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 +$defaultBcContainerHelperVersion = "https://github.com/freddydk/navcontainerhelper/archive/refs/heads/renamecache.zip" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step $microsoftTelemetryConnectionString = "InstrumentationKey=84bd9223-67d4-4378-8590-9e4a46023be2;IngestionEndpoint=https://westeurope-1.in.applicationinsights.azure.com/" $notSecretProperties = @("Scopes","TenantId","BlobName","ContainerName","StorageAccountName","ServerUrl") diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index b10aac177..a4ebefddd 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -218,9 +218,6 @@ try { Get-Item -Path (Join-Path $folder[0] "*.app") | ForEach-Object { $parameters = @{ "gitHubRepository" = "$ENV:GITHUB_SERVER_URL/$ENV:GITHUB_REPOSITORY" - "includeNuGetDependencies" = $true - "dependencyIdTemplate" = "AL-Go-{id}" - "packageId" = "AL-Go-{id}" } $parameters.appFiles = $_.FullName $package = New-BcNuGetPackage @parameters diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index a60a20265..eaa97748e 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -302,7 +302,7 @@ try { $publishParams = @{ "nuGetServerUrl" = $gitHubPackagesCredential.serverUrl "nuGetToken" = $gitHubPackagesCredential.token - "packageName" = "AL-Go-$appId" + "packageName" = $appId "version" = $version } if ($parameters.ContainsKey('CopyInstalledAppsToFolder')) { @@ -311,10 +311,10 @@ try { } } if ($parameters.ContainsKey('containerName')) { - Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification @publishParams + Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification @publishParams -Verbose } else { - Copy-BcNuGetPackageToFolder -appSymbolsFolder $parameters.appSymbolsFolder @publishParams + Download-BcNuGetPackageToFolder -folder $parameters.appSymbolsFolder @publishParams -Verbose } } From f3eb2ee6de8784d8e8f6aa363011d7ff9021653b Mon Sep 17 00:00:00 2001 From: freddydk Date: Sat, 16 Dec 2023 09:38:41 +0100 Subject: [PATCH 02/62] add perpage --- Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 index 492e06735..d51830b92 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 @@ -28,7 +28,7 @@ function DownloadTemplateRepository { if ($downloadLatest) { # Get Branches from template repository - $response = InvokeWebRequest -Headers $headers -Uri "$apiUrl/branches" -retry + $response = InvokeWebRequest -Headers $headers -Uri "$apiUrl/branches?per_page=100" -retry $branchInfo = ($response.content | ConvertFrom-Json) | Where-Object { $_.Name -eq $branch } if (!$branchInfo) { throw "$templateUrl doesn't exist" From dc704ea7a9c921cee44e2304a91726bcccb0f6ba Mon Sep 17 00:00:00 2001 From: freddydk Date: Mon, 18 Dec 2023 12:02:35 +0100 Subject: [PATCH 03/62] add authtokenSecret for TrustedNuGetFeeds --- Actions/DownloadProjectDependencies/README.md | 2 +- Actions/ReadSecrets/README.md | 4 +-- Actions/ReadSecrets/ReadSecrets.ps1 | 25 ++++++++++++------- Actions/RunPipeline/RunPipeline.ps1 | 13 ++++++++++ .../.github/workflows/_BuildALGoProject.yaml | 2 +- .../.github/workflows/_BuildALGoProject.yaml | 2 +- 6 files changed, 34 insertions(+), 14 deletions(-) diff --git a/Actions/DownloadProjectDependencies/README.md b/Actions/DownloadProjectDependencies/README.md index 24774fb61..f56e3f135 100644 --- a/Actions/DownloadProjectDependencies/README.md +++ b/Actions/DownloadProjectDependencies/README.md @@ -9,7 +9,7 @@ The action constructs arrays of paths to .app files, that are dependencies of th | Name | Description | | :-- | :-- | | Settings | env.Settings must be set by a prior call to the ReadSettings Action | -| Secrets | env.Secrets must be read by a prior call to the ReadSecrets Action with appDependencyProbingPathsSecrets in getSecrets | +| Secrets | env.Secrets must be read by a prior call to the ReadSecrets Action with appDependencySecrets in getSecrets | ### Parameters | Name | Required | Description | Default value | diff --git a/Actions/ReadSecrets/README.md b/Actions/ReadSecrets/README.md index d67b2c9c0..bc4576aa3 100644 --- a/Actions/ReadSecrets/README.md +++ b/Actions/ReadSecrets/README.md @@ -1,7 +1,7 @@ # Read secrets Read secrets from GitHub secrets or Azure Keyvault for AL-Go workflows The secrets read and added to the output are the secrets specified in the getSecrets parameter -Additionally, the secrets specified by the authToken secret in AppDependencyProbingPaths are read if appDependencyProbingPathsSecrets is specified in getSecrets +Additionally, the secrets specified by the authTokenSecret in AppDependencyProbingPaths and TrustedNuGetFeeds are read if appDependencySecrets is specified in getSecrets All secrets included in the Secrets output are Base64 encoded to avoid issues with national characters Secrets, which name is preceded by an asterisk (*) are encrypted and Base64 encoded @@ -17,7 +17,7 @@ Secrets, which name is preceded by an asterisk (*) are encrypted and Base64 enco | :-- | :-: | :-- | :-- | | shell | | The shell (powershell or pwsh) in which the PowerShell script in this action should run | powershell | | gitHubSecrets | Yes | GitHub secrets in a json structure | | -| getSecrets | Yes | Comma-separated list of secrets to get (add appDependencyProbingPathsSecrets to request secrets needed for resolving dependencies in AppDependencyProbingPaths, add TokenForPush in order to request a token to use for pull requests and commits). Secrets preceded by an asterisk are returned encrypted | | +| getSecrets | Yes | Comma-separated list of secrets to get (add appDependencySecrets to request secrets needed for resolving dependencies in AppDependencyProbingPaths and TrustedNuGetFeeds, add TokenForPush in order to request a token to use for pull requests and commits). Secrets preceded by an asterisk are returned encrypted | | | useGhTokenWorkflowForPush | false | Determines whether you want to use the GhTokenWorkflow secret for TokenForPush | false | ## OUTPUT diff --git a/Actions/ReadSecrets/ReadSecrets.ps1 b/Actions/ReadSecrets/ReadSecrets.ps1 index ff23b3c85..12a3c819b 100644 --- a/Actions/ReadSecrets/ReadSecrets.ps1 +++ b/Actions/ReadSecrets/ReadSecrets.ps1 @@ -27,7 +27,7 @@ try { $outSecrets = [ordered]@{} $settings = $env:Settings | ConvertFrom-Json | ConvertTo-HashTable $keyVaultCredentials = GetKeyVaultCredentials - $getAppDependencyProbingPathsSecrets = $false + $getAppDependencySecrets = $false $getTokenForPush = $false [System.Collections.ArrayList]$secretsCollection = @() foreach($secret in ($getSecrets.Split(',') | Select-Object -Unique)) { @@ -38,8 +38,8 @@ try { $secret = 'ghTokenWorkflow' } $secretNameProperty = "$($secret.TrimStart('*'))SecretName" - if ($secret -eq 'AppDependencyProbingPathsSecrets') { - $getAppDependencyProbingPathsSecrets = $true + if ($secret -eq 'AppDependencySecrets') { + $getAppDependencySecrets = $true } else { $secretName = $secret @@ -61,12 +61,19 @@ try { } } - # Loop through appDependencyProbingPaths and add secrets to the collection of secrets to get - if ($getAppDependencyProbingPathsSecrets -and $settings.Keys -contains 'appDependencyProbingPaths') { - foreach($appDependencyProbingPath in $settings.appDependencyProbingPaths) { - if ($appDependencyProbingPath.PsObject.Properties.name -eq "AuthTokenSecret") { - if ($secretsCollection -notcontains $appDependencyProbingPath.authTokenSecret) { - $secretsCollection += $appDependencyProbingPath.authTokenSecret + if ($getAppDependencySecrets) { + # Loop through appDependencyProbingPaths and trustedNuGetFeeds and add secrets to the collection of secrets to get + $settingsCollection = @() + if ($settings.Keys -contains 'appDependencyProbingPaths') { + $settingsCollection += $settings.appDependencyProbingPaths + } + if ($settings.Keys -contains 'trustedNuGetFeeds') { + $settingsCollection += $settings.trustedNuGetFeeds + } + foreach($settingsItem in $settingsCollection) { + if ($settingsItem.PsObject.Properties.name -eq "AuthTokenSecret") { + if ($secretsCollection -notcontains $settingsItem.authTokenSecret) { + $secretsCollection += $settingsItem.authTokenSecret } } } diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index eaa97748e..5578dd74c 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -120,6 +120,19 @@ try { $settings = AnalyzeRepo -settings $settings -baseFolder $baseFolder -project $project @analyzeRepoParams $settings = CheckAppDependencyProbingPaths -settings $settings -token $token -baseFolder $baseFolder -project $project + if ($settings.ContainsKey('TrustedNuGetFeeds')) { + foreach($trustedNuGetFeed in $settings.TrustedNuGetFeeds) { + if ($trustedNuGetFeed.TokenSecretName) { + if ($secrets.Keys -notcontains $trustedNuGetFeed.TokenSecretName) { + OutputWarning -message "Secret $($trustedNuGetFeed.TokenSecretName) needed for trusted NuGetFeeds cannot be found" + } + else { + $trustedNuGetFeed.Token = $secrets."$($trustedNuGetFeed.TokenSecretName)" + } + } + } + } + if ((-not $settings.appFolders) -and (-not $settings.testFolders) -and (-not $settings.bcptTestFolders)) { Write-Host "Repository is empty, exiting" exit diff --git a/Templates/AppSource App/.github/workflows/_BuildALGoProject.yaml b/Templates/AppSource App/.github/workflows/_BuildALGoProject.yaml index c9e7c4737..02dba5176 100644 --- a/Templates/AppSource App/.github/workflows/_BuildALGoProject.yaml +++ b/Templates/AppSource App/.github/workflows/_BuildALGoProject.yaml @@ -105,7 +105,7 @@ jobs: with: shell: ${{ inputs.shell }} gitHubSecrets: ${{ toJson(secrets) }} - getSecrets: '${{ inputs.secrets }},appDependencyProbingPathsSecrets' + getSecrets: '${{ inputs.secrets }},appDependencySecrets' - name: Determine ArtifactUrl uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@main diff --git a/Templates/Per Tenant Extension/.github/workflows/_BuildALGoProject.yaml b/Templates/Per Tenant Extension/.github/workflows/_BuildALGoProject.yaml index c9e7c4737..02dba5176 100644 --- a/Templates/Per Tenant Extension/.github/workflows/_BuildALGoProject.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/_BuildALGoProject.yaml @@ -105,7 +105,7 @@ jobs: with: shell: ${{ inputs.shell }} gitHubSecrets: ${{ toJson(secrets) }} - getSecrets: '${{ inputs.secrets }},appDependencyProbingPathsSecrets' + getSecrets: '${{ inputs.secrets }},appDependencySecrets' - name: Determine ArtifactUrl uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@main From 679d5cf17e51b1cd558453f429df6e59bf2ce95c Mon Sep 17 00:00:00 2001 From: freddydk Date: Mon, 18 Dec 2023 12:03:06 +0100 Subject: [PATCH 04/62] use nuget branch --- Actions/AL-Go-Helper.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index 9bb0320be..090e0f79f 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -18,7 +18,7 @@ $defaultCICDPushBranches = @( 'main', 'release/*', 'feature/*' ) [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', 'defaultCICDPullRequestBranches', Justification = 'False positive.')] $defaultCICDPullRequestBranches = @( 'main' ) $runningLocal = $local.IsPresent -$defaultBcContainerHelperVersion = "https://github.com/freddydk/navcontainerhelper/archive/refs/heads/renamecache.zip" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step +$defaultBcContainerHelperVersion = "https://github.com/freddydk/navcontainerhelper/archive/refs/heads/nuget.zip" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step $microsoftTelemetryConnectionString = "InstrumentationKey=84bd9223-67d4-4378-8590-9e4a46023be2;IngestionEndpoint=https://westeurope-1.in.applicationinsights.azure.com/" $notSecretProperties = @("Scopes","TenantId","BlobName","ContainerName","StorageAccountName","ServerUrl") From 552b2890b3887eab8500d843d69dd104a6933a85 Mon Sep 17 00:00:00 2001 From: freddydk Date: Mon, 18 Dec 2023 19:33:41 +0100 Subject: [PATCH 05/62] remove verbose --- Actions/RunPipeline/RunPipeline.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 5578dd74c..716bda14a 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -324,10 +324,10 @@ try { } } if ($parameters.ContainsKey('containerName')) { - Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification @publishParams -Verbose + Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification @publishParams } else { - Download-BcNuGetPackageToFolder -folder $parameters.appSymbolsFolder @publishParams -Verbose + Download-BcNuGetPackageToFolder -folder $parameters.appSymbolsFolder @publishParams } } From d370247e3b321d624b092a6b3688b3d07a4a06cc Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 07:04:00 +0100 Subject: [PATCH 06/62] use packages permissions --- Actions/AL-Go-Helper.ps1 | 1 + Actions/RunPipeline/RunPipeline.ps1 | 4 ++++ Templates/AppSource App/.github/workflows/CICD.yaml | 5 +++++ Templates/AppSource App/.github/workflows/Current.yaml | 1 + Templates/AppSource App/.github/workflows/NextMajor.yaml | 1 + Templates/AppSource App/.github/workflows/NextMinor.yaml | 1 + .../AppSource App/.github/workflows/PullRequestHandler.yaml | 1 + Templates/Per Tenant Extension/.github/workflows/CICD.yaml | 5 +++++ .../Per Tenant Extension/.github/workflows/Current.yaml | 1 + .../Per Tenant Extension/.github/workflows/NextMajor.yaml | 1 + .../Per Tenant Extension/.github/workflows/NextMinor.yaml | 1 + .../.github/workflows/PullRequestHandler.yaml | 1 + 12 files changed, 23 insertions(+) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index 090e0f79f..c22ff245a 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -628,6 +628,7 @@ function ReadSettings { "environments" = @() "buildModes" = @() "useCompilerFolder" = $false + "useGitHubPackages" = $false "pullRequestTrigger" = "pull_request_target" "fullBuildPatterns" = @() "excludeEnvironments" = @() diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 716bda14a..3e8ab6317 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -302,6 +302,10 @@ try { } } + if ($settings.useGitHubPackages) { # } -and !($gitHubPackagesContext)) { + $gitHubPackagesContext = @{ "serverUrl" = "https://nuget.pkg.github.com/$($ENV:GITHUB_REPOSITORY_OWNER)/index.json"; "token" = $token } | ConvertTo-Json -Compress + } + if ($gitHubPackagesContext -and ($runAlPipelineParams.Keys -notcontains 'InstallMissingDependencies')) { $gitHubPackagesCredential = $gitHubPackagesContext | ConvertFrom-Json $runAlPipelineParams += @{ diff --git a/Templates/AppSource App/.github/workflows/CICD.yaml b/Templates/AppSource App/.github/workflows/CICD.yaml index a803ab54c..752e9bb0a 100644 --- a/Templates/AppSource App/.github/workflows/CICD.yaml +++ b/Templates/AppSource App/.github/workflows/CICD.yaml @@ -16,6 +16,7 @@ defaults: permissions: contents: read actions: read + packages: read env: workflowDepth: 1 @@ -263,6 +264,10 @@ jobs: fail-fast: false runs-on: [ windows-latest ] name: Deliver to ${{ matrix.deliveryTarget }} + permissions: + contents: read + actions: read + packages: write steps: - name: Checkout uses: actions/checkout@v3 diff --git a/Templates/AppSource App/.github/workflows/Current.yaml b/Templates/AppSource App/.github/workflows/Current.yaml index 08994ede3..5a5b4a450 100644 --- a/Templates/AppSource App/.github/workflows/Current.yaml +++ b/Templates/AppSource App/.github/workflows/Current.yaml @@ -5,6 +5,7 @@ on: permissions: contents: read + packages: read defaults: run: diff --git a/Templates/AppSource App/.github/workflows/NextMajor.yaml b/Templates/AppSource App/.github/workflows/NextMajor.yaml index ccad75801..9f382ccc8 100644 --- a/Templates/AppSource App/.github/workflows/NextMajor.yaml +++ b/Templates/AppSource App/.github/workflows/NextMajor.yaml @@ -5,6 +5,7 @@ on: permissions: contents: read + packages: read defaults: run: diff --git a/Templates/AppSource App/.github/workflows/NextMinor.yaml b/Templates/AppSource App/.github/workflows/NextMinor.yaml index a29c4dcae..8270f83c4 100644 --- a/Templates/AppSource App/.github/workflows/NextMinor.yaml +++ b/Templates/AppSource App/.github/workflows/NextMinor.yaml @@ -5,6 +5,7 @@ on: permissions: contents: read + packages: read defaults: run: diff --git a/Templates/AppSource App/.github/workflows/PullRequestHandler.yaml b/Templates/AppSource App/.github/workflows/PullRequestHandler.yaml index 0200d1aaa..057da458f 100644 --- a/Templates/AppSource App/.github/workflows/PullRequestHandler.yaml +++ b/Templates/AppSource App/.github/workflows/PullRequestHandler.yaml @@ -16,6 +16,7 @@ permissions: contents: read actions: read pull-requests: read + packages: read env: workflowDepth: 1 diff --git a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml index a803ab54c..752e9bb0a 100644 --- a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml @@ -16,6 +16,7 @@ defaults: permissions: contents: read actions: read + packages: read env: workflowDepth: 1 @@ -263,6 +264,10 @@ jobs: fail-fast: false runs-on: [ windows-latest ] name: Deliver to ${{ matrix.deliveryTarget }} + permissions: + contents: read + actions: read + packages: write steps: - name: Checkout uses: actions/checkout@v3 diff --git a/Templates/Per Tenant Extension/.github/workflows/Current.yaml b/Templates/Per Tenant Extension/.github/workflows/Current.yaml index 08994ede3..5a5b4a450 100644 --- a/Templates/Per Tenant Extension/.github/workflows/Current.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/Current.yaml @@ -5,6 +5,7 @@ on: permissions: contents: read + packages: read defaults: run: diff --git a/Templates/Per Tenant Extension/.github/workflows/NextMajor.yaml b/Templates/Per Tenant Extension/.github/workflows/NextMajor.yaml index ccad75801..9f382ccc8 100644 --- a/Templates/Per Tenant Extension/.github/workflows/NextMajor.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/NextMajor.yaml @@ -5,6 +5,7 @@ on: permissions: contents: read + packages: read defaults: run: diff --git a/Templates/Per Tenant Extension/.github/workflows/NextMinor.yaml b/Templates/Per Tenant Extension/.github/workflows/NextMinor.yaml index a29c4dcae..8270f83c4 100644 --- a/Templates/Per Tenant Extension/.github/workflows/NextMinor.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/NextMinor.yaml @@ -5,6 +5,7 @@ on: permissions: contents: read + packages: read defaults: run: diff --git a/Templates/Per Tenant Extension/.github/workflows/PullRequestHandler.yaml b/Templates/Per Tenant Extension/.github/workflows/PullRequestHandler.yaml index 0200d1aaa..057da458f 100644 --- a/Templates/Per Tenant Extension/.github/workflows/PullRequestHandler.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/PullRequestHandler.yaml @@ -16,6 +16,7 @@ permissions: contents: read actions: read pull-requests: read + packages: read env: workflowDepth: 1 From 19eb11f5872fe22a4371ec42ce3ad72267fba538 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 07:15:57 +0100 Subject: [PATCH 07/62] use permissions --- Actions/Deliver/Deliver.ps1 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index a4ebefddd..a2719861e 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -207,7 +207,20 @@ try { . $customScript -parameters $parameters } elseif ($deliveryTarget -eq "GitHubPackages") { - $githubPackagesCredential = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.githubPackagesContext)) | ConvertFrom-Json + if ($secrets.gitHubPackagesContext) { + $githubPackagesCredential = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.githubPackagesContext)) | ConvertFrom-Json + } + else { + $githubPackagesCredential = @{ + "serverUrl" = "https://nuget.pkg.github.com/$($ENV:GITHUB_REPOSITORY_OWNER)/index.json" + "token" = $token + } + } + $githubPackagesCredential = @{ + "serverUrl" = "https://nuget.pkg.github.com/$($ENV:GITHUB_REPOSITORY_OWNER)/index.json" + "token" = $token + } + 'Apps' | ForEach-Object { $folder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$($_)-*.*.*.*") | Where-Object { $_.PSIsContainer }) if ($folder.Count -gt 1) { From 16f3e6d280dd1308226d7ab6149c693f48057319 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 07:29:53 +0100 Subject: [PATCH 08/62] transfer token --- .../DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 | 6 +++++- Templates/AppSource App/.github/workflows/CICD.yaml | 1 + Templates/Per Tenant Extension/.github/workflows/CICD.yaml | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 b/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 index d460444c4..a93e5ffb0 100644 --- a/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 +++ b/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 @@ -49,11 +49,15 @@ Get-Item -Path (Join-Path $ENV:GITHUB_WORKSPACE ".github/$($namePrefix)*.ps1") | $deliveryTarget = [System.IO.Path]::GetFileNameWithoutExtension($_.Name.SubString($namePrefix.Length)) $deliveryTargets += @($deliveryTarget) } -$deliveryTargets = @($deliveryTargets | Select-Object -unique) if ($checkContextSecrets) { # Check all delivery targets and include only the ones needed $deliveryTargets = @($deliveryTargets | Where-Object { IncludeDeliveryTarget -deliveryTarget $_ }) } +if ($settings.useGitHubPackages) { + # If useGitHubPackages is set to true, we will always include GitHubPackages as a delivery target (even if no context secret exists) + $deliveryTargets += @('GitHubPackages') +} +$deliveryTargets = @($deliveryTargets | Select-Object -unique) $contextSecrets = @($deliveryTargets | ForEach-Object { "$($_)Context" }) #region Action: Output diff --git a/Templates/AppSource App/.github/workflows/CICD.yaml b/Templates/AppSource App/.github/workflows/CICD.yaml index 752e9bb0a..450278081 100644 --- a/Templates/AppSource App/.github/workflows/CICD.yaml +++ b/Templates/AppSource App/.github/workflows/CICD.yaml @@ -296,6 +296,7 @@ jobs: Secrets: '${{ steps.ReadSecrets.outputs.Secrets }}' with: shell: powershell + token: ${{ github.token }} type: 'CD' projects: ${{ needs.Initialization.outputs.projects }} deliveryTarget: ${{ matrix.deliveryTarget }} diff --git a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml index 752e9bb0a..450278081 100644 --- a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml @@ -296,6 +296,7 @@ jobs: Secrets: '${{ steps.ReadSecrets.outputs.Secrets }}' with: shell: powershell + token: ${{ github.token }} type: 'CD' projects: ${{ needs.Initialization.outputs.projects }} deliveryTarget: ${{ matrix.deliveryTarget }} From 8dfe5c95a13b120bd11549bad1a0a84535891b8d Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 08:34:10 +0100 Subject: [PATCH 09/62] dump token permissions --- Actions/Deliver/Deliver.ps1 | 5 +++++ Templates/Per Tenant Extension/.github/workflows/CICD.yaml | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index a2719861e..40a8c24da 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -221,6 +221,11 @@ try { "token" = $token } + Write-Host "------------------" + (Invoke-WebRequest -UseBasicParsing -uri 'https://api.github.com' -Headers @{ "Authorization" = "token $($token)" }).Headers | Out-Host + Write-Host "------------------" + (Invoke-WebRequest -UseBasicParsing -uri 'https://api.github.com' -Headers @{ "Authorization" = "token $($env:GITHUB_TOKEN)" }).Headers | Out-Host + 'Apps' | ForEach-Object { $folder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$($_)-*.*.*.*") | Where-Object { $_.PSIsContainer }) if ($folder.Count -gt 1) { diff --git a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml index 450278081..2d4f7867e 100644 --- a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml @@ -290,6 +290,10 @@ jobs: gitHubSecrets: ${{ toJson(secrets) }} getSecrets: '${{ matrix.deliveryTarget }}Context' + - name: dump + run: | + (Invoke-WebRequest -UseBasicParsing -uri 'https://api.github.com' -Headers @{ "Authorization" = "token $($env:GITHUB_TOKEN)" }).Headers | Out-Host + - name: Deliver uses: microsoft/AL-Go-Actions/Deliver@main env: From ae4b501dde722fe960f3cbd3a980aaf2341e342a Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 08:41:33 +0100 Subject: [PATCH 10/62] env --- Templates/Per Tenant Extension/.github/workflows/CICD.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml index 2d4f7867e..7c489ad02 100644 --- a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml @@ -291,6 +291,8 @@ jobs: getSecrets: '${{ matrix.deliveryTarget }}Context' - name: dump + env: + GITHUB_TOKEN: ${{ github.token }} run: | (Invoke-WebRequest -UseBasicParsing -uri 'https://api.github.com' -Headers @{ "Authorization" = "token $($env:GITHUB_TOKEN)" }).Headers | Out-Host From 87a69600e0f69021424a88ff97a198ba29e46d74 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 08:55:52 +0100 Subject: [PATCH 11/62] dump hash --- Actions/Deliver/Deliver.ps1 | 6 ++++-- Templates/Per Tenant Extension/.github/workflows/CICD.yaml | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index 40a8c24da..25ad918b0 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -222,9 +222,11 @@ try { } Write-Host "------------------" - (Invoke-WebRequest -UseBasicParsing -uri 'https://api.github.com' -Headers @{ "Authorization" = "token $($token)" }).Headers | Out-Host + $mystream = [IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($token)) + (Get-FileHash -InputStream $mystream -Algorithm SHA256).Hash | Out-Host Write-Host "------------------" - (Invoke-WebRequest -UseBasicParsing -uri 'https://api.github.com' -Headers @{ "Authorization" = "token $($env:GITHUB_TOKEN)" }).Headers | Out-Host + $mystream = [IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($ENV:GITHUB_TOKEN)) + (Get-FileHash -InputStream $mystream -Algorithm SHA256).Hash | Out-Host 'Apps' | ForEach-Object { $folder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$($_)-*.*.*.*") | Where-Object { $_.PSIsContainer }) diff --git a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml index 7c489ad02..9e92e74a8 100644 --- a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml @@ -294,7 +294,8 @@ jobs: env: GITHUB_TOKEN: ${{ github.token }} run: | - (Invoke-WebRequest -UseBasicParsing -uri 'https://api.github.com' -Headers @{ "Authorization" = "token $($env:GITHUB_TOKEN)" }).Headers | Out-Host + $mystream = [IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($ENV:GITHUB_TOKEN)) + (Get-FileHash -InputStream $mystream -Algorithm SHA256).Hash | Out-Host - name: Deliver uses: microsoft/AL-Go-Actions/Deliver@main From 3f5fb90d1501aebc6c53622181035d1a82154cae Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 09:11:34 +0100 Subject: [PATCH 12/62] remove useghp --- Actions/AL-Go-Helper.ps1 | 1 - .../DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 | 6 +----- Actions/RunPipeline/RunPipeline.ps1 | 4 ---- Templates/AppSource App/.github/workflows/CICD.yaml | 2 -- Templates/AppSource App/.github/workflows/Current.yaml | 1 - Templates/AppSource App/.github/workflows/NextMajor.yaml | 1 - Templates/AppSource App/.github/workflows/NextMinor.yaml | 1 - .../AppSource App/.github/workflows/PullRequestHandler.yaml | 1 - Templates/Per Tenant Extension/.github/workflows/CICD.yaml | 2 -- .../Per Tenant Extension/.github/workflows/Current.yaml | 1 - .../Per Tenant Extension/.github/workflows/NextMajor.yaml | 1 - .../Per Tenant Extension/.github/workflows/NextMinor.yaml | 1 - .../.github/workflows/PullRequestHandler.yaml | 1 - 13 files changed, 1 insertion(+), 22 deletions(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index c22ff245a..090e0f79f 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -628,7 +628,6 @@ function ReadSettings { "environments" = @() "buildModes" = @() "useCompilerFolder" = $false - "useGitHubPackages" = $false "pullRequestTrigger" = "pull_request_target" "fullBuildPatterns" = @() "excludeEnvironments" = @() diff --git a/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 b/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 index a93e5ffb0..d460444c4 100644 --- a/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 +++ b/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 @@ -49,15 +49,11 @@ Get-Item -Path (Join-Path $ENV:GITHUB_WORKSPACE ".github/$($namePrefix)*.ps1") | $deliveryTarget = [System.IO.Path]::GetFileNameWithoutExtension($_.Name.SubString($namePrefix.Length)) $deliveryTargets += @($deliveryTarget) } +$deliveryTargets = @($deliveryTargets | Select-Object -unique) if ($checkContextSecrets) { # Check all delivery targets and include only the ones needed $deliveryTargets = @($deliveryTargets | Where-Object { IncludeDeliveryTarget -deliveryTarget $_ }) } -if ($settings.useGitHubPackages) { - # If useGitHubPackages is set to true, we will always include GitHubPackages as a delivery target (even if no context secret exists) - $deliveryTargets += @('GitHubPackages') -} -$deliveryTargets = @($deliveryTargets | Select-Object -unique) $contextSecrets = @($deliveryTargets | ForEach-Object { "$($_)Context" }) #region Action: Output diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 3e8ab6317..716bda14a 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -302,10 +302,6 @@ try { } } - if ($settings.useGitHubPackages) { # } -and !($gitHubPackagesContext)) { - $gitHubPackagesContext = @{ "serverUrl" = "https://nuget.pkg.github.com/$($ENV:GITHUB_REPOSITORY_OWNER)/index.json"; "token" = $token } | ConvertTo-Json -Compress - } - if ($gitHubPackagesContext -and ($runAlPipelineParams.Keys -notcontains 'InstallMissingDependencies')) { $gitHubPackagesCredential = $gitHubPackagesContext | ConvertFrom-Json $runAlPipelineParams += @{ diff --git a/Templates/AppSource App/.github/workflows/CICD.yaml b/Templates/AppSource App/.github/workflows/CICD.yaml index 450278081..1a34a1f3c 100644 --- a/Templates/AppSource App/.github/workflows/CICD.yaml +++ b/Templates/AppSource App/.github/workflows/CICD.yaml @@ -16,7 +16,6 @@ defaults: permissions: contents: read actions: read - packages: read env: workflowDepth: 1 @@ -267,7 +266,6 @@ jobs: permissions: contents: read actions: read - packages: write steps: - name: Checkout uses: actions/checkout@v3 diff --git a/Templates/AppSource App/.github/workflows/Current.yaml b/Templates/AppSource App/.github/workflows/Current.yaml index 5a5b4a450..08994ede3 100644 --- a/Templates/AppSource App/.github/workflows/Current.yaml +++ b/Templates/AppSource App/.github/workflows/Current.yaml @@ -5,7 +5,6 @@ on: permissions: contents: read - packages: read defaults: run: diff --git a/Templates/AppSource App/.github/workflows/NextMajor.yaml b/Templates/AppSource App/.github/workflows/NextMajor.yaml index 9f382ccc8..ccad75801 100644 --- a/Templates/AppSource App/.github/workflows/NextMajor.yaml +++ b/Templates/AppSource App/.github/workflows/NextMajor.yaml @@ -5,7 +5,6 @@ on: permissions: contents: read - packages: read defaults: run: diff --git a/Templates/AppSource App/.github/workflows/NextMinor.yaml b/Templates/AppSource App/.github/workflows/NextMinor.yaml index 8270f83c4..a29c4dcae 100644 --- a/Templates/AppSource App/.github/workflows/NextMinor.yaml +++ b/Templates/AppSource App/.github/workflows/NextMinor.yaml @@ -5,7 +5,6 @@ on: permissions: contents: read - packages: read defaults: run: diff --git a/Templates/AppSource App/.github/workflows/PullRequestHandler.yaml b/Templates/AppSource App/.github/workflows/PullRequestHandler.yaml index 057da458f..0200d1aaa 100644 --- a/Templates/AppSource App/.github/workflows/PullRequestHandler.yaml +++ b/Templates/AppSource App/.github/workflows/PullRequestHandler.yaml @@ -16,7 +16,6 @@ permissions: contents: read actions: read pull-requests: read - packages: read env: workflowDepth: 1 diff --git a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml index 9e92e74a8..0b07e7a14 100644 --- a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml @@ -16,7 +16,6 @@ defaults: permissions: contents: read actions: read - packages: read env: workflowDepth: 1 @@ -267,7 +266,6 @@ jobs: permissions: contents: read actions: read - packages: write steps: - name: Checkout uses: actions/checkout@v3 diff --git a/Templates/Per Tenant Extension/.github/workflows/Current.yaml b/Templates/Per Tenant Extension/.github/workflows/Current.yaml index 5a5b4a450..08994ede3 100644 --- a/Templates/Per Tenant Extension/.github/workflows/Current.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/Current.yaml @@ -5,7 +5,6 @@ on: permissions: contents: read - packages: read defaults: run: diff --git a/Templates/Per Tenant Extension/.github/workflows/NextMajor.yaml b/Templates/Per Tenant Extension/.github/workflows/NextMajor.yaml index 9f382ccc8..ccad75801 100644 --- a/Templates/Per Tenant Extension/.github/workflows/NextMajor.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/NextMajor.yaml @@ -5,7 +5,6 @@ on: permissions: contents: read - packages: read defaults: run: diff --git a/Templates/Per Tenant Extension/.github/workflows/NextMinor.yaml b/Templates/Per Tenant Extension/.github/workflows/NextMinor.yaml index 8270f83c4..a29c4dcae 100644 --- a/Templates/Per Tenant Extension/.github/workflows/NextMinor.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/NextMinor.yaml @@ -5,7 +5,6 @@ on: permissions: contents: read - packages: read defaults: run: diff --git a/Templates/Per Tenant Extension/.github/workflows/PullRequestHandler.yaml b/Templates/Per Tenant Extension/.github/workflows/PullRequestHandler.yaml index 057da458f..0200d1aaa 100644 --- a/Templates/Per Tenant Extension/.github/workflows/PullRequestHandler.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/PullRequestHandler.yaml @@ -16,7 +16,6 @@ permissions: contents: read actions: read pull-requests: read - packages: read env: workflowDepth: 1 From c8dbc8eb858deebfc835252fc379a9f8463f48c6 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 09:14:56 +0100 Subject: [PATCH 13/62] remove token --- Actions/Deliver/Deliver.ps1 | 22 +------------------ .../AppSource App/.github/workflows/CICD.yaml | 4 ---- .../.github/workflows/CICD.yaml | 11 ---------- 3 files changed, 1 insertion(+), 36 deletions(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index 25ad918b0..a4ebefddd 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -207,27 +207,7 @@ try { . $customScript -parameters $parameters } elseif ($deliveryTarget -eq "GitHubPackages") { - if ($secrets.gitHubPackagesContext) { - $githubPackagesCredential = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.githubPackagesContext)) | ConvertFrom-Json - } - else { - $githubPackagesCredential = @{ - "serverUrl" = "https://nuget.pkg.github.com/$($ENV:GITHUB_REPOSITORY_OWNER)/index.json" - "token" = $token - } - } - $githubPackagesCredential = @{ - "serverUrl" = "https://nuget.pkg.github.com/$($ENV:GITHUB_REPOSITORY_OWNER)/index.json" - "token" = $token - } - - Write-Host "------------------" - $mystream = [IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($token)) - (Get-FileHash -InputStream $mystream -Algorithm SHA256).Hash | Out-Host - Write-Host "------------------" - $mystream = [IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($ENV:GITHUB_TOKEN)) - (Get-FileHash -InputStream $mystream -Algorithm SHA256).Hash | Out-Host - + $githubPackagesCredential = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.githubPackagesContext)) | ConvertFrom-Json 'Apps' | ForEach-Object { $folder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$($_)-*.*.*.*") | Where-Object { $_.PSIsContainer }) if ($folder.Count -gt 1) { diff --git a/Templates/AppSource App/.github/workflows/CICD.yaml b/Templates/AppSource App/.github/workflows/CICD.yaml index 1a34a1f3c..a803ab54c 100644 --- a/Templates/AppSource App/.github/workflows/CICD.yaml +++ b/Templates/AppSource App/.github/workflows/CICD.yaml @@ -263,9 +263,6 @@ jobs: fail-fast: false runs-on: [ windows-latest ] name: Deliver to ${{ matrix.deliveryTarget }} - permissions: - contents: read - actions: read steps: - name: Checkout uses: actions/checkout@v3 @@ -294,7 +291,6 @@ jobs: Secrets: '${{ steps.ReadSecrets.outputs.Secrets }}' with: shell: powershell - token: ${{ github.token }} type: 'CD' projects: ${{ needs.Initialization.outputs.projects }} deliveryTarget: ${{ matrix.deliveryTarget }} diff --git a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml index 0b07e7a14..a803ab54c 100644 --- a/Templates/Per Tenant Extension/.github/workflows/CICD.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/CICD.yaml @@ -263,9 +263,6 @@ jobs: fail-fast: false runs-on: [ windows-latest ] name: Deliver to ${{ matrix.deliveryTarget }} - permissions: - contents: read - actions: read steps: - name: Checkout uses: actions/checkout@v3 @@ -288,20 +285,12 @@ jobs: gitHubSecrets: ${{ toJson(secrets) }} getSecrets: '${{ matrix.deliveryTarget }}Context' - - name: dump - env: - GITHUB_TOKEN: ${{ github.token }} - run: | - $mystream = [IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($ENV:GITHUB_TOKEN)) - (Get-FileHash -InputStream $mystream -Algorithm SHA256).Hash | Out-Host - - name: Deliver uses: microsoft/AL-Go-Actions/Deliver@main env: Secrets: '${{ steps.ReadSecrets.outputs.Secrets }}' with: shell: powershell - token: ${{ github.token }} type: 'CD' projects: ${{ needs.Initialization.outputs.projects }} deliveryTarget: ${{ matrix.deliveryTarget }} From 9f87f327b36c47d24afb9b7dd2104dc521542d77 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 09:22:03 +0100 Subject: [PATCH 14/62] use authtokensecret --- Actions/RunPipeline/RunPipeline.ps1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 716bda14a..3ff4bad5d 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -120,14 +120,14 @@ try { $settings = AnalyzeRepo -settings $settings -baseFolder $baseFolder -project $project @analyzeRepoParams $settings = CheckAppDependencyProbingPaths -settings $settings -token $token -baseFolder $baseFolder -project $project - if ($settings.ContainsKey('TrustedNuGetFeeds')) { - foreach($trustedNuGetFeed in $settings.TrustedNuGetFeeds) { - if ($trustedNuGetFeed.TokenSecretName) { - if ($secrets.Keys -notcontains $trustedNuGetFeed.TokenSecretName) { - OutputWarning -message "Secret $($trustedNuGetFeed.TokenSecretName) needed for trusted NuGetFeeds cannot be found" + if ($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds')) { + foreach($trustedNuGetFeed in $bcContainerHelperConfig.TrustedNuGetFeeds) { + if ($trustedNuGetFeed.AuthTokenSecret) { + if ($secrets.Keys -notcontains $trustedNuGetFeed.AuthTokenSecret) { + OutputWarning -message "Secret $($trustedNuGetFeed.AuthTokenSecret) needed for trusted NuGetFeeds cannot be found" } else { - $trustedNuGetFeed.Token = $secrets."$($trustedNuGetFeed.TokenSecretName)" + $trustedNuGetFeed.Token = $secrets."$($trustedNuGetFeed.AuthTokenSecret)" } } } From 0d89e3cb1288e878bc5b9fd85b8694a4da08df22 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 09:35:27 +0100 Subject: [PATCH 15/62] psc --- Actions/RunPipeline/RunPipeline.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 3ff4bad5d..bdcf5b973 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -127,7 +127,12 @@ try { OutputWarning -message "Secret $($trustedNuGetFeed.AuthTokenSecret) needed for trusted NuGetFeeds cannot be found" } else { - $trustedNuGetFeed.Token = $secrets."$($trustedNuGetFeed.AuthTokenSecret)" + if ($trustedNuGetFeed -is [HashTable] -or $trustedNuGetFeed.PSObject.Properties.Name -contains 'Token') { + $trustedNuGetFeed.Token = $secrets."$($trustedNuGetFeed.AuthTokenSecret)" + } + else { + $trustedNuGetFeed | Add-Member -MemberType NoteProperty -Name Token -Value $secrets."$($trustedNuGetFeed.AuthTokenSecret)" + } } } } From c177e0194b6f916fb9b3c038fd82159562cc7c0d Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 09:50:50 +0100 Subject: [PATCH 16/62] add missing when trusted feeds --- Actions/RunPipeline/RunPipeline.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index bdcf5b973..3689810f4 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -307,7 +307,7 @@ try { } } - if ($gitHubPackagesContext -and ($runAlPipelineParams.Keys -notcontains 'InstallMissingDependencies')) { + if ((($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds') -and ($bcContainerHelperConfig.TrustedNuGetFeeds.Count -gt 0)) -or ($gitHubPackagesContext)) -and ($runAlPipelineParams.Keys -notcontains 'InstallMissingDependencies')) { $gitHubPackagesCredential = $gitHubPackagesContext | ConvertFrom-Json $runAlPipelineParams += @{ "InstallMissingDependencies" = { From 8b5fa702e341aff584bf3e26d4f507df55a87ff7 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 09:53:07 +0100 Subject: [PATCH 17/62] empty ghp --- Actions/RunPipeline/RunPipeline.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 3689810f4..8e9d2d4a4 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -308,7 +308,12 @@ try { } if ((($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds') -and ($bcContainerHelperConfig.TrustedNuGetFeeds.Count -gt 0)) -or ($gitHubPackagesContext)) -and ($runAlPipelineParams.Keys -notcontains 'InstallMissingDependencies')) { - $gitHubPackagesCredential = $gitHubPackagesContext | ConvertFrom-Json + if ($githubPackagesContext) { + $gitHubPackagesCredential = $gitHubPackagesContext | ConvertFrom-Json + } + else { + $gitHubPackagesCredential = [PSCustomObject]@{ "serverUrl" = ''; "token" = '' } + } $runAlPipelineParams += @{ "InstallMissingDependencies" = { Param([Hashtable]$parameters) From 1b9e2ee77d2562c9327ffbb297ec0e3499dfa56c Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 10:05:22 +0100 Subject: [PATCH 18/62] no hash --- Actions/RunPipeline/RunPipeline.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 8e9d2d4a4..9fea36794 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -127,7 +127,7 @@ try { OutputWarning -message "Secret $($trustedNuGetFeed.AuthTokenSecret) needed for trusted NuGetFeeds cannot be found" } else { - if ($trustedNuGetFeed -is [HashTable] -or $trustedNuGetFeed.PSObject.Properties.Name -contains 'Token') { + if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { $trustedNuGetFeed.Token = $secrets."$($trustedNuGetFeed.AuthTokenSecret)" } else { From 711a2f2aee073c228c7bb13db86cff07bc344fb3 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 10:15:28 +0100 Subject: [PATCH 19/62] base64 decode --- Actions/RunPipeline/RunPipeline.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 9fea36794..e4fea2a60 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -127,11 +127,12 @@ try { OutputWarning -message "Secret $($trustedNuGetFeed.AuthTokenSecret) needed for trusted NuGetFeeds cannot be found" } else { + $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($trustedNuGetFeed.AuthTokenSecret)")) if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { - $trustedNuGetFeed.Token = $secrets."$($trustedNuGetFeed.AuthTokenSecret)" + $trustedNuGetFeed.Token = $token } else { - $trustedNuGetFeed | Add-Member -MemberType NoteProperty -Name Token -Value $secrets."$($trustedNuGetFeed.AuthTokenSecret)" + $trustedNuGetFeed | Add-Member -MemberType NoteProperty -Name Token -Value $token } } } From af6b129cd14406858c47b8926571cce11cc823f2 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 20 Dec 2023 10:21:07 +0100 Subject: [PATCH 20/62] var --- Actions/RunPipeline/RunPipeline.ps1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index e4fea2a60..d47b9796f 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -123,11 +123,12 @@ try { if ($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds')) { foreach($trustedNuGetFeed in $bcContainerHelperConfig.TrustedNuGetFeeds) { if ($trustedNuGetFeed.AuthTokenSecret) { - if ($secrets.Keys -notcontains $trustedNuGetFeed.AuthTokenSecret) { - OutputWarning -message "Secret $($trustedNuGetFeed.AuthTokenSecret) needed for trusted NuGetFeeds cannot be found" + $authTokenSecret = $trustedNuGetFeed.AuthTokenSecret + if ($secrets.Keys -notcontains $authTokenSecret) { + OutputWarning -message "Secret $authTokenSecret needed for trusted NuGetFeeds cannot be found" } else { - $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($trustedNuGetFeed.AuthTokenSecret)")) + $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$authTokenSecret")) if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { $trustedNuGetFeed.Token = $token } From 711062889b3c7e9e83f1ed06f25184588d6bef23 Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 21 Dec 2023 19:28:33 +0100 Subject: [PATCH 21/62] nuget preview --- Actions/Deliver/Deliver.ps1 | 98 ++++--------------- .../DetermineDeliveryTargets.ps1 | 12 ++- 2 files changed, 29 insertions(+), 81 deletions(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index a4ebefddd..f7b139e9e 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -206,9 +206,21 @@ try { Write-Host "Calling custom script: $customScript" . $customScript -parameters $parameters } - elseif ($deliveryTarget -eq "GitHubPackages") { - $githubPackagesCredential = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.githubPackagesContext)) | ConvertFrom-Json - 'Apps' | ForEach-Object { + elseif ($deliveryTarget -eq 'GitHubPackages' -or $deliveryTarget -eq 'NuGet') { + $preReleaseTag = '' + try { + $nuGetAccount = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) | ConvertFrom-Json | ConvertTo-HashTable + if ($deliveryTarget -eq 'NuGet' -and $type -eq 'CD') { + $preReleaseTag = '-preview' + } + $nuGetServerUrl = $nuGetAccount.ServerUrl + $nuGetToken = $nuGetAccount.Token + Write-Host "$($deliveryTarget)Context secret OK" + } + catch { + throw "$($deliveryTarget)Context secret is malformed. Needs to be formatted as Json, containing serverUrl and token as a minimum." + } + 'Apps','TestApps' | ForEach-Object { $folder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$($_)-*.*.*.*") | Where-Object { $_.PSIsContainer }) if ($folder.Count -gt 1) { $folder | Out-Host @@ -218,89 +230,15 @@ try { Get-Item -Path (Join-Path $folder[0] "*.app") | ForEach-Object { $parameters = @{ "gitHubRepository" = "$ENV:GITHUB_SERVER_URL/$ENV:GITHUB_REPOSITORY" + "preReleaseTag" = $preReleaseTag + "appFile" = $_.FullName } - $parameters.appFiles = $_.FullName $package = New-BcNuGetPackage @parameters - Push-BcNuGetPackage -nuGetServerUrl $gitHubPackagesCredential.serverUrl -nuGetToken $gitHubPackagesCredential.token -bcNuGetPackage $package + Push-BcNuGetPackage -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -bcNuGetPackage $package } } } } - elseif ($deliveryTarget -eq "NuGet") { - try { - $nuGetAccount = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.nuGetContext)) | ConvertFrom-Json | ConvertTo-HashTable - $nuGetServerUrl = $nuGetAccount.ServerUrl - $nuGetToken = $nuGetAccount.Token - Write-Host "NuGetContext secret OK" - } - catch { - throw "NuGetContext secret is malformed. Needs to be formatted as Json, containing serverUrl and token as a minimum." - } - $appsfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-Apps-*.*.*.*") | Where-Object { $_.PSIsContainer }) - if ($appsFolder.Count -eq 0) { - throw "Internal error - unable to locate apps folder" - } - elseif ($appsFolder.Count -gt 1) { - $appsFolder | Out-Host - throw "Internal error - multiple apps folders located" - } - $testAppsFolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-TestApps-*.*.*.*") | Where-Object { $_.PSIsContainer }) - if ($testAppsFolder.Count -gt 1) { - $testAppsFolder | Out-Host - throw "Internal error - multiple testApps folders located" - } - $dependenciesFolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-Dependencies-*.*.*.*") | Where-Object { $_.PSIsContainer }) - if ($dependenciesFolder.Count -gt 1) { - $dependenciesFolder | Out-Host - throw "Internal error - multiple dependencies folders located" - } - - $parameters = @{ - "gitHubRepository" = "$ENV:GITHUB_SERVER_URL/$ENV:GITHUB_REPOSITORY" - } - $parameters.appFiles = @(Get-Item -Path (Join-Path $appsFolder[0] "*.app") | ForEach-Object { $_.FullName }) - if ($testAppsFolder.Count -gt 0) { - $parameters.testAppFiles = @(Get-Item -Path (Join-Path $testAppsFolder[0] "*.app") | ForEach-Object { $_.FullName }) - } - if ($dependenciesFolder.Count -gt 0) { - $parameters.dependencyAppFiles = @(Get-Item -Path (Join-Path $dependenciesFolder[0] "*.app") | ForEach-Object { $_.FullName }) - } - if ($nuGetAccount.Keys -contains 'PackageName') { - $parameters.packageId = $nuGetAccount.PackageName.replace('{project}',$projectName).replace('{owner}',$ENV:GITHUB_REPOSITORY_OWNER).replace('{repo}',$settings.repoName) - } - else { - if ($thisProject -and ($thisProject -eq '.')) { - $parameters.packageId = "$($ENV:GITHUB_REPOSITORY_OWNER)-$($settings.repoName)" - } - else { - $parameters.packageId = "$($ENV:GITHUB_REPOSITORY_OWNER)-$($settings.repoName)-$ProjectName" - } - } - if ($type -eq 'CD') { - $parameters.packageId += "-preview" - } - $parameters.packageVersion = [System.Version]$appsFolder[0].Name.SubString($appsFolder[0].Name.IndexOf("-Apps-")+6) - if ($nuGetAccount.Keys -contains 'PackageTitle') { - $parameters.packageTitle = $nuGetAccount.PackageTitle - } - else { - $parameters.packageTitle = $parameters.packageId - } - if ($nuGetAccount.Keys -contains 'PackageDescription') { - $parameters.packageDescription = $nuGetAccount.PackageDescription - } - else { - $parameters.packageDescription = $parameters.packageTitle - } - if ($nuGetAccount.Keys -contains 'PackageAuthors') { - $parameters.packageAuthors = $nuGetAccount.PackageAuthors - } - else { - $parameters.packageAuthors = $actor - } - $package = New-BcNuGetPackage @parameters - Push-BcNuGetPackage -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -bcNuGetPackage $package - } elseif ($deliveryTarget -eq "Storage") { EnsureAzStorageModule try { diff --git a/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 b/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 index d460444c4..6d0c6d958 100644 --- a/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 +++ b/Actions/DetermineDeliveryTargets/DetermineDeliveryTargets.ps1 @@ -5,6 +5,16 @@ [bool] $checkContextSecrets ) +function ContinuousDelivery([string] $deliveryTarget) { + $settingsName = "DeliverTo$deliveryTarget" + if ($settings.Contains($settingsName) -and $settings."$settingsName".Contains('ContinuousDelivery')) { + return $settings."$settingsName".ContinuousDelivery + } + else { + return $true + } +} + function IncludeBranch([string] $deliveryTarget) { $settingsName = "DeliverTo$deliveryTarget" if ($settings.Contains($settingsName) -and $settings."$settingsName".Contains('Branches')) { @@ -26,7 +36,7 @@ function IncludeDeliveryTarget([string] $deliveryTarget) { Write-Host "- Secret '$contextName' not found" return $false } - return (IncludeBranch -deliveryTarget $deliveryTarget) + return (IncludeBranch -deliveryTarget $deliveryTarget) -and (ContinuousDelivery -deliveryTarget $deliveryTarget) } . (Join-Path -Path $PSScriptRoot -ChildPath "..\AL-Go-Helper.ps1" -Resolve) From ccf5b5b25fb618c9dbfde4662b7017eb9d8f94f2 Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 21 Dec 2023 19:38:57 +0100 Subject: [PATCH 22/62] no dash --- Actions/Deliver/Deliver.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index f7b139e9e..e63a818f1 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -211,7 +211,7 @@ try { try { $nuGetAccount = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) | ConvertFrom-Json | ConvertTo-HashTable if ($deliveryTarget -eq 'NuGet' -and $type -eq 'CD') { - $preReleaseTag = '-preview' + $preReleaseTag = 'preview' } $nuGetServerUrl = $nuGetAccount.ServerUrl $nuGetToken = $nuGetAccount.Token From cabbfdc8a9d5e0e7d5982895a79942c121f024a3 Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 21 Dec 2023 21:57:36 +0100 Subject: [PATCH 23/62] remove spaces --- Actions/Deliver/Deliver.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index e63a818f1..29ffe0713 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -231,8 +231,9 @@ try { $parameters = @{ "gitHubRepository" = "$ENV:GITHUB_SERVER_URL/$ENV:GITHUB_REPOSITORY" "preReleaseTag" = $preReleaseTag - "appFile" = $_.FullName + "appFile" = $_.FullName } + $parameters | Out-Host $package = New-BcNuGetPackage @parameters Push-BcNuGetPackage -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -bcNuGetPackage $package } From 61656d5124adf4e3d5b1cd5ff24c3f428204a196 Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 21 Dec 2023 21:58:34 +0100 Subject: [PATCH 24/62] remove dump --- Actions/Deliver/Deliver.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index 29ffe0713..988d9c6c7 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -233,7 +233,6 @@ try { "preReleaseTag" = $preReleaseTag "appFile" = $_.FullName } - $parameters | Out-Host $package = New-BcNuGetPackage @parameters Push-BcNuGetPackage -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -bcNuGetPackage $package } From f73051ea2d79512505efd62a95a5de8da3f85e9d Mon Sep 17 00:00:00 2001 From: freddydk Date: Sat, 23 Dec 2023 06:08:55 +0100 Subject: [PATCH 25/62] use latest --- Actions/AL-Go-Helper.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index 090e0f79f..254d65067 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -19,6 +19,7 @@ $defaultCICDPushBranches = @( 'main', 'release/*', 'feature/*' ) $defaultCICDPullRequestBranches = @( 'main' ) $runningLocal = $local.IsPresent $defaultBcContainerHelperVersion = "https://github.com/freddydk/navcontainerhelper/archive/refs/heads/nuget.zip" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step +$defaultBcContainerHelperVersion = "latest" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step $microsoftTelemetryConnectionString = "InstrumentationKey=84bd9223-67d4-4378-8590-9e4a46023be2;IngestionEndpoint=https://westeurope-1.in.applicationinsights.azure.com/" $notSecretProperties = @("Scopes","TenantId","BlobName","ContainerName","StorageAccountName","ServerUrl") From 1168d1a88603ad571a60c88799897859d20e5c17 Mon Sep 17 00:00:00 2001 From: freddydk Date: Sat, 23 Dec 2023 06:27:30 +0100 Subject: [PATCH 26/62] use nuget --- Actions/AL-Go-Helper.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index 254d65067..090e0f79f 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -19,7 +19,6 @@ $defaultCICDPushBranches = @( 'main', 'release/*', 'feature/*' ) $defaultCICDPullRequestBranches = @( 'main' ) $runningLocal = $local.IsPresent $defaultBcContainerHelperVersion = "https://github.com/freddydk/navcontainerhelper/archive/refs/heads/nuget.zip" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step -$defaultBcContainerHelperVersion = "latest" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step $microsoftTelemetryConnectionString = "InstrumentationKey=84bd9223-67d4-4378-8590-9e4a46023be2;IngestionEndpoint=https://westeurope-1.in.applicationinsights.azure.com/" $notSecretProperties = @("Scopes","TenantId","BlobName","ContainerName","StorageAccountName","ServerUrl") From b02500b002cfd3b7ce713388258c1abab81b3f04 Mon Sep 17 00:00:00 2001 From: freddydk Date: Sat, 23 Dec 2023 07:09:49 +0100 Subject: [PATCH 27/62] do not fail on publish --- Actions/RunPipeline/RunPipeline.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index d47b9796f..afe2af3a2 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -336,7 +336,7 @@ try { } } if ($parameters.ContainsKey('containerName')) { - Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification @publishParams + Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification @publishParams -ErrorAction SilentlyContinue } else { Download-BcNuGetPackageToFolder -folder $parameters.appSymbolsFolder @publishParams From 9ce422f3a69e885024e12fb88e0998d04ec128ce Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 28 Dec 2023 14:38:39 +0100 Subject: [PATCH 28/62] outnull --- Actions/RunPipeline/RunPipeline.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index afe2af3a2..8b6f18979 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -339,7 +339,7 @@ try { Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification @publishParams -ErrorAction SilentlyContinue } else { - Download-BcNuGetPackageToFolder -folder $parameters.appSymbolsFolder @publishParams + Download-BcNuGetPackageToFolder -folder $parameters.appSymbolsFolder @publishParams | Out-Null } } From 56bae86a39ffbf54816057ad92af413908cc1234 Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 28 May 2024 10:41:32 +0200 Subject: [PATCH 29/62] release notes --- Actions/AL-Go-Helper.ps1 | 2 +- RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index 4e656b071..0a5b1432c 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -18,7 +18,7 @@ $defaultCICDPushBranches = @( 'main', 'release/*', 'feature/*' ) [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', 'defaultCICDPullRequestBranches', Justification = 'False positive.')] $defaultCICDPullRequestBranches = @( 'main' ) $runningLocal = $local.IsPresent -$defaultBcContainerHelperVersion = "https://github.com/freddydk/navcontainerhelper/archive/refs/heads/nuget.zip" # Must be double quotes. Will be replaced by BcContainerHelperVersion if necessary in the deploy step +$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" $microsoftTelemetryConnectionString = "InstrumentationKey=84bd9223-67d4-4378-8590-9e4a46023be2;IngestionEndpoint=https://westeurope-1.in.applicationinsights.azure.com/" $notSecretProperties = @("Scopes","TenantId","BlobName","ContainerName","StorageAccountName","ServerUrl","ppUserName") diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 06ef58616..3dd97e6dc 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -2,6 +2,7 @@ - `PowerPlatformSolutionFolder`: Contains the name of the folder containing a PowerPlatform Solution (only one) - `DeployTo` now has two additional properties `companyId` is the Company Id from Business Central (for PowerPlatform connection) and `ppEnvironmentUrl` is the Url of the PowerPlatform environment to deploy to. +- `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. ### New Actions From e259734ea70e15a543ca001fb833fae0773b9dce Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 28 May 2024 10:55:50 +0200 Subject: [PATCH 30/62] use gh to get branches --- .../CheckForUpdates.HelperFunctions.ps1 | 10 ++++++---- Actions/CheckForUpdates/CheckForUpdates.ps1 | 8 +------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 index 4c1956b5c..b9d4f52a1 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 @@ -12,14 +12,15 @@ If true, the latest SHA of the template repository will be downloaded #> function DownloadTemplateRepository { Param( - [hashtable] $headers, + [string] $token, [string] $templateUrl, [ref] $templateSha, [bool] $downloadLatest ) # Construct API URL - $apiUrl = $templateUrl.Split('@')[0] -replace "^(https:\/\/github\.com\/)(.*)$", "$ENV:GITHUB_API_URL/repos/`$2" + $templateRepo = $templateUrl.Split('@')[0] -replace "^(https:\/\/github\.com\/)(.*)$", "`$2" + $apiUrl = "$ENV:GITHUB_API_URL/repos/$templateRepo" $branch = $templateUrl.Split('@')[1] Write-Host "TemplateUrl: $templateUrl" @@ -28,8 +29,9 @@ function DownloadTemplateRepository { if ($downloadLatest) { # Get Branches from template repository - $response = InvokeWebRequest -Headers $headers -Uri "$apiUrl/branches?per_page=100" -retry - $branchInfo = ($response.content | ConvertFrom-Json) | Where-Object { $_.Name -eq $branch } + # Use Authenticated API request to avoid the 60 API calls per hour limit + $branches = gh api -paginate -H "Authorization: Bearer $token" -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/$templateRepo/branches | ConvertFrom-Json + $branchInfo = $branches | Where-Object { $_.Name -eq $branch } if (!$branchInfo) { throw "$templateUrl doesn't exist" } diff --git a/Actions/CheckForUpdates/CheckForUpdates.ps1 b/Actions/CheckForUpdates/CheckForUpdates.ps1 index 74d0a2e58..8d878ba70 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.ps1 @@ -31,12 +31,6 @@ if ($update -eq 'Y') { } } -# Use Authenticated API request to avoid the 60 API calls per hour limit -$headers = @{ - "Accept" = "application/vnd.github.baptiste-preview+json" - "Authorization" = "Bearer $token" -} - if (-not $templateUrl.Contains('@')) { $templateUrl += "@main" } @@ -69,7 +63,7 @@ if ($repoSettings.templateUrl -ne $templateUrl -or $templateSha -eq '') { $downloadLatest = $true } -$templateFolder = DownloadTemplateRepository -headers $headers -templateUrl $templateUrl -templateSha ([ref]$templateSha) -downloadLatest $downloadLatest +$templateFolder = DownloadTemplateRepository -token $token -templateUrl $templateUrl -templateSha ([ref]$templateSha) -downloadLatest $downloadLatest Write-Host "Template Folder: $templateFolder" $templateBranch = $templateUrl.Split('@')[1] From c57e936e7aa971a926693822c6503d8bbc489e6b Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 28 May 2024 11:21:18 +0200 Subject: [PATCH 31/62] env --- Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 index b9d4f52a1..886f91631 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 @@ -30,7 +30,8 @@ function DownloadTemplateRepository { if ($downloadLatest) { # Get Branches from template repository # Use Authenticated API request to avoid the 60 API calls per hour limit - $branches = gh api -paginate -H "Authorization: Bearer $token" -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/$templateRepo/branches | ConvertFrom-Json + $env:GH_TOKEN = $token + $branches = gh api --paginate -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/$templateRepo/branches | ConvertFrom-Json $branchInfo = $branches | Where-Object { $_.Name -eq $branch } if (!$branchInfo) { throw "$templateUrl doesn't exist" From 95d9b3a6fa3c33112b378b25b56e7c12d8069103 Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 28 May 2024 11:23:49 +0200 Subject: [PATCH 32/62] headers --- Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 index 886f91631..c9d924bb7 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 @@ -44,6 +44,12 @@ function DownloadTemplateRepository { # Download template repository $tempName = Join-Path ([System.IO.Path]::GetTempPath()) ([Guid]::NewGuid().ToString()) + + # Use Authenticated API request to avoid the 60 API calls per hour limit + $headers = @{ + "Accept" = "application/vnd.github.baptiste-preview+json" + "Authorization" = "Bearer $token" + } InvokeWebRequest -Headers $headers -Uri $archiveUrl -OutFile "$tempName.zip" -retry Expand-7zipArchive -Path "$tempName.zip" -DestinationPath $tempName Remove-Item -Path "$tempName.zip" From c01708a3346ea0e3bf7a550dd6a0d9c389dc8993 Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 28 May 2024 12:13:06 +0200 Subject: [PATCH 33/62] dump url --- Actions/Deliver/Deliver.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index ee3595be1..cc2efda35 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -224,6 +224,7 @@ try { $preReleaseTag = 'preview' } $nuGetServerUrl = $nuGetAccount.ServerUrl + Write-Host $nuGetAccount.ServerUrl $nuGetToken = $nuGetAccount.Token Write-Host "$($deliveryTarget)Context secret OK" } From ab4a50674c882febb020695fe07882ea10d74793 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 29 May 2024 14:35:26 +0200 Subject: [PATCH 34/62] dumps --- Actions/RunPipeline/RunPipeline.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index f4e5ee962..1918c57d3 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -121,12 +121,16 @@ try { if ($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds')) { foreach($trustedNuGetFeed in $bcContainerHelperConfig.TrustedNuGetFeeds) { + Write-Host $trustedNuGetFeed.Url if ($trustedNuGetFeed.AuthTokenSecret) { + Write-Host $trustedNuGetFeed.AuthTokenSecret $authTokenSecret = $trustedNuGetFeed.AuthTokenSecret if ($secrets.Keys -notcontains $authTokenSecret) { OutputWarning -message "Secret $authTokenSecret needed for trusted NuGetFeeds cannot be found" } else { + Wite-Host "Set token" + $trustedNuGetFeed | Out-Host $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$authTokenSecret")) if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { $trustedNuGetFeed.Token = $token From dce32ac3889d6826dd2c238841aee0167c157e93 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 29 May 2024 14:38:07 +0200 Subject: [PATCH 35/62] dumps --- Actions/RunPipeline/RunPipeline.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 1918c57d3..e26bd6ca6 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -119,6 +119,12 @@ try { $settings = AnalyzeRepo -settings $settings -baseFolder $baseFolder -project $project @analyzeRepoParams $settings = CheckAppDependencyProbingPaths -settings $settings -token $token -baseFolder $baseFolder -project $project + Write-Host "Test TrustedNugetFeeds" + $bcContainerHelperConfig.GetType().FullName | Out-Host + $bcContainerHelperConfig.TrustedNuGetFeeds | ForEach-Object { + Write-Host $_.Url + } + if ($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds')) { foreach($trustedNuGetFeed in $bcContainerHelperConfig.TrustedNuGetFeeds) { Write-Host $trustedNuGetFeed.Url From ed009da4237b6e8c387d2bdb8711603c6fea922c Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 29 May 2024 14:44:40 +0200 Subject: [PATCH 36/62] wite --- Actions/RunPipeline/RunPipeline.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index e26bd6ca6..57022f0f8 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -135,7 +135,7 @@ try { OutputWarning -message "Secret $authTokenSecret needed for trusted NuGetFeeds cannot be found" } else { - Wite-Host "Set token" + Write-Host "Set token" $trustedNuGetFeed | Out-Host $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$authTokenSecret")) if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { From 84394b99125aa5010701dea5d349765418eba942 Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 29 May 2024 14:52:55 +0200 Subject: [PATCH 37/62] -dumps --- Actions/RunPipeline/RunPipeline.ps1 | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 57022f0f8..7331fca2e 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -119,13 +119,8 @@ try { $settings = AnalyzeRepo -settings $settings -baseFolder $baseFolder -project $project @analyzeRepoParams $settings = CheckAppDependencyProbingPaths -settings $settings -token $token -baseFolder $baseFolder -project $project - Write-Host "Test TrustedNugetFeeds" - $bcContainerHelperConfig.GetType().FullName | Out-Host - $bcContainerHelperConfig.TrustedNuGetFeeds | ForEach-Object { - Write-Host $_.Url - } - if ($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds')) { + Write-Host "Reading TrustedNuGetFeeds" foreach($trustedNuGetFeed in $bcContainerHelperConfig.TrustedNuGetFeeds) { Write-Host $trustedNuGetFeed.Url if ($trustedNuGetFeed.AuthTokenSecret) { @@ -135,13 +130,13 @@ try { OutputWarning -message "Secret $authTokenSecret needed for trusted NuGetFeeds cannot be found" } else { - Write-Host "Set token" - $trustedNuGetFeed | Out-Host $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$authTokenSecret")) if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { + Write-Host "Set token" $trustedNuGetFeed.Token = $token } else { + Write-Host "Add token" $trustedNuGetFeed | Add-Member -MemberType NoteProperty -Name Token -Value $token } } From 6ecd45ceccdb80aa67ef51d279b48f28301eb362 Mon Sep 17 00:00:00 2001 From: freddydk Date: Fri, 7 Jun 2024 10:22:20 +0200 Subject: [PATCH 38/62] move release note --- RELEASENOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index bbff93805..0a44505d8 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,3 +1,6 @@ +### New Settings + +- `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. ## v5.2 From 10e70a8dd3ba72626c030465c6779c7d0f64371a Mon Sep 17 00:00:00 2001 From: freddydk Date: Mon, 24 Jun 2024 19:30:59 +0200 Subject: [PATCH 39/62] pre-commit --- RELEASENOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 141960fe9..f9f5f2a9e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -11,6 +11,7 @@ In the summary after a Test Run, you now also have the result of performance tes - `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. - `bcptThresholds` is a JSON object with properties for the default thresholds for the Business Central Performance Toolkit + - **DurationWarning** - a warning is issued if the duration of a bcpt test degrades more than this percentage (default 10) - **DurationError** - an error is issued if the duration of a bcpt test degrades more than this percentage (default 25) - **NumberOfSqlStmtsWarning** - a warning is issued if the number of SQL statements from a bcpt test increases more than this percentage (default 5) From d6e9722cb1a640a510441185eaadb15ff234f6ea Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 22 Aug 2024 13:54:21 +0200 Subject: [PATCH 40/62] remove telemetry --- Actions/Deliver/Deliver.ps1 | 632 +++++++++++++++++------------------- 1 file changed, 297 insertions(+), 335 deletions(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index 0e3acc712..3cd2aedf4 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -3,8 +3,6 @@ [string] $actor, [Parameter(HelpMessage = "The GitHub token running the action", Mandatory = $false)] [string] $token, - [Parameter(HelpMessage = "Specifies the parent telemetry scope for the telemetry signal", Mandatory = $false)] - [string] $parentTelemetryScopeJson = '7b7d', [Parameter(HelpMessage = "Projects to deliver (default is all)", Mandatory = $false)] [string] $projects = "*", [Parameter(HelpMessage = "Delivery target (AppSource or Storage)", Mandatory = $true)] @@ -12,7 +10,7 @@ [Parameter(HelpMessage = "The artifacts to deliver or a folder in which the artifacts have been downloaded", Mandatory = $true)] [string] $artifacts, [Parameter(HelpMessage = "Type of delivery (CD or Release)", Mandatory = $false)] - [ValidateSet('CD','Release')] + [ValidateSet('CD', 'Release')] [string] $type = "CD", [Parameter(HelpMessage = "Types of artifacts to deliver (Apps,Dependencies,TestApps)", Mandatory = $false)] [string] $atypes = "Apps,Dependencies,TestApps", @@ -61,82 +59,91 @@ function ConnectAzStorageAccount { return $azStorageContext } -$telemetryScope = $null - -try { - . (Join-Path -Path $PSScriptRoot -ChildPath "../AL-Go-Helper.ps1" -Resolve) - DownloadAndImportBcContainerHelper - - import-module (Join-Path -path $PSScriptRoot -ChildPath "../TelemetryHelper.psm1" -Resolve) - $telemetryScope = CreateScope -eventId 'DO0081' -parentTelemetryScopeJson $parentTelemetryScopeJson - - $refname = "$ENV:GITHUB_REF_NAME".Replace('/','_') - - $artifacts = $artifacts.Replace('/',([System.IO.Path]::DirectorySeparatorChar)).Replace('\',([System.IO.Path]::DirectorySeparatorChar)) - - $baseFolder = $ENV:GITHUB_WORKSPACE - $settings = ReadSettings -baseFolder $baseFolder - $projectList = @(GetProjectsFromRepository -baseFolder $baseFolder -projectsFromSettings $settings.projects -selectProjects $projects) - if ($deliveryTarget -eq "AppSource") { - $atypes = "Apps,Dependencies" +. (Join-Path -Path $PSScriptRoot -ChildPath "../AL-Go-Helper.ps1" -Resolve) +DownloadAndImportBcContainerHelper +import-module (Join-Path -path $PSScriptRoot -ChildPath "../TelemetryHelper.psm1" -Resolve) +$telemetryScope = CreateScope -eventId 'DO0081' -parentTelemetryScopeJson $parentTelemetryScopeJson +$refname = "$ENV:GITHUB_REF_NAME".Replace('/','_') +$artifacts = $artifacts.Replace('/',([System.IO.Path]::DirectorySeparatorChar)).Replace('\',([System.IO.Path]::DirectorySeparatorChar)) +$baseFolder = $ENV:GITHUB_WORKSPACE +$settings = ReadSettings -baseFolder $baseFolder +$projectList = @(GetProjectsFromRepository -baseFolder $baseFolder -projectsFromSettings $settings.projects -selectProjects $projects) +if ($deliveryTarget -eq "AppSource") { + $atypes = "Apps,Dependencies" +} +Write-Host "Artifacts $artifacts" +Write-Host "Projects:" +$projectList | Out-Host +$secrets = $env:Secrets | ConvertFrom-Json +foreach($thisProject in $projectList) { + # $project should be the project part of the artifact name generated from the build + if ($thisProject -and ($thisProject -ne '.')) { + $project = $thisProject.Replace('\','_').Replace('/','_') } - Write-Host "Artifacts $artifacts" - Write-Host "Projects:" - $projectList | Out-Host - - $secrets = $env:Secrets | ConvertFrom-Json - foreach($thisProject in $projectList) { - # $project should be the project part of the artifact name generated from the build - if ($thisProject -and ($thisProject -ne '.')) { - $project = $thisProject.Replace('\','_').Replace('/','_') - } - else { - $project = $settings.repoName + else { + $project = $settings.repoName + } + # projectName is the project name stripped for special characters + $projectName = $project -replace "[^a-z0-9]", "-" + Write-Host "ProjectName '$projectName'" + if ($artifacts -like "$($baseFolder)*") { + $artifactsFolder = $artifacts + } + else { + $artifactsFolder = Join-Path $baseFolder ".artifacts" + $artifactsFolderCreated = $false + if (!(Test-Path $artifactsFolder)) { + New-Item $artifactsFolder -ItemType Directory | Out-Null + $artifactsFolderCreated = $true } - # projectName is the project name stripped for special characters - $projectName = $project -replace "[^a-z0-9]", "-" - Write-Host "ProjectName '$projectName'" - - if ($artifacts -like "$($baseFolder)*") { - $artifactsFolder = $artifacts + if ($artifacts -eq '.artifacts') { + # Artifacts from this build have been downloaded } - else { - $artifactsFolder = Join-Path $baseFolder ".artifacts" - $artifactsFolderCreated = $false - if (!(Test-Path $artifactsFolder)) { - New-Item $artifactsFolder -ItemType Directory | Out-Null - $artifactsFolderCreated = $true + elseif ($artifacts -eq "current" -or $artifacts -eq "prerelease" -or $artifacts -eq "draft") { + # project is the project name as used in release asset names + $project = [Uri]::EscapeDataString($project.Replace(' ','.')).Replace('%','') + # latest released version + $releases = GetReleases -token $token -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY + if ($artifacts -eq "current") { + $release = $releases | Where-Object { -not ($_.prerelease -or $_.draft) } | Select-Object -First 1 } - if ($artifacts -eq '.artifacts') { - # Artifacts from this build have been downloaded + elseif ($artifacts -eq "prerelease") { + $release = $releases | Where-Object { -not ($_.draft) } | Select-Object -First 1 } - elseif ($artifacts -eq "current" -or $artifacts -eq "prerelease" -or $artifacts -eq "draft") { - # project is the project name as used in release asset names - $project = [Uri]::EscapeDataString($project.Replace(' ','.')).Replace('%','') - - # latest released version - $releases = GetReleases -token $token -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY - if ($artifacts -eq "current") { - $release = $releases | Where-Object { -not ($_.prerelease -or $_.draft) } | Select-Object -First 1 - } - elseif ($artifacts -eq "prerelease") { - $release = $releases | Where-Object { -not ($_.draft) } | Select-Object -First 1 - } - elseif ($artifacts -eq "draft") { - $release = $releases | Select-Object -First 1 + elseif ($artifacts -eq "draft") { + $release = $releases | Select-Object -First 1 + } + if (!($release)) { + throw "Unable to locate $artifacts release" + } + foreach($mask in $atypes.Split(',')) { + $artifactFile = DownloadRelease -token $token -projects $project -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY -release $release -path $artifactsFolder -mask $mask + Write-Host "'$artifactFile'" + if (!$artifactFile -or !(Test-Path $artifactFile)) { + if ($mask -eq 'Apps') { + throw "Artifact $artifacts was not found on any release. Make sure that the artifact files exist and files are not corrupted." + } } - if (!($release)) { - throw "Unable to locate $artifacts release" + else { + if ($artifactFile -notlike '*.zip') { + throw "Downloaded artifact is not a .zip file" + } + Expand-Archive -Path $artifactFile -DestinationPath ($artifactFile.SubString(0,$artifactFile.Length-4)) + Remove-Item $artifactFile -Force } - foreach($mask in $atypes.Split(',')) { - $artifactFile = DownloadRelease -token $token -projects $project -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY -release $release -path $artifactsFolder -mask $mask - Write-Host "'$artifactFile'" - if (!$artifactFile -or !(Test-Path $artifactFile)) { - if ($mask -eq 'Apps') { - throw "Artifact $artifacts was not found on any release. Make sure that the artifact files exist and files are not corrupted." + } + } + else { + $atypes.Split(',') | ForEach-Object { + $atype = $_ + $allArtifacts = GetArtifacts -token $token -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY -mask $atype -projects $project -version $artifacts -branch $ENV:GITHUB_REF_NAME + if ($allArtifacts) { + $allArtifacts | ForEach-Object { + $artifactFile = DownloadArtifact -token $token -artifact $_ -path $artifactsFolder + Write-Host $artifactFile + if (!(Test-Path $artifactFile)) { + throw "Unable to download artifact $($_.name)" } - } - else { if ($artifactFile -notlike '*.zip') { throw "Downloaded artifact is not a .zip file" } @@ -144,303 +151,258 @@ try { Remove-Item $artifactFile -Force } } - } - else { - $atypes.Split(',') | ForEach-Object { - $atype = $_ - $allArtifacts = GetArtifacts -token $token -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY -mask $atype -projects $project -version $artifacts -branch $ENV:GITHUB_REF_NAME - if ($allArtifacts) { - $allArtifacts | ForEach-Object { - $artifactFile = DownloadArtifact -token $token -artifact $_ -path $artifactsFolder - Write-Host $artifactFile - if (!(Test-Path $artifactFile)) { - throw "Unable to download artifact $($_.name)" - } - if ($artifactFile -notlike '*.zip') { - throw "Downloaded artifact is not a .zip file" - } - Expand-Archive -Path $artifactFile -DestinationPath ($artifactFile.SubString(0,$artifactFile.Length-4)) - Remove-Item $artifactFile -Force - } + else { + if ($atype -eq "Apps") { + throw "ERROR: Could not find any $atype artifacts for projects $projects, version $artifacts" } else { - if ($atype -eq "Apps") { - throw "ERROR: Could not find any $atype artifacts for projects $projects, version $artifacts" - } - else { - Write-Host "WARNING: Could not find any $atype artifacts for projects $projects, version $artifacts" - } + Write-Host "WARNING: Could not find any $atype artifacts for projects $projects, version $artifacts" } } } } - - Write-Host "Project '$project'" - Write-Host "Artifacts:" - Get-ChildItem -Path $artifactsFolder | ForEach-Object { - Write-Host "- $($_.Name)" + } + Write-Host "Project '$project'" + Write-Host "Artifacts:" + Get-ChildItem -Path $artifactsFolder | ForEach-Object { + Write-Host "- $($_.Name)" + } + # Check if there is a custom script to run for the delivery target + $customScript = Join-Path $baseFolder ".github/DeliverTo$deliveryTarget.ps1" + if (Test-Path $customScript -PathType Leaf) { + Write-Host "Found custom script $customScript for delivery target $deliveryTarget" + $projectSettings = ReadSettings -baseFolder $baseFolder -project $thisProject + $projectSettings = AnalyzeRepo -settings $projectSettings -baseFolder $baseFolder -project $thisProject -doNotCheckArtifactSetting -doNotIssueWarnings + $parameters = @{ + "Project" = $thisProject + "ProjectName" = $projectName + "type" = $type + "Context" = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) + "RepoSettings" = $settings + "ProjectSettings" = $projectSettings } - - # Check if there is a custom script to run for the delivery target - $customScript = Join-Path $baseFolder ".github/DeliverTo$deliveryTarget.ps1" - - if (Test-Path $customScript -PathType Leaf) { - Write-Host "Found custom script $customScript for delivery target $deliveryTarget" - - $projectSettings = ReadSettings -baseFolder $baseFolder -project $thisProject - $projectSettings = AnalyzeRepo -settings $projectSettings -baseFolder $baseFolder -project $thisProject -doNotCheckArtifactSetting -doNotIssueWarnings - $parameters = @{ - "Project" = $thisProject - "ProjectName" = $projectName - "type" = $type - "Context" = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) - "RepoSettings" = $settings - "ProjectSettings" = $projectSettings - } - #Calculate the folders per artifact type - - #Calculate the folders per artifact type - 'Apps', 'TestApps', 'Dependencies' | ForEach-Object { - $artifactType = $_ - $singleArtifactFilter = "$project-$refname-$artifactType-*.*.*.*"; - - # Get the folder holding the artifacts from the standard build - $artifactFolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder $singleArtifactFilter) -Directory) - - # Verify that there is an apps folder - if ($artifactFolder.Count -eq 0 -and $artifactType -eq "Apps") { - throw "Internal error - unable to locate apps folder" - } - - # Verify that there is only at most one artifact folder for the standard build - if ($artifactFolder.Count -gt 1) { - $artifactFolder | Out-Host - throw "Internal error - multiple $artifactType folders located" - } - - # Add the artifact folder to the parameters - if ($artifactFolder.Count -ne 0) { - $parameters[$artifactType.ToLowerInvariant() + "Folder"] = $artifactFolder[0].FullName - } - - # Get the folders holding the artifacts from all build modes - $multipleArtifactFilter = "$project-$refname-*$artifactType-*.*.*.*"; - $artifactFolders = @(Get-ChildItem -Path (Join-Path $artifactsFolder $multipleArtifactFilter) -Directory) - if ($artifactFolders.Count -gt 0) { - $parameters[$artifactType.ToLowerInvariant() + "Folders"] = $artifactFolders.FullName - } + #Calculate the folders per artifact type + #Calculate the folders per artifact type + 'Apps', 'TestApps', 'Dependencies' | ForEach-Object { + $artifactType = $_ + $singleArtifactFilter = "$project-$refname-$artifactType-*.*.*.*"; + # Get the folder holding the artifacts from the standard build + $artifactFolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder $singleArtifactFilter) -Directory) + # Verify that there is an apps folder + if ($artifactFolder.Count -eq 0 -and $artifactType -eq "Apps") { + throw "Internal error - unable to locate apps folder" } - - Write-Host "Calling custom script: $customScript" - . $customScript -parameters $parameters - } - elseif ($deliveryTarget -eq 'GitHubPackages' -or $deliveryTarget -eq 'NuGet') { - $preReleaseTag = '' - try { - $nuGetAccount = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) | ConvertFrom-Json | ConvertTo-HashTable - if ($deliveryTarget -eq 'NuGet' -and $type -eq 'CD') { - $preReleaseTag = 'preview' - } - $nuGetServerUrl = $nuGetAccount.ServerUrl - Write-Host $nuGetAccount.ServerUrl - $nuGetToken = $nuGetAccount.Token - Write-Host "$($deliveryTarget)Context secret OK" + # Verify that there is only at most one artifact folder for the standard build + if ($artifactFolder.Count -gt 1) { + $artifactFolder | Out-Host + throw "Internal error - multiple $artifactType folders located" } - catch { - throw "$($deliveryTarget)Context secret is malformed. Needs to be formatted as Json, containing serverUrl and token as a minimum." + # Add the artifact folder to the parameters + if ($artifactFolder.Count -ne 0) { + $parameters[$artifactType.ToLowerInvariant() + "Folder"] = $artifactFolder[0].FullName } - 'Apps','TestApps' | ForEach-Object { - $folder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$($_)-*.*.*.*") | Where-Object { $_.PSIsContainer }) - if ($folder.Count -gt 1) { - $folder | Out-Host - throw "Internal error - multiple $_ folders located" - } - elseif ($folder.Count -eq 1) { - Get-Item -Path (Join-Path $folder[0] "*.app") | ForEach-Object { - $parameters = @{ - "gitHubRepository" = "$ENV:GITHUB_SERVER_URL/$ENV:GITHUB_REPOSITORY" - "preReleaseTag" = $preReleaseTag - "appFile" = $_.FullName - } - $package = New-BcNuGetPackage @parameters - Push-BcNuGetPackage -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -bcNuGetPackage $package - } - } + # Get the folders holding the artifacts from all build modes + $multipleArtifactFilter = "$project-$refname-*$artifactType-*.*.*.*"; + $artifactFolders = @(Get-ChildItem -Path (Join-Path $artifactsFolder $multipleArtifactFilter) -Directory) + if ($artifactFolders.Count -gt 0) { + $parameters[$artifactType.ToLowerInvariant() + "Folders"] = $artifactFolders.FullName } } - elseif ($deliveryTarget -eq "Storage") { - InstallAzModuleIfNeeded -name 'Az.Storage' - try { - $storageAccountCredentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.storageContext)) | ConvertFrom-Json - $storageAccountCredentials.StorageAccountName | Out-Null - $storageContainerName = $storageAccountCredentials.ContainerName.ToLowerInvariant().replace('{project}',$projectName).replace('{branch}',$refname).ToLowerInvariant() - $storageBlobName = $storageAccountCredentials.BlobName.ToLowerInvariant() - } - catch { - throw "StorageContext secret is malformed. Needs to be formatted as Json, containing StorageAccountName, containerName, blobName.`nError was: $($_.Exception.Message)" - } - $azStorageContext = ConnectAzStorageAccount -storageAccountCredentials $storageAccountCredentials - Write-Host "Storage Container Name is $storageContainerName" - Write-Host "Storage Blob Name is $storageBlobName" - - $containerExists = $true - try { - Get-AzStorageContainer -Context $azStorageContext -name $storageContainerName | Out-Null - } - catch { - $containerExists = $false + Write-Host "Calling custom script: $customScript" + . $customScript -parameters $parameters + } + elseif ($deliveryTarget -eq 'GitHubPackages' -or $deliveryTarget -eq 'NuGet') { + $preReleaseTag = '' + try { + $nuGetAccount = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) | ConvertFrom-Json | ConvertTo-HashTable + if ($deliveryTarget -eq 'NuGet' -and $type -eq 'CD') { + $preReleaseTag = 'preview' } - - if (-not $containerExists -and $settings.Contains('DeliverToStorage') -and $settings."DeliverToStorage".Contains('CreateContainerIfNotExist') -and $settings."DeliverToStorage"."CreateContainerIfNotExist" -eq $true) { - Write-Host "Container $storageContainerName does not exist. Creating..." - New-AzStorageContainer -Context $azStorageContext -Name $storageContainerName | Out-Null + $nuGetServerUrl = $nuGetAccount.ServerUrl + Write-Host $nuGetAccount.ServerUrl + $nuGetToken = $nuGetAccount.Token + Write-Host "$($deliveryTarget)Context secret OK" + } + catch { + throw "$($deliveryTarget)Context secret is malformed. Needs to be formatted as Json, containing serverUrl and token as a minimum." + } + 'Apps','TestApps' | ForEach-Object { + $folder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$($_)-*.*.*.*") | Where-Object { $_.PSIsContainer }) + if ($folder.Count -gt 1) { + $folder | Out-Host + throw "Internal error - multiple $_ folders located" } - - Write-Host "Delivering to $storageContainerName in $($storageAccountCredentials.StorageAccountName)" - $atypes.Split(',') | ForEach-Object { - $atype = $_ - Write-Host "Looking for: $project-$refname-$atype-*.*.*.*" - $artfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$atype-*.*.*.*") | Where-Object { $_.PSIsContainer }) - if ($artFolder.Count -eq 0) { - if ($atype -eq "Apps") { - throw "Error - unable to locate apps" - } - else { - Write-Host "WARNING: Unable to locate $atype" + elseif ($folder.Count -eq 1) { + Get-Item -Path (Join-Path $folder[0] "*.app") | ForEach-Object { + $parameters = @{ + "gitHubRepository" = "$ENV:GITHUB_SERVER_URL/$ENV:GITHUB_REPOSITORY" + "preReleaseTag" = $preReleaseTag + "appFile" = $_.FullName } + $package = New-BcNuGetPackage @parameters + Push-BcNuGetPackage -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -bcNuGetPackage $package } - elseif ($artFolder.Count -gt 1) { - $artFolder | Out-Host - throw "Internal error - multiple $atype folders located" + } + } + } + elseif ($deliveryTarget -eq "Storage") { + InstallAzModuleIfNeeded -name 'Az.Storage' + try { + $storageAccountCredentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.storageContext)) | ConvertFrom-Json + $storageAccountCredentials.StorageAccountName | Out-Null + $storageContainerName = $storageAccountCredentials.ContainerName.ToLowerInvariant().replace('{project}',$projectName).replace('{branch}',$refname).ToLowerInvariant() + $storageBlobName = $storageAccountCredentials.BlobName.ToLowerInvariant() + } + catch { + throw "StorageContext secret is malformed. Needs to be formatted as Json, containing StorageAccountName, containerName, blobName.`nError was: $($_.Exception.Message)" + } + $azStorageContext = ConnectAzStorageAccount -storageAccountCredentials $storageAccountCredentials + Write-Host "Storage Container Name is $storageContainerName" + Write-Host "Storage Blob Name is $storageBlobName" + $containerExists = $true + try { + Get-AzStorageContainer -Context $azStorageContext -name $storageContainerName | Out-Null + } + catch { + $containerExists = $false + } + if (-not $containerExists -and $settings.Contains('DeliverToStorage') -and $settings."DeliverToStorage".Contains('CreateContainerIfNotExist') -and $settings."DeliverToStorage"."CreateContainerIfNotExist" -eq $true) { + Write-Host "Container $storageContainerName does not exist. Creating..." + New-AzStorageContainer -Context $azStorageContext -Name $storageContainerName | Out-Null + } + Write-Host "Delivering to $storageContainerName in $($storageAccountCredentials.StorageAccountName)" + $atypes.Split(',') | ForEach-Object { + $atype = $_ + Write-Host "Looking for: $project-$refname-$atype-*.*.*.*" + $artfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-$atype-*.*.*.*") | Where-Object { $_.PSIsContainer }) + if ($artFolder.Count -eq 0) { + if ($atype -eq "Apps") { + throw "Error - unable to locate apps" } else { - $artfolder = $artfolder[0].FullName - $version = $artfolder.SubString($artfolder.IndexOf("-$refname-$atype-")+"-$refname-$atype-".Length) - Write-Host $artfolder - $versions = @("$version-preview","preview") - if ($type -eq "Release") { - $versions += @($version,"latest") - } - $tempFile = Join-Path ([System.IO.Path]::GetTempPath()) "$([Guid]::newguid().ToString()).zip" - try { - Write-Host "Compressing" - Compress-Archive -Path (Join-Path $artfolder '*') -DestinationPath $tempFile -Force - $versions | ForEach-Object { - $version = $_ - $blob = $storageBlobName.replace('{project}',$projectName).replace('{branch}',$refname).replace('{version}',$version).replace('{type}',$atype).ToLowerInvariant() - Write-Host "Delivering $blob" - Set-AzStorageBlobContent -Context $azStorageContext -Container $storageContainerName -File $tempFile -blob $blob -Force | Out-Null - } - } - finally { - Remove-Item $tempFile -Force -ErrorAction SilentlyContinue - } + Write-Host "WARNING: Unable to locate $atype" } } - } - elseif ($deliveryTarget -eq "AppSource") { - $projectSettings = ReadSettings -baseFolder $baseFolder -project $thisProject - $projectSettings = AnalyzeRepo -settings $projectSettings -baseFolder $baseFolder -project $thisProject -doNotCheckArtifactSetting -doNotIssueWarnings - # Use old settings and issue warnings - 'continuousDelivery','mainAppFolder','productId' | ForEach-Object { - if ($projectSettings.Keys -contains "AppSource$_") { - OutputWarning "Using AppSource$_ in $thisProject/.AL-Go/settings.json is deprecated. Use deliverToAppSource.$_ instead. If both values are defined, the value in AppSource$_ is used (even if it is deprecated)." - $projectSettings.deliverToAppSource."$_" = $projectSettings."AppSource$_" - } + elseif ($artFolder.Count -gt 1) { + $artFolder | Out-Host + throw "Internal error - multiple $atype folders located" } - # if type is Release, we only get here with the projects that needs to be delivered to AppSource - # if type is CD, we get here for all projects, but should only deliver to AppSource if AppSourceContinuousDelivery is set to true - if ($type -eq 'Release' -or $projectSettings.deliverToAppSource.continuousDelivery) { - # AppSource submission requires the Az.Storage module - InstallAzModuleIfNeeded -name 'Az.Storage' - $appSourceContext = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.appSourceContext)) | ConvertFrom-Json | ConvertTo-HashTable - if (!$appSourceContext) { - throw "appSourceContext secret is missing" - } - $authContext = New-BcAuthContext @appSourceContext - - if ($projectSettings.deliverToAppSource.MainAppFolder) { - $AppSourceMainAppFolder = $projectSettings.deliverToAppSource.MainAppFolder + else { + $artfolder = $artfolder[0].FullName + $version = $artfolder.SubString($artfolder.IndexOf("-$refname-$atype-")+"-$refname-$atype-".Length) + Write-Host $artfolder + $versions = @("$version-preview","preview") + if ($type -eq "Release") { + $versions += @($version,"latest") } - else { - try { - $AppSourceMainAppFolder = $projectSettings.appFolders[0] - } - catch { - throw "Unable to determine main App folder" + $tempFile = Join-Path ([System.IO.Path]::GetTempPath()) "$([Guid]::newguid().ToString()).zip" + try { + Write-Host "Compressing" + Compress-Archive -Path (Join-Path $artfolder '*') -DestinationPath $tempFile -Force + $versions | ForEach-Object { + $version = $_ + $blob = $storageBlobName.replace('{project}',$projectName).replace('{branch}',$refname).replace('{version}',$version).replace('{type}',$atype).ToLowerInvariant() + Write-Host "Delivering $blob" + Set-AzStorageBlobContent -Context $azStorageContext -Container $storageContainerName -File $tempFile -blob $blob -Force | Out-Null } } - if (!$projectSettings.deliverToAppSource.ProductId) { - throw "deliverToAppSource.ProductId needs to be specified in $thisProject/.AL-Go/settings.json in order to deliver to AppSource" - } - Write-Host "AppSource MainAppFolder $AppSourceMainAppFolder" - - $mainAppJson = Get-Content -Path (Join-Path $baseFolder "$thisProject/$AppSourceMainAppFolder/app.json") -Encoding UTF8 | ConvertFrom-Json - $mainAppFileName = ("$($mainAppJson.Publisher)_$($mainAppJson.Name)_".Split([System.IO.Path]::GetInvalidFileNameChars()) -join '') + "*.*.*.*.app" - $artfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-Apps-*.*.*.*") | Where-Object { $_.PSIsContainer }) - if ($artFolder.Count -eq 0) { - throw "Internal error - unable to locate apps folder" + finally { + Remove-Item $tempFile -Force -ErrorAction SilentlyContinue } - if ($artFolder.Count -gt 1) { - $artFolder | Out-Host - throw "Internal error - multiple apps folders located" - } - $artfolder = $artfolder[0].FullName - $appFile = Get-ChildItem -path $artFolder | Where-Object { $_.name -like $mainAppFileName } | ForEach-Object { $_.FullName } - $libraryAppFiles = @(Get-ChildItem -path $artFolder | Where-Object { $_.name -notlike $mainAppFileName } | ForEach-Object { $_.FullName }) - - $appSourceIncludeDependencies = $projectSettings.deliverToAppSource.includeDependencies - if ($appSourceIncludeDependencies -and $appSourceIncludeDependencies.count -gt 0) { - $depfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-Dependencies-*.*.*.*") | Where-Object { $_.PSIsContainer }) - if ($depFolder.Count -eq 0) { - throw "Unable to locate dependencies. You need to set generateDependencyArtifact to true in $thisProject/.AL-Go/settings.json in order to deliver dependencies to AppSource" - } - if ($depFolder.Count -gt 1) { - $depFolder | Out-Host - throw "Internal error - multiple dependencies folders located" - } - $depfolder = $depfolder[0].FullName - $libraryAppFiles += @(Get-ChildItem -path $depFolder | Where-Object { - $name = $_.name - $appSourceIncludeDependencies | Where-Object { $name -like $_ } - } | ForEach-Object { $_.FullName }) + } + } + } + elseif ($deliveryTarget -eq "AppSource") { + $projectSettings = ReadSettings -baseFolder $baseFolder -project $thisProject + $projectSettings = AnalyzeRepo -settings $projectSettings -baseFolder $baseFolder -project $thisProject -doNotCheckArtifactSetting -doNotIssueWarnings + # Use old settings and issue warnings + 'continuousDelivery','mainAppFolder','productId' | ForEach-Object { + if ($projectSettings.Keys -contains "AppSource$_") { + OutputWarning "Using AppSource$_ in $thisProject/.AL-Go/settings.json is deprecated. Use deliverToAppSource.$_ instead. If both values are defined, the value in AppSource$_ is used (even if it is deprecated)." + $projectSettings.deliverToAppSource."$_" = $projectSettings."AppSource$_" + } + } + # if type is Release, we only get here with the projects that needs to be delivered to AppSource + # if type is CD, we get here for all projects, but should only deliver to AppSource if AppSourceContinuousDelivery is set to true + if ($type -eq 'Release' -or $projectSettings.deliverToAppSource.continuousDelivery) { + # AppSource submission requires the Az.Storage module + InstallAzModuleIfNeeded -name 'Az.Storage' + $appSourceContext = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.appSourceContext)) | ConvertFrom-Json | ConvertTo-HashTable + if (!$appSourceContext) { + throw "appSourceContext secret is missing" + } + $authContext = New-BcAuthContext @appSourceContext + if ($projectSettings.deliverToAppSource.MainAppFolder) { + $AppSourceMainAppFolder = $projectSettings.deliverToAppSource.MainAppFolder + } + else { + try { + $AppSourceMainAppFolder = $projectSettings.appFolders[0] } - - Write-Host "Main App File:" - Write-Host "- $([System.IO.Path]::GetFileName($appFile))" - Write-Host "Library App Files:" - if ($libraryAppFiles.Count -eq 0) { - Write-Host "- None" + catch { + throw "Unable to determine main App folder" } - else { - $libraryAppFiles | ForEach-Object { Write-Host "- $([System.IO.Path]::GetFileName($_))" } + } + if (!$projectSettings.deliverToAppSource.ProductId) { + throw "deliverToAppSource.ProductId needs to be specified in $thisProject/.AL-Go/settings.json in order to deliver to AppSource" + } + Write-Host "AppSource MainAppFolder $AppSourceMainAppFolder" + $mainAppJson = Get-Content -Path (Join-Path $baseFolder "$thisProject/$AppSourceMainAppFolder/app.json") -Encoding UTF8 | ConvertFrom-Json + $mainAppFileName = ("$($mainAppJson.Publisher)_$($mainAppJson.Name)_".Split([System.IO.Path]::GetInvalidFileNameChars()) -join '') + "*.*.*.*.app" + $artfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-Apps-*.*.*.*") | Where-Object { $_.PSIsContainer }) + if ($artFolder.Count -eq 0) { + throw "Internal error - unable to locate apps folder" + } + if ($artFolder.Count -gt 1) { + $artFolder | Out-Host + throw "Internal error - multiple apps folders located" + } + $artfolder = $artfolder[0].FullName + $appFile = Get-ChildItem -path $artFolder | Where-Object { $_.name -like $mainAppFileName } | ForEach-Object { $_.FullName } + $libraryAppFiles = @(Get-ChildItem -path $artFolder | Where-Object { $_.name -notlike $mainAppFileName } | ForEach-Object { $_.FullName }) + $appSourceIncludeDependencies = $projectSettings.deliverToAppSource.includeDependencies + if ($appSourceIncludeDependencies -and $appSourceIncludeDependencies.count -gt 0) { + $depfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-Dependencies-*.*.*.*") | Where-Object { $_.PSIsContainer }) + if ($depFolder.Count -eq 0) { + throw "Unable to locate dependencies. You need to set generateDependencyArtifact to true in $thisProject/.AL-Go/settings.json in order to deliver dependencies to AppSource" } - if (-not $appFile) { - throw "Unable to locate main app file ($mainAppFileName doesn't exist)" + if ($depFolder.Count -gt 1) { + $depFolder | Out-Host + throw "Internal error - multiple dependencies folders located" } - Write-Host "Submitting to AppSource" - $status = New-AppSourceSubmission -authContext $authContext -productId $projectSettings.deliverToAppSource.productId -appFile $appFile -libraryAppFiles $libraryAppFiles -doNotWait -autoPromote:$goLive -Force - if ($goLive) { - if ($status.state -ne 'Published' -or ($status.substate -ne 'ReadyToPublish' -and $status.substate -ne 'InStore')) { - throw "AppSource submission failed. Status is $($status.state)/$($status.substate)" - } + $depfolder = $depfolder[0].FullName + $libraryAppFiles += @(Get-ChildItem -path $depFolder | Where-Object { + $name = $_.name + $appSourceIncludeDependencies | Where-Object { $name -like $_ } + } | ForEach-Object { $_.FullName }) + } + Write-Host "Main App File:" + Write-Host "- $([System.IO.Path]::GetFileName($appFile))" + Write-Host "Library App Files:" + if ($libraryAppFiles.Count -eq 0) { + Write-Host "- None" + } + else { + $libraryAppFiles | ForEach-Object { Write-Host "- $([System.IO.Path]::GetFileName($_))" } + } + if (-not $appFile) { + throw "Unable to locate main app file ($mainAppFileName doesn't exist)" + } + Write-Host "Submitting to AppSource" + $status = New-AppSourceSubmission -authContext $authContext -productId $projectSettings.deliverToAppSource.productId -appFile $appFile -libraryAppFiles $libraryAppFiles -doNotWait -autoPromote:$goLive -Force + if ($goLive) { + if ($status.state -ne 'Published' -or ($status.substate -ne 'ReadyToPublish' -and $status.substate -ne 'InStore')) { + throw "AppSource submission failed. Status is $($status.state)/$($status.substate)" } } } - else { - throw "Internal error, no handler for $deliveryTarget" - } - - if ($artifactsFolderCreated) { - Remove-Item $artifactsFolder -Recurse -Force - } + } + else { + throw "Internal error, no handler for $deliveryTarget" } - TrackTrace -telemetryScope $telemetryScope -} -catch { - if (Get-Module BcContainerHelper) { - TrackException -telemetryScope $telemetryScope -errorRecord $_ + if ($artifactsFolderCreated) { + Remove-Item $artifactsFolder -Recurse -Force } - throw } + From a55d1513a89a3264d6b438edb6985da1932da144 Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 22 Aug 2024 14:04:25 +0200 Subject: [PATCH 41/62] format --- Actions/Deliver/Deliver.ps1 | 52 ++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index 296b98c75..3518cb076 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -61,10 +61,11 @@ function ConnectAzStorageAccount { . (Join-Path -Path $PSScriptRoot -ChildPath "../AL-Go-Helper.ps1" -Resolve) DownloadAndImportBcContainerHelper -import-module (Join-Path -path $PSScriptRoot -ChildPath "../TelemetryHelper.psm1" -Resolve) -$telemetryScope = CreateScope -eventId 'DO0081' -parentTelemetryScopeJson $parentTelemetryScopeJson + $refname = "$ENV:GITHUB_REF_NAME".Replace('/','_') + $artifacts = $artifacts.Replace('/',([System.IO.Path]::DirectorySeparatorChar)).Replace('\',([System.IO.Path]::DirectorySeparatorChar)) + $baseFolder = $ENV:GITHUB_WORKSPACE $settings = ReadSettings -baseFolder $baseFolder $projectList = @(GetProjectsFromRepository -baseFolder $baseFolder -projectsFromSettings $settings.projects -selectProjects $projects) @@ -74,8 +75,9 @@ if ($deliveryTarget -eq "AppSource") { Write-Host "Artifacts $artifacts" Write-Host "Projects:" $projectList | Out-Host + $secrets = $env:Secrets | ConvertFrom-Json -foreach($thisProject in $projectList) { +foreach ($thisProject in $projectList) { # $project should be the project part of the artifact name generated from the build if ($thisProject -and ($thisProject -ne '.')) { $project = $thisProject.Replace('\','_').Replace('/','_') @@ -86,6 +88,7 @@ foreach($thisProject in $projectList) { # projectName is the project name stripped for special characters $projectName = $project -replace "[^a-z0-9]", "-" Write-Host "ProjectName '$projectName'" + if ($artifacts -like "$($baseFolder)*") { $artifactsFolder = $artifacts } @@ -101,7 +104,8 @@ foreach($thisProject in $projectList) { } elseif ($artifacts -eq "current" -or $artifacts -eq "prerelease" -or $artifacts -eq "draft") { # project is the project name as used in release asset names - $project = [Uri]::EscapeDataString($project.Replace(' ','.')).Replace('%','') + $project = [Uri]::EscapeDataString($project.Replace(' ', '.')).Replace('%', '') + # latest released version $releases = GetReleases -token $token -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY if ($artifacts -eq "current") { @@ -116,7 +120,7 @@ foreach($thisProject in $projectList) { if (!($release)) { throw "Unable to locate $artifacts release" } - foreach($mask in $atypes.Split(',')) { + foreach ($mask in $atypes.Split(',')) { $artifactFile = DownloadRelease -token $token -projects $project -api_url $ENV:GITHUB_API_URL -repository $ENV:GITHUB_REPOSITORY -release $release -path $artifactsFolder -mask $mask Write-Host "'$artifactFile'" if (!$artifactFile -or !(Test-Path $artifactFile)) { @@ -128,7 +132,7 @@ foreach($thisProject in $projectList) { if ($artifactFile -notlike '*.zip') { throw "Downloaded artifact is not a .zip file" } - Expand-Archive -Path $artifactFile -DestinationPath ($artifactFile.SubString(0,$artifactFile.Length-4)) + Expand-Archive -Path $artifactFile -DestinationPath ($artifactFile.SubString(0, $artifactFile.Length - 4)) Remove-Item $artifactFile -Force } } @@ -147,7 +151,7 @@ foreach($thisProject in $projectList) { if ($artifactFile -notlike '*.zip') { throw "Downloaded artifact is not a .zip file" } - Expand-Archive -Path $artifactFile -DestinationPath ($artifactFile.SubString(0,$artifactFile.Length-4)) + Expand-Archive -Path $artifactFile -DestinationPath ($artifactFile.SubString(0, $artifactFile.Length - 4)) Remove-Item $artifactFile -Force } } @@ -162,45 +166,54 @@ foreach($thisProject in $projectList) { } } } + Write-Host "Project '$project'" Write-Host "Artifacts:" Get-ChildItem -Path $artifactsFolder | ForEach-Object { Write-Host "- $($_.Name)" } + # Check if there is a custom script to run for the delivery target $customScript = Join-Path $baseFolder ".github/DeliverTo$deliveryTarget.ps1" + if (Test-Path $customScript -PathType Leaf) { Write-Host "Found custom script $customScript for delivery target $deliveryTarget" + $projectSettings = ReadSettings -baseFolder $baseFolder -project $thisProject $projectSettings = AnalyzeRepo -settings $projectSettings -baseFolder $baseFolder -project $thisProject -doNotCheckArtifactSetting -doNotIssueWarnings $parameters = @{ - "Project" = $thisProject - "ProjectName" = $projectName - "type" = $type - "Context" = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) - "RepoSettings" = $settings + "Project" = $thisProject + "ProjectName" = $projectName + "type" = $type + "Context" = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) + "RepoSettings" = $settings "ProjectSettings" = $projectSettings } - #Calculate the folders per artifact type + #Calculate the folders per artifact type 'Apps', 'TestApps', 'Dependencies' | ForEach-Object { $artifactType = $_ $singleArtifactFilter = "$project-$refname-$artifactType-*.*.*.*"; + # Get the folder holding the artifacts from the standard build $artifactFolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder $singleArtifactFilter) -Directory) + # Verify that there is an apps folder if ($artifactFolder.Count -eq 0 -and $artifactType -eq "Apps") { throw "Internal error - unable to locate apps folder" } + # Verify that there is only at most one artifact folder for the standard build if ($artifactFolder.Count -gt 1) { $artifactFolder | Out-Host throw "Internal error - multiple $artifactType folders located" } + # Add the artifact folder to the parameters if ($artifactFolder.Count -ne 0) { $parameters[$artifactType.ToLowerInvariant() + "Folder"] = $artifactFolder[0].FullName } + # Get the folders holding the artifacts from all build modes $multipleArtifactFilter = "$project-$refname-*$artifactType-*.*.*.*"; $artifactFolders = @(Get-ChildItem -Path (Join-Path $artifactsFolder $multipleArtifactFilter) -Directory) @@ -250,7 +263,7 @@ foreach($thisProject in $projectList) { try { $storageAccountCredentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.storageContext)) | ConvertFrom-Json $storageAccountCredentials.StorageAccountName | Out-Null - $storageContainerName = $storageAccountCredentials.ContainerName.ToLowerInvariant().replace('{project}',$projectName).replace('{branch}',$refname).ToLowerInvariant() + $storageContainerName = $storageAccountCredentials.ContainerName.ToLowerInvariant().replace('{project}', $projectName).replace('{branch}', $refname).ToLowerInvariant() $storageBlobName = $storageAccountCredentials.BlobName.ToLowerInvariant() } catch { @@ -259,6 +272,7 @@ foreach($thisProject in $projectList) { $azStorageContext = ConnectAzStorageAccount -storageAccountCredentials $storageAccountCredentials Write-Host "Storage Container Name is $storageContainerName" Write-Host "Storage Blob Name is $storageBlobName" + $containerExists = $true try { Get-AzStorageContainer -Context $azStorageContext -name $storageContainerName | Out-Null @@ -266,10 +280,12 @@ foreach($thisProject in $projectList) { catch { $containerExists = $false } + if (-not $containerExists -and $settings.Contains('DeliverToStorage') -and $settings."DeliverToStorage".Contains('CreateContainerIfNotExist') -and $settings."DeliverToStorage"."CreateContainerIfNotExist" -eq $true) { Write-Host "Container $storageContainerName does not exist. Creating..." New-AzStorageContainer -Context $azStorageContext -Name $storageContainerName | Out-Null } + Write-Host "Delivering to $storageContainerName in $($storageAccountCredentials.StorageAccountName)" $atypes.Split(',') | ForEach-Object { $atype = $_ @@ -289,11 +305,11 @@ foreach($thisProject in $projectList) { } else { $artfolder = $artfolder[0].FullName - $version = $artfolder.SubString($artfolder.IndexOf("-$refname-$atype-")+"-$refname-$atype-".Length) + $version = $artfolder.SubString($artfolder.IndexOf("-$refname-$atype-") + "-$refname-$atype-".Length) Write-Host $artfolder - $versions = @("$version-preview","preview") + $versions = @("$version-preview", "preview") if ($type -eq "Release") { - $versions += @($version,"latest") + $versions += @($version, "latest") } $tempFile = Join-Path ([System.IO.Path]::GetTempPath()) "$([Guid]::newguid().ToString()).zip" try { @@ -301,7 +317,7 @@ foreach($thisProject in $projectList) { Compress-Archive -Path (Join-Path $artfolder '*') -DestinationPath $tempFile -Force $versions | ForEach-Object { $version = $_ - $blob = $storageBlobName.replace('{project}',$projectName).replace('{branch}',$refname).replace('{version}',$version).replace('{type}',$atype).ToLowerInvariant() + $blob = $storageBlobName.replace('{project}', $projectName).replace('{branch}', $refname).replace('{version}', $version).replace('{type}', $atype).ToLowerInvariant() Write-Host "Delivering $blob" Set-AzStorageBlobContent -Context $azStorageContext -Container $storageContainerName -File $tempFile -blob $blob -Force | Out-Null } From 3cda6f44700a3b159815fdb4ebde76c553bf8745 Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 22 Aug 2024 14:08:47 +0200 Subject: [PATCH 42/62] merge --- Actions/Deliver/Deliver.ps1 | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index 3518cb076..bf8d7919a 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -62,9 +62,9 @@ function ConnectAzStorageAccount { . (Join-Path -Path $PSScriptRoot -ChildPath "../AL-Go-Helper.ps1" -Resolve) DownloadAndImportBcContainerHelper -$refname = "$ENV:GITHUB_REF_NAME".Replace('/','_') +$refname = "$ENV:GITHUB_REF_NAME".Replace('/', '_') -$artifacts = $artifacts.Replace('/',([System.IO.Path]::DirectorySeparatorChar)).Replace('\',([System.IO.Path]::DirectorySeparatorChar)) +$artifacts = $artifacts.Replace('/', ([System.IO.Path]::DirectorySeparatorChar)).Replace('\', ([System.IO.Path]::DirectorySeparatorChar)) $baseFolder = $ENV:GITHUB_WORKSPACE $settings = ReadSettings -baseFolder $baseFolder @@ -80,7 +80,7 @@ $secrets = $env:Secrets | ConvertFrom-Json foreach ($thisProject in $projectList) { # $project should be the project part of the artifact name generated from the build if ($thisProject -and ($thisProject -ne '.')) { - $project = $thisProject.Replace('\','_').Replace('/','_') + $project = $thisProject.Replace('\', '_').Replace('/', '_') } else { $project = $settings.repoName @@ -196,7 +196,7 @@ foreach ($thisProject in $projectList) { $singleArtifactFilter = "$project-$refname-$artifactType-*.*.*.*"; # Get the folder holding the artifacts from the standard build - $artifactFolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder $singleArtifactFilter) -Directory) + $artifactFolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder $singleArtifactFilter) -Directory) # Verify that there is an apps folder if ($artifactFolder.Count -eq 0 -and $artifactType -eq "Apps") { @@ -221,6 +221,7 @@ foreach ($thisProject in $projectList) { $parameters[$artifactType.ToLowerInvariant() + "Folders"] = $artifactFolders.FullName } } + Write-Host "Calling custom script: $customScript" . $customScript -parameters $parameters } @@ -249,8 +250,8 @@ foreach ($thisProject in $projectList) { Get-Item -Path (Join-Path $folder[0] "*.app") | ForEach-Object { $parameters = @{ "gitHubRepository" = "$ENV:GITHUB_SERVER_URL/$ENV:GITHUB_REPOSITORY" - "preReleaseTag" = $preReleaseTag - "appFile" = $_.FullName + "preReleaseTag" = $preReleaseTag + "appFile" = $_.FullName } $package = New-BcNuGetPackage @parameters Push-BcNuGetPackage -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -bcNuGetPackage $package @@ -263,7 +264,7 @@ foreach ($thisProject in $projectList) { try { $storageAccountCredentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.storageContext)) | ConvertFrom-Json $storageAccountCredentials.StorageAccountName | Out-Null - $storageContainerName = $storageAccountCredentials.ContainerName.ToLowerInvariant().replace('{project}', $projectName).replace('{branch}', $refname).ToLowerInvariant() + $storageContainerName = $storageAccountCredentials.ContainerName.ToLowerInvariant().replace('{project}', $projectName).replace('{branch}', $refname).ToLowerInvariant() $storageBlobName = $storageAccountCredentials.BlobName.ToLowerInvariant() } catch { @@ -332,7 +333,7 @@ foreach ($thisProject in $projectList) { $projectSettings = ReadSettings -baseFolder $baseFolder -project $thisProject $projectSettings = AnalyzeRepo -settings $projectSettings -baseFolder $baseFolder -project $thisProject -doNotCheckArtifactSetting -doNotIssueWarnings # Use old settings and issue warnings - 'continuousDelivery','mainAppFolder','productId' | ForEach-Object { + 'continuousDelivery', 'mainAppFolder', 'productId' | ForEach-Object { if ($projectSettings.Keys -contains "AppSource$_") { OutputWarning "Using AppSource$_ in $thisProject/.AL-Go/settings.json is deprecated. Use deliverToAppSource.$_ instead. If both values are defined, the value in AppSource$_ is used (even if it is deprecated)." $projectSettings.deliverToAppSource."$_" = $projectSettings."AppSource$_" @@ -348,6 +349,7 @@ foreach ($thisProject in $projectList) { throw "appSourceContext secret is missing" } $authContext = New-BcAuthContext @appSourceContext + if ($projectSettings.deliverToAppSource.MainAppFolder) { $AppSourceMainAppFolder = $projectSettings.deliverToAppSource.MainAppFolder } @@ -363,6 +365,7 @@ foreach ($thisProject in $projectList) { throw "deliverToAppSource.ProductId needs to be specified in $thisProject/.AL-Go/settings.json in order to deliver to AppSource" } Write-Host "AppSource MainAppFolder $AppSourceMainAppFolder" + $mainAppJson = Get-Content -Path (Join-Path $baseFolder "$thisProject/$AppSourceMainAppFolder/app.json") -Encoding UTF8 | ConvertFrom-Json $mainAppFileName = ("$($mainAppJson.Publisher)_$($mainAppJson.Name)_".Split([System.IO.Path]::GetInvalidFileNameChars()) -join '') + "*.*.*.*.app" $artfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-Apps-*.*.*.*") | Where-Object { $_.PSIsContainer }) @@ -376,6 +379,7 @@ foreach ($thisProject in $projectList) { $artfolder = $artfolder[0].FullName $appFile = Get-ChildItem -path $artFolder | Where-Object { $_.name -like $mainAppFileName } | ForEach-Object { $_.FullName } $libraryAppFiles = @(Get-ChildItem -path $artFolder | Where-Object { $_.name -notlike $mainAppFileName } | ForEach-Object { $_.FullName }) + $appSourceIncludeDependencies = $projectSettings.deliverToAppSource.includeDependencies if ($appSourceIncludeDependencies -and $appSourceIncludeDependencies.count -gt 0) { $depfolder = @(Get-ChildItem -Path (Join-Path $artifactsFolder "$project-$refname-Dependencies-*.*.*.*") | Where-Object { $_.PSIsContainer }) @@ -392,6 +396,7 @@ foreach ($thisProject in $projectList) { $appSourceIncludeDependencies | Where-Object { $name -like $_ } } | ForEach-Object { $_.FullName }) } + Write-Host "Main App File:" Write-Host "- $([System.IO.Path]::GetFileName($appFile))" Write-Host "Library App Files:" @@ -421,4 +426,3 @@ foreach ($thisProject in $projectList) { Remove-Item $artifactsFolder -Recurse -Force } } - From cebfbf350fbffea8eb3cc459b4443580b2aad335 Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 22 Aug 2024 14:11:11 +0200 Subject: [PATCH 43/62] move --- RELEASENOTES.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 8b0d6d351..70a616c2f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,3 +1,7 @@ +### New Settings + +- `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. + ## v5.3 ### Issues @@ -37,8 +41,6 @@ AL-Go for GitHub now includes a new telemetry module. For detailed information o ### New Settings -- `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. - - `deployTo`: is not really new, but has a new property: - **Scope** = specifies the scope of the deployment: Dev, PTE. If not specified, AL-Go for GitHub will always use the Dev Scope for AppSource Apps, but also for PTEs when deploying to sandbox environments when impersonation (refreshtoken) is used for authentication. @@ -65,7 +67,6 @@ AL-Go for GitHub now includes a new telemetry module. For detailed information o - `PowerPlatformSolutionFolder`: Contains the name of the folder containing a PowerPlatform Solution (only one) - `DeployTo` now has two additional properties `companyId` is the Company Id from Business Central (for PowerPlatform connection) and `ppEnvironmentUrl` is the Url of the PowerPlatform environment to deploy to. -- `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. ### New Actions From 49cecb34d42c703b2952c58e65d2b2804f25fbe0 Mon Sep 17 00:00:00 2001 From: freddydk Date: Thu, 22 Aug 2024 14:13:23 +0200 Subject: [PATCH 44/62] remove dumps --- Actions/RunPipeline/RunPipeline.ps1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index a1ea7c802..29728808c 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -126,11 +126,9 @@ try { else { $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$authTokenSecret")) if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { - Write-Host "Set token" $trustedNuGetFeed.Token = $token } else { - Write-Host "Add token" $trustedNuGetFeed | Add-Member -MemberType NoteProperty -Name Token -Value $token } } From 16aaf75c37d0d19fcd332779745171c6e2f236a9 Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 3 Sep 2024 14:24:38 +0200 Subject: [PATCH 45/62] Release notes and token --- Actions/RunPipeline/RunPipeline.ps1 | 18 +++++++++--------- RELEASENOTES.md | 10 ++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 29728808c..19339c660 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -116,21 +116,21 @@ try { if ($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds')) { Write-Host "Reading TrustedNuGetFeeds" foreach($trustedNuGetFeed in $bcContainerHelperConfig.TrustedNuGetFeeds) { - Write-Host $trustedNuGetFeed.Url + if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { + if ($trustedNuGetFeed.Token -ne '') { + OutputWarning -message "Auth token for NuGet feed is defined in settings. This is not recommended. Use a secret instead and specify the secret name in the AuthTokenSecret property" + } + } + else { + $trustedNuGetFeed | Add-Member -MemberType NoteProperty -Name 'Token' -Value '' + } if ($trustedNuGetFeed.AuthTokenSecret) { - Write-Host $trustedNuGetFeed.AuthTokenSecret $authTokenSecret = $trustedNuGetFeed.AuthTokenSecret if ($secrets.Keys -notcontains $authTokenSecret) { OutputWarning -message "Secret $authTokenSecret needed for trusted NuGetFeeds cannot be found" } else { - $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$authTokenSecret")) - if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'Token') { - $trustedNuGetFeed.Token = $token - } - else { - $trustedNuGetFeed | Add-Member -MemberType NoteProperty -Name Token -Value $token - } + $trustedNuGetFeed.Token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$authTokenSecret")) } } } diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 31bd95a46..237739943 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -5,6 +5,16 @@ ### New Settings - `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. +- `TrustedNuGetFeeds` - TODO: write docs + - Url - NuGet Server Url + - Token - + - Patterns - only download packages, which matches any of the name patterns in this list + - FingerPrints - only download packages signed with fingerprints in this list + - AuthTokenSecret + +### Support for delivering to NuGet and GitHub Packages + +TODO: Write documentation ## v5.3 From 55d2364ce265d56b63dfa9664ac3ea93ee2aea96 Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 3 Sep 2024 14:34:21 +0200 Subject: [PATCH 46/62] remove token --- RELEASENOTES.md | 1 - 1 file changed, 1 deletion(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 237739943..1514eab6c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -7,7 +7,6 @@ - `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. - `TrustedNuGetFeeds` - TODO: write docs - Url - NuGet Server Url - - Token - - Patterns - only download packages, which matches any of the name patterns in this list - FingerPrints - only download packages signed with fingerprints in this list - AuthTokenSecret From bf9109c9002fe170afa3a8b2c51a8497e1505e88 Mon Sep 17 00:00:00 2001 From: freddydk Date: Fri, 13 Sep 2024 12:59:22 -0400 Subject: [PATCH 47/62] headers --- .../CheckForUpdates.HelperFunctions.ps1 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 index 7a1770e22..4ce697eab 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 @@ -18,6 +18,12 @@ function DownloadTemplateRepository { [bool] $downloadLatest ) + # Use Authenticated API request to avoid the 60 API calls per hour limit + $headers = @{ + "Accept" = "application/vnd.github.baptiste-preview+json" + "Authorization" = "Bearer $token" + } + # Construct API URL $apiUrl = $templateUrl.Split('@')[0] -replace "^(https:\/\/github\.com\/)(.*)$", "$ENV:GITHUB_API_URL/repos/`$2" @@ -36,11 +42,6 @@ function DownloadTemplateRepository { # Download template repository $tempName = Join-Path ([System.IO.Path]::GetTempPath()) ([Guid]::NewGuid().ToString()) - # Use Authenticated API request to avoid the 60 API calls per hour limit - $headers = @{ - "Accept" = "application/vnd.github.baptiste-preview+json" - "Authorization" = "Bearer $token" - } InvokeWebRequest -Headers $headers -Uri $archiveUrl -OutFile "$tempName.zip" -retry Expand-7zipArchive -Path "$tempName.zip" -DestinationPath $tempName Remove-Item -Path "$tempName.zip" From 6b02290165c520855fe92faa9d58d741e2f7bf92 Mon Sep 17 00:00:00 2001 From: freddydk Date: Fri, 13 Sep 2024 13:03:32 -0400 Subject: [PATCH 48/62] convertto-ht --- Actions/AL-Go-Helper.ps1 | 74 +++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index e2e4dd549..1f02f40b7 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -113,49 +113,47 @@ function ConvertTo-HashTable() { [switch] $recurse ) - Process { - function AddValueToHashTable { - Param( - [hashtable] $ht, - [string] $name, - $value, - [switch] $recurse - ) - - if ($ht.Contains($name)) { - throw "Duplicate key $name" - } - if ($recurse -and ($value -is [System.Collections.Specialized.OrderedDictionary] -or $value -is [hashtable] -or $value -is [System.Management.Automation.PSCustomObject])) { - $ht[$name] = ConvertTo-HashTable $value -recurse - } - elseif ($recurse -and $value -is [array]) { - $ht[$name] = @($value | ForEach-Object { - if (($_ -is [System.Collections.Specialized.OrderedDictionary]) -or ($_ -is [hashtable]) -or ($_ -is [System.Management.Automation.PSCustomObject])) { - ConvertTo-HashTable $_ -recurse - } - else { - $_ - } - }) - } - else { - $ht[$name] = $value - } + function AddValueToHashTable { + Param( + [hashtable] $ht, + [string] $name, + $value, + [switch] $recurse + ) + + if ($ht.Contains($name)) { + throw "Duplicate key $name" + } + if ($recurse -and ($value -is [System.Collections.Specialized.OrderedDictionary] -or $value -is [hashtable] -or $value -is [System.Management.Automation.PSCustomObject])) { + $ht[$name] = ConvertTo-HashTable $value -recurse } + elseif ($recurse -and $value -is [array]) { + $ht[$name] = @($value | ForEach-Object { + if (($_ -is [System.Collections.Specialized.OrderedDictionary]) -or ($_ -is [hashtable]) -or ($_ -is [System.Management.Automation.PSCustomObject])) { + ConvertTo-HashTable $_ -recurse + } + else { + $_ + } + }) + } + else { + $ht[$name] = $value + } + } - $ht = @{} - if ($object -is [System.Collections.Specialized.OrderedDictionary] -or $object -is [hashtable]) { - foreach($key in $object.Keys) { - AddValueToHashTable -ht $ht -name $key -value $object."$key" -recurse:$recurse - } + $ht = @{} + if ($object -is [System.Collections.Specialized.OrderedDictionary] -or $object -is [hashtable]) { + $object.Keys | ForEach-Object { + AddValueToHashTable -ht $ht -name $_ -value $object."$_" -recurse:$recurse } - elseif ($object -is [System.Management.Automation.PSCustomObject]) { - foreach($property in $object.PSObject.Properties) { - AddValueToHashTable -ht $ht -name $property.Name -value $property.Value -recurse:$recurse - } + } + elseif ($object -is [System.Management.Automation.PSCustomObject]) { + $object.PSObject.Properties | ForEach-Object { + AddValueToHashTable -ht $ht -name $_.Name -value $_.Value -recurse:$recurse } - $ht } + $ht } function OutputError { From eb4adaab5c7ef0b37322697bd604bda4fecac7d6 Mon Sep 17 00:00:00 2001 From: freddydk Date: Fri, 13 Sep 2024 13:10:13 -0400 Subject: [PATCH 49/62] check authtokensecret --- Actions/RunPipeline/RunPipeline.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 19339c660..b79b350c2 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -124,7 +124,7 @@ try { else { $trustedNuGetFeed | Add-Member -MemberType NoteProperty -Name 'Token' -Value '' } - if ($trustedNuGetFeed.AuthTokenSecret) { + if ($trustedNuGetFeed.PSObject.Properties.Name -eq 'AuthTokenSecret' -and $trustedNuGetFeed.AuthTokenSecret) { $authTokenSecret = $trustedNuGetFeed.AuthTokenSecret if ($secrets.Keys -notcontains $authTokenSecret) { OutputWarning -message "Secret $authTokenSecret needed for trusted NuGetFeeds cannot be found" From 16fb8cdf7e758c372716d1cf866d40cde164a125 Mon Sep 17 00:00:00 2001 From: freddydk Date: Fri, 13 Sep 2024 13:27:01 -0400 Subject: [PATCH 50/62] back --- Actions/AL-Go-Helper.ps1 | 74 +++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index 1f02f40b7..e2e4dd549 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -113,47 +113,49 @@ function ConvertTo-HashTable() { [switch] $recurse ) - function AddValueToHashTable { - Param( - [hashtable] $ht, - [string] $name, - $value, - [switch] $recurse - ) - - if ($ht.Contains($name)) { - throw "Duplicate key $name" - } - if ($recurse -and ($value -is [System.Collections.Specialized.OrderedDictionary] -or $value -is [hashtable] -or $value -is [System.Management.Automation.PSCustomObject])) { - $ht[$name] = ConvertTo-HashTable $value -recurse - } - elseif ($recurse -and $value -is [array]) { - $ht[$name] = @($value | ForEach-Object { - if (($_ -is [System.Collections.Specialized.OrderedDictionary]) -or ($_ -is [hashtable]) -or ($_ -is [System.Management.Automation.PSCustomObject])) { - ConvertTo-HashTable $_ -recurse - } - else { - $_ - } - }) - } - else { - $ht[$name] = $value + Process { + function AddValueToHashTable { + Param( + [hashtable] $ht, + [string] $name, + $value, + [switch] $recurse + ) + + if ($ht.Contains($name)) { + throw "Duplicate key $name" + } + if ($recurse -and ($value -is [System.Collections.Specialized.OrderedDictionary] -or $value -is [hashtable] -or $value -is [System.Management.Automation.PSCustomObject])) { + $ht[$name] = ConvertTo-HashTable $value -recurse + } + elseif ($recurse -and $value -is [array]) { + $ht[$name] = @($value | ForEach-Object { + if (($_ -is [System.Collections.Specialized.OrderedDictionary]) -or ($_ -is [hashtable]) -or ($_ -is [System.Management.Automation.PSCustomObject])) { + ConvertTo-HashTable $_ -recurse + } + else { + $_ + } + }) + } + else { + $ht[$name] = $value + } } - } - $ht = @{} - if ($object -is [System.Collections.Specialized.OrderedDictionary] -or $object -is [hashtable]) { - $object.Keys | ForEach-Object { - AddValueToHashTable -ht $ht -name $_ -value $object."$_" -recurse:$recurse + $ht = @{} + if ($object -is [System.Collections.Specialized.OrderedDictionary] -or $object -is [hashtable]) { + foreach($key in $object.Keys) { + AddValueToHashTable -ht $ht -name $key -value $object."$key" -recurse:$recurse + } } - } - elseif ($object -is [System.Management.Automation.PSCustomObject]) { - $object.PSObject.Properties | ForEach-Object { - AddValueToHashTable -ht $ht -name $_.Name -value $_.Value -recurse:$recurse + elseif ($object -is [System.Management.Automation.PSCustomObject]) { + foreach($property in $object.PSObject.Properties) { + AddValueToHashTable -ht $ht -name $property.Name -value $property.Value -recurse:$recurse + } } + $ht } - $ht } function OutputError { From 53ef60ecec7934aca3fda403ada17beaaa1352bc Mon Sep 17 00:00:00 2001 From: freddydk Date: Fri, 13 Sep 2024 13:27:47 -0400 Subject: [PATCH 51/62] remove empty line --- Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 index 4ce697eab..1d0285b0b 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 @@ -41,7 +41,6 @@ function DownloadTemplateRepository { # Download template repository $tempName = Join-Path ([System.IO.Path]::GetTempPath()) ([Guid]::NewGuid().ToString()) - InvokeWebRequest -Headers $headers -Uri $archiveUrl -OutFile "$tempName.zip" -retry Expand-7zipArchive -Path "$tempName.zip" -DestinationPath $tempName Remove-Item -Path "$tempName.zip" From 808354aa5e2b47366975696f19598f1056231306 Mon Sep 17 00:00:00 2001 From: freddydk Date: Sun, 15 Sep 2024 06:55:11 -0400 Subject: [PATCH 52/62] use headers --- .../CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 | 8 +------- Actions/CheckForUpdates/CheckForUpdates.ps1 | 8 +++++++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 index 1d0285b0b..766d7ee8b 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.HelperFunctions.ps1 @@ -12,18 +12,12 @@ If true, the latest SHA of the template repository will be downloaded #> function DownloadTemplateRepository { Param( - [string] $token, + [hashtable] $headers, [string] $templateUrl, [ref] $templateSha, [bool] $downloadLatest ) - # Use Authenticated API request to avoid the 60 API calls per hour limit - $headers = @{ - "Accept" = "application/vnd.github.baptiste-preview+json" - "Authorization" = "Bearer $token" - } - # Construct API URL $apiUrl = $templateUrl.Split('@')[0] -replace "^(https:\/\/github\.com\/)(.*)$", "$ENV:GITHUB_API_URL/repos/`$2" diff --git a/Actions/CheckForUpdates/CheckForUpdates.ps1 b/Actions/CheckForUpdates/CheckForUpdates.ps1 index bed193658..3a9454008 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.ps1 @@ -31,6 +31,12 @@ if ($update -eq 'Y') { } } +# Use Authenticated API request to avoid the 60 API calls per hour limit +$headers = @{ + "Accept" = "application/vnd.github.baptiste-preview+json" + "Authorization" = "Bearer $token" +} + if (-not $templateUrl.Contains('@')) { $templateUrl += "@main" } @@ -63,7 +69,7 @@ if ($repoSettings.templateUrl -ne $templateUrl -or $templateSha -eq '') { $downloadLatest = $true } -$templateFolder = DownloadTemplateRepository -token $token -templateUrl $templateUrl -templateSha ([ref]$templateSha) -downloadLatest $downloadLatest +$templateFolder = DownloadTemplateRepository -headers $headers -templateUrl $templateUrl -templateSha ([ref]$templateSha) -downloadLatest $downloadLatest Write-Host "Template Folder: $templateFolder" $templateBranch = $templateUrl.Split('@')[1] From f6f53859e7b92caa80aabc9d8272da7fb1da080b Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 17 Sep 2024 11:02:08 +0200 Subject: [PATCH 53/62] use nuget containerhelper --- Actions/AL-Go-Helper.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index e2e4dd549..cbb066454 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -18,7 +18,7 @@ $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" +$defaultBcContainerHelperVersion = "https://github.com/freddydk/navcontainerhelper/archive/refs/heads/nuget.zip" # 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") $runAlPipelineOverrides = @( From bf078d651ff0bc389a3ac721a0acf8a77d864056 Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 17 Sep 2024 19:28:58 +0200 Subject: [PATCH 54/62] appsymbols --- Actions/RunPipeline/RunPipeline.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index b79b350c2..e23621f13 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -326,7 +326,7 @@ try { } } if ($parameters.ContainsKey('containerName')) { - Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification @publishParams -ErrorAction SilentlyContinue + Publish-BcNuGetPackageToContainer -containerName $parameters.containerName -tenant $parameters.tenant -skipVerification -appSymbolsFolder $parameters.appSymbolsFolder @publishParams -ErrorAction SilentlyContinue } else { Download-BcNuGetPackageToFolder -folder $parameters.appSymbolsFolder @publishParams | Out-Null From 1e2c635140026d27e58d72610192779e8733b9c5 Mon Sep 17 00:00:00 2001 From: freddydk Date: Tue, 17 Sep 2024 19:29:34 +0200 Subject: [PATCH 55/62] empty line --- Actions/RunPipeline/RunPipeline.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index e23621f13..02ad6e926 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -331,7 +331,6 @@ try { else { Download-BcNuGetPackageToFolder -folder $parameters.appSymbolsFolder @publishParams | Out-Null } - } } } From ed79ca7a32ac963ab61a3a385acb859ebaffa54e Mon Sep 17 00:00:00 2001 From: freddydk Date: Wed, 18 Sep 2024 07:57:46 +0200 Subject: [PATCH 56/62] use preview --- Actions/AL-Go-Helper.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index cbb066454..e2e4dd549 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -18,7 +18,7 @@ $defaultCICDPushBranches = @( 'main', 'release/*', 'feature/*' ) [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', 'defaultCICDPullRequestBranches', Justification = 'False positive.')] $defaultCICDPullRequestBranches = @( 'main' ) $runningLocal = $local.IsPresent -$defaultBcContainerHelperVersion = "https://github.com/freddydk/navcontainerhelper/archive/refs/heads/nuget.zip" # 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" +$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") $runAlPipelineOverrides = @( From a019cc71628a06bda34008fe2df47c95953343cd Mon Sep 17 00:00:00 2001 From: freddydk Date: Sun, 22 Sep 2024 22:23:01 +0200 Subject: [PATCH 57/62] add settings and secrets --- Actions/AL-Go-Helper.ps1 | 1 + Actions/RunPipeline/RunPipeline.ps1 | 9 +++++++++ Scenarios/secrets.md | 8 +++++++- Scenarios/settings.md | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index e2e4dd549..3b817b6e3 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -657,6 +657,7 @@ function ReadSettings { "defaultIndexMD" = "## Reference documentation\n\nThis is the generated reference documentation for [{REPOSITORY}](https://github.com/{REPOSITORY}).\n\nYou can use the navigation bar at the top and the table of contents to the left to navigate your documentation.\n\nYou can change this content by creating/editing the **{INDEXTEMPLATERELATIVEPATH}** file in your repository or use the alDoc:defaultIndexMD setting in your repository settings file (.github/AL-Go-Settings.json)\n\n{RELEASENOTES}" "defaultReleaseMD" = "## Release reference documentation\n\nThis is the generated reference documentation for [{REPOSITORY}](https://github.com/{REPOSITORY}).\n\nYou can use the navigation bar at the top and the table of contents to the left to navigate your documentation.\n\nYou can change this content by creating/editing the **{INDEXTEMPLATERELATIVEPATH}** file in your repository or use the alDoc:defaultReleaseMD setting in your repository settings file (.github/AL-Go-Settings.json)\n\n{RELEASENOTES}" } + "trustMicrosoftNuGetFeeds" = $true } # Read settings from files and merge them into the settings object diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 02ad6e926..794fe4ec0 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -135,6 +135,15 @@ try { } } } + else { + $bcContainerHelperConfig.TrustedNuGetFeeds = @() + } + if ($settings.trustMicrosoftNuGetFeeds) { + $bcContainerHelperConfig.TrustedNuGetFeeds += @([PSCustomObject]@{ + "url" = "https://dynamicssmb2.pkgs.visualstudio.com/DynamicsBCPublicFeeds/_packaging/AppSourceSymbols/nuget/v3/index.json" + "token" = '' + }) + } if ((-not $settings.appFolders) -and (-not $settings.testFolders) -and (-not $settings.bcptTestFolders)) { Write-Host "Repository is empty, exiting" diff --git a/Scenarios/secrets.md b/Scenarios/secrets.md index 01676892c..28e43bd80 100644 --- a/Scenarios/secrets.md +++ b/Scenarios/secrets.md @@ -181,6 +181,12 @@ Example: `{"storageAccountName":"MyStorageName","storageAccountKey":"JHFZErCyfQ8 ## **GitHubPackagesContext** -> Deliver to GitHub Packages -If you create a secret called GitHubPackagesContext, then AL-Go for GitHub will automagically deliver apps to this NuGet feed after every successful build. AL-Go for GitHub will also use this NuGet feed for dependency resolution when building apps, giving you automatic dependency resolution within all your apps. +If you create a secret called GitHubPackagesContext, then AL-Go for GitHub will automagically deliver apps to this NuGet feed after every successful build. AL-Go for GitHub will also use this NuGet feed for dependency resolution when building apps, giving you automatic dependency resolution within all your repositories sharing this secret. Example: `{"token":"ghp_NDdI2ExxxxxxxxxxxxxxxxxAYQh","serverUrl":"https://nuget.pkg.github.com/mygithuborg/index.json"}` + +## **NuGetContext** -> Deliver to NuGet + +If you create a secret called NuGetContext, then AL-Go for GitHub will automagically deliver apps to this NuGet feed after every successful build. AL-Go for GitHub will NOT use this NuGet feed for dependency resolution when building apps. If you want to use this feed for dependency resolution as well, you need to add this to the [trustedNuGetFeeds](https://aka.ms/algosettings#trustedNuGetFeeds) setting. + +Example: `{"token":"ydtaxlw66xxxxxxxxxxxxxxgqdq","serverUrl":"https://pkgs.dev.azure.com/myorg/apps/_packaging/myrepo/nuget/v3/index.json"}` diff --git a/Scenarios/settings.md b/Scenarios/settings.md index 72297b761..9f4d69def 100644 --- a/Scenarios/settings.md +++ b/Scenarios/settings.md @@ -116,6 +116,8 @@ 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. | \[ \] | +| 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 one of the fingerprints specified in this array of fingerprints. | \[ \] | ## AppSource specific advanced settings From deb9f263e66905062ba25b74b35b39f20f0dbfd0 Mon Sep 17 00:00:00 2001 From: freddydk Date: Sun, 22 Sep 2024 23:00:03 +0200 Subject: [PATCH 58/62] precommit --- Scenarios/settings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scenarios/settings.md b/Scenarios/settings.md index 9f4d69def..8747f51b6 100644 --- a/Scenarios/settings.md +++ b/Scenarios/settings.md @@ -117,7 +117,7 @@ The repository settings are only read from the repository settings file (.github | 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. | \[ \] | | 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 one of the fingerprints specified in this array of fingerprints. | \[ \] | +| 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 one of the fingerprints specified in this array of fingerprints. | \[ \] | ## AppSource specific advanced settings From df3cc37580e96291c53cd35e8bf08fed616a1a02 Mon Sep 17 00:00:00 2001 From: freddydk Date: Sun, 22 Sep 2024 23:33:21 +0200 Subject: [PATCH 59/62] releasenotes --- RELEASENOTES.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 1c6ba1ff8..931951c20 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -4,16 +4,17 @@ ### New Settings -- `DeliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. -- `TrustedNuGetFeeds` - TODO: write docs - - Url - NuGet Server Url - - Patterns - only download packages, which matches any of the name patterns in this list - - FingerPrints - only download packages signed with fingerprints in this list - - AuthTokenSecret +- `deliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. +- `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. +- `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") + - 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 one of the fingerprints specified in this array of fingerprints. + - 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 -### Support for delivering to NuGet and GitHub Packages +### Support for delivering to GitHub Packages and NuGet -TODO: Write documentation +With this release the implementation for delivering to NuGet packages (by adding the NuGetContext secret), is similar to the functionality behind delivering to GitHub packages and the implementation is final. ### Allow GitHubRunner and GitHubRunnerShell as project settings From 88c60ab4a5e07bb1c937d5980d9aff09f6e3abea Mon Sep 17 00:00:00 2001 From: freddydk Date: Mon, 23 Sep 2024 10:50:48 +0200 Subject: [PATCH 60/62] review comments --- Actions/Deliver/Deliver.ps1 | 2 ++ Actions/RunPipeline/RunPipeline.ps1 | 10 +++++----- RELEASENOTES.md | 8 ++++---- Scenarios/secrets.md | 26 +++++++++++++------------- Scenarios/settings.md | 2 +- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/Actions/Deliver/Deliver.ps1 b/Actions/Deliver/Deliver.ps1 index bf8d7919a..d2de49ae3 100644 --- a/Actions/Deliver/Deliver.ps1 +++ b/Actions/Deliver/Deliver.ps1 @@ -230,6 +230,8 @@ foreach ($thisProject in $projectList) { try { $nuGetAccount = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$($deliveryTarget)Context")) | ConvertFrom-Json | ConvertTo-HashTable if ($deliveryTarget -eq 'NuGet' -and $type -eq 'CD') { + # When doing continuous delivery to NuGet, we always use the preview tag + # When doing a release, we do not add a preview tag $preReleaseTag = 'preview' } $nuGetServerUrl = $nuGetAccount.ServerUrl diff --git a/Actions/RunPipeline/RunPipeline.ps1 b/Actions/RunPipeline/RunPipeline.ps1 index 794fe4ec0..fb0a42573 100644 --- a/Actions/RunPipeline/RunPipeline.ps1 +++ b/Actions/RunPipeline/RunPipeline.ps1 @@ -113,6 +113,11 @@ try { $settings = AnalyzeRepo -settings $settings -baseFolder $baseFolder -project $project @analyzeRepoParams $settings = CheckAppDependencyProbingPaths -settings $settings -token $token -baseFolder $baseFolder -project $project + if ((-not $settings.appFolders) -and (-not $settings.testFolders) -and (-not $settings.bcptTestFolders)) { + Write-Host "Repository is empty, exiting" + exit + } + if ($bcContainerHelperConfig.ContainsKey('TrustedNuGetFeeds')) { Write-Host "Reading TrustedNuGetFeeds" foreach($trustedNuGetFeed in $bcContainerHelperConfig.TrustedNuGetFeeds) { @@ -145,11 +150,6 @@ try { }) } - if ((-not $settings.appFolders) -and (-not $settings.testFolders) -and (-not $settings.bcptTestFolders)) { - Write-Host "Repository is empty, exiting" - exit - } - $installApps = $settings.installApps $installTestApps = $settings.installTestApps diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 931951c20..ea799e88a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -6,15 +6,15 @@ - `deliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. - `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. -- `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: +- `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") - - 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 one of the fingerprints specified in this array of fingerprints. + - Patterns - AL-Go for GitHub will only trust packages, where the ID matches this pattern. Default is all packages (\*). + - Thumbprints - If specified, AL-Go for GitHub will only trust packages signed with a certificate with a thumbprint matching one of the thumbprints in this array. - 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 ### Support for delivering to GitHub Packages and NuGet -With this release the implementation for delivering to NuGet packages (by adding the NuGetContext secret), is similar to the functionality behind delivering to GitHub packages and the implementation is final. +With this release the implementation for delivering to NuGet packages (by adding the NuGetContext secret), is similar to the functionality behind delivering to GitHub packages and the implementation is no longer in preview. ### Allow GitHubRunner and GitHubRunnerShell as project settings diff --git a/Scenarios/secrets.md b/Scenarios/secrets.md index 28e43bd80..d1f1a6823 100644 --- a/Scenarios/secrets.md +++ b/Scenarios/secrets.md @@ -77,13 +77,13 @@ Whether you use a managed identity or an app registration for authentication, yo Using a federated credential, you need to register your GitHub repository in your managed identity under settings -> federated credentials or in the app registration under Certificates & Secrets. This registration will allow AL-Go for GitHub running in this repository to authenticate without the Client Secret stored. You still need to create a secret containing the clientId and the tenantId. The way this works is that AL-Go for GitHub will request an ID_TOKEN from GitHub as a proof of authenticity and use this when authenticating. This way, only workflows running in the specified branch/environment in GitHub will be able to authenticate. -Example: `{"keyVaultName":"MyKeyVault","clientId":"ed79570c-0384-4826-8099-bf0577af6667","tenantId":"c645f7e7-0613-4b82-88ca-71f3dbb40045"}` +Example: `{"keyVaultName":"MyKeyVault","clientId":"","tenantId":""}` #### ClientSecret ClientSecret can only be used using an app registration. Under Certificates & Secrets in the app registration, you need to create a Client Secret, which you can specify in the Azure_Credentials secret in AL-Go for GitHub. With the ClientId and ClientSecret, anybody can authenticate and perform actions as the connected user inside Business Central. -Example: `{"keyVaultName":"MyKeyVault","clientId":"d48b773f-2c26-4394-8bd2-c5b64e0cae32","clientSecret":"OPXxxxxxxxxxxxxxxxxxxxxxxabge","tenantId":"c645f7e7-0613-4b82-88ca-71f3dbb40045"}` +Example: `{"keyVaultName":"MyKeyVault","clientId":"","clientSecret":"","tenantId":""}` With this setup, you can create a setting called `keyVaultCodesignCertificateName` containing the name of the imported certificate in your Key Vault in order for AL-Go for GitHub to sign your apps. @@ -101,7 +101,7 @@ Specifying a RefreshToken allows AL-Go for GitHub to get access to impersonate t Providing an AuthContext secret with a refreshtoken typically allows you to get access for 90 days. After the 90 days, you need to refresh the AuthContext secret with a new refreshToken. Note that anybody with the refreshToken can get access to call the API on behalf of the user, it doesn't have to be inside a workflow/pipeline. -Example: `{"tenantId":"d630ce39-5a0c-41ec-bf0d-6758ad558f0c","scopes":"https://api.businesscentral.dynamics.com/","RefreshToken":"0.AUUAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_s6Eo4YOI","clientId":"1950a258-227b-4e31-a9cf-717495945fc2"}` +Example: `{"tenantId":"","scopes":"https://api.businesscentral.dynamics.com/","RefreshToken":"","clientId":""}` ### App Registration (Service to service authentication) @@ -117,7 +117,7 @@ Example:`{"tenantId":"d630ce39-5a0c-41ec-bf0d-6758ad558f0c","scopes":"https://ap Under Certificates & Secrets in the app registration, you can create a Client Secret, which you can specify in the AuthContext secret in AL-Go for GitHub. With the ClientId and ClientSecret, anybody can authenticate and perform actions as the connected user inside Business Central. -Example: `{"tenantId":"d630ce39-5a0c-41ec-bf0d-6758ad558f0c","scopes":"https://api.businesscentral.dynamics.com/","clientId":"d48b773f-2c26-4394-8bd2-c5b64e0cae32","clientSecret":"OPXxxxxxxxxxxxxxxxxxxxxxxabge"}` +Example: `{"tenantId":"","scopes":"https://api.businesscentral.dynamics.com/","clientId":"","clientSecret":""}` ## **AppSourceContext** -> Deliver to AppSource @@ -135,13 +135,13 @@ In order to use an app registration for publishing apps to AppSource, you need t Using a federated credential, you need to register your GitHub repository in the app registration under Certificates & Secrets. This registration will allow AL-Go for GitHub running in this repository to authenticate without the Client Secret stored. You still need to create a secret containing this information. The way this works is that AL-Go for GitHub will request an ID_TOKEN from GitHub as a proof of authenticity and use this when authenticating. This way, only workflows running in the specified branch/environment in GitHub will be able to authenticate. -Example:`{"clientId":"d48b773f-2c26-4394-8bd2-c5b64e0cae32","tenantId":"c645f7e7-0613-4b82-88ca-71f3dbb40045","scopes":"https://api.partner.microsoft.com/.default"}` +Example:`{"clientId":"","tenantId":"","scopes":"https://api.partner.microsoft.com/.default"}` #### Client Secret Under Certificates & Secrets in the app registration, you can create a Client Secret, which you can specify in the AuthContext secret in AL-Go for GitHub. Note that who ever has access to the clientId and clientSecret can publish apps on AppSource on your behalf. -Example: `{"tenantId":"c645f7e7-0613-4b82-88ca-71f3dbb40045","scopes":"https://api.partner.microsoft.com/.default","clientId":"d48b773f-2c26-4394-8bd2-c5b64e0cae32","clientSecret":"OPXxxxxxxxxxxxxxxxxxxxxxxabge"}` +Example: `{"tenantId":"c645f7e7-0613-4b82-88ca-71f3dbb40045","scopes":"https://api.partner.microsoft.com/.default","clientId":"","clientSecret":""}` ## **StorageContext** -> Deliver to storage @@ -153,40 +153,40 @@ In AL-Go for GitHub, the Storage Context can be specified in 5 different ways, 5 As a storage account is an Azure resource, we can use managed identities. Managed identities are like virtual users in Azure, using federated credentials for authentication. Using a federated credential, you need to register your GitHub repository in the managed identity under Settings -> Federated Credentials. The way this works is that AL-Go for GitHub will request an ID_TOKEN from GitHub as a proof of authenticity and use this when authenticating. This way, only workflows running in the specified branch/environment in GitHub will be able to authenticate. -Example: `{"storageAccountName":"MyStorageName","clientId":"08b6d80c-68cf-48f9-a5ff-b054326e2ec3","tenantId":"c645f7e7-0613-4b82-88ca-71f3dbb40045","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"}` +Example: `{"storageAccountName":"MyStorageName","clientId":"","tenantId":"","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"}` ### App Registration/Federated credential An app registration with federated credential is harder to setup than a managed identity, but just as secure. The mechanism is the same for obtaining an ID_TOKEN and providing this as proof of authenticity towards the app registration. -Example: `{"storageAccountName":"MyStorageName","clientId":"d48b773f-2c26-4394-8bd2-c5b64e0cae32","tenantId":"c645f7e7-0613-4b82-88ca-71f3dbb40045","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"}` +Example: `{"storageAccountName":"MyStorageName","clientId":"","tenantId":"","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"}` ### App Registration/Client Secret An app registration with a client Secret is less secure than using federated credentials. Who ever has access to the clientSecret has access to everything the app registration has access to, until you recycle the client Secret. -Example: `{"storageAccountName":"MyStorageName","clientId":"d48b773f-2c26-4394-8bd2-c5b64e0cae32","clientSecret":"OPXxxxxxxxxxxxxxxxxxxxxxxabge","tenantId":"c645f7e7-0613-4b82-88ca-71f3dbb40045","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"}` +Example: `{"storageAccountName":"MyStorageName","clientId":"","clientSecret":"","tenantId":"","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"}` ### storageAccountName/sastoken A sas token for a storage account can be setup to function in a limited timeframe, giving access to perform a certain number of tasks on the storage account. Who ever has access to the sastoken can perform these tasks on the storage account until it expires or you recycle the storage account key used to create the sastoken. -Example: `{"storageAccountName":"MyStorageName","sastoken":"sv=2022-11-02&ss=b&srt=sco&sp=rwdlaciytf&se=2024-08-06T20:22:08Z&st=2024-04-06T12:22:08Z&spr=https&sig=IZyIf5xxxxxxxxxxxxxxxxxxxxxtq7tj6b5I%3D","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"}` +Example: `{"storageAccountName":"MyStorageName","sastoken":"sv=2022-11-02&ss=b&srt=sco&sp=rwdlaciytf&se=2024-08-06T20:22:08Z&st=2024-04-06T12:22:08Z&spr=https&sig=","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"}` ### storageAccountName/storageAccountKey Using storageAccount Name and Key is by far the most unsecure way of authenticating to an Azure Storage Account. If ever compromised, people can do anything with these credentials, until the storageAccount key is cycled. -Example: `{"storageAccountName":"MyStorageName","storageAccountKey":"JHFZErCyfQ8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxStj7AHXQ==","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"} ` +Example: `{"storageAccountName":"MyStorageName","storageAccountKey":"","containerName":"{project}","blobName":"{version}/{project}-{type}.zip"} ` ## **GitHubPackagesContext** -> Deliver to GitHub Packages If you create a secret called GitHubPackagesContext, then AL-Go for GitHub will automagically deliver apps to this NuGet feed after every successful build. AL-Go for GitHub will also use this NuGet feed for dependency resolution when building apps, giving you automatic dependency resolution within all your repositories sharing this secret. -Example: `{"token":"ghp_NDdI2ExxxxxxxxxxxxxxxxxAYQh","serverUrl":"https://nuget.pkg.github.com/mygithuborg/index.json"}` +Example: `{"token":"","serverUrl":"https://nuget.pkg.github.com/mygithuborg/index.json"}` ## **NuGetContext** -> Deliver to NuGet If you create a secret called NuGetContext, then AL-Go for GitHub will automagically deliver apps to this NuGet feed after every successful build. AL-Go for GitHub will NOT use this NuGet feed for dependency resolution when building apps. If you want to use this feed for dependency resolution as well, you need to add this to the [trustedNuGetFeeds](https://aka.ms/algosettings#trustedNuGetFeeds) setting. -Example: `{"token":"ydtaxlw66xxxxxxxxxxxxxxgqdq","serverUrl":"https://pkgs.dev.azure.com/myorg/apps/_packaging/myrepo/nuget/v3/index.json"}` +Example: `{"token":"","serverUrl":"https://pkgs.dev.azure.com/myorg/apps/_packaging/myrepo/nuget/v3/index.json"}` diff --git a/Scenarios/settings.md b/Scenarios/settings.md index 8747f51b6..7011dcafc 100644 --- a/Scenarios/settings.md +++ b/Scenarios/settings.md @@ -117,7 +117,7 @@ The repository settings are only read from the repository settings file (.github | 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. | \[ \] | | 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 one of the fingerprints specified in this array of fingerprints. | \[ \] | +| 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 (\*).
**thumbprints** = - Thumbprints - If specified, AL-Go for GitHub will only trust packages signed with a certificate with a thumbprint matching one of the thumbprints in this array. | \[ \] | ## AppSource specific advanced settings From 4d355f47d7855c29eb6109c92a68efc4f9e3906d Mon Sep 17 00:00:00 2001 From: freddydk Date: Mon, 23 Sep 2024 11:07:21 +0200 Subject: [PATCH 61/62] fingerprint --- RELEASENOTES.md | 8 ++++---- Scenarios/settings.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ea799e88a..81971b6c5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -7,10 +7,10 @@ - `deliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. - `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. - `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") - - Patterns - AL-Go for GitHub will only trust packages, where the ID matches this pattern. Default is all packages (\*). - - Thumbprints - If specified, AL-Go for GitHub will only trust packages signed with a certificate with a thumbprint matching one of the thumbprints in this array. - - 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 + - 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") + - 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. + - 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 ### Support for delivering to GitHub Packages and NuGet diff --git a/Scenarios/settings.md b/Scenarios/settings.md index 7011dcafc..1d59eebb9 100644 --- a/Scenarios/settings.md +++ b/Scenarios/settings.md @@ -117,7 +117,7 @@ The repository settings are only read from the repository settings file (.github | 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. | \[ \] | | 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 (\*).
**thumbprints** = - Thumbprints - If specified, AL-Go for GitHub will only trust packages signed with a certificate with a thumbprint matching one of the thumbprints in this array. | \[ \] | +| 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. | \[ \] | ## AppSource specific advanced settings From 65bb808d50f04990c021fd8cb11d37aabfb34b48 Mon Sep 17 00:00:00 2001 From: freddydk Date: Mon, 23 Sep 2024 11:12:53 +0200 Subject: [PATCH 62/62] periods --- RELEASENOTES.md | 4 ++-- Scenarios/settings.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 81971b6c5..bf77cdaa9 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -7,10 +7,10 @@ - `deliverTo` now has an additional property called `ContinuousDelivery`, indicating whether or not to run continuous delivery to this deliveryTarget. Default is true. - `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. - `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") + - 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"). - 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. - - 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 + - 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. ### Support for delivering to GitHub Packages and NuGet diff --git a/Scenarios/settings.md b/Scenarios/settings.md index 1d59eebb9..295c647f8 100644 --- a/Scenarios/settings.md +++ b/Scenarios/settings.md @@ -117,7 +117,7 @@ The repository settings are only read from the repository settings file (.github | 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. | \[ \] | | 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. | \[ \] | +| 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. | \[ \] | ## AppSource specific advanced settings