diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index a8d2fe6b..fbbcdf42 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -49,33 +49,6 @@ jobs: if-no-files-found: error retention-days: 1 - - name: Commit all changes - uses: PSModule/GitHub-Script@8083ec1f733f00357ee4d0db0c6056686e483bc0 # v1.9.0 - with: - Debug: ${{ fromJson(inputs.Settings).Debug }} - Prerelease: ${{ fromJson(inputs.Settings).Prerelease }} - Verbose: ${{ fromJson(inputs.Settings).Verbose }} - Version: ${{ fromJson(inputs.Settings).Version }} - WorkingDirectory: ${{ fromJson(inputs.Settings).WorkingDirectory }} - Script: | - # Rename the gitignore file to .gitignore.bak - if (Test-Path -Path .gitignore) { - Rename-Item -Path '.gitignore' -NewName '.gitignore.bak' -Force - } - - try { - # Add all changes to the repository - git add . - git commit -m 'Update documentation' - } catch { - Write-Host "No changes to commit" - } - - # Restore the gitignore file - if (Test-Path -Path .gitignore.bak) { - Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force - } - - name: Lint documentation id: super-linter uses: super-linter/super-linter/slim@4ce20838b8ab83717e78138c5b3a1407148e0918 # v8.7.0 diff --git a/.github/workflows/Lint-SourceCode.yml b/.github/workflows/Lint-SourceCode.yml index 1b3db811..ce1cffe5 100644 --- a/.github/workflows/Lint-SourceCode.yml +++ b/.github/workflows/Lint-SourceCode.yml @@ -26,7 +26,7 @@ jobs: persist-credentials: false - name: Lint-SourceCode - uses: PSModule/Invoke-ScriptAnalyzer@4d633e4df1f1fa575949a328839d33c3a0838765 # v5.0.0 + uses: PSModule/Invoke-ScriptAnalyzer@9acddbd55ff4634b738be3a219c76e3676aaf1cd # v5.0.1 with: Debug: ${{ fromJson(inputs.Settings).Debug }} GitHubPrerelease: ${{ fromJson(inputs.Settings).Prerelease }} @@ -35,4 +35,26 @@ jobs: Path: src WorkingDirectory: ${{ fromJson(inputs.Settings).WorkingDirectory }} TestResult_Enabled: true + TestResult_OutputPath: .PSModule/TestResult/PSModuleLint-SourceCode-${{ runner.os }}-TestResult-Report.xml TestResult_TestSuiteName: PSModuleLint-SourceCode-${{ runner.os }} + + - name: Verify analyzer report location + shell: pwsh + working-directory: ${{ fromJson(inputs.Settings).WorkingDirectory }} + run: | + $reportPath = '.PSModule/TestResult/PSModuleLint-SourceCode-${{ runner.os }}-TestResult-Report.xml' + if (-not (Test-Path -Path $reportPath)) { + throw "Expected analyzer report was not created at $reportPath." + } + + $legacyArtifactPaths = @( + 'TestResult' + 'CodeCoverage' + '.temp' + ) + + foreach ($path in $legacyArtifactPaths) { + if (Test-Path -Path $path) { + throw "Legacy root artifact path was created: $path" + } + } diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 1d48d2f6..5f1cbb67 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -70,7 +70,7 @@ jobs: path: ${{ fromJson(inputs.Settings).WorkingDirectory }}/.PSModule/module - name: Lint-Module - uses: PSModule/Invoke-ScriptAnalyzer@4d633e4df1f1fa575949a328839d33c3a0838765 # v5.0.0 + uses: PSModule/Invoke-ScriptAnalyzer@9acddbd55ff4634b738be3a219c76e3676aaf1cd # v5.0.1 with: Path: .PSModule/module Debug: ${{ fromJson(inputs.Settings).Debug }} @@ -79,4 +79,26 @@ jobs: Verbose: ${{ fromJson(inputs.Settings).Verbose }} WorkingDirectory: ${{ fromJson(inputs.Settings).WorkingDirectory }} TestResult_Enabled: true + TestResult_OutputPath: .PSModule/TestResult/PSModuleLint-Module-${{ runner.os }}-TestResult-Report.xml TestResult_TestSuiteName: PSModuleLint-Module-${{ runner.os }} + + - name: Verify analyzer report location + shell: pwsh + working-directory: ${{ fromJson(inputs.Settings).WorkingDirectory }} + run: | + $reportPath = '.PSModule/TestResult/PSModuleLint-Module-${{ runner.os }}-TestResult-Report.xml' + if (-not (Test-Path -Path $reportPath)) { + throw "Expected analyzer report was not created at $reportPath." + } + + $legacyArtifactPaths = @( + 'TestResult' + 'CodeCoverage' + '.temp' + ) + + foreach ($path in $legacyArtifactPaths) { + if (Test-Path -Path $path) { + throw "Legacy root artifact path was created: $path" + } + } diff --git a/.github/workflows/Workflow-Test-Default.yml b/.github/workflows/Workflow-Test-Default.yml index 5b3da9fb..132c3d5e 100644 --- a/.github/workflows/Workflow-Test-Default.yml +++ b/.github/workflows/Workflow-Test-Default.yml @@ -76,6 +76,54 @@ jobs: persist-credentials: false fetch-depth: 0 + - name: Verify generated artifacts remain isolated + shell: pwsh + run: | + $runnerOsExpression = '$' + '{{ runner.os }}' + $expectedAnalyzerReportPaths = @{ + '.github/workflows/Test-Module.yml' = "TestResult_OutputPath: .PSModule/TestResult/PSModuleLint-Module-$runnerOsExpression-TestResult-Report.xml" + '.github/workflows/Lint-SourceCode.yml' = "TestResult_OutputPath: .PSModule/TestResult/PSModuleLint-SourceCode-$runnerOsExpression-TestResult-Report.xml" + } + + foreach ($workflowPath in $expectedAnalyzerReportPaths.Keys) { + $content = Get-Content -Path $workflowPath -Raw + $expectedPath = $expectedAnalyzerReportPaths[$workflowPath] + + if (-not $content.Contains($expectedPath)) { + throw "Expected isolated analyzer report path was not found in $workflowPath." + } + + $expectedAction = 'uses: PSModule/Invoke-ScriptAnalyzer@9acddbd55ff4634b738be3a219c76e3676aaf1cd # v5.0.1' + if (-not $content.Contains($expectedAction)) { + throw "Expected released analyzer action pin was not found in $workflowPath." + } + } + + $buildDocsWorkflow = Get-Content -Path '.github/workflows/Build-Docs.yml' -Raw + $forbiddenStagingPatterns = @( + 'Rename-Item\s+-Path\s+[''"]\.gitignore[''"]' + 'git add \.' + 'PSModule/GitHub-Script' + ) + + foreach ($pattern in $forbiddenStagingPatterns) { + if ($buildDocsWorkflow -match $pattern) { + throw "Build-Docs.yml must not use generated-artifact staging: $pattern" + } + } + + $legacyArtifactPaths = @( + 'tests/srcTestRepo/TestResult' + 'tests/srcTestRepo/CodeCoverage' + 'tests/srcTestRepo/.temp' + ) + + foreach ($path in $legacyArtifactPaths) { + if (Test-Path -Path $path) { + throw "Legacy root artifact path was created: $path" + } + } + - name: Download docs artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: diff --git a/docs/content/reference/pipeline-stages.md b/docs/content/reference/pipeline-stages.md index 7611b9d5..29d53918 100644 --- a/docs/content/reference/pipeline-stages.md +++ b/docs/content/reference/pipeline-stages.md @@ -11,6 +11,25 @@ implements it. For which of these jobs run in a given trigger scenario, see the [scenario matrix](scenario-matrix.md). +## Consumer artifact root + +The framework stores consumer build, documentation, test, and coverage artifacts +under `/.PSModule/`. This keeps generated output separate from +the module source. Consumer repositories SHOULD ignore `.PSModule/`. + +| Path | Contents | +| --- | --- | +| `.PSModule/module/` | The compiled, versioned module artifact. | +| `.PSModule/docs/` | Generated command documentation passed to the site build. | +| `.PSModule/site/` | Assembled site input and generated static site output at `_site/`. | +| `.PSModule/TestResult/` | Per-suite Pester and analyzer test-result reports. | +| `.PSModule/CodeCoverage/` | Per-suite code-coverage reports. | + +Pester stores its temporary execution state outside the consumer checkout. +Runner-only output, including `TestResults/`, `CodeCoverage/`, +`CodeCoverage-MissedPaths/`, and `super-linter-output/`, is not a consumer +repository artifact. + ## Plan [workflow](https://github.com/PSModule/Process-PSModule/blob/main/.github/workflows/Plan.yml)