1
1
name : Run QA Test # Runs automated tests on a self-hosted QA machine
2
2
3
+ permissions :
4
+ contents : read
5
+
3
6
on :
4
7
workflow_run :
5
8
workflows : ["Build"]
6
9
types :
7
10
- completed
11
+ workflow_dispatch :
12
+ inputs :
13
+ branch_name :
14
+ description : ' Branch name to simulate workflow (e.g. develop)'
15
+ required : true
16
+ default : ' develop'
17
+ build_id :
18
+ description : ' Build workflow run ID (e.g. For github.com/secondlife/viewer/actions/runs/1234567890 the ID is 1234567890)'
19
+ required : true
20
+ default : ' 14806728332'
8
21
9
22
concurrency :
10
- group : qa-test-run
11
- cancel-in-progress : true # Cancels any queued job when a new one starts
23
+ group : qa-test-run-${{ matrix.runner }}
24
+ cancel-in-progress : false # Prevents cancellation of in-progress jobs
12
25
13
26
jobs :
14
27
debug-workflow :
@@ -26,39 +39,75 @@ jobs:
26
39
echo "GitHub Workflow Name: ${{ github.workflow }}"
27
40
28
41
install-viewer-and-run-tests :
29
- runs-on : [self-hosted, qa-machine]
30
- # Run test only on successful builds of Second_Life_X branches
42
+ strategy :
43
+ matrix :
44
+ include :
45
+ - os : windows
46
+ runner : qa-windows-atlas
47
+ artifact : Windows-installer
48
+ install-path : ' C:\viewer-sikulix-main'
49
+ - os : windows
50
+ runner : qa-dan-asus
51
+ artifact : Windows-installer
52
+ install-path : ' C:\viewer-sikulix-main'
53
+ # Commented out until mac runner is available
54
+ # - os: mac
55
+ # runner: qa-mac
56
+ # artifact: Mac-installer
57
+ # install-path: 'HOME/Documents/viewer-sikulix-main'
58
+ fail-fast : false
59
+
60
+ runs-on : [self-hosted, "${{ matrix.runner }}"]
61
+ # Run test only on successful builds of Second_Life_X branches or on manual dispatch
31
62
if : >
63
+ (github.event_name == 'workflow_run' &&
32
64
github.event.workflow_run.conclusion == 'success' &&
33
- (
34
- startsWith(github.event.workflow_run.head_branch, 'Second_Life')
35
- )
65
+ startsWith(github.event.workflow_run.head_branch, 'Second_Life')) ||
66
+ github.event_name == 'workflow_dispatch'
36
67
37
68
steps :
38
- - name : Temporarily Allow PowerShell Scripts (Process Scope)
69
+ # Common steps for both OSes
70
+ - name : Set Build ID
71
+ shell : bash
72
+ run : |
73
+ if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
74
+ echo "BUILD_ID=${{ github.event.inputs.build_id }}" >> $GITHUB_ENV
75
+ echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.inputs.build_id }}/artifacts" >> $GITHUB_ENV
76
+ else
77
+ echo "BUILD_ID=${{ github.event.workflow_run.id }}" >> $GITHUB_ENV
78
+ echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.workflow_run.id }}/artifacts" >> $GITHUB_ENV
79
+ fi
80
+
81
+ # Windows-specific steps
82
+ - name : Temporarily Allow PowerShell Scripts (Windows)
83
+ if : matrix.os == 'windows'
84
+ shell : pwsh
39
85
run : |
40
86
Set-ExecutionPolicy RemoteSigned -Scope Process -Force
41
87
42
- - name : Verify viewer-sikulix-main Exists
88
+ - name : Verify viewer-sikulix-main Exists (Windows)
89
+ if : matrix.os == 'windows'
90
+ shell : pwsh
43
91
run : |
44
- if (-Not (Test-Path -Path 'C:\viewer-sikulix-main ')) {
92
+ if (-Not (Test-Path -Path '${{ matrix.install-path }} ')) {
45
93
Write-Host '❌ Error: viewer-sikulix not found on runner!'
46
94
exit 1
47
95
}
48
96
Write-Host '✅ viewer-sikulix is already available.'
49
97
50
- - name : Fetch & Download Windows Installer Artifact
98
+ - name : Fetch & Download Installer Artifact (Windows)
99
+ if : matrix.os == 'windows'
51
100
shell : pwsh
52
101
run : |
53
- $BUILD_ID = "${{ github.event.workflow_run.id }}"
54
- $ARTIFACTS_URL = "https://api.github.com/repos/secondlife/viewer/actions/runs/$BUILD_ID/artifacts "
102
+ $BUILD_ID = "${{ env.BUILD_ID }}"
103
+ $ARTIFACTS_URL = "${{ env.ARTIFACTS_URL }} "
55
104
56
105
# Fetch the correct artifact URL
57
106
$response = Invoke-RestMethod -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}" } -Uri $ARTIFACTS_URL
58
- $ARTIFACT_NAME = ($response.artifacts | Where-Object { $_.name -eq "Windows-installer " }).archive_download_url
107
+ $ARTIFACT_NAME = ($response.artifacts | Where-Object { $_.name -eq "${{ matrix.artifact }} " }).archive_download_url
59
108
60
109
if (-Not $ARTIFACT_NAME) {
61
- Write-Host "❌ Error: Windows-installer artifact not found!"
110
+ Write-Host "❌ Error: ${{ matrix.artifact }} artifact not found!"
62
111
exit 1
63
112
}
64
113
@@ -74,16 +123,19 @@ jobs:
74
123
75
124
# Ensure download succeeded
76
125
if (-Not (Test-Path $InstallerPath)) {
77
- Write-Host "❌ Error: Failed to download Windows-installer .zip"
126
+ Write-Host "❌ Error: Failed to download ${{ matrix.artifact }} .zip"
78
127
exit 1
79
128
}
80
129
81
- - name : Extract Installer & Locate Executable
130
+ # Set the path for other steps
131
+ echo "DOWNLOAD_PATH=$DownloadPath" | Out-File -FilePath $env:GITHUB_ENV -Append
132
+
133
+ - name : Extract Installer & Locate Executable (Windows)
134
+ if : matrix.os == 'windows'
82
135
shell : pwsh
83
136
run : |
84
- # Explicitly set BUILD_ID again (since it does not appear to persist across steps)
85
- $BUILD_ID = "${{ github.event.workflow_run.id }}"
86
- $ExtractPath = "$env:TEMP\secondlife-build-$BUILD_ID"
137
+ $BUILD_ID = "${{ env.BUILD_ID }}"
138
+ $ExtractPath = "${{ env.DOWNLOAD_PATH }}"
87
139
$InstallerZip = "$ExtractPath\installer.zip"
88
140
89
141
# Print paths for debugging
@@ -113,16 +165,19 @@ jobs:
113
165
Write-Host "✅ Installer found: $INSTALLER_PATH"
114
166
echo "INSTALLER_PATH=$INSTALLER_PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
115
167
116
- - name : Install Second Life Using Task Scheduler (Bypass UAC)
168
+ - name : Install Second Life (Windows)
169
+ if : matrix.os == 'windows'
117
170
shell : pwsh
118
171
run : |
172
+ # Windows - Use Task Scheduler to bypass UAC
119
173
$action = New-ScheduledTaskAction -Execute "${{ env.INSTALLER_PATH }}" -Argument "/S"
120
174
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
121
175
$task = New-ScheduledTask -Action $action -Principal $principal
122
176
Register-ScheduledTask -TaskName "SilentSLInstaller" -InputObject $task -Force
123
177
Start-ScheduledTask -TaskName "SilentSLInstaller"
124
178
125
- - name : Wait for Installation to Complete
179
+ - name : Wait for Installation to Complete (Windows)
180
+ if : matrix.os == 'windows'
126
181
shell : pwsh
127
182
run : |
128
183
Write-Host "Waiting for the Second Life installer to finish..."
@@ -133,18 +188,16 @@ jobs:
133
188
134
189
Write-Host "✅ Installation completed!"
135
190
136
- - name : Cleanup Task Scheduler Entry
191
+ - name : Cleanup After Installation (Windows)
192
+ if : matrix.os == 'windows'
137
193
shell : pwsh
138
194
run : |
195
+ # Cleanup Task Scheduler Entry
139
196
Unregister-ScheduledTask -TaskName "SilentSLInstaller" -Confirm:$false
140
197
Write-Host "✅ Task Scheduler entry removed."
141
198
142
- - name : Delete Installer ZIP
143
- shell : pwsh
144
- run : |
145
- # Explicitly set BUILD_ID again
146
- $BUILD_ID = "${{ github.event.workflow_run.id }}"
147
- $DeletePath = "$env:TEMP\secondlife-build-$BUILD_ID\installer.zip"
199
+ # Delete Installer ZIP
200
+ $DeletePath = "${{ env.DOWNLOAD_PATH }}\installer.zip"
148
201
149
202
Write-Host "Checking if installer ZIP exists: $DeletePath"
150
203
@@ -156,13 +209,164 @@ jobs:
156
209
Write-Host "⚠️ Warning: ZIP file does not exist, skipping deletion."
157
210
}
158
211
159
- - name : Run QA Test Script
212
+ - name : Run QA Test Script (Windows)
213
+ if : matrix.os == 'windows'
214
+ shell : pwsh
215
+ run : |
216
+ Write-Host "Running QA Test script on Windows runner: ${{ matrix.runner }}..."
217
+ python "${{ matrix.install-path }}\runTests.py"
218
+
219
+ # Mac-specific steps
220
+ - name : Verify viewer-sikulix-main Exists (Mac)
221
+ if : matrix.os == 'mac'
222
+ shell : bash
223
+ run : |
224
+ if [ ! -d "${{ matrix.install-path }}" ]; then
225
+ echo "❌ Error: viewer-sikulix not found on runner!"
226
+ exit 1
227
+ fi
228
+ echo "✅ viewer-sikulix is already available."
229
+
230
+ - name : Fetch & Download Installer Artifact (Mac)
231
+ if : matrix.os == 'mac'
232
+ shell : bash
233
+ run : |
234
+ # Mac-specific Bash commands
235
+ response=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -s ${{ env.ARTIFACTS_URL }})
236
+ ARTIFACT_NAME=$(echo $response | jq -r '.artifacts[] | select(.name=="${{ matrix.artifact }}") | .archive_download_url')
237
+
238
+ if [ -z "$ARTIFACT_NAME" ]; then
239
+ echo "❌ Error: ${{ matrix.artifact }} artifact not found!"
240
+ exit 1
241
+ fi
242
+
243
+ echo "✅ Artifact found: $ARTIFACT_NAME"
244
+
245
+ # Secure download path
246
+ DOWNLOAD_PATH="/tmp/secondlife-build-${{ env.BUILD_ID }}"
247
+ mkdir -p $DOWNLOAD_PATH
248
+ INSTALLER_PATH="$DOWNLOAD_PATH/installer.zip"
249
+
250
+ # Download the ZIP
251
+ curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -L $ARTIFACT_NAME -o $INSTALLER_PATH
252
+
253
+ # Ensure download succeeded
254
+ if [ ! -f "$INSTALLER_PATH" ]; then
255
+ echo "❌ Error: Failed to download ${{ matrix.artifact }}.zip"
256
+ exit 1
257
+ fi
258
+
259
+ # Set the path for other steps
260
+ echo "DOWNLOAD_PATH=$DOWNLOAD_PATH" >> $GITHUB_ENV
261
+
262
+ - name : Extract Installer & Locate Executable (Mac)
263
+ if : matrix.os == 'mac'
264
+ shell : bash
265
+ run : |
266
+ EXTRACT_PATH="${{ env.DOWNLOAD_PATH }}"
267
+ INSTALLER_ZIP="$EXTRACT_PATH/installer.zip"
268
+
269
+ # Debug output
270
+ echo "Extract Path: $EXTRACT_PATH"
271
+ echo "Installer ZIP Path: $INSTALLER_ZIP"
272
+
273
+ # Verify ZIP exists
274
+ if [ ! -f "$INSTALLER_ZIP" ]; then
275
+ echo "❌ Error: ZIP file not found at $INSTALLER_ZIP!"
276
+ exit 1
277
+ fi
278
+
279
+ echo "✅ ZIP file exists and is valid. Extracting..."
280
+
281
+ # Extract the ZIP
282
+ unzip -o "$INSTALLER_ZIP" -d "$EXTRACT_PATH"
283
+
284
+ # Find DMG file
285
+ INSTALLER_PATH=$(find "$EXTRACT_PATH" -name "*.dmg" -type f | head -1)
286
+
287
+ if [ -z "$INSTALLER_PATH" ]; then
288
+ echo "❌ Error: No installer DMG found in the extracted files!"
289
+ echo "📂 Extracted Files:"
290
+ ls -la "$EXTRACT_PATH"
291
+ exit 1
292
+ fi
293
+
294
+ echo "✅ Installer found: $INSTALLER_PATH"
295
+ echo "INSTALLER_PATH=$INSTALLER_PATH" >> $GITHUB_ENV
296
+
297
+ - name : Install Second Life (Mac)
298
+ if : matrix.os == 'mac'
299
+ shell : bash
300
+ run : |
301
+ # Mac installation
302
+ echo "Mounting DMG installer..."
303
+ MOUNT_POINT="/tmp/secondlife-dmg"
304
+ mkdir -p "$MOUNT_POINT"
305
+
306
+ # Mount the DMG
307
+ hdiutil attach "${{ env.INSTALLER_PATH }}" -mountpoint "$MOUNT_POINT" -nobrowse
308
+
309
+ echo "✅ DMG mounted at $MOUNT_POINT"
310
+
311
+ # Find the app in the mounted DMG
312
+ APP_PATH=$(find "$MOUNT_POINT" -name "*.app" -type d | head -1)
313
+
314
+ if [ -z "$APP_PATH" ]; then
315
+ echo "❌ Error: No .app bundle found in the mounted DMG!"
316
+ exit 1
317
+ fi
318
+
319
+ echo "Installing application to Applications folder..."
320
+
321
+ # Copy the app to the Applications folder (or specified install path)
322
+ cp -R "$APP_PATH" "${{ matrix.install-path }}"
323
+
324
+ # Verify the app was copied successfully
325
+ if [ ! -d "${{ matrix.install-path }}/$(basename "$APP_PATH")" ]; then
326
+ echo "❌ Error: Failed to install application to ${{ matrix.install-path }}!"
327
+ exit 1
328
+ fi
329
+
330
+ echo "✅ Application installed successfully to ${{ matrix.install-path }}"
331
+
332
+ # Save mount point for cleanup
333
+ echo "MOUNT_POINT=$MOUNT_POINT" >> $GITHUB_ENV
334
+
335
+ - name : Wait for Installation to Complete (Mac)
336
+ if : matrix.os == 'mac'
337
+ shell : bash
338
+ run : |
339
+ echo "Waiting for installation to complete..."
340
+ # Sleep to allow installation to finish (adjust as needed)
341
+ sleep 30
342
+ echo "✅ Installation completed"
343
+
344
+ - name : Cleanup After Installation (Mac)
345
+ if : matrix.os == 'mac'
346
+ shell : bash
347
+ run : |
348
+ # Mac cleanup
349
+ # Unmount the DMG
350
+ echo "Unmounting DMG..."
351
+ hdiutil detach "${{ env.MOUNT_POINT }}" -force
352
+
353
+ # Clean up temporary files
354
+ echo "Cleaning up temporary files..."
355
+ rm -rf "${{ env.DOWNLOAD_PATH }}"
356
+ rm -rf "${{ env.MOUNT_POINT }}"
357
+
358
+ echo "✅ Cleanup completed"
359
+
360
+ - name : Run QA Test Script (Mac)
361
+ if : matrix.os == 'mac'
362
+ shell : bash
160
363
run : |
161
- Write-Host "Running QA Test script..."
162
- python C:\viewer-sikulix-main\ runTests.py
364
+ echo "Running QA Test script on Mac runner: ${{ matrix.runner }} ..."
365
+ python "${{ matrix.install-path }}/ runTests.py"
163
366
164
367
# - name: Upload Test Results
165
- # uses: actions/upload-artifact@v3
368
+ # if: always()
369
+ # uses: actions/upload-artifact@v4
166
370
# with:
167
- # name: test-results
168
- # path: C:\viewer-sikulix-main\ regressionTest\ test_results.html
371
+ # name: test-results-${{ matrix.runner }}
372
+ # path: ${{ matrix.install-path }}/ regressionTest/ test_results.html
0 commit comments