-
Notifications
You must be signed in to change notification settings - Fork 3
595 lines (532 loc) Β· 24.9 KB
/
Copy pathpre-release.yml
File metadata and controls
595 lines (532 loc) Β· 24.9 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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
name: Pre-Release Validation
on:
pull_request:
branches: [ main ]
types: [opened, synchronize, reopened]
workflow_dispatch:
inputs:
validation_level:
description: 'Validation level to run'
required: true
default: 'comprehensive'
type: choice
options:
- 'quick'
- 'comprehensive'
- 'release-candidate'
target_branch:
description: 'Target branch for validation (default: main)'
required: false
default: 'main'
type: string
skip_tests:
description: 'Skip test execution (development use only)'
required: false
default: false
type: boolean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
determine-validation:
name: Determine Validation Level
runs-on: ubuntu-latest
outputs:
level: ${{ steps.determine-level.outputs.level }}
run-quick: ${{ steps.determine-level.outputs.run-quick }}
run-comprehensive: ${{ steps.determine-level.outputs.run-comprehensive }}
run-release-candidate: ${{ steps.determine-level.outputs.run-release-candidate }}
steps:
- name: π― Determine Validation Level
id: determine-level
run: |
echo "::group::Validation Level Determination"
if [ "${{ github.event_name }}" = "pull_request" ]; then
LEVEL="quick"
echo "π Pull request triggered - using quick validation"
else
LEVEL="${{ github.event.inputs.validation_level }}"
echo "π§ Manual dispatch - using $LEVEL validation"
fi
# Set outputs based on validation level
case "$LEVEL" in
"quick")
RUN_QUICK="true"
RUN_COMPREHENSIVE="false"
RUN_RELEASE_CANDIDATE="false"
echo "β‘ Quick validation: Code quality + build + development tests"
;;
"comprehensive")
RUN_QUICK="true"
RUN_COMPREHENSIVE="true"
RUN_RELEASE_CANDIDATE="false"
echo "π Comprehensive validation: All tests + full validation"
;;
"release-candidate")
RUN_QUICK="true"
RUN_COMPREHENSIVE="true"
RUN_RELEASE_CANDIDATE="true"
echo "π Release candidate validation: Complete release preparation"
;;
*)
echo "::error::Invalid validation level: $LEVEL"
exit 1
;;
esac
echo "level=$LEVEL" >> $GITHUB_OUTPUT
echo "run-quick=$RUN_QUICK" >> $GITHUB_OUTPUT
echo "run-comprehensive=$RUN_COMPREHENSIVE" >> $GITHUB_OUTPUT
echo "run-release-candidate=$RUN_RELEASE_CANDIDATE" >> $GITHUB_OUTPUT
echo "::notice title=Validation Level::Running $LEVEL validation"
echo "β
Validation level determined: $LEVEL"
echo "::endgroup::"
quick-validation:
name: Quick Validation
runs-on: macos-latest
needs: determine-validation
if: needs.determine-validation.outputs.run-quick == 'true'
steps:
- name: β‘ Starting Quick Validation
run: |
echo "::notice title=Quick Validation::Starting fast validation for immediate feedback"
echo "β‘ This stage provides rapid feedback on code quality and basic functionality"
echo "π Status: STARTING"
echo "π― Components: Code quality, build verification, development tests"
- name: Checkout code
uses: actions/checkout@v4
- name: Cache SwiftLint
uses: actions/cache@v3
with:
path: |
/usr/local/bin/swiftlint
/opt/homebrew/bin/swiftlint
key: ${{ runner.os }}-swiftlint-${{ hashFiles('.swiftlint.yml') }}
restore-keys: |
${{ runner.os }}-swiftlint-
- name: π§ Install SwiftLint
run: |
echo "::group::SwiftLint Installation"
if ! command -v swiftlint &> /dev/null; then
echo "::notice title=SwiftLint Installation::Installing SwiftLint for code quality validation"
brew install swiftlint
echo "β
SwiftLint installation completed"
else
echo "::notice title=SwiftLint Found::Using cached SwiftLint installation"
echo "β
SwiftLint version: $(swiftlint version)"
fi
echo "::endgroup::"
- name: π Code Quality Check
run: |
echo "::group::Quick Code Quality Validation"
echo "::notice title=Code Quality::Running SwiftLint for immediate feedback"
echo "π Checking code quality for PR readiness..."
if swiftlint lint --strict --reporter xcode; then
echo "::notice title=Code Quality Success::Code passes quality standards"
echo "β
Code quality check PASSED"
else
echo "::error title=Code Quality Failed::Code quality issues found"
echo "β PR blocked by code quality violations"
echo "π§ Fix SwiftLint violations before merging"
exit 1
fi
echo "::endgroup::"
- name: Cache Swift packages
uses: actions/cache@v3
with:
path: |
.build
~/Library/Caches/org.swift.swiftpm
~/Library/org.swift.swiftpm
key: ${{ runner.os }}-swift-${{ hashFiles('Package.swift', 'Package.resolved') }}
restore-keys: |
${{ runner.os }}-swift-
- name: π¨ Build Verification
run: |
echo "::group::Quick Build Verification"
echo "::notice title=Build Verification::Verifying all targets compile successfully"
echo "π¨ Building all targets for compilation verification..."
if swift build --verbose; then
echo "::notice title=Build Success::All targets compile successfully"
echo "β
Build verification PASSED"
echo "π¦ All Swift modules compiled correctly"
else
echo "::error title=Build Failed::Compilation errors prevent PR merge"
echo "β PR blocked by build failures"
echo "π§ Fix compilation errors before merging"
exit 1
fi
echo "::endgroup::"
- name: π§ͺ Development Tests
if: ${{ !inputs.skip_tests }}
run: |
echo "::group::Development Test Execution"
echo "::notice title=Development Tests::Running fast development test suite"
echo "π§ͺ Running development tests for immediate feedback..."
# Make test scripts executable
chmod +x Scripts/run-development-tests.sh
chmod +x Scripts/test-environment-setup.sh
# Setup test environment
if ./Scripts/test-environment-setup.sh validate; then
echo "β
Development test environment ready"
else
echo "::warning::Development test environment validation failed - proceeding with basic tests"
fi
# Run development tests
if ./Scripts/run-development-tests.sh; then
echo "::notice title=Development Tests Success::Development tests passed"
echo "β
Development tests PASSED"
echo "π Core functionality validated"
else
echo "::error title=Development Tests Failed::Development test failures block PR"
echo "β PR blocked by development test failures"
echo "π§ Fix failing tests before merging"
exit 1
fi
echo "::endgroup::"
- name: π Quick Validation Summary
if: always()
run: |
echo "::group::Quick Validation Summary"
if [ ${{ job.status }} == 'success' ]; then
echo "::notice title=Quick Validation Complete::All quick validation checks passed"
echo "β
**Quick Validation Results:**"
echo " β’ Code Quality (SwiftLint): PASSED"
echo " β’ Build Verification: PASSED"
echo " β’ Development Tests: PASSED"
echo ""
echo "π― **PR Status:** Ready for review and merge"
echo "π **Next Steps:** PR can proceed through review process"
# Add different messaging based on validation level
if [ "${{ needs.determine-validation.outputs.level }}" = "quick" ]; then
echo "π‘ **Tip:** Use workflow_dispatch with 'comprehensive' for full validation"
fi
else
echo "::error title=Quick Validation Failed::Quick validation found issues"
echo "β **Quick Validation Issues Found**"
echo "π§ **Required Actions:**"
echo " β’ Fix any SwiftLint violations"
echo " β’ Resolve compilation errors"
echo " β’ Address failing development tests"
echo " β’ Push fixes and validation will re-run automatically"
fi
echo "::endgroup::"
comprehensive-validation:
name: Comprehensive Validation
runs-on: macos-latest
needs: [determine-validation, quick-validation]
if: needs.determine-validation.outputs.run-comprehensive == 'true' && needs.quick-validation.result == 'success'
steps:
- name: π Starting Comprehensive Validation
run: |
echo "::notice title=Comprehensive Validation::Starting full validation with complete test suite"
echo "π This stage runs the complete test suite matching production release validation"
echo "π Status: STARTING"
echo "π― Components: CI tests, production tests, security scanning"
- name: Checkout code
uses: actions/checkout@v4
- name: Cache Swift packages
uses: actions/cache@v3
with:
path: |
.build
~/Library/Caches/org.swift.swiftpm
~/Library/org.swift.swiftpm
key: ${{ runner.os }}-swift-${{ hashFiles('Package.swift', 'Package.resolved') }}
restore-keys: |
${{ runner.os }}-swift-
- name: π§ Setup Comprehensive Test Environment
run: |
echo "::group::Comprehensive Test Environment Setup"
echo "::notice title=Test Environment::Setting up comprehensive test environment"
# Make all test scripts executable
chmod +x Scripts/run-ci-tests.sh
chmod +x Scripts/run-production-tests.sh
chmod +x Scripts/test-environment-setup.sh
# Validate comprehensive test environment
if ./Scripts/test-environment-setup.sh validate; then
echo "::notice title=Environment Ready::Comprehensive test environment validated"
echo "β
Test environment ready for comprehensive validation"
else
echo "::error title=Environment Failed::Comprehensive test environment setup failed"
echo "β Cannot proceed with comprehensive validation"
exit 1
fi
echo "::endgroup::"
- name: π§ͺ CI Test Suite
if: ${{ !inputs.skip_tests }}
run: |
echo "::group::CI Test Suite Execution"
echo "::notice title=CI Tests::Running complete CI test suite"
echo "π§ͺ Executing CI tests for comprehensive validation..."
if ./Scripts/run-ci-tests.sh; then
echo "::notice title=CI Tests Success::All CI tests passed"
echo "β
CI test suite PASSED"
echo "π Protocol and network functionality validated"
else
echo "::error title=CI Tests Failed::CI test failures found"
echo "β Comprehensive validation blocked by CI test failures"
echo "π§ Review CI test logs and fix issues"
exit 1
fi
echo "::endgroup::"
- name: π Production Test Suite
if: ${{ !inputs.skip_tests }}
run: |
echo "::group::Production Test Suite Execution"
echo "::notice title=Production Tests::Running production test validation"
echo "π Executing production tests with CI constraints..."
# Run production tests with appropriate CI limitations
if ./Scripts/run-production-tests.sh --no-qemu --no-system-extension --no-hardware --timeout 300; then
echo "::notice title=Production Tests Success::Production tests validated"
echo "β
Production test suite PASSED"
echo "π End-to-end functionality validated"
else
echo "::error title=Production Tests Failed::Production test failures found"
echo "β Comprehensive validation blocked by production test failures"
echo "π§ Review production test logs and fix issues"
exit 1
fi
echo "::endgroup::"
- name: π Security Scanning
run: |
echo "::group::Security Validation"
echo "::notice title=Security Scanning::Running security validation checks"
echo "π Performing security analysis..."
# Check for hardcoded secrets or sensitive data
echo "π Scanning for hardcoded secrets..."
if git log --all --full-history --grep="password\|secret\|key\|token" --grep="API" -i | head -5; then
echo "::warning::Found potential sensitive data in commit messages - please review"
fi
# Basic dependency security check using Swift Package Manager
echo "π Checking dependency security..."
swift package show-dependencies --format json > dependencies.json || echo "::warning::Could not analyze dependencies"
echo "::notice title=Security Scan Complete::Security validation completed"
echo "β
Security scanning completed"
echo "::endgroup::"
- name: π Comprehensive Validation Summary
if: always()
run: |
echo "::group::Comprehensive Validation Summary"
if [ ${{ job.status }} == 'success' ]; then
echo "::notice title=Comprehensive Validation Complete::All comprehensive validation checks passed"
echo "β
**Comprehensive Validation Results:**"
echo " β’ Quick Validation: PASSED (inherited)"
echo " β’ CI Test Suite: PASSED"
echo " β’ Production Tests: PASSED"
echo " β’ Security Scanning: COMPLETED"
echo ""
echo "π― **Status:** Ready for production release"
echo "π **Quality Assurance:** Code meets all release standards"
# Add messaging based on validation level
if [ "${{ needs.determine-validation.outputs.level }}" = "comprehensive" ]; then
echo "π **Tip:** Use 'release-candidate' validation for complete release preparation"
fi
else
echo "::error title=Comprehensive Validation Failed::Comprehensive validation found issues"
echo "β **Comprehensive Validation Issues:**"
echo "π§ **Required Actions:**"
echo " β’ Review and fix CI test failures"
echo " β’ Address production test issues"
echo " β’ Resolve any security concerns"
echo " β’ Re-run validation after fixes"
fi
echo "::endgroup::"
release-candidate-validation:
name: Release Candidate Validation
runs-on: macos-latest
needs: [determine-validation, comprehensive-validation]
if: needs.determine-validation.outputs.run-release-candidate == 'true' && needs.comprehensive-validation.result == 'success'
steps:
- name: π Starting Release Candidate Validation
run: |
echo "::notice title=Release Candidate::Starting complete release candidate validation"
echo "π This stage performs full release preparation validation"
echo "π Status: STARTING"
echo "π― Components: Release build, artifact validation, release readiness"
- name: Checkout code
uses: actions/checkout@v4
- name: Cache Swift packages
uses: actions/cache@v3
with:
path: |
.build
~/Library/Caches/org.swift.swiftpm
~/Library/org.swift.swiftpm
key: ${{ runner.os }}-swift-${{ hashFiles('Package.swift', 'Package.resolved') }}
restore-keys: |
${{ runner.os }}-swift-
- name: ποΈ Release Build Validation
run: |
echo "::group::Release Build Validation"
echo "::notice title=Release Build::Validating release configuration build"
echo "ποΈ Building with release configuration for artifact validation..."
# Build in release mode to validate release configuration
if swift build --configuration release --verbose; then
echo "::notice title=Release Build Success::Release configuration builds successfully"
echo "β
Release build PASSED"
echo "π¦ Release binaries ready for distribution"
else
echo "::error title=Release Build Failed::Release configuration build failed"
echo "β Release candidate validation blocked by build failures"
echo "π§ Fix release build issues before proceeding"
exit 1
fi
echo "::endgroup::"
- name: π¦ Artifact Validation
run: |
echo "::group::Release Artifact Validation"
echo "::notice title=Artifact Validation::Validating release artifact creation"
echo "π¦ Validating release artifact generation..."
# Validate that all expected binaries are created
EXPECTED_BINARIES=("usbipd")
MISSING_BINARIES=()
for binary in "${EXPECTED_BINARIES[@]}"; do
if [ -f ".build/release/$binary" ]; then
echo "β
Found $binary binary"
# Get basic info about the binary
ls -la ".build/release/$binary"
file ".build/release/$binary"
else
echo "β Missing $binary binary"
MISSING_BINARIES+=("$binary")
fi
done
# Check for optional binaries
if [ -f ".build/release/QEMUTestServer" ]; then
echo "β
Found QEMUTestServer binary (optional)"
ls -la ".build/release/QEMUTestServer"
else
echo "βΉοΈ QEMUTestServer binary not found (optional)"
fi
if [ ${#MISSING_BINARIES[@]} -eq 0 ]; then
echo "::notice title=Artifact Validation Success::All required artifacts generated"
echo "β
Artifact validation PASSED"
else
echo "::error title=Artifact Validation Failed::Missing required binaries: ${MISSING_BINARIES[*]}"
echo "β Release candidate validation blocked by missing artifacts"
exit 1
fi
echo "::endgroup::"
- name: π Release Readiness Check
run: |
echo "::group::Release Readiness Assessment"
echo "::notice title=Release Readiness::Assessing overall release readiness"
echo "π Performing final release readiness assessment..."
# Check Git status for clean state
echo "π Git Status Check:"
if [ -z "$(git status --porcelain)" ]; then
echo "β
Working directory is clean"
else
echo "::warning::Working directory has uncommitted changes"
git status --short
fi
# Check for version-related files
echo "π Version File Check:"
if [ -f "VERSION" ]; then
echo "β
Found VERSION file: $(cat VERSION)"
else
echo "βΉοΈ No VERSION file found (using Git tags)"
fi
# Check recent commits for release-worthy changes
echo "π Recent Changes:"
echo "Recent commits since last tag (if any):"
git log --oneline -10 || echo "No previous tags found"
echo "::notice title=Release Assessment Complete::Release readiness assessment completed"
echo "β
Release readiness check PASSED"
echo "π― Branch appears ready for production release"
echo "::endgroup::"
- name: π Release Candidate Summary
if: always()
run: |
echo "::group::Release Candidate Validation Summary"
if [ ${{ job.status }} == 'success' ]; then
echo "::notice title=Release Candidate Ready::Complete release candidate validation passed"
echo "π **Release Candidate Validation Results:**"
echo " β’ Quick Validation: PASSED (inherited)"
echo " β’ Comprehensive Validation: PASSED (inherited)"
echo " β’ Release Build: PASSED"
echo " β’ Artifact Generation: PASSED"
echo " β’ Release Readiness: PASSED"
echo ""
echo "π **Status:** READY FOR PRODUCTION RELEASE"
echo "π **Next Steps:**"
echo " β’ Create and push a semantic version tag (e.g., v1.2.3)"
echo " β’ The release workflow will automatically trigger"
echo " β’ Monitor the release workflow for completion"
echo ""
echo "π‘ **Release Commands:**"
echo " git tag v1.2.3"
echo " git push origin v1.2.3"
else
echo "::error title=Release Candidate Failed::Release candidate validation found critical issues"
echo "β **Release Candidate Issues:**"
echo "π§ **Required Actions Before Release:**"
echo " β’ Fix release build configuration issues"
echo " β’ Resolve artifact generation problems"
echo " β’ Address any release readiness concerns"
echo " β’ Re-run release candidate validation"
echo ""
echo "β οΈ **Do not proceed with release until all issues are resolved**"
fi
echo "::endgroup::"
validation-complete:
name: Validation Complete
runs-on: ubuntu-latest
needs: [determine-validation, quick-validation, comprehensive-validation, release-candidate-validation]
if: always()
steps:
- name: π Final Validation Status
run: |
echo "::group::Pre-Release Validation Complete"
LEVEL="${{ needs.determine-validation.outputs.level }}"
QUICK_STATUS="${{ needs.quick-validation.result }}"
COMPREHENSIVE_STATUS="${{ needs.comprehensive-validation.result }}"
RELEASE_CANDIDATE_STATUS="${{ needs.release-candidate-validation.result }}"
echo "π― **Validation Level:** $LEVEL"
echo ""
echo "π **Results Summary:**"
echo " β’ Quick Validation: $QUICK_STATUS"
if [ "$COMPREHENSIVE_STATUS" != "" ]; then
echo " β’ Comprehensive Validation: $COMPREHENSIVE_STATUS"
fi
if [ "$RELEASE_CANDIDATE_STATUS" != "" ]; then
echo " β’ Release Candidate Validation: $RELEASE_CANDIDATE_STATUS"
fi
# Determine overall status
case "$LEVEL" in
"quick")
if [ "$QUICK_STATUS" = "success" ]; then
OVERALL_STATUS="SUCCESS"
echo "::notice title=Validation Success::Quick validation completed successfully"
else
OVERALL_STATUS="FAILED"
echo "::error title=Validation Failed::Quick validation failed"
fi
;;
"comprehensive")
if [ "$QUICK_STATUS" = "success" ] && [ "$COMPREHENSIVE_STATUS" = "success" ]; then
OVERALL_STATUS="SUCCESS"
echo "::notice title=Validation Success::Comprehensive validation completed successfully"
else
OVERALL_STATUS="FAILED"
echo "::error title=Validation Failed::Comprehensive validation failed"
fi
;;
"release-candidate")
if [ "$QUICK_STATUS" = "success" ] && [ "$COMPREHENSIVE_STATUS" = "success" ] && [ "$RELEASE_CANDIDATE_STATUS" = "success" ]; then
OVERALL_STATUS="SUCCESS"
echo "::notice title=Validation Success::Release candidate validation completed successfully"
else
OVERALL_STATUS="FAILED"
echo "::error title=Validation Failed::Release candidate validation failed"
fi
;;
esac
echo ""
echo "π **Overall Status:** $OVERALL_STATUS"
if [ "$OVERALL_STATUS" = "SUCCESS" ]; then
echo "β
All validation checks passed for $LEVEL level"
else
echo "β Validation failed - review job logs for details"
exit 1
fi
echo "::endgroup::"