forked from microsoft/AL-Go
-
Notifications
You must be signed in to change notification settings - Fork 1
198 lines (186 loc) · 8.99 KB
/
Deploy.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
name: Deploy
run-name: "Deploy from [${{ github.ref_name }}] to [${{ inputs.branch }}]"
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to deploy to (NOTE: Use preview when deploying preview releases on microsoft/al-go)'
required: true
copyToMain:
type: boolean
description: 'Additionally deploy templates to main+preview branch? Set if this is a release to PROD on microsoft/al-go'
required: false
default: false
directCommit:
type: boolean
description: Push directly to the target branch. If not set, a PR will be created.
required: false
default: false
requireEndToEndTests:
type: boolean
description: Require successful end 2 end tests before deploying
required: false
default: true
createRelease:
type: boolean
description: Create a release in this repository
required: false
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: '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' && needs.Inputs.outputs.requireEndToEndTests == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
$errorActionPreference = "Stop"
$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 { $_.Name -eq "End to end tests - $latestSha" } | select-object -first 1
if (!$latestRun) {
throw "No End to end tests run found for the latest commit on main"
}
if ($latestRun.status -ne '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 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, Inputs ]
environment: Production
permissions:
contents: write
steps:
- name: Validate Deployment
if: github.repository_owner == 'microsoft'
env:
GH_TOKEN: ${{ github.token }}
branch: ${{ needs.Inputs.outputs.branch }}
runId: ${{ github.run_id }}
run: |
$errorActionPreference = "Stop"
if ($env:branch -eq 'preview') {
Write-Host "Deploying to preview branch. No validation required"
} else {
$approval = gh api /repos/$($env:GITHUB_REPOSITORY)/actions/runs/$($env:runId)/approvals | ConvertFrom-Json
$run = gh api /repos/$($env:GITHUB_REPOSITORY)/actions/runs/$($env:runId) | ConvertFrom-Json
if ($approval.user.login -eq $run.actor.login) {
throw "You cannot approve your own deployment"
}
}
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Deploy
env:
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 {
$token = '${{ Secrets.OrgPAT }}'
if (!$token) {
throw "In order to run the Deploy workflow, you need a Secret called OrgPAT containing a valid Personal Access Token"
}
$githubOwner = "$env:GITHUB_REPOSITORY_OWNER"
if ("$env:defaultBcContainerHelperVersion" -eq "") {
if ($env:branch -eq 'preview') {
$env:defaultBcContainerHelperVersion = 'preview'
} else {
$env:defaultBcContainerHelperVersion = 'latest'
}
}
$config = @{
"githubOwner" = $githubOwner
"actionsRepo" = "AL-Go-Actions"
"perTenantExtensionRepo" = "AL-Go-PTE"
"appSourceAppRepo" = "AL-Go-AppSource"
"branch" = $env:branch
"copyToMain" = ($env:copyToMain -eq 'true')
"defaultBcContainerHelperVersion" = $env:defaultBcContainerHelperVersion
}
. ".\Internal\Deploy.ps1" -config $config -token $token -directCommit ($env:directCommit -eq 'true')
}
catch {
Write-Host "::Error::Error deploying repositories. The error was $($_.Exception.Message)"
exit 1
}
- name: Calculate Release Notes
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"
$releaseNotes = (Get-Content -Encoding utf8 -Path $releaseNotesFile) -join "`n"
$lastVersion = $releaseNotes.indexof("`n## ")
$releaseNotes = $releaseNotes.Substring(0, $lastVersion)
Add-Content -encoding UTF8 -Path $env:GITHUB_ENV -Value "ReleaseNotes=$([Uri]::EscapeDataString($releaseNotes))"
- name: Create release
if: github.repository_owner == 'microsoft' && needs.Inputs.outputs.createRelease == 'true'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: createrelease
env:
branch: ${{ needs.Inputs.outputs.branch }}
bodyMD: ${{ env.ReleaseNotes }}
with:
github-token: ${{ github.token }}
script: |
var bodyMD = process.env.bodyMD
const createReleaseResponse = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: '${{ env.branch }}',
name: '${{ env.branch }}',
body: decodeURIComponent(bodyMD),
draft: false,
prerelease: false
});
const {
data: { id: releaseId, html_url: htmlUrl, upload_url: uploadUrl }
} = createReleaseResponse;
core.setOutput('releaseId', releaseId);