Pin GitHub Actions to full-length commit SHAs #5001
Workflow file for this run
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: Rust | |
| on: | |
| push: | |
| branches: [ "main", "release/*" ] | |
| pull_request: | |
| branches: [ "main", "release/*" ] | |
| paths-ignore: | |
| - "docs/**" | |
| - "*.md" | |
| - ".vscode/*.json" | |
| - ".github/ISSUE_TEMPLATE/**" | |
| env: | |
| CARGO_TERM_COLOR: always | |
| defaults: | |
| run: | |
| shell: pwsh | |
| jobs: | |
| docs: | |
| strategy: | |
| matrix: | |
| platform: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{matrix.platform}} | |
| steps: | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| - name: Add WinGet links to PATH | |
| if: matrix.platform == 'windows-latest' | |
| run: | | |
| "$env:LOCALAPPDATA\\Microsoft\\WinGet\\Links" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_PATH | |
| - name: Install prerequisites | |
| run: ./build.ps1 -SkipBuild -Clippy -Verbose | |
| - name: Generate documentation | |
| run: ./build.ps1 -RustDocs -Verbose | |
| - name: Test documentation | |
| run: |- | |
| $testParams = @{ | |
| SkipBuild = $true | |
| RustDocs = $true | |
| Test = $true | |
| ExcludeRustTests = $true | |
| ExcludePesterTests = $true | |
| Verbose = $true | |
| } | |
| ./build.ps1 @testParams | |
| linux-build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install prerequisites | |
| run: ./build.ps1 -SkipBuild -Clippy -Verbose | |
| - name: Build and test with code coverage | |
| run: ./build.ps1 -Clippy -Test -CodeCoverage -ExcludePesterTests -Verbose | |
| - name: Upload coverage data | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: linux-coverage | |
| path: lcov.info | |
| if-no-files-found: ignore | |
| - name: Prepare build artifact | |
| run: tar -cvf bin.tar bin/ | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: linux-bin | |
| path: bin.tar | |
| linux-pester: | |
| needs: linux-build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| group: [dsc, adapters, extensions, resources] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| - name: Download build artifact | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: linux-bin | |
| - name: Expand build artifact | |
| run: tar -xvf bin.tar | |
| - name: Install llvm-tools for coverage | |
| run: rustup component add llvm-tools-preview | |
| - name: Set coverage profile environment | |
| id: coverage-env | |
| run: |- | |
| $profDir = New-Item -ItemType Directory -Path (Join-Path ([System.IO.Path]::GetTempPath()) "dsc-pester-cov-$([System.Guid]::NewGuid().ToString('N'))") -Force | |
| $profPattern = Join-Path $profDir.FullName '%m_%p.profraw' | |
| "LLVM_PROFILE_FILE=$profPattern" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_ENV | |
| "prof_dir=$($profDir.FullName)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| - name: Test ${{matrix.group}} | |
| run: |- | |
| $params = @{ | |
| SkipBuild = $true | |
| Test = $true | |
| ExcludeRustTests = $true | |
| Verbose = $true | |
| } | |
| ./build.ps1 @params -PesterTestGroup ${{matrix.group}} | |
| - name: Generate coverage report | |
| if: always() | |
| run: |- | |
| Import-Module ./helpers.build.psm1 -Force | |
| $binPath = Get-ArtifactDirectoryPath | Select-Object -ExpandProperty Bin | |
| $exportParams = @{ | |
| BinDirectory = $binPath | |
| ProfileDirectory = '${{ steps.coverage-env.outputs.prof_dir }}' | |
| OutputPath = 'pester-lcov.info' | |
| Verbose = $true | |
| } | |
| Export-PesterCodeCoverageReport @exportParams | |
| - name: Clean up coverage temp data | |
| if: always() | |
| run: |- | |
| $profDir = '${{ steps.coverage-env.outputs.prof_dir }}' | |
| if (Test-Path $profDir) { | |
| Remove-Item -Path $profDir -Recurse -Force | |
| Write-Host "Cleaned up temp coverage data: $profDir" | |
| } | |
| - name: Upload coverage data | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: linux-pester-${{matrix.group}}-coverage | |
| path: pester-lcov.info | |
| if-no-files-found: ignore | |
| macos-build: | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install prerequisites | |
| run: ./build.ps1 -SkipBuild -Clippy -Verbose | |
| - name: Build and test with code coverage | |
| run: ./build.ps1 -Clippy -Test -CodeCoverage -ExcludePesterTests -Verbose | |
| - name: Upload coverage data | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: macos-coverage | |
| path: lcov.info | |
| if-no-files-found: ignore | |
| - name: Prepare build artifact | |
| run: tar -cvf bin.tar bin/ | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: macos-bin | |
| path: bin.tar | |
| macos-pester: | |
| needs: macos-build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| group: [dsc, adapters, extensions, resources] | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| - name: Download build artifact | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: macos-bin | |
| - name: Expand build artifact | |
| run: tar -xvf bin.tar | |
| - name: Install llvm-tools for coverage | |
| run: rustup component add llvm-tools-preview | |
| - name: Set coverage profile environment | |
| id: coverage-env | |
| run: |- | |
| $profDir = New-Item -ItemType Directory -Path (Join-Path ([System.IO.Path]::GetTempPath()) "dsc-pester-cov-$([System.Guid]::NewGuid().ToString('N'))") -Force | |
| $profPattern = Join-Path $profDir.FullName '%m_%p.profraw' | |
| "LLVM_PROFILE_FILE=$profPattern" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_ENV | |
| "prof_dir=$($profDir.FullName)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| - name: Test ${{matrix.group}} | |
| run: |- | |
| $params = @{ | |
| SkipBuild = $true | |
| Test = $true | |
| ExcludeRustTests = $true | |
| Verbose = $true | |
| } | |
| ./build.ps1 @params -PesterTestGroup ${{matrix.group}} | |
| - name: Generate coverage report | |
| if: always() | |
| run: |- | |
| Import-Module ./helpers.build.psm1 -Force | |
| $binPath = Get-ArtifactDirectoryPath | Select-Object -ExpandProperty Bin | |
| $exportParams = @{ | |
| BinDirectory = $binPath | |
| ProfileDirectory = '${{ steps.coverage-env.outputs.prof_dir }}' | |
| OutputPath = 'pester-lcov.info' | |
| Verbose = $true | |
| } | |
| Export-PesterCodeCoverageReport @exportParams | |
| - name: Clean up coverage temp data | |
| if: always() | |
| run: |- | |
| $profDir = '${{ steps.coverage-env.outputs.prof_dir }}' | |
| if (Test-Path $profDir) { | |
| Remove-Item -Path $profDir -Recurse -Force | |
| Write-Host "Cleaned up temp coverage data: $profDir" | |
| } | |
| - name: Upload coverage data | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: macos-pester-${{matrix.group}}-coverage | |
| path: pester-lcov.info | |
| if-no-files-found: ignore | |
| # Windows | |
| windows-build: | |
| runs-on: windows-latest | |
| steps: | |
| - name: Add WinGet links to PATH | |
| run: | | |
| "$env:LOCALAPPDATA\\Microsoft\\WinGet\\Links" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_PATH | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install prerequisites | |
| run: ./build.ps1 -SkipBuild -Clippy -Verbose | |
| - name: Build and test with code coverage | |
| run: ./build.ps1 -Clippy -Test -CodeCoverage -ExcludePesterTests -Verbose | |
| - name: Upload coverage data | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: windows-coverage | |
| path: lcov.info | |
| if-no-files-found: ignore | |
| - name: List bin folder files | |
| run: Get-ChildItem bin | |
| - name: Prepare build artifact | |
| run: tar -cvf bin.tar bin | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: windows-bin | |
| path: bin.tar | |
| windows-pester: | |
| needs: windows-build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| group: [dsc, adapters, extensions, resources] | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| - name: Download build artifact | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: windows-bin | |
| - name: Expand build artifact | |
| run: tar -xvf bin.tar | |
| - name: Install llvm-tools for coverage | |
| run: rustup component add llvm-tools-preview | |
| - name: Set coverage profile environment | |
| id: coverage-env | |
| run: |- | |
| $profDir = New-Item -ItemType Directory -Path (Join-Path ([System.IO.Path]::GetTempPath()) "dsc-pester-cov-$([System.Guid]::NewGuid().ToString('N'))") -Force | |
| $profPattern = Join-Path $profDir.FullName '%m_%p.profraw' | |
| "LLVM_PROFILE_FILE=$profPattern" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_ENV | |
| "prof_dir=$($profDir.FullName)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| - name: Test ${{matrix.group}} | |
| run: |- | |
| $params = @{ | |
| SkipBuild = $true | |
| Test = $true | |
| ExcludeRustTests = $true | |
| Verbose = $true | |
| } | |
| ./build.ps1 @params -PesterTestGroup ${{matrix.group}} | |
| - name: Generate coverage report | |
| if: always() | |
| run: |- | |
| Import-Module ./helpers.build.psm1 -Force | |
| $binPath = Get-ArtifactDirectoryPath | Select-Object -ExpandProperty Bin | |
| $exportParams = @{ | |
| BinDirectory = $binPath | |
| ProfileDirectory = '${{ steps.coverage-env.outputs.prof_dir }}' | |
| OutputPath = 'pester-lcov.info' | |
| Verbose = $true | |
| } | |
| Export-PesterCodeCoverageReport @exportParams | |
| - name: Clean up coverage temp data | |
| if: always() | |
| run: |- | |
| $profDir = '${{ steps.coverage-env.outputs.prof_dir }}' | |
| if (Test-Path $profDir) { | |
| Remove-Item -Path $profDir -Recurse -Force | |
| Write-Host "Cleaned up temp coverage data: $profDir" | |
| } | |
| - name: Upload coverage data | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: windows-pester-${{matrix.group}}-coverage | |
| path: pester-lcov.info | |
| if-no-files-found: ignore | |
| coverage-report: | |
| if: github.event_name == 'pull_request' | |
| # Use all platforms for changed-code coverage so platform-specific files are | |
| # included. Keep full-codebase coverage Linux-only to avoid inflating its | |
| # denominator with platform-specific sources. | |
| needs: | |
| - linux-build | |
| - linux-pester | |
| - macos-build | |
| - macos-pester | |
| - windows-build | |
| - windows-pester | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download coverage artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| pattern: '*coverage' | |
| path: coverage-data | |
| - name: Consolidate coverage data | |
| id: coverage | |
| run: |- | |
| Import-Module ./helpers.build.psm1 -Force | |
| $baseSha = '${{ github.event.pull_request.base.sha }}' | |
| $headSha = '${{ github.event.pull_request.head.sha }}' | |
| # Compute the merge-base to get an accurate diff of only PR changes. | |
| $mergeBase = git merge-base $baseSha $headSha 2>$null | |
| if ($LASTEXITCODE -eq 0 -and $mergeBase) { | |
| Write-Verbose -Verbose "Using merge-base $mergeBase (base=$baseSha, head=$headSha)" | |
| $baseSha = $mergeBase | |
| } | |
| # Changed-code coverage uses every platform so platform-specific Rust | |
| # files are analyzed. Full-codebase coverage remains Linux-only to | |
| # avoid inflating its denominator with platform-specific sources. | |
| $lcovFiles = Get-ChildItem -Path 'coverage-data' -Filter 'lcov.info' -Recurse | |
| $pesterLcovFiles = Get-ChildItem -Path 'coverage-data' -Filter 'pester-lcov.info' -Recurse | |
| $allLcovFiles = @($lcovFiles) + @($pesterLcovFiles) | Where-Object { $_ } | |
| $linuxLcovFiles = @($allLcovFiles | Where-Object { | |
| ($_.FullName -match '[/\\]linux-[^/\\]+-coverage[/\\]') -or | |
| ($_.FullName -match '[/\\]linux-coverage[/\\]') | |
| }) | |
| if ($allLcovFiles.Count -eq 0) { | |
| Write-Warning 'No coverage data found from any platform.' | |
| "coverage_failed=true" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| return | |
| } | |
| if ($linuxLcovFiles.Count -eq 0) { | |
| Write-Warning 'No Linux coverage data found for the full-codebase report.' | |
| "coverage_failed=true" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| return | |
| } | |
| "coverage_failed=false" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| Write-Verbose -Verbose "Found $($allLcovFiles.Count) cross-platform LCOV file(s)" | |
| Write-Verbose -Verbose "Found $($linuxLcovFiles.Count) Linux LCOV file(s)" | |
| # Merge all platforms for changed-code coverage. | |
| $mergedLcovPath = Join-Path $PWD 'merged-lcov.info' | |
| if ($allLcovFiles.Count -eq 1) { | |
| Copy-Item -Path $allLcovFiles[0].FullName -Destination $mergedLcovPath | |
| } else { | |
| Merge-LcovFile -Path ($allLcovFiles | ForEach-Object { $_.FullName }) -OutputPath $mergedLcovPath -Verbose | |
| } | |
| # Merge Linux coverage separately for the full-codebase report. | |
| $linuxMergedLcovPath = Join-Path $PWD 'linux-merged-lcov.info' | |
| if ($linuxLcovFiles.Count -eq 1) { | |
| Copy-Item -Path $linuxLcovFiles[0].FullName -Destination $linuxMergedLcovPath | |
| } else { | |
| Merge-LcovFile -Path ($linuxLcovFiles | ForEach-Object { $_.FullName }) -OutputPath $linuxMergedLcovPath -Verbose | |
| } | |
| $fullReport = Get-FullCodeCoverageReport -LcovPath $linuxMergedLcovPath -Verbose | |
| "full_percentage=$($fullReport.Percentage)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| "full_covered=$($fullReport.CoveredLines)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| "full_total=$($fullReport.TotalLines)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| "full_emoji=$($fullReport.Emoji)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| "full_label=$($fullReport.Label)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| # Changed-code coverage report (only when Rust files were modified) | |
| $changedFiles = git diff --name-only --diff-filter=ACMR "$baseSha..$headSha" -- '*.rs' | Where-Object { $_ } | |
| if (-not $changedFiles) { | |
| "has_rust_changes=false" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| return | |
| } | |
| "has_rust_changes=true" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| $report = Get-CodeCoverageReport -LcovPath $mergedLcovPath -BaseSha $baseSha -HeadSha $headSha -Verbose | |
| "percentage=$($report.Percentage)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| "covered=$($report.CoveredLines)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| "total=$($report.TotalLines)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| "emoji=$($report.Emoji)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| "label=$($report.Label)" | Out-File -Append -Encoding utf8 -FilePath $env:GITHUB_OUTPUT | |
| - name: Post coverage comment | |
| if: >- | |
| steps.coverage.outputs.has_rust_changes == 'true' | |
| && steps.coverage.outputs.coverage_failed != 'true' | |
| && github.event.pull_request.head.repo.full_name == github.repository | |
| uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 | |
| with: | |
| header: coverage-report | |
| message: | | |
| ## ${{ steps.coverage.outputs.emoji }} Code Coverage Report | |
| ### Changed Code Coverage | |
| **${{ steps.coverage.outputs.percentage }}%** (${{ steps.coverage.outputs.label }}) | |
| | Metric | Value | | |
| |--------|-------| | |
| | Changed lines analyzed | ${{ steps.coverage.outputs.total }} | | |
| | Lines covered by tests | ${{ steps.coverage.outputs.covered }} | | |
| | Coverage percentage | ${{ steps.coverage.outputs.percentage }}% | | |
| ### ${{ steps.coverage.outputs.full_emoji }} Full Codebase Coverage | |
| **${{ steps.coverage.outputs.full_percentage }}%** (${{ steps.coverage.outputs.full_label }}) | |
| | Metric | Value | | |
| |--------|-------| | |
| | Total executable lines | ${{ steps.coverage.outputs.full_total }} | | |
| | Lines covered by tests | ${{ steps.coverage.outputs.full_covered }} | | |
| | Coverage percentage | ${{ steps.coverage.outputs.full_percentage }}% | | |
| > Changed code coverage measures only Rust lines added/modified in this PR. | |
| > Full codebase coverage measures all instrumented Rust lines across the project. | |
| - name: Post coverage comment (report failed) | |
| if: >- | |
| steps.coverage.outputs.coverage_failed == 'true' | |
| && github.event.pull_request.head.repo.full_name == github.repository | |
| uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 | |
| with: | |
| header: coverage-report | |
| message: | | |
| ## :x: Code Coverage Report | |
| **Coverage report could not be generated.** The build or test run failed before | |
| producing coverage data. Check the workflow logs for details. | |
| - name: Post no-changes comment | |
| if: >- | |
| steps.coverage.outputs.has_rust_changes == 'false' | |
| && steps.coverage.outputs.coverage_failed != 'true' | |
| && github.event.pull_request.head.repo.full_name == github.repository | |
| uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 | |
| with: | |
| header: coverage-report | |
| message: | | |
| ## Code Coverage Report | |
| No Rust files were changed in this PR. | |
| ### ${{ steps.coverage.outputs.full_emoji }} Full Codebase Coverage | |
| **${{ steps.coverage.outputs.full_percentage }}%** (${{ steps.coverage.outputs.full_label }}) | |
| | Metric | Value | | |
| |--------|-------| | |
| | Total executable lines | ${{ steps.coverage.outputs.full_total }} | | |
| | Lines covered by tests | ${{ steps.coverage.outputs.full_covered }} | | |
| | Coverage percentage | ${{ steps.coverage.outputs.full_percentage }}% | | |
| > Full codebase coverage measures all instrumented Rust lines across the project. | |
| - name: Fail if coverage is below 70% | |
| if: >- | |
| steps.coverage.outputs.has_rust_changes == 'true' | |
| && steps.coverage.outputs.coverage_failed != 'true' | |
| && steps.coverage.outputs.percentage < 70 | |
| && !contains(github.event.pull_request.labels.*.name, 'Ok-CodeCoverage') | |
| run: | | |
| Write-Error "Code coverage is ${{ steps.coverage.outputs.percentage }}%, which is below the 70% minimum threshold." | |
| exit 1 |