diff --git a/.github/workflows/Deploy.yaml b/.github/workflows/Deploy.yaml index 2daad115a..c3bf0c155 100644 --- a/.github/workflows/Deploy.yaml +++ b/.github/workflows/Deploy.yaml @@ -27,49 +27,88 @@ on: type: boolean description: Create a release in this repository required: false - default: true + default: false defaultBcContainerHelperVersion: description: 'Which version of BcContainerHelper to use? (latest, preview, private, a specific version number or a direct download URL like https://github.com/freddydk/navcontainerhelper/archive/master.zip). Leave empty to use latest (or preview for preview branches)' required: false - default: '' + default: 'latest' + +permissions: + contents: read + actions: read defaults: run: shell: pwsh jobs: + Inputs: + runs-on: [ ubuntu-latest ] + outputs: + branch: ${{ steps.CreateInputs.outputs.branch }} + copyToMain: ${{ steps.CreateInputs.outputs.copyToMain }} + directCommit: ${{ steps.CreateInputs.outputs.directCommit }} + requireEndToEndTests: ${{ steps.CreateInputs.outputs.requireEndToEndTests }} + createRelease: ${{ steps.CreateInputs.outputs.createRelease }} + defaultBcContainerHelperVersion: ${{ steps.CreateInputs.outputs.defaultBcContainerHelperVersion }} + steps: + - name: Create inputs + id: CreateInputs + run: | + $branch = '${{ github.event.inputs.branch }}' + $copyToMain = '${{ github.event.inputs.copyToMain }}' + $directCommit = '${{ github.event.inputs.directCommit }}' + $requireEndToEndTests = '${{ github.event.inputs.requireEndToEndTests }}' + $createRelease = '${{ github.event.inputs.createRelease }}' + $defaultBcContainerHelperVersion = '${{ github.event.inputs.defaultBcContainerHelperVersion }}' + Add-Content -encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "branch=$branch" + Add-Content -encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "copyToMain=$copyToMain" + Add-Content -encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "directCommit=$directCommit" + Add-Content -encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "requireEndToEndTests=$requireEndToEndTests" + Add-Content -encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "createRelease=$createRelease" + Add-Content -encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "defaultBcContainerHelperVersion=$defaultBcContainerHelperVersion" + CheckEndToEnd: runs-on: [ ubuntu-latest ] + needs: [ Inputs ] steps: - name: Check successful end 2 end tests have run - if: github.repository_owner == 'microsoft' && github.event.inputs.requireEndToEndTests == 'true' + if: github.repository_owner == 'microsoft' && needs.Inputs.outputs.requireEndToEndTests == 'true' env: GH_TOKEN: ${{ github.token }} run: | $errorActionPreference = "Stop" - $end2endRuns = (gh api /repos/$($env:GITHUB_REPOSITORY)/actions/runs?per_page=100 | ConvertFrom-Json).workflow_runs | Where-Object { $_.name -eq 'End 2 End Tests' } + $end2endRuns = (gh api "/repos/$($env:GITHUB_REPOSITORY)/actions/workflows/E2E.yaml/runs?per_page=100&branch=main" | ConvertFrom-Json).workflow_runs $latestSha = (gh api /repos/$($env:GITHUB_REPOSITORY)/commits/main | ConvertFrom-Json).sha - $latestRun = $end2endruns | Where-Object { $_.head_sha -eq $latestSha } + $latestRun = $end2endruns | Where-Object { $_.Name -eq "End to end tests - $latestSha" } | select-object -first 1 if (!$latestRun) { - throw "No End 2 End Tests run found for the latest commit on main" + throw "No End to end tests run found for the latest commit on main" } if ($latestRun.status -ne 'completed') { - throw "End 2 End Tests run for the latest commit on main is not completed" + throw "End to end tests run for the latest commit on main is not completed - see $($latestRun.html_url)" } if ($latestRun.conclusion -ne 'success') { - throw "End 2 End Tests run for the latest commit on main did not succeed" + throw "End to end tests run for the latest commit on main did not succeed - see $($latestRun.html_url)" + } + $allJobs = (gh api --paginate /repos/$($env:GITHUB_REPOSITORY)/actions/runs/$($latestRun.id)/jobs | ConvertFrom-Json).jobs + foreach($job in $allJobs) { + if ($job.conclusion -ne 'success') { + throw "Some jobs in the end to end tests run for the latest commit was skipped, failed or cancelled - see $($latestRun.html_url)" + } } Deploy: runs-on: [ ubuntu-latest ] - needs: [ CheckEndToEnd ] + needs: [ CheckEndToEnd, Inputs ] environment: Production + permissions: + contents: write steps: - name: Validate Deployment if: github.repository_owner == 'microsoft' env: GH_TOKEN: ${{ github.token }} - branch: ${{ github.event.inputs.branch }} + branch: ${{ needs.Inputs.outputs.branch }} runId: ${{ github.run_id }} run: | $errorActionPreference = "Stop" @@ -88,10 +127,10 @@ jobs: - name: Deploy env: - branch: ${{ github.event.inputs.branch }} - copyToMain: ${{ github.event.inputs.copyToMain }} - directCommit: ${{ github.event.inputs.directCommit }} - defaultBcContainerHelperVersion: ${{ github.event.inputs.defaultBcContainerHelperVersion }} + branch: ${{ needs.Inputs.outputs.branch }} + copyToMain: ${{ needs.Inputs.outputs.copyToMain }} + directCommit: ${{ needs.Inputs.outputs.directCommit }} + defaultBcContainerHelperVersion: ${{ needs.Inputs.outputs.defaultBcContainerHelperVersion }} run: | $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 try { @@ -124,7 +163,7 @@ jobs: } - name: Calculate Release Notes - if: github.repository_owner == 'microsoft' && github.event.inputs.createRelease == 'true' + if: github.repository_owner == 'microsoft' && needs.Inputs.outputs.createRelease == 'true' run: | $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 $releaseNotesFile = Join-Path $env:GITHUB_WORKSPACE "RELEASENOTES.md" @@ -134,14 +173,14 @@ jobs: Add-Content -encoding UTF8 -Path $env:GITHUB_ENV -Value "ReleaseNotes=$([Uri]::EscapeDataString($releaseNotes))" - name: Create release - if: github.repository_owner == 'microsoft' && github.event.inputs.createRelease == 'true' + if: github.repository_owner == 'microsoft' && needs.Inputs.outputs.createRelease == 'true' uses: actions/github-script@v7 id: createrelease env: - branch: ${{ github.event.inputs.branch }} + branch: ${{ needs.Inputs.outputs.branch }} bodyMD: ${{ env.ReleaseNotes }} with: - github-token: ${{ secrets.OrgPAT }} + github-token: ${{ github.token }} script: | var bodyMD = process.env.bodyMD const createReleaseResponse = await github.rest.repos.createRelease({ diff --git a/.github/workflows/E2E.yaml b/.github/workflows/E2E.yaml index 37603ef9c..6e38fb890 100644 --- a/.github/workflows/E2E.yaml +++ b/.github/workflows/E2E.yaml @@ -1,5 +1,7 @@ name: End to end tests +run-name: End to end tests - ${{ github.event.inputs.ref != '' && github.event.inputs.ref || github.sha }} + on: workflow_dispatch: inputs: @@ -15,6 +17,10 @@ on: description: Run the end to end test scenario for the full test matrix type: boolean default: true + includePrivateRepos: + description: Include private repos in full test matrix + type: boolean + default: false runScenarios: description: Run the end to end scenario tests type: boolean @@ -28,6 +34,9 @@ on: required: false default: 'preview' +env: + TestUpgradesFromVersion: 'v3.1' + defaults: run: shell: pwsh @@ -55,10 +64,6 @@ jobs: Write-Host "::Error::In order to run end to end tests, you need a Secret called adminCenterApiCredentials containing API access credentials for BC Admin Center" $err = $true } - if ('${{ Secrets.licenseFileUrl }}' -eq '') { - Write-Host "::Error::In order to run end to end tests, you need a Secret called licenseFileUrl containing a secure Url to a build license file" - $err = $true - } if ($err) { exit 1 } @@ -101,7 +106,8 @@ jobs: runs-on: [ ubuntu-latest ] needs: [ Check ] outputs: - testruns: ${{ steps.Analyze.outputs.testruns }} + publictestruns: ${{ steps.Analyze.outputs.publictestruns }} + privatetestruns: ${{ steps.Analyze.outputs.privatetestruns }} releases: ${{ steps.Analyze.outputs.releases }} scenarios: ${{ steps.Analyze.outputs.scenarios }} steps: @@ -118,35 +124,43 @@ jobs: SetTokenAndRepository -github -githubOwner '${{ needs.Check.outputs.githubowner }}' -token '${{ Secrets.E2EPAT }}' -repository "microsoft/AL-Go" $maxParallel = [int]'${{ needs.Check.outputs.maxParallel }}' - $testrunsJson = @{ + $publicTestruns = @{ + "max-parallel" = $maxParallel + "fail-fast" = $false "matrix" = @{ - "include" = @( - @('private','public') | ForEach-Object { - $visibility = $_ - @('appSourceApp','PTE') | ForEach-Object { - $type = $_ - @('linux','windows') | ForEach-Object { - $os = $_ - @('multiProject','singleProject') | ForEach-Object { - $style = $_ - @{ "visibility" = $visibility; "type" = $type; "os" = $os; "style" = $style; "Compiler" = "Container" } - if ($visibility -eq "public" -and $type -eq "PTE") { - # Run end 2 end tests using CompilerFolder with Windows+Linux and single/multiproject - @{ "visibility" = $visibility; "type" = $type; "os" = $os; "style" = $style; "Compiler" = "CompilerFolder" } - } - } - } - } - } - ) + "include" = @() } + } + $privateTestruns = @{ "max-parallel" = $maxParallel "fail-fast" = $false - } | ConvertTo-Json -depth 99 -compress - Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "testruns=$testrunsJson" - Write-Host "testruns=$testrunsJson" + "matrix" = @{ + "include" = @() + } + } + @('appSourceApp','PTE') | ForEach-Object { + $type = $_ + @('linux','windows') | ForEach-Object { + $os = $_ + @('multiProject','singleProject') | ForEach-Object { + $style = $_ + $publicTestruns.matrix.include += @{ "type" = $type; "os" = $os; "style" = $style; "Compiler" = "Container" } + $privateTestruns.matrix.include += @{ "type" = $type; "os" = $os; "style" = $style; "Compiler" = "Container" } + if ($type -eq "PTE") { + # Run end 2 end tests using CompilerFolder with Windows+Linux and single/multiproject + $publicTestruns.matrix.include += @{ "type" = $type; "os" = $os; "style" = $style; "Compiler" = "CompilerFolder" } + } + } + } + } + $publicTestrunsJson = $publicTestruns | ConvertTo-Json -depth 99 -compress + $privateTestrunsJson = $privateTestruns | ConvertTo-Json -depth 99 -compress + Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "publictestruns=$publicTestrunsJson" + Write-Host "publictestruns=$publicTestrunsJson" + Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "privatetestruns=$privateTestrunsJson" + Write-Host "privatetestruns=$privateTestrunsJson" - $releases = @(gh release list --repo microsoft/AL-Go | ForEach-Object { $_.split("`t")[0] }) + $releases = @(gh release list --repo microsoft/AL-Go | ForEach-Object { $_.split("`t")[0] }) | Where-Object { [Version]($_.trimStart('v')) -ge [Version]("$env:TestUpgradesFromVersion".TrimStart('v')) } $releasesJson = @{ "matrix" = @{ "include" = @($releases | ForEach-Object { @{ "Release" = $_; "type" = 'appSourceApp' }; @{ "Release" = $_; "type" = 'PTE' } } ) @@ -189,7 +203,7 @@ jobs: - name: Run test run: | try { - . (Join-Path "." "e2eTests/scenarios/${{ matrix.scenario }}/runtest.ps1") -github -githubOwner '${{ needs.Check.outputs.githubowner }}' -repoName ${{ steps.calculateParams.outputs.repoName }} -token '${{ Secrets.E2EPAT }}' -pteTemplate '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.perTenantExtensionRepo }}' -appSourceTemplate '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.appSourceAppRepo }}' -adminCenterApiToken '${{ Secrets.adminCenterApiCredentials }}' -licenseFileUrl '${{ Secrets.licenseFileUrl }}' + . (Join-Path "." "e2eTests/scenarios/${{ matrix.scenario }}/runtest.ps1") -github -githubOwner '${{ needs.Check.outputs.githubowner }}' -repoName ${{ steps.calculateParams.outputs.repoName }} -token '${{ Secrets.E2EPAT }}' -pteTemplate '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.perTenantExtensionRepo }}' -appSourceTemplate '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.appSourceAppRepo }}' -adminCenterApiToken '${{ Secrets.adminCenterApiCredentials }}' } catch { Write-Host $_.Exception.Message @@ -198,11 +212,54 @@ jobs: $host.SetShouldExit(1) } - TestAlGo: + TestAlGoPublic: runs-on: [ ubuntu-latest ] needs: [ Check, SetupRepositories, Analyze ] if: github.event.inputs.runTestMatrix == 'true' - strategy: ${{ fromJson(needs.Analyze.outputs.testruns) }} + strategy: ${{ fromJson(needs.Analyze.outputs.publictestruns) }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref }} + + - name: Calculate parameters + id: calculateParams + run: | + $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 + $adminCenterApiCredentials = '' + if ('${{ matrix.type }}' -eq 'PTE' -and '${{ matrix.style }}' -eq 'singleProject' -and '${{ matrix.os }}' -eq 'windows') { + $adminCenterApiCredentials = '${{ Secrets.adminCenterApiCredentials }}' + } + if ('${{ matrix.type }}' -eq 'appSourceApp') { + $template = '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.appSourceAppRepo }}' + } + else { + $template = '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.perTenantExtensionRepo }}' + } + Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "adminCenterApiCredentials='$adminCenterApiCredentials'" + Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "template='$template'" + $reponame = [System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetTempFileName()) + Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "repoName='$repoName'" + Write-Host "repoName='$repoName'" + Write-Host "Repo URL: https://github.com/${{ needs.Check.outputs.githubowner }}/$repoName" + + - name: Run tests + run: | + try { + . (Join-Path "." "e2eTests/Test-AL-Go.ps1") -github -githubOwner '${{ needs.Check.outputs.githubowner }}' -repoName ${{ steps.calculateParams.outputs.repoName }} -token '${{ Secrets.E2EPAT }}' -template ${{ steps.calculateParams.outputs.template }} -adminCenterApiToken ${{ steps.calculateParams.outputs.adminCenterApiCredentials }} -multiProject:('${{ matrix.style }}' -eq 'multiProject') -appSource:('${{ matrix.type }}' -eq 'appSourceApp') -linux:('${{ matrix.os }}' -eq 'linux') -useCompilerFolder:('${{ matrix.Compiler }}' -eq 'CompilerFolder') + } + catch { + Write-Host $_.Exception.Message + Write-Host $_.ScriptStackTrace + Write-Host "::Error::$($_.Exception.Message)" + $host.SetShouldExit(1) + } + + TestAlGoPrivate: + runs-on: [ ubuntu-latest ] + needs: [ Check, SetupRepositories, Analyze ] + if: github.event.inputs.runTestMatrix == 'true' && github.event.inputs.includePrivateRepos == 'true' + strategy: ${{ fromJson(needs.Analyze.outputs.privatetestruns) }} steps: - uses: actions/checkout@v4 with: @@ -213,19 +270,16 @@ jobs: run: | $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 $adminCenterApiCredentials = '' - $licenseFileUrl = '' if ('${{ matrix.type }}' -eq 'PTE' -and '${{ matrix.style }}' -eq 'singleProject' -and '${{ matrix.os }}' -eq 'windows') { $adminCenterApiCredentials = '${{ Secrets.adminCenterApiCredentials }}' } if ('${{ matrix.type }}' -eq 'appSourceApp') { - $licenseFileUrl='${{ secrets.licenseFileUrl }}' $template = '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.appSourceAppRepo }}' } else { $template = '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.perTenantExtensionRepo }}' } Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "adminCenterApiCredentials='$adminCenterApiCredentials'" - Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "licenseFileUrl='$licenseFileUrl'" Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "template='$template'" $reponame = [System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetTempFileName()) Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "repoName='$repoName'" @@ -235,7 +289,7 @@ jobs: - name: Run tests run: | try { - . (Join-Path "." "e2eTests/Test-AL-Go.ps1") -github -githubOwner '${{ needs.Check.outputs.githubowner }}' -repoName ${{ steps.calculateParams.outputs.repoName }} -token '${{ Secrets.E2EPAT }}' -template ${{ steps.calculateParams.outputs.template }} -adminCenterApiToken ${{ steps.calculateParams.outputs.adminCenterApiCredentials }} -licenseFileUrl ${{ steps.calculateParams.outputs.licenseFileUrl }} -multiProject:('${{ matrix.style }}' -eq 'multiProject') -appSource:('${{ matrix.type }}' -eq 'appSourceApp') -linux:('${{ matrix.os }}' -eq 'linux') -private:('${{ matrix.visibility }}' -eq 'private') -useCompilerFolder:('${{ matrix.Compiler }}' -eq 'CompilerFolder') + . (Join-Path "." "e2eTests/Test-AL-Go.ps1") -private -github -githubOwner '${{ needs.Check.outputs.githubowner }}' -repoName ${{ steps.calculateParams.outputs.repoName }} -token '${{ Secrets.E2EPAT }}' -template ${{ steps.calculateParams.outputs.template }} -adminCenterApiToken ${{ steps.calculateParams.outputs.adminCenterApiCredentials }} -multiProject:('${{ matrix.style }}' -eq 'multiProject') -appSource:('${{ matrix.type }}' -eq 'appSourceApp') -linux:('${{ matrix.os }}' -eq 'linux') -useCompilerFolder:('${{ matrix.Compiler }}' -eq 'CompilerFolder') } catch { Write-Host $_.Exception.Message @@ -244,6 +298,7 @@ jobs: $host.SetShouldExit(1) } + TestAlGoUpgrade: runs-on: [ ubuntu-latest ] needs: [ Check, SetupRepositories, Analyze ] @@ -259,16 +314,13 @@ jobs: run: | $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 if ('${{ matrix.type }}' -eq 'appSourceApp') { - $licenseFileUrl = '${{ secrets.licenseFileUrl }}' $template = '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.appSourceAppRepo }}' $contentPath = 'appsourceapp' } else { - $licenseFileUrl = '' $template = '${{ needs.Check.outputs.githubowner }}/${{ needs.SetupRepositories.outputs.perTenantExtensionRepo }}' $contentPath = 'pte' } - Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "licenseFileUrl='$licenseFileUrl'" Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "template='$template'" Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "contentPath='$contentPath'" $reponame = [System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetTempFileName()) @@ -279,7 +331,7 @@ jobs: - name: Run tests run: | try { - . (Join-Path "." "e2eTests/Test-AL-Go-Upgrade.ps1") -github -githubOwner '${{ needs.Check.outputs.githubowner }}' -repoName ${{ steps.calculateParams.outputs.repoName }} -token '${{ Secrets.E2EPAT }}' -template ${{ steps.calculateParams.outputs.template }} -licenseFileUrl ${{ steps.calculateParams.outputs.licenseFileUrl }} -appSource:('${{ matrix.type }}' -eq 'appSourceApp') -release '${{ matrix.release }}' -contentPath ${{ steps.calculateParams.outputs.contentPath }} + . (Join-Path "." "e2eTests/Test-AL-Go-Upgrade.ps1") -github -githubOwner '${{ needs.Check.outputs.githubowner }}' -repoName ${{ steps.calculateParams.outputs.repoName }} -token '${{ Secrets.E2EPAT }}' -template ${{ steps.calculateParams.outputs.template }} -appSource:('${{ matrix.type }}' -eq 'appSourceApp') -release '${{ matrix.release }}' -contentPath ${{ steps.calculateParams.outputs.contentPath }} } catch { Write-Host $_.Exception.Message @@ -290,8 +342,8 @@ jobs: RemoveRepositories: runs-on: [ ubuntu-latest ] - needs: [ Check, SetupRepositories, TestAlGo, TestAlGoUpgrade, Scenario ] - if: always() && (!Cancelled()) && (needs.SetupRepositories.result == 'Success') && (needs.TestAlGo.result == 'Success' || needs.TestAlGo.result == 'Skipped') && (needs.TestAlGoUpgrade.result == 'Success' || needs.TestAlGoUpgrade.result == 'Skipped') && (needs.Scenario.result == 'Success' || needs.Scenario.result == 'Skipped') + needs: [ Check, SetupRepositories, TestAlGoPublic, TestAlGoPrivate, TestAlGoUpgrade, Scenario ] + if: always() && (!Cancelled()) && (needs.SetupRepositories.result == 'Success') && (needs.TestAlGoPublic.result == 'Success' || needs.TestAlGoPublic.result == 'Skipped') && (needs.TestAlGoPrivate.result == 'Success' || needs.TestAlGoPrivate.result == 'Skipped') && (needs.TestAlGoUpgrade.result == 'Success' || needs.TestAlGoUpgrade.result == 'Skipped') && (needs.Scenario.result == 'Success' || needs.Scenario.result == 'Skipped') steps: - uses: actions/checkout@v4 with: diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index 0a5b1432c..b4f62578e 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -1310,9 +1310,8 @@ function CloneIntoNewFolder { Set-Location * invoke-git checkout $updateBranch - $branch = '' + $branch = "$newBranchPrefix/$updateBranch/$((Get-Date).ToUniversalTime().ToString(`"yyMMddHHmmss`"))" # e.g. create-development-environment/main/210101120000 if (!$directCommit) { - $branch = "$newBranchPrefix/$updateBranch/$((Get-Date).ToUniversalTime().ToString(`"yyMMddHHmmss`"))" # e.g. create-development-environment/main/210101120000 invoke-git checkout -b $branch } @@ -1334,17 +1333,28 @@ function CommitFromNewFolder { $commitMessage = "$($commitMessage.Substring(0,250))...)" } invoke-git commit --allow-empty -m "$commitMessage" - if ($branch) { - invoke-git push -u $serverUrl $branch + $activeBranch = invoke-git -returnValue -silent name-rev --name-only HEAD + # $branch is the name of the branch to be used when creating a Pull Request + # $activeBranch is the name of the branch that is currently checked out + # If activeBranch and branch are the same - we are creating a PR + if ($activeBranch -ne $branch) { try { - invoke-gh pr create --fill --head $branch --repo $env:GITHUB_REPOSITORY --base $ENV:GITHUB_REF_NAME + invoke-git push $serverUrl + return $true } catch { - OutputError("GitHub actions are not allowed to create Pull Requests (see GitHub Organization or Repository Actions Settings). You can create the PR manually by navigating to $($env:GITHUB_SERVER_URL)/$($env:GITHUB_REPOSITORY)/tree/$branch") + OutputWarning("Direct Commit wasn't allowed, trying to create a Pull Request instead") + invoke-git reset --soft HEAD~ + invoke-git checkout -b $branch + invoke-git commit --allow-empty -m "$commitMessage" } } - else { - invoke-git push $serverUrl + invoke-git push -u $serverUrl $branch + try { + invoke-gh pr create --fill --head $branch --repo $env:GITHUB_REPOSITORY --base $ENV:GITHUB_REF_NAME + } + catch { + OutputError("GitHub actions are not allowed to create Pull Requests (see GitHub Organization or Repository Actions Settings). You can create the PR manually by navigating to $($env:GITHUB_SERVER_URL)/$($env:GITHUB_REPOSITORY)/tree/$branch") } return $true } diff --git a/Actions/CheckForUpdates/CheckForUpdates.ps1 b/Actions/CheckForUpdates/CheckForUpdates.ps1 index ea78f9b18..47e70d742 100644 --- a/Actions/CheckForUpdates/CheckForUpdates.ps1 +++ b/Actions/CheckForUpdates/CheckForUpdates.ps1 @@ -277,6 +277,15 @@ if ($update -ne 'Y') { else { # $update set, update the files try { + # If a pull request already exists with the same REF, then exit + $commitMessage = "[$updateBranch] Update AL-Go System Files - $templateSha" + $env:GH_TOKEN = $token + $existingPullRequest = (gh api --paginate "/repos/$env:GITHUB_REPOSITORY/pulls?base=$updateBranch" -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" | ConvertFrom-Json) | Where-Object { $_.title -eq $commitMessage } | Select-Object -First 1 + if ($existingPullRequest) { + OutputWarning "Pull request already exists for $($commitMessage): $($existingPullRequest.html_url)." + exit + } + # If $directCommit, then changes are made directly to the default branch $serverUrl, $branch = CloneIntoNewFolder -actor $actor -token $token -updateBranch $updateBranch -DirectCommit $directCommit -newBranchPrefix 'update-al-go-system-files' @@ -326,7 +335,7 @@ else { Write-Host "ReleaseNotes:" Write-Host $releaseNotes - if (!(CommitFromNewFolder -serverUrl $serverUrl -commitMessage "Update AL-Go System Files" -branch $branch)) { + if (!(CommitFromNewFolder -serverUrl $serverUrl -commitMessage $commitMessage -branch $branch)) { OutputWarning "No updates available for AL-Go for GitHub." } } diff --git a/Internal/Deploy.ps1 b/Internal/Deploy.ps1 index 8229ea0e1..62eba2435 100644 --- a/Internal/Deploy.ps1 +++ b/Internal/Deploy.ps1 @@ -245,7 +245,7 @@ try { $releaseNotesFile = Join-Path $baseRepoPath "RELEASENOTES.md" $releaseNotes = (Get-Content -Encoding utf8 -Path $releaseNotesFile) -join "`n" if ($config.branch -eq 'preview') { - $releaseNotes = "## $($config.branch)`n`nNote that when using the preview version of AL-Go for GitHub, we recommend you Update your AL-Go system files, as soon as possible when informed that an update is available.`n`n$reserveReleaseNotes" + $releaseNotes = "## $($config.branch)`n`nNote that when using the preview version of AL-Go for GitHub, we recommend you Update your AL-Go system files, as soon as possible when informed that an update is available.`n`n$releaseNotes" } else { $releaseNotes = "## $($config.branch)`n`n$releaseNotes" diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3c9596cdd..605ae0e3b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,3 +1,9 @@ + +## v5.2 + +### Issues +- Issue 1084 Automatic updates for AL-Go are failing when main branch requires Pull Request + ### New Settings - `PowerPlatformSolutionFolder`: Contains the name of the folder containing a PowerPlatform Solution (only one) diff --git a/Scenarios/SetupCiCdForExistingPTE.md b/Scenarios/SetupCiCdForExistingPTE.md index 3d1981ca9..faafe07d7 100644 --- a/Scenarios/SetupCiCdForExistingPTE.md +++ b/Scenarios/SetupCiCdForExistingPTE.md @@ -1,6 +1,6 @@ # #10 Set up CI/CD for an existing per-tenant extension (BingMaps) *Prerequisites: A GitHub account. -We will use the BingMaps sample app, which can be found on GitHub in the [Business Central BingMaps.PTE repo](https://github.com/BusinessCentralApps/BingMaps.PTE). Copy the following URL (a direct download of the latest released app file from BingMaps sample) to the clipboard: [https://businesscentralapps.blob.core.windows.net/bingmaps-pte/latest/bingmaps-pte-apps.zip](https://businesscentralapps.blob.core.windows.net/bingmaps-pte/latest/bingmaps-pte-apps.zip) – you can also download the .zip file and see the content of it. +We will use the BingMaps sample app, which can be found on GitHub in the [Business Central BingMaps.PTE repo](https://github.com/microsoft/bcsamples-bingmaps.pte). Copy the URL to the Apps artifact of the latest release to the clipboard (currently [https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/24.0.0/bcsamples-bingmaps.pte-main-Apps-24.0.169.0.zip](https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/24.0.0/bcsamples-bingmaps.pte-main-Apps-24.0.169.0.zip) – you can also download the .zip file and see the content of it. 1. Navigate to [https://github.com/microsoft/AL-Go-PTE](https://github.com/microsoft/AL-Go-PTE) and then choose **Use this template**. ![Use this template](https://github.com/microsoft/AL-Go/assets/10775043/b4e32467-723d-434e-8c0a-45c6254699b4) diff --git a/Templates/AppSource App/.github/workflows/UpdateGitHubGoSystemFiles.yaml b/Templates/AppSource App/.github/workflows/UpdateGitHubGoSystemFiles.yaml index bf064b34e..0e35b03bc 100644 --- a/Templates/AppSource App/.github/workflows/UpdateGitHubGoSystemFiles.yaml +++ b/Templates/AppSource App/.github/workflows/UpdateGitHubGoSystemFiles.yaml @@ -29,6 +29,7 @@ env: jobs: UpdateALGoSystemFiles: + name: 'Update AL-Go System Files' needs: [ ] runs-on: [ windows-latest ] steps: diff --git a/Templates/Per Tenant Extension/.github/workflows/UpdateGitHubGoSystemFiles.yaml b/Templates/Per Tenant Extension/.github/workflows/UpdateGitHubGoSystemFiles.yaml index bf064b34e..0e35b03bc 100644 --- a/Templates/Per Tenant Extension/.github/workflows/UpdateGitHubGoSystemFiles.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/UpdateGitHubGoSystemFiles.yaml @@ -29,6 +29,7 @@ env: jobs: UpdateALGoSystemFiles: + name: 'Update AL-Go System Files' needs: [ ] runs-on: [ windows-latest ] steps: diff --git a/e2eTests/Test-AL-Go-Upgrade.ps1 b/e2eTests/Test-AL-Go-Upgrade.ps1 index dcdb59849..f2a74fa2f 100644 --- a/e2eTests/Test-AL-Go-Upgrade.ps1 +++ b/e2eTests/Test-AL-Go-Upgrade.ps1 @@ -7,7 +7,6 @@ Param( [string] $contentPath = "pte", [string] $release = "v2.2", [string] $template = $global:pteTemplate, - [string] $licenseFileUrl = "", [switch] $appSourceApp, [switch] $private ) @@ -27,7 +26,6 @@ Write-Host -ForegroundColor Yellow @' # # - Login # - Create a new repository based on the selected template and the selected version -# - If (AppSource App) Create a licensefileurl secret # - Run CI/CD workflow # - Test that the number of workflows ran is correct and the artifacts created from CI/CD are correct and of the right version # - Create the GHTOKENWORKFLOW secret @@ -52,15 +50,9 @@ $releaseVersion = [System.Version]$release.Substring(1) if ($appSourceApp) { $orgTemplate = 'https://github.com/microsoft/al-go-appSource' - if (!$licenseFileUrl) { - throw "License file secret must be set" - } } else { $orgTemplate = 'https://github.com/microsoft/al-go-pte' - if ($licenseFileUrl) { - throw "License file secret should not be set" - } } $template = "https://github.com/$template" @@ -89,11 +81,6 @@ CommitAndPush -commitMessage "Update settings.json" # Expected Run: CI/CD triggered on push $runs++ -# Add Existing App -if ($appSourceApp) { - SetRepositorySecret -repository $repository -name 'LICENSEFILEURL' -value $licenseFileUrl -} - # Run CI/CD and wait $run = RunCICD -wait -branch $branch Test-ArtifactsFromRun -runid $run.id -expectedArtifacts @{"Apps"=1;"TestApps"=1} -expectedNumberOfTests 1 -folder 'artifacts' -repoVersion '1.0' -appVersion '' diff --git a/e2eTests/Test-AL-Go.ps1 b/e2eTests/Test-AL-Go.ps1 index 13445574d..a976130ea 100644 --- a/e2eTests/Test-AL-Go.ps1 +++ b/e2eTests/Test-AL-Go.ps1 @@ -6,7 +6,6 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $template = $global:pteTemplate, [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText), [switch] $multiProject, [switch] $appSourceApp, [switch] $private, @@ -26,7 +25,6 @@ Write-Host -ForegroundColor Yellow @' # # - Login to GitHub # - Create a new repository based on the selected template -# - If (AppSource App) Create a licensefileurl secret # - Run the "Add an existing app" workflow and add an app as a Pull Request # - Test that a Pull Request was created and merge the Pull Request # - Run the "CI/CD" workflow @@ -70,13 +68,13 @@ $repository = "$githubOwner/$repoName" $branch = "main" if ($appSourceApp) { - $sampleApp1 = "https://businesscentralapps.blob.core.windows.net/githubhelloworld-appsource-preview/2.0.47.0/apps.zip" - $sampleTestApp1 = "https://businesscentralapps.blob.core.windows.net/githubhelloworld-appsource-preview/2.0.47.0/testapps.zip" + $sampleApp1 = "https://github.com/BusinessCentralApps/helloworld.appsource/releases/download/2.0.0/helloworld.appsource-main-Apps-2.0.6.0.zip" + $sampleTestApp1 = "https://github.com/BusinessCentralApps/helloworld.appsource/releases/download/2.0.0/helloworld.appsource-main-TestApps-2.0.6.0.zip" $idRange = @{ "from" = 75055000; "to" = 75056000 } } else { - $sampleApp1 = "https://businesscentralapps.blob.core.windows.net/githubhelloworld-preview/2.0.82.0/apps.zip" - $sampleTestApp1 = "https://businesscentralapps.blob.core.windows.net/githubhelloworld-preview/2.0.82.0/testapps.zip" + $sampleApp1 = "https://github.com/BusinessCentralApps/helloworld.pte/releases/download/2.0.0/helloworld.pte-main-Apps-2.0.5.0.zip" + $sampleTestApp1 = "https://github.com/BusinessCentralApps/helloworld.pte/releases/download/2.0.0/helloworld.pte-main-TestApps-2.0.5.0.zip" $idRange = @{ "from" = 55000; "to" = 56000 } } if ($multiProject) { @@ -116,9 +114,6 @@ Start-Sleep -Seconds 60 $runs = GetNumberOfRuns -repository $repository # Add Existing App -if ($appSourceApp) { - SetRepositorySecret -repository $repository -name 'LICENSEFILEURL' -value $licenseFileUrl -} RunAddExistingAppOrTestApp @project1Param -url $sampleApp1 -wait -directCommit -branch $branch | Out-Null $runs++ if ($appSourceApp) { @@ -168,11 +163,11 @@ if ($appSourceApp) { "brief" = "Hello World for AppSource" "description" = "Hello World sample app for AppSource" "logo" = "helloworld256x240.png" - "url" = "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource" - "EULA" = "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource" - "privacyStatement" = "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource" - "help" = "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource" - "contextSensitiveHelpUrl" = "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource" + "url" = "https://github.com/BusinessCentralApps/helloworld.appsource" + "EULA" = "https://github.com/BusinessCentralApps/helloworld.appsource" + "privacyStatement" = "https://github.com/BusinessCentralApps/helloworld.appsource" + "help" = "https://github.com/BusinessCentralApps/helloworld.appsource" + "contextSensitiveHelpUrl" = "https://github.com/BusinessCentralApps/helloworld.appsource" "features" = @( "TranslationFile" ) } $runs++ diff --git a/e2eTests/appsourceapp/My App/app.json b/e2eTests/appsourceapp/My App/app.json index c333facd4..2abecdb70 100644 --- a/e2eTests/appsourceapp/My App/app.json +++ b/e2eTests/appsourceapp/My App/app.json @@ -5,11 +5,11 @@ "version": "1.0.0.0", "brief": "Hello World for AppSource", "description": "Hello World sample app for AppSource", - "privacyStatement": "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource", - "EULA": "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource", - "help": "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource", - "url": "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource", - "contextSensitiveHelpUrl": "https://dev.azure.com/businesscentralapps/HelloWorld.AppSource", + "privacyStatement": "https://github.com/BusinessCentralApps/helloworld.appsource", + "EULA": "https://github.com/BusinessCentralApps/helloworld.appsource", + "help": "https://github.com/BusinessCentralApps/helloworld.appsource", + "url": "https://github.com/BusinessCentralApps/helloworld.appsource", + "contextSensitiveHelpUrl": "https://github.com/BusinessCentralApps/helloworld.appsource", "logo": "helloworld256x240.png", "dependencies": [ diff --git a/e2eTests/e2eTestHelper.psm1 b/e2eTests/e2eTestHelper.psm1 index b99a77a15..e223d6be3 100644 --- a/e2eTests/e2eTestHelper.psm1 +++ b/e2eTests/e2eTestHelper.psm1 @@ -453,11 +453,6 @@ function CreateAlGoRepository { $repoSettings = Get-Content $repoSettingsFile -Encoding UTF8 | ConvertFrom-Json $runson = "windows-latest" $shell = "powershell" - if ($private) { - $repoSettings | Add-Member -MemberType NoteProperty -Name "gitHubRunner" -Value "self-hosted" - $repoSettings | Add-Member -MemberType NoteProperty -Name "gitHubRunnerShell" -Value "powershell" - $runson = "self-hosted" - } if ($linux) { $runson = "ubuntu-latest" $shell = "pwsh" diff --git a/e2eTests/scenarios/BuildModes/runtest.ps1 b/e2eTests/scenarios/BuildModes/runtest.ps1 index 8de795674..b1ac852f1 100644 --- a/e2eTests/scenarios/BuildModes/runtest.ps1 +++ b/e2eTests/scenarios/BuildModes/runtest.ps1 @@ -7,8 +7,7 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $pteTemplate = $global:pteTemplate, [string] $appSourceTemplate = $global:appSourceTemplate, - [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText) + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText) ) Write-Host -ForegroundColor Yellow @' diff --git a/e2eTests/scenarios/GitHubPackages/runtest.ps1 b/e2eTests/scenarios/GitHubPackages/runtest.ps1 index 778c75570..5ce0ecb71 100644 --- a/e2eTests/scenarios/GitHubPackages/runtest.ps1 +++ b/e2eTests/scenarios/GitHubPackages/runtest.ps1 @@ -7,8 +7,7 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $pteTemplate = $global:pteTemplate, [string] $appSourceTemplate = $global:appSourceTemplate, - [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText) + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText) ) Write-Host -ForegroundColor Yellow @' diff --git a/e2eTests/scenarios/IncludeDependencies/runtest.ps1 b/e2eTests/scenarios/IncludeDependencies/runtest.ps1 index ba6122416..129111caa 100644 --- a/e2eTests/scenarios/IncludeDependencies/runtest.ps1 +++ b/e2eTests/scenarios/IncludeDependencies/runtest.ps1 @@ -7,8 +7,7 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $pteTemplate = $global:pteTemplate, [string] $appSourceTemplate = $global:appSourceTemplate, - [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText) + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText) ) Write-Host -ForegroundColor Yellow @' diff --git a/e2eTests/scenarios/PowerPlatform/runtest.ps1 b/e2eTests/scenarios/PowerPlatform/runtest.ps1 index 2067f29fa..4103c8ee5 100644 --- a/e2eTests/scenarios/PowerPlatform/runtest.ps1 +++ b/e2eTests/scenarios/PowerPlatform/runtest.ps1 @@ -7,8 +7,7 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $pteTemplate = $global:pteTemplate, [string] $appSourceTemplate = $global:appSourceTemplate, - [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText) + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText) ) Write-Host -ForegroundColor Yellow @' diff --git a/e2eTests/scenarios/ReferenceDocumentation/runtest.ps1 b/e2eTests/scenarios/ReferenceDocumentation/runtest.ps1 index 89968975f..7830f3523 100644 --- a/e2eTests/scenarios/ReferenceDocumentation/runtest.ps1 +++ b/e2eTests/scenarios/ReferenceDocumentation/runtest.ps1 @@ -7,8 +7,7 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $pteTemplate = $global:pteTemplate, [string] $appSourceTemplate = $global:appSourceTemplate, - [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText) + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText) ) Write-Host -ForegroundColor Yellow @' diff --git a/e2eTests/scenarios/ReleaseBranches/runtest.ps1 b/e2eTests/scenarios/ReleaseBranches/runtest.ps1 index b46cee5a5..bbfafafab 100644 --- a/e2eTests/scenarios/ReleaseBranches/runtest.ps1 +++ b/e2eTests/scenarios/ReleaseBranches/runtest.ps1 @@ -7,8 +7,7 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $pteTemplate = $global:pteTemplate, [string] $appSourceTemplate = $global:appSourceTemplate, - [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText) + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText) ) Write-Host -ForegroundColor Yellow @' diff --git a/e2eTests/scenarios/SpecialCharacters/runtest.ps1 b/e2eTests/scenarios/SpecialCharacters/runtest.ps1 index dd5002150..29b0b5ed3 100644 --- a/e2eTests/scenarios/SpecialCharacters/runtest.ps1 +++ b/e2eTests/scenarios/SpecialCharacters/runtest.ps1 @@ -7,8 +7,7 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $pteTemplate = $global:pteTemplate, [string] $appSourceTemplate = $global:appSourceTemplate, - [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText) + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText) ) Write-Host -ForegroundColor Yellow @' diff --git a/e2eTests/scenarios/UseProjectDependencies/runtest.ps1 b/e2eTests/scenarios/UseProjectDependencies/runtest.ps1 index 64aa73de9..109fad1f0 100644 --- a/e2eTests/scenarios/UseProjectDependencies/runtest.ps1 +++ b/e2eTests/scenarios/UseProjectDependencies/runtest.ps1 @@ -7,8 +7,7 @@ Param( [string] $token = ($Global:SecureE2EPAT | Get-PlainText), [string] $pteTemplate = $global:pteTemplate, [string] $appSourceTemplate = $global:appSourceTemplate, - [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), - [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText) + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText) ) Write-Host -ForegroundColor Yellow @'