docs(workflow): codify batch release consolidation and decimal versio… #44
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI Quality Gate | |
| on: | |
| push: | |
| branches: [ main, master ] | |
| pull_request: | |
| branches: [ main, master ] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| quality-gate-core: | |
| name: Quality Gate (PowerShell 7 Core) | |
| runs-on: windows-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Ensure Pester 5 Module Available | |
| shell: pwsh | |
| run: | | |
| $pester = Get-Module -ListAvailable -Name Pester | Where-Object { $_.Version.Major -ge 5 } | Select-Object -First 1 | |
| if (-not $pester) { | |
| Write-Host "Installing Pester 5 for pwsh..." | |
| Install-Module -Name Pester -Scope CurrentUser -Force -SkipPublisherCheck -MinimumVersion 5.0.0 | |
| } | |
| - name: Run 7-Pillar Master Quality Gate | |
| shell: pwsh | |
| run: | | |
| ./scripts/Test-MasterGate.ps1 -TestResultsPath "test-results/pester-pwsh.xml" -CodeCoveragePath "test-results/coverage-pwsh.xml" | |
| - name: Publish Test Summary to GitHub Actions | |
| if: always() | |
| shell: pwsh | |
| run: | | |
| $xmlPath = "test-results/pester-pwsh.xml" | |
| $covPath = "test-results/coverage-pwsh.xml" | |
| if (Test-Path $xmlPath) { | |
| [xml]$xml = Get-Content $xmlPath | |
| $total = $xml.'test-results'.total | |
| $failures = $xml.'test-results'.failures | |
| $notRun = $xml.'test-results'.'not-run' | |
| $passed = [int]$total - [int]$failures - [int]$notRun | |
| $suiteTime = $xml.'test-results'.'test-suite'.time | |
| $statusEmoji = if ([int]$failures -gt 0) { ':x: FAILED' } else { ':white_check_mark: PASSED' } | |
| $summaryLines = @( | |
| "## :test_tube: Pester Unit Test Results: PowerShell 7 Core ($statusEmoji)", | |
| "", | |
| "| Metric | Value |", | |
| "| :--- | :--- |", | |
| "| **Total Tests** | $total |", | |
| "| **Passed** | $passed |", | |
| "| **Failed** | $failures |", | |
| "| **Skipped / Not Run** | $notRun |", | |
| "| **Duration** | ${suiteTime}s |" | |
| ) | |
| if (Test-Path $covPath) { | |
| [xml]$covXml = Get-Content $covPath | |
| $lineNode = $covXml.report.counter | Where-Object { $_.type -eq 'LINE' } | |
| $instNode = $covXml.report.counter | Where-Object { $_.type -eq 'INSTRUCTION' } | |
| $lineCov = [int]$lineNode.covered | |
| $lineTotal = $lineCov + [int]$lineNode.missed | |
| $linePct = if ($lineTotal -gt 0) { [math]::Round(($lineCov / $lineTotal) * 100, 1) } else { 0 } | |
| $instCov = [int]$instNode.covered | |
| $instTotal = $instCov + [int]$instNode.missed | |
| $instPct = if ($instTotal -gt 0) { [math]::Round(($instCov / $instTotal) * 100, 1) } else { 0 } | |
| $summaryLines += @( | |
| "", | |
| "### :bar_chart: Code Coverage: unslop.ps1", | |
| "| Metric | Covered | Total | Coverage % |", | |
| "| :--- | :--- | :--- | :--- |", | |
| "| **Lines** | $lineCov | $lineTotal | ${linePct}% |", | |
| "| **Instructions** | $instCov | $instTotal | ${instPct}% |" | |
| ) | |
| } | |
| if ($env:GITHUB_STEP_SUMMARY) { | |
| ($summaryLines -join "`n") | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8 | |
| } | |
| if ([int]$failures -gt 0) { | |
| foreach ($tc in $xml.SelectNodes("//test-case[@result='Failure']")) { | |
| $msg = $tc.failure.message.Trim() -replace '\r?\n', ' ' | |
| Write-Host "::error file=tests/unslop.Tests.ps1,title=Pester Test Failure::$($tc.name): $msg" | |
| } | |
| } | |
| } | |
| - name: Upload Pester Test Results & Coverage Artifact | |
| if: always() | |
| uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 | |
| with: | |
| name: pester-results-pwsh | |
| path: test-results/ | |
| if-no-files-found: ignore | |
| - name: Run Diagnostic System State Auditor | |
| shell: pwsh | |
| run: | | |
| ./scripts/Measure-SystemState.ps1 | |
| quality-gate-desktop: | |
| name: Quality Gate (Windows PowerShell 5.1) | |
| runs-on: windows-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Ensure Pester 5 Module Available | |
| shell: powershell | |
| run: | | |
| $pester = Get-Module -ListAvailable -Name Pester | Where-Object { $_.Version.Major -ge 5 } | Select-Object -First 1 | |
| if (-not $pester) { | |
| Write-Host "Installing Pester 5 for powershell..." | |
| Install-Module -Name Pester -Scope CurrentUser -Force -SkipPublisherCheck -MinimumVersion 5.0.0 | |
| } | |
| - name: Run 7-Pillar Master Quality Gate | |
| shell: powershell | |
| run: | | |
| ./scripts/Test-MasterGate.ps1 -TestResultsPath "test-results/pester-powershell.xml" -CodeCoveragePath "test-results/coverage-powershell.xml" | |
| - name: Publish Test Summary to GitHub Actions | |
| if: always() | |
| shell: powershell | |
| run: | | |
| $xmlPath = "test-results/pester-powershell.xml" | |
| $covPath = "test-results/coverage-powershell.xml" | |
| if (Test-Path $xmlPath) { | |
| [xml]$xml = Get-Content $xmlPath | |
| $total = $xml.'test-results'.total | |
| $failures = $xml.'test-results'.failures | |
| $notRun = $xml.'test-results'.'not-run' | |
| $passed = [int]$total - [int]$failures - [int]$notRun | |
| $suiteTime = $xml.'test-results'.'test-suite'.time | |
| $statusEmoji = if ([int]$failures -gt 0) { ':x: FAILED' } else { ':white_check_mark: PASSED' } | |
| $summaryLines = @( | |
| "## :test_tube: Pester Unit Test Results: Windows PowerShell 5.1 ($statusEmoji)", | |
| "", | |
| "| Metric | Value |", | |
| "| :--- | :--- |", | |
| "| **Total Tests** | $total |", | |
| "| **Passed** | $passed |", | |
| "| **Failed** | $failures |", | |
| "| **Skipped / Not Run** | $notRun |", | |
| "| **Duration** | ${suiteTime}s |" | |
| ) | |
| if (Test-Path $covPath) { | |
| [xml]$covXml = Get-Content $covPath | |
| $lineNode = $covXml.report.counter | Where-Object { $_.type -eq 'LINE' } | |
| $instNode = $covXml.report.counter | Where-Object { $_.type -eq 'INSTRUCTION' } | |
| $lineCov = [int]$lineNode.covered | |
| $lineTotal = $lineCov + [int]$lineNode.missed | |
| $linePct = if ($lineTotal -gt 0) { [math]::Round(($lineCov / $lineTotal) * 100, 1) } else { 0 } | |
| $instCov = [int]$instNode.covered | |
| $instTotal = $instCov + [int]$instNode.missed | |
| $instPct = if ($instTotal -gt 0) { [math]::Round(($instCov / $instTotal) * 100, 1) } else { 0 } | |
| $summaryLines += @( | |
| "", | |
| "### :bar_chart: Code Coverage: unslop.ps1", | |
| "| Metric | Covered | Total | Coverage % |", | |
| "| :--- | :--- | :--- | :--- |", | |
| "| **Lines** | $lineCov | $lineTotal | ${linePct}% |", | |
| "| **Instructions** | $instCov | $instTotal | ${instPct}% |" | |
| ) | |
| } | |
| if ($env:GITHUB_STEP_SUMMARY) { | |
| ($summaryLines -join "`n") | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8 | |
| } | |
| if ([int]$failures -gt 0) { | |
| foreach ($tc in $xml.SelectNodes("//test-case[@result='Failure']")) { | |
| $msg = $tc.failure.message.Trim() -replace '\r?\n', ' ' | |
| Write-Host "::error file=tests/unslop.Tests.ps1,title=Pester Test Failure::$($tc.name): $msg" | |
| } | |
| } | |
| } | |
| - name: Upload Pester Test Results & Coverage Artifact | |
| if: always() | |
| uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 | |
| with: | |
| name: pester-results-powershell | |
| path: test-results/ | |
| if-no-files-found: ignore | |
| - name: Run Diagnostic System State Auditor | |
| shell: powershell | |
| run: | | |
| ./scripts/Measure-SystemState.ps1 | |
| psscriptanalyzer: | |
| name: PSScriptAnalyzer | |
| needs: [quality-gate-core, quality-gate-desktop] | |
| runs-on: windows-latest | |
| steps: | |
| - name: Confirm Status Check | |
| shell: pwsh | |
| run: Write-Host "PSScriptAnalyzer status check passed via dual quality-gate suite." |