Repository navigation
190 lines (183 loc) · 8.93 KB
/
Copy pathcloud-database-tests.yml
File metadata and controls
190 lines (183 loc) · 8.93 KB
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
name: Cloud database tests
on:
schedule:
- cron: '17 3 * * *'
workflow_call:
workflow_dispatch:
inputs:
target:
description: Which managed database to test against
required: true
default: all
type: choice
options:
- all
- azure-sqlserver
- azure-postgresql
- aurora-postgresql
- rds-sqlserver
env:
DOTNET_NOLOGO: true
# Its own region rather than the AWS_REGION secret the SQS tests use: that one is at its VPC
# ceiling, so RDS has no default VPC to place a publicly accessible instance in. us-east-2 already
# has one, has VPC headroom, and offers both instance classes these targets ask for.
AWS_DATABASE_REGION: us-east-2
defaults:
run:
shell: pwsh
concurrency:
# Cancelling is safe because the provisioner deletes its database in a post step, which still runs
# on cancellation.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
plan:
name: Plan
runs-on: ubuntu-latest
outputs:
targets: ${{ steps.select.outputs.targets }}
skip: ${{ steps.tested.outputs.skip }}
steps:
- name: Skip if this commit already passed
id: tested
if: github.event_name == 'schedule'
env:
GH_TOKEN: ${{ github.token }}
run: |
$passed = gh run list --repo $Env:GITHUB_REPOSITORY --workflow cloud-database-tests.yml --event schedule --status success --commit $Env:GITHUB_SHA --limit 1 --json url | ConvertFrom-Json
if ($passed) {
Write-Output "$Env:GITHUB_SHA already passed in $($passed[0].url), skipping"
"skip=true" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append
}
- name: Select targets
id: select
run: |
$all = @(
@{ target = 'azure-sqlserver'; provider = 'SqlServer' }
@{ target = 'azure-postgresql'; provider = 'PostgreSql' }
@{ target = 'aurora-postgresql'; provider = 'PostgreSql' }
@{ target = 'rds-sqlserver'; provider = 'SqlServer' }
)
# A tag push or the nightly schedule has no input, and runs everything.
$requested = '${{ inputs.target }}'
$targets = if (-not $requested -or $requested -eq 'all') { $all } else { $all | Where-Object { $_.target -eq $requested } }
if (-not $targets) {
throw "No cloud target named '$requested'."
}
$targets | ForEach-Object { Write-Output "Will test against $($_.target)" }
$matrix = @{ include = @($targets) }
"targets=$(ConvertTo-Json -InputObject $matrix -Compress -Depth 4)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append
test:
name: ${{ matrix.target }}
needs: plan
if: needs.plan.outputs.skip != 'true'
runs-on: ubuntu-latest
# The slowest complete job so far took 70 minutes (rds-sqlserver from a runner far from
# us-east-2), and provisioning alone can take 25. Without a cap, a hung test run keeps its
# database and its runner for six hours.
timeout-minutes: 90
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.plan.outputs.targets) }}
# The suites that exercise the primary and audit persisters. Named outright rather than
# selected by test category, because the category also carries the transport tests, which test
# the queue transport against its own connection string and have no business running here.
env:
PERSISTENCE_PROJECT: src/ServiceControl.Persistence.Tests.${{ matrix.provider }}/ServiceControl.Persistence.Tests.${{ matrix.provider }}.csproj
ACCEPTANCE_PROJECT: src/ServiceControl.AcceptanceTests.${{ matrix.provider }}/ServiceControl.AcceptanceTests.${{ matrix.provider }}.csproj
AUDIT_PERSISTENCE_PROJECT: src/ServiceControl.Audit.Persistence.Tests.${{ matrix.provider }}/ServiceControl.Audit.Persistence.Tests.${{ matrix.provider }}.csproj
AUDIT_ACCEPTANCE_PROJECT: src/ServiceControl.Audit.AcceptanceTests.${{ matrix.provider }}/ServiceControl.Audit.AcceptanceTests.${{ matrix.provider }}.csproj
steps:
- name: Check for secrets
env:
SECRETS_AVAILABLE: ${{ secrets.SECRETS_AVAILABLE }}
run: exit $(If ($env:SECRETS_AVAILABLE -eq 'true') { 0 } Else { 1 })
- name: Checkout
uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- name: Setup .NET SDK
uses: actions/setup-dotnet@v6.0.0
with:
global-json-file: global.json
- name: Determine runtime version
run: |
# Read settings from Custom.Build.props
[xml]$xml = Get-Content ./src/Custom.Build.props
$runtimeVersion = $xml.selectNodes('/Project/PropertyGroup/RuntimeFrameworkVersion').InnerText
if (-not ($runtimeVersion)) {
throw "Missing RuntimeFrameworkVersion setting in Custom.Build.props"
}
echo "RuntimeVersion=$runtimeVersion" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
- name: Install .NET Runtime
shell: bash
run: |
./tools/dotnet-install.sh --skip-non-versioned-files --install-dir /usr/share/dotnet --runtime dotnet --version ${{ env.RuntimeVersion }}
./tools/dotnet-install.sh --skip-non-versioned-files --install-dir /usr/share/dotnet --runtime aspnetcore --version ${{ env.RuntimeVersion }}
- name: Build
id: build
background: true
run: |
dotnet build $Env:PERSISTENCE_PROJECT --configuration Release
dotnet build $Env:ACCEPTANCE_PROJECT --configuration Release
dotnet build $Env:AUDIT_PERSISTENCE_PROJECT --configuration Release
dotnet build $Env:AUDIT_ACCEPTANCE_PROJECT --configuration Release
- name: Azure login
uses: azure/login@v3.1.0
if: startsWith(matrix.target, 'azure-')
with:
creds: ${{ secrets.AZURE_ACI_CREDENTIALS }}
- name: Setup AWS environment variables
if: startsWith(matrix.target, 'aurora-') || startsWith(matrix.target, 'rds-')
run: |
echo "AWS_REGION=${{ env.AWS_DATABASE_REGION }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
# Unlike ci.yml, which holds its cloud resources back until the build is done, provisioning
# starts first: it is the long pole here at anywhere from 3 to 25 minutes, and the database is
# torn down by this action's post step whatever the job does afterwards.
#
# It has to come after the login steps above. Post steps run in reverse, so this one's teardown
# runs before azure/login's post step signs the CLI out from under it.
- name: Provision database
uses: ./.github/actions/cloud-database
with:
target: ${{ matrix.target }}
# The server is what isolates one run from another, so this has to be unique per run. It
# includes the attempt because run_id does not change when a run is retried, and the
# previous attempt's server may still be there or still be deleting.
name: sc-ct-${{ github.run_id }}-${{ github.run_attempt }}
- name: Wait for build
wait: build
- name: Run tests
uses: Particular/run-tests-action@v1.9.0
with:
projects: ${{ env.PERSISTENCE_PROJECT }};${{ env.ACCEPTANCE_PROJECT }};${{ env.AUDIT_PERSISTENCE_PROJECT }};${{ env.AUDIT_ACCEPTANCE_PROJECT }}
max-parallel: 2
env:
ServiceControl_TESTS_FILTER: ${{ matrix.provider }}
PARTICULARSOFTWARE_LICENSE: ${{ secrets.LICENSETEXT }}
notify:
name: Notify Slack
needs: [plan, test]
# Only the nightly run reports, because whoever starts a run by hand or through a release is
# already watching it.
if: ${{ !cancelled() && github.event_name == 'schedule' && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }}
runs-on: ubuntu-latest
steps:
- name: Notify Slack on failure
run: |
$headers = @{
'Authorization' = "Bearer ${{ secrets.SLACK_TOKEN }}"
}
$body = @{
channel = 'pulse-and-control'
text = "Nightly cloud database tests failed on ${{ github.ref_name }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
username = 'Cloud database tests'
icon_emoji = 'github_actions'
unfurl_links = false
unfurl_media = false
} | ConvertTo-Json
$result = Invoke-RestMethod -Method POST -Uri https://slack.com/api/chat.postMessage -ContentType "application/json; charset=utf-8" -Headers $headers -Body $body
Write-Output $result
exit $(If ($result.ok) { 0 } Else { 1 })