From 2b8e82f67a2474de69cea65cae2ca4ce55dac4c3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 18:46:46 +0100 Subject: [PATCH 001/324] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20lint?= =?UTF-8?q?er=20configurations=20and=20license=20year;=20enhance=20VS=20Co?= =?UTF-8?q?de=20ignore=20rules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/linters/.jscpd.json | 10 + .../linters/.powershell-psscriptanalyzer.psd1 | 68 ++- .github/linters/.textlintrc | 513 ++++++++++++++++++ .github/workflows/CI.yml | 3 +- .github/workflows/Linter.yml | 2 +- .github/workflows/workflow.yml | 3 +- .gitignore | 11 +- LICENSE | 2 +- 8 files changed, 586 insertions(+), 26 deletions(-) create mode 100644 .github/linters/.jscpd.json create mode 100644 .github/linters/.textlintrc diff --git a/.github/linters/.jscpd.json b/.github/linters/.jscpd.json new file mode 100644 index 00000000..23970e85 --- /dev/null +++ b/.github/linters/.jscpd.json @@ -0,0 +1,10 @@ +{ + "threshold": 0, + "reporters": [ + "consoleFull" + ], + "ignore": [ + "**/tests/**" + ], + "absolute": true +} diff --git a/.github/linters/.powershell-psscriptanalyzer.psd1 b/.github/linters/.powershell-psscriptanalyzer.psd1 index 40d11d60..09cc3d0c 100644 --- a/.github/linters/.powershell-psscriptanalyzer.psd1 +++ b/.github/linters/.powershell-psscriptanalyzer.psd1 @@ -1,18 +1,56 @@ -#Documentation: https://github.com/PowerShell/PSScriptAnalyzer/blob/master/docs/Cmdlets/Invoke-ScriptAnalyzer.md#-settings -@{ - #CustomRulePath='path\to\CustomRuleModule.psm1' - #RecurseCustomRulePath='path\of\customrules' - #Severity = @( - # 'Error' - # 'Warning' - #) - #IncludeDefaultRules=${true} +@{ + Rules = @{ + PSAlignAssignmentStatement = @{ + Enable = $true + CheckHashtable = $true + } + PSAvoidLongLines = @{ + Enable = $true + MaximumLineLength = 150 + } + PSAvoidSemicolonsAsLineTerminators = @{ + Enable = $true + } + PSPlaceCloseBrace = @{ + Enable = $true + NewLineAfter = $false + IgnoreOneLineBlock = $true + NoEmptyLineBefore = $false + } + PSPlaceOpenBrace = @{ + Enable = $true + OnSameLine = $true + NewLineAfter = $true + IgnoreOneLineBlock = $true + } + PSProvideCommentHelp = @{ + Enable = $true + ExportedOnly = $false + BlockComment = $true + VSCodeSnippetCorrection = $false + Placement = 'begin' + } + PSUseConsistentIndentation = @{ + Enable = $true + IndentationSize = 4 + PipelineIndentation = 'IncreaseIndentationForFirstPipeline' + Kind = 'space' + } + PSUseConsistentWhitespace = @{ + Enable = $true + CheckInnerBrace = $true + CheckOpenBrace = $true + CheckOpenParen = $true + CheckOperator = $true + CheckPipe = $true + CheckPipeForRedundantWhitespace = $true + CheckSeparator = $true + CheckParameter = $true + IgnoreAssignmentOperatorInsideHashTable = $true + } + } ExcludeRules = @( - 'PSMissingModuleManifestField' - 'PSAvoidUsingWriteHost' + 'PSMissingModuleManifestField', # This rule is not applicable until the module is built. + 'PSUseToExportFieldsInManifest' ) - #IncludeRules = @( - # 'PSAvoidUsingWriteHost', - # 'MyCustomRuleName' - #) } diff --git a/.github/linters/.textlintrc b/.github/linters/.textlintrc new file mode 100644 index 00000000..db48de80 --- /dev/null +++ b/.github/linters/.textlintrc @@ -0,0 +1,513 @@ +{ + "filters": { + "comments": true + }, + "rules": { + "terminology": { + "defaultTerms": false, + "terms": [ + "Airbnb", + "Android", + "AppleScript", + "AppVeyor", + "AVA", + "BrowserStack", + "Browsersync", + "Codecov", + "CodePen", + "CodeSandbox", + "DefinitelyTyped", + "EditorConfig", + "ESLint", + "GitHub", + "GraphQL", + "GraphiQL", + "iOS", + "JavaScript", + "JetBrains", + "jQuery", + "LinkedIn", + "Lodash", + "MacBook", + "Markdown", + "OpenType", + "PayPal", + "PhpStorm", + "PowerShell", + "PlayStation", + "RubyMine", + "Sass", + "SemVer", + "TypeScript", + "UglifyJS", + "Wasm", + "WebAssembly", + "WebStorm", + "WordPress", + "YouTube", + [ + "Common[ .]js", + "CommonJS" + ], + [ + "JSDocs?", + "JSDoc" + ], + [ + "Node[ .]js", + "Node.js" + ], + [ + "React[ .]js", + "React" + ], + [ + "SauceLabs", + "Sauce Labs" + ], + [ + "StackOverflow", + "Stack Overflow" + ], + [ + "styled ?components", + "styled-components" + ], + [ + "HTTP[ /]2(?:\\.0)?", + "HTTP/2" + ], + [ + "OS X", + "macOS" + ], + [ + "Mac ?OS", + "macOS" + ], + [ + "a npm", + "an npm" + ], + "ECMAScript", + [ + "ES2015", + "ES6" + ], + [ + "ES7", + "ES2016" + ], + "3D", + [ + "3-D", + "3D" + ], + "Ajax", + "API", + "APIs", + "API's", + [ + "(? Date: Sun, 16 Feb 2025 19:22:05 +0100 Subject: [PATCH 002/324] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20buil?= =?UTF-8?q?d=20scripts=20to=20output=20messages=20directly=20instead=20of?= =?UTF-8?q?=20using=20Write-Host?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/srcWithManifestTestRepo/tools/1-build.ps1 | 2 +- tests/srcWithManifestTestRepo/tools/2-build.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/srcWithManifestTestRepo/tools/1-build.ps1 b/tests/srcWithManifestTestRepo/tools/1-build.ps1 index f3a17f23..e762395b 100644 --- a/tests/srcWithManifestTestRepo/tools/1-build.ps1 +++ b/tests/srcWithManifestTestRepo/tools/1-build.ps1 @@ -1 +1 @@ -Write-Host "1 - Build script executed." +"1 - Build script executed." diff --git a/tests/srcWithManifestTestRepo/tools/2-build.ps1 b/tests/srcWithManifestTestRepo/tools/2-build.ps1 index d839b516..d2575a02 100644 --- a/tests/srcWithManifestTestRepo/tools/2-build.ps1 +++ b/tests/srcWithManifestTestRepo/tools/2-build.ps1 @@ -1 +1 @@ -Write-Host "2 - Build script executed." +"2 - Build script executed." From cb33eb33d4b595be5ba51f436394121c64afd7c6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 19:42:08 +0100 Subject: [PATCH 003/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Create=20r?= =?UTF-8?q?eusable=20workflow=20for=20testing=20source=20code=20in=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/reusable/Test-SourceCode.yml | 72 ++++++++++++++++++++++++++++ .github/workflows/CI.yml | 37 ++++---------- .github/workflows/workflow.yml | 37 ++++---------- 3 files changed, 90 insertions(+), 56 deletions(-) create mode 100644 .github/reusable/Test-SourceCode.yml diff --git a/.github/reusable/Test-SourceCode.yml b/.github/reusable/Test-SourceCode.yml new file mode 100644 index 00000000..26137fff --- /dev/null +++ b/.github/reusable/Test-SourceCode.yml @@ -0,0 +1,72 @@ +name: Test-SourceCode + +on: + workflow_call: + inputs: + RunsOn: + type: string + description: The type of runner to use for the job. + required: true + Name: + type: string + description: The name of the module to process. Scripts default to the repository name if nothing is specified. + required: false + Path: + type: string + description: The path to the source code of the module. + required: false + default: src + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + +permissions: + contents: read # to checkout the repo and create releases on the repo + +jobs: + TestSourceCode: + name: Test source code (pwsh, ${{ inputs.runs-on }}) + runs-on: ${{ inputs.runs-on }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Debug + if: ${{ inputs.Debug }} + uses: PSModule/Debug@v0 + + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + - name: Test source code + id: test + uses: PSModule/Test-PSModule@v2 + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + TestType: SourceCode + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f149faee..fbd78459 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -101,34 +101,15 @@ jobs: TestSourceCode-pwsh-ubuntu-latest: name: Test source code (pwsh, ubuntu-latest) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, 'Linux')) }} - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Test source code - id: test - uses: PSModule/Test-PSModule@v2 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - TestType: SourceCode - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + uses: ./.github/reusable/Test-SourceCode.yml + with: + RunsOn: ubuntu-latest + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} TestSourceCode-pwsh-macos-latest: name: Test source code (pwsh, macos-latest) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 53d8fc71..69f197d1 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -108,34 +108,15 @@ jobs: TestSourceCode-pwsh-ubuntu-latest: name: Test source code (pwsh, ubuntu-latest) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, 'Linux')) }} - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Test source code - id: test - uses: PSModule/Test-PSModule@v2 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - TestType: SourceCode - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + uses: ./.github/reusable/Test-SourceCode.yml + with: + RunsOn: ubuntu-latest + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} TestSourceCode-pwsh-macos-latest: name: Test source code (pwsh, macos-latest) From 67acdcd0b05ce9ab4e69dcab4a17bbd3c7b31525 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 19:43:51 +0100 Subject: [PATCH 004/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20j?= =?UTF-8?q?ob=20in=20reusable=20workflow=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/reusable/Test-SourceCode.yml | 4 +- .github/workflows/CI.yml | 74 +++++++--------------------- .github/workflows/workflow.yml | 74 +++++++--------------------- 3 files changed, 38 insertions(+), 114 deletions(-) diff --git a/.github/reusable/Test-SourceCode.yml b/.github/reusable/Test-SourceCode.yml index 26137fff..77e2edd7 100644 --- a/.github/reusable/Test-SourceCode.yml +++ b/.github/reusable/Test-SourceCode.yml @@ -40,8 +40,8 @@ permissions: contents: read # to checkout the repo and create releases on the repo jobs: - TestSourceCode: - name: Test source code (pwsh, ${{ inputs.runs-on }}) + Test-SourceCode: + name: Test-SourceCode runs-on: ${{ inputs.runs-on }} steps: - name: Checkout Code diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index fbd78459..0bdf86e7 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -114,66 +114,28 @@ jobs: TestSourceCode-pwsh-macos-latest: name: Test source code (pwsh, macos-latest) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'macOS')) }} - runs-on: macos-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Test source code - id: test - uses: PSModule/Test-PSModule@v2 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - TestType: SourceCode - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + uses: ./.github/reusable/Test-SourceCode.yml + with: + RunsOn: macos-latest + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} TestSourceCode-pwsh-windows-latest: name: Test source code (pwsh, windows-latest) if: ${{ !(contains(inputs.SkipTests, 'All' ) || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'Windows')) }} - runs-on: windows-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Test source code - id: test - uses: PSModule/Test-PSModule@v2 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - TestType: SourceCode - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + uses: ./.github/reusable/Test-SourceCode.yml + with: + RunsOn: windows-latest + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} BuildModule: name: Build module diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 69f197d1..efe37ad7 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -121,66 +121,28 @@ jobs: TestSourceCode-pwsh-macos-latest: name: Test source code (pwsh, macos-latest) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'macOS')) }} - runs-on: macos-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Test source code - id: test - uses: PSModule/Test-PSModule@v2 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - TestType: SourceCode - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + uses: ./.github/reusable/Test-SourceCode.yml + with: + RunsOn: macos-latest + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} TestSourceCode-pwsh-windows-latest: name: Test source code (pwsh, windows-latest) if: ${{ !(contains(inputs.SkipTests, 'All' ) || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'Windows')) }} - runs-on: windows-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Test source code - id: test - uses: PSModule/Test-PSModule@v2 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - TestType: SourceCode - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + uses: ./.github/reusable/Test-SourceCode.yml + with: + RunsOn: windows-latest + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} BuildModule: name: Build module From 98f5cbaeeb0cd796c72355caef144aba36f22f95 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 19:46:59 +0100 Subject: [PATCH 005/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Add=20d?= =?UTF-8?q?efault=20value=20for=20GitHub=20module=20version=20in=20CI=20wo?= =?UTF-8?q?rkflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 1 + .github/workflows/workflow.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0bdf86e7..a60244d6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -76,6 +76,7 @@ on: type: string description: Specifies the version of the GitHub module to be installed. The value must be an exact version. required: false + default: null Prerelease: type: boolean description: Whether to use a prerelease version of the 'GitHub' module. diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index efe37ad7..856d3b52 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -81,6 +81,7 @@ on: type: string description: Specifies the version of the GitHub module to be installed. The value must be an exact version. required: false + default: null Prerelease: type: boolean description: Whether to use a prerelease version of the 'GitHub' module. From 2b7cdc8d8c9570e493b300fff903d2440abcc31b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 19:48:50 +0100 Subject: [PATCH 006/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Set=20d?= =?UTF-8?q?efault=20value=20to=20an=20empty=20string=20for=20GitHub=20modu?= =?UTF-8?q?le=20version=20in=20CI=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 2 +- .github/workflows/workflow.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a60244d6..450d3493 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -76,7 +76,7 @@ on: type: string description: Specifies the version of the GitHub module to be installed. The value must be an exact version. required: false - default: null + default: '' Prerelease: type: boolean description: Whether to use a prerelease version of the 'GitHub' module. diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 856d3b52..451a3016 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -81,7 +81,7 @@ on: type: string description: Specifies the version of the GitHub module to be installed. The value must be an exact version. required: false - default: null + default: '' Prerelease: type: boolean description: Whether to use a prerelease version of the 'GitHub' module. From 104e9aedcb575265d997f3f6eb3d9c1c9c8ceb60 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 19:53:17 +0100 Subject: [PATCH 007/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Set=20d?= =?UTF-8?q?efault=20value=20to=20an=20empty=20string=20for=20GitHub=20modu?= =?UTF-8?q?le=20version=20in=20reusable=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/reusable/Test-SourceCode.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/reusable/Test-SourceCode.yml b/.github/reusable/Test-SourceCode.yml index 77e2edd7..9fd00142 100644 --- a/.github/reusable/Test-SourceCode.yml +++ b/.github/reusable/Test-SourceCode.yml @@ -30,6 +30,7 @@ on: type: string description: Specifies the version of the GitHub module to be installed. The value must be an exact version. required: false + default: '' Prerelease: type: boolean description: Whether to use a prerelease version of the 'GitHub' module. From 39e1d7fb728a65a22e0b85e90d534afd3efb8d59 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 19:55:40 +0100 Subject: [PATCH 008/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20r?= =?UTF-8?q?eusable=20Test-SourceCode=20workflow=20and=20migrate=20to=20wor?= =?UTF-8?q?kflows=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 6 +++--- .github/{reusable => workflows}/Test-SourceCode.yml | 0 .github/workflows/workflow.yml | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename .github/{reusable => workflows}/Test-SourceCode.yml (100%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 450d3493..e3c1989d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -102,7 +102,7 @@ jobs: TestSourceCode-pwsh-ubuntu-latest: name: Test source code (pwsh, ubuntu-latest) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, 'Linux')) }} - uses: ./.github/reusable/Test-SourceCode.yml + uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: ubuntu-latest Name: ${{ inputs.Name }} @@ -115,7 +115,7 @@ jobs: TestSourceCode-pwsh-macos-latest: name: Test source code (pwsh, macos-latest) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'macOS')) }} - uses: ./.github/reusable/Test-SourceCode.yml + uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: macos-latest Name: ${{ inputs.Name }} @@ -128,7 +128,7 @@ jobs: TestSourceCode-pwsh-windows-latest: name: Test source code (pwsh, windows-latest) if: ${{ !(contains(inputs.SkipTests, 'All' ) || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'Windows')) }} - uses: ./.github/reusable/Test-SourceCode.yml + uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: windows-latest Name: ${{ inputs.Name }} diff --git a/.github/reusable/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml similarity index 100% rename from .github/reusable/Test-SourceCode.yml rename to .github/workflows/Test-SourceCode.yml diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 451a3016..24ab6c32 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -109,7 +109,7 @@ jobs: TestSourceCode-pwsh-ubuntu-latest: name: Test source code (pwsh, ubuntu-latest) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, 'Linux')) }} - uses: ./.github/reusable/Test-SourceCode.yml + uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: ubuntu-latest Name: ${{ inputs.Name }} @@ -122,7 +122,7 @@ jobs: TestSourceCode-pwsh-macos-latest: name: Test source code (pwsh, macos-latest) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'macOS')) }} - uses: ./.github/reusable/Test-SourceCode.yml + uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: macos-latest Name: ${{ inputs.Name }} @@ -135,7 +135,7 @@ jobs: TestSourceCode-pwsh-windows-latest: name: Test source code (pwsh, windows-latest) if: ${{ !(contains(inputs.SkipTests, 'All' ) || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'Windows')) }} - uses: ./.github/reusable/Test-SourceCode.yml + uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: windows-latest Name: ${{ inputs.Name }} From e5bfff57a6596500e3b89e07510aae26f4b00789 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 20:03:43 +0100 Subject: [PATCH 009/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Correct=20casin?= =?UTF-8?q?g=20of=20'runs-on'=20input=20in=20Test-SourceCode=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-SourceCode.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 9fd00142..fc3dce1a 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -43,7 +43,7 @@ permissions: jobs: Test-SourceCode: name: Test-SourceCode - runs-on: ${{ inputs.runs-on }} + runs-on: ${{ inputs.RunsOn }} steps: - name: Checkout Code uses: actions/checkout@v4 From 09b08284056fe080b9cd1bca642cc5f15b0493ba Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 20:38:43 +0100 Subject: [PATCH 010/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Consolidat?= =?UTF-8?q?e=20TestSourceCode=20jobs=20into=20a=20single=20matrix=20strate?= =?UTF-8?q?gy=20for=20improved=20maintainability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 43 ++++++++------------------- .github/workflows/Test-SourceCode.yml | 12 +++++++- .github/workflows/workflow.yml | 43 ++++++++------------------- 3 files changed, 37 insertions(+), 61 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e3c1989d..e3597a68 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -99,40 +99,23 @@ permissions: statuses: write # to update the status of the workflow from linter jobs: - TestSourceCode-pwsh-ubuntu-latest: - name: Test source code (pwsh, ubuntu-latest) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, 'Linux')) }} + TestSourceCode: + strategy: + matrix: + include: + - OSName: Linux + RunsOn: ubuntu-latest + - OSName: macOS + RunsOn: macos-latest + - OSName: Windows + RunsOn: windows-latest uses: ./.github/workflows/Test-SourceCode.yml with: - RunsOn: ubuntu-latest - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - TestSourceCode-pwsh-macos-latest: - name: Test source code (pwsh, macos-latest) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'macOS')) }} - uses: ./.github/workflows/Test-SourceCode.yml - with: - RunsOn: macos-latest - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - TestSourceCode-pwsh-windows-latest: - name: Test source code (pwsh, windows-latest) - if: ${{ !(contains(inputs.SkipTests, 'All' ) || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'Windows')) }} - uses: ./.github/workflows/Test-SourceCode.yml - with: - RunsOn: windows-latest + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} + SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index fc3dce1a..97969099 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -7,6 +7,10 @@ on: type: string description: The type of runner to use for the job. required: true + OS: + type: string + description: The operating system name. + required: true Name: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. @@ -16,6 +20,11 @@ on: description: The path to the source code of the module. required: false default: src + SkipTests: + type: string + description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. + required: false + default: None Debug: type: boolean description: Enable debug output. @@ -42,7 +51,8 @@ permissions: jobs: Test-SourceCode: - name: Test-SourceCode + name: Test source code (${{ inputs.RunsOn }}) + if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - name: Checkout Code diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 24ab6c32..2e3172ab 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -106,40 +106,23 @@ permissions: id-token: write # to verify the deployment originates from an appropriate source jobs: - TestSourceCode-pwsh-ubuntu-latest: - name: Test source code (pwsh, ubuntu-latest) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, 'Linux')) }} + TestSourceCode: + strategy: + matrix: + include: + - OSName: Linux + RunsOn: ubuntu-latest + - OSName: macOS + RunsOn: macos-latest + - OSName: Windows + RunsOn: windows-latest uses: ./.github/workflows/Test-SourceCode.yml with: - RunsOn: ubuntu-latest - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - TestSourceCode-pwsh-macos-latest: - name: Test source code (pwsh, macos-latest) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'macOS')) }} - uses: ./.github/workflows/Test-SourceCode.yml - with: - RunsOn: macos-latest - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - TestSourceCode-pwsh-windows-latest: - name: Test source code (pwsh, windows-latest) - if: ${{ !(contains(inputs.SkipTests, 'All' ) || contains(inputs.SkipTests, 'SourceCode' ) || contains(inputs.SkipTests, 'Windows')) }} - uses: ./.github/workflows/Test-SourceCode.yml - with: - RunsOn: windows-latest + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} + SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} From 880e511a840815bc9cb7350cdc229ec9289152a6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 20:51:14 +0100 Subject: [PATCH 011/324] =?UTF-8?q?=F0=9F=A9=B9=20[Feature]:=20Add=20Build?= =?UTF-8?q?-Module=20workflow=20for=20modular=20build=20process?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Module.yml | 73 ++++++++++++++++++++++++++++++ .github/workflows/CI.yml | 55 ++++++++-------------- .github/workflows/workflow.yml | 53 +++++++--------------- 3 files changed, 108 insertions(+), 73 deletions(-) create mode 100644 .github/workflows/Build-Module.yml diff --git a/.github/workflows/Build-Module.yml b/.github/workflows/Build-Module.yml new file mode 100644 index 00000000..46a72534 --- /dev/null +++ b/.github/workflows/Build-Module.yml @@ -0,0 +1,73 @@ +name: Build-Module + +on: + workflow_call: + inputs: + Name: + type: string + description: The name of the module to process. Scripts default to the repository name if nothing is specified. + required: false + Path: + type: string + description: The path to the source code of the module. + required: false + default: src + ModulesOutputPath: + type: string + description: The path to the output directory for the modules. + required: false + default: outputs/modules + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + +permissions: + contents: read # to checkout the repository + +jobs: + Build-Module: + name: Build-Module + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Debug + if: ${{ inputs.Debug }} + uses: PSModule/Debug@v0 + + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + - name: Build module + uses: PSModule/Build-PSModule@v3 + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + ModulesOutputPath: ${{ inputs.ModulesOutputPath }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e3597a68..987ed224 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -99,7 +99,7 @@ permissions: statuses: write # to update the status of the workflow from linter jobs: - TestSourceCode: + Test-SourceCode: strategy: matrix: include: @@ -121,40 +121,21 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - BuildModule: - name: Build module - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Build module - uses: PSModule/Build-PSModule@v3 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + Build-Module: + uses: ./.github/workflows/Build-Module.yml + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + ModulesOutputPath: ${{ inputs.ModulesOutputPath }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} BuildDocs: name: Build docs needs: - - BuildModule + - Build-Module runs-on: ubuntu-latest steps: - name: Checkout Code @@ -312,8 +293,8 @@ jobs: # This is necessary as there is no way to get output from a matrix job TestModule-pwsh-ubuntu-latest: name: Test module (pwsh, ubuntu-latest) - if: ${{ needs.BuildModule.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} - needs: BuildModule + if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} + needs: Build-Module runs-on: ubuntu-latest outputs: passed: ${{ steps.test.outputs.passed }} @@ -366,8 +347,8 @@ jobs: TestModule-pwsh-macos-latest: name: Test module (pwsh, macos-latest) - if: ${{ needs.BuildModule.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} - needs: BuildModule + if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} + needs: Build-Module runs-on: macos-latest outputs: passed: ${{ steps.test.outputs.passed }} @@ -418,8 +399,8 @@ jobs: TestModule-pwsh-windows-latest: name: Test module (pwsh, windows-latest) - if: ${{ needs.BuildModule.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} - needs: BuildModule + if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} + needs: Build-Module runs-on: windows-latest outputs: passed: ${{ steps.test.outputs.passed }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 2e3172ab..3a5c71cd 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -128,40 +128,21 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - BuildModule: - name: Build module - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Build module - uses: PSModule/Build-PSModule@v3 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + Build-Module: + uses: ./.github/workflows/Build-Module.yml + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + ModulesOutputPath: ${{ inputs.ModulesOutputPath }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} BuildDocs: name: Build docs needs: - - BuildModule + - Build-Module runs-on: ubuntu-latest steps: - name: Checkout Code @@ -318,8 +299,8 @@ jobs: #This is necessary as there is no way to get output from a matrix job TestModule-pwsh-ubuntu-latest: name: Test module (pwsh, ubuntu-latest) - if: ${{ needs.BuildModule.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} - needs: BuildModule + if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} + needs: Build-Module runs-on: ubuntu-latest outputs: passed: ${{ steps.test.outputs.passed }} @@ -370,8 +351,8 @@ jobs: TestModule-pwsh-macos-latest: name: Test module (pwsh, macos-latest) - if: ${{ needs.BuildModule.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} - needs: BuildModule + if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} + needs: Build-Module runs-on: macos-latest outputs: passed: ${{ steps.test.outputs.passed }} @@ -422,8 +403,8 @@ jobs: TestModule-pwsh-windows-latest: name: Test module (pwsh, windows-latest) - if: ${{ needs.BuildModule.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} - needs: BuildModule + if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} + needs: Build-Module runs-on: windows-latest outputs: passed: ${{ steps.test.outputs.passed }} From f6aa1f1c3bc5c3582b7670b7e5951fdf081216ac Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 21:02:09 +0100 Subject: [PATCH 012/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Add=20M?= =?UTF-8?q?oduleArtifactName=20input=20and=20upload=20module=20artifact=20?= =?UTF-8?q?step=20in=20Build-Module=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Module.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Build-Module.yml b/.github/workflows/Build-Module.yml index 46a72534..567eebec 100644 --- a/.github/workflows/Build-Module.yml +++ b/.github/workflows/Build-Module.yml @@ -17,6 +17,11 @@ on: description: The path to the output directory for the modules. required: false default: outputs/modules + ModuleArtifactName: + type: string + description: Name of the module artifact to upload. + required: false + default: module Debug: type: boolean description: Enable debug output. @@ -62,7 +67,7 @@ jobs: Version: ${{ inputs.Version }} - name: Build module - uses: PSModule/Build-PSModule@v3 + uses: PSModule/Build-PSModule@v4 with: Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} @@ -71,3 +76,11 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + + - name: Upload module artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.ModuleArtifactName }} + path: ${{ inputs.ModulesOutputPath }} + if-no-files-found: error + retention-days: 1 From 6a5f485899c4db7d295e4dffe384b699fc4faa47 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 21:34:18 +0100 Subject: [PATCH 013/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20B?= =?UTF-8?q?uildDocs=20job=20to=20Build-Docs=20and=20streamline=20its=20ste?= =?UTF-8?q?ps=20by=20using=20a=20separate=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 209 +++++++++++++++++++++++++++++++ .github/workflows/CI.yml | 167 ++---------------------- .github/workflows/workflow.yml | 172 +++---------------------- 3 files changed, 236 insertions(+), 312 deletions(-) create mode 100644 .github/workflows/Build-Docs.yml diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml new file mode 100644 index 00000000..d7b5980d --- /dev/null +++ b/.github/workflows/Build-Docs.yml @@ -0,0 +1,209 @@ +name: Build-Docs + +on: + workflow_call: + inputs: + Name: + type: string + description: The name of the module to process. Scripts default to the repository name if nothing is specified. + required: false + Path: + type: string + description: The path to the source code of the module. + required: false + default: src + ModulesOutputPath: + type: string + description: The path to the output directory for the modules. + required: false + default: outputs/modules + DocsOutputPath: + type: string + description: The path to the output directory for the documentation. + required: false + default: outputs/docs + SiteOutputPath: + type: string + description: The path to the output directory for the site. + required: false + default: outputs/site + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + +permissions: + contents: read # to checkout the repo + +jobs: + Build-Docs: + name: Build-Docs + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Debug + if: ${{ inputs.Debug }} + uses: PSModule/Debug@v0 + + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + - name: Document module + uses: PSModule/Document-PSModule@v0 + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + ModulesOutputPath: ${{ inputs.ModulesOutputPath }} + DocsOutputPath: ${{ inputs.DocsOutputPath }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + - name: Commit all changes + continue-on-error: true + shell: pwsh + run: | + # Rename the gitignore file to .gitignore.bak + 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 + Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force + + - name: Lint documentation + uses: super-linter/super-linter/slim@latest + env: + FILTER_REGEX_INCLUDE: ${{ inputs.DocsOutputPath }} + DEFAULT_BRANCH: main + DEFAULT_WORKSPACE: ${{ github.workspace }} + ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true + GITHUB_TOKEN: ${{ github.token }} + RUN_LOCAL: true + VALIDATE_ALL_CODEBASE: true + VALIDATE_JSON_PRETTIER: false + VALIDATE_MARKDOWN_PRETTIER: false + VALIDATE_YAML_PRETTIER: false + VALIDATE_GITLEAKS: false + + - uses: actions/configure-pages@v5 + + - name: Install mkdoks-material + shell: pwsh + run: | + pip install mkdocs-material + pip install mkdocs-git-authors-plugin + pip install mkdocs-git-revision-date-localized-plugin + pip install mkdocs-git-committers-plugin-2 + + - name: Structure site + uses: PSModule/GitHub-Script@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + Script: | + New-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -ItemType Directory -Force + Copy-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.DocsOutputPath }}/*" -Destination "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -Recurse -Force + $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' + $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' + $SiteOutputPath = Join-Path $PWD -ChildPath '${{ inputs.SiteOutputPath }}' + + LogGroup "Get folder structure" { + Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List + } + + $functionDocsFolder = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Functions' | Get-Item + Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { + $fileName = $_.Name + LogGroup " - $fileName" { + Show-FileContent -Path $_ + } + } + + LogGroup 'Build docs - Process about topics' { + $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' + $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force + $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } + Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | + Rename-Item -NewName { $_.Name -replace '.txt', '.md' } + } + + LogGroup 'Build docs - Copy icon to assets' { + $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' + $null = New-Item -Path $assetsFolderPath -ItemType Directory -Force + $rootPath = Split-Path -Path $ModuleSourcePath -Parent + $iconPath = Join-Path -Path $rootPath -ChildPath 'icon\icon.png' + Copy-Item -Path $iconPath -Destination $assetsFolderPath -Force -Verbose + } + + LogGroup 'Build docs - Copy readme.md' { + $rootPath = Split-Path -Path $ModuleSourcePath -Parent + $readmePath = Join-Path -Path $rootPath -ChildPath 'README.md' + $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' + Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose + } + + LogGroup 'Build docs - Create mkdocs.yml' { + $rootPath = Split-Path -Path $ModuleSourcePath -Parent + # This should be moved to an action so that we can use a default one, and not have to copy it from the repo. + $mkdocsSourcePath = Join-Path -Path $rootPath -ChildPath 'mkdocs.yml' + $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' + $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw + $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) + $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) + $mkdocsContent | Set-Content -Path $mkdocsTargetPath -Force + Show-FileContent -Path $mkdocsTargetPath + } + + - name: Debug File system + shell: pwsh + run: | + Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse | Select-Object -ExpandProperty FullName | Sort-Object + + - name: Build mkdocs-material project + working-directory: ${{ inputs.SiteOutputPath }} + shell: pwsh + run: | + Start-LogGroup 'Build docs - mkdocs build - content' + Show-FileContent -Path mkdocs.yml + Stop-LogGroup + Start-LogGroup 'Build docs - mkdocs build' + mkdocs build --config-file mkdocs.yml --site-dir ${{ github.workspace }}/_site + Stop-LogGroup + + - uses: actions/upload-pages-artifact@v3 + diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 987ed224..88c8f69a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -132,163 +132,20 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - BuildDocs: - name: Build docs + Build-Docs: needs: - Build-Module - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Document module - uses: PSModule/Document-PSModule@v0 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} - DocsOutputPath: ${{ inputs.DocsOutputPath }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Commit all changes - continue-on-error: true - shell: pwsh - run: | - # Rename the gitignore file to .gitignore.bak - 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 - Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force - - - name: Lint documentation - uses: super-linter/super-linter/slim@latest - env: - FILTER_REGEX_INCLUDE: '${{ inputs.DocsOutputPath }}/**' - DEFAULT_BRANCH: main - DEFAULT_WORKSPACE: ${{ github.workspace }} - ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true - GITHUB_TOKEN: ${{ github.token }} - RUN_LOCAL: true - VALIDATE_ALL_CODEBASE: true - VALIDATE_JSON_PRETTIER: false - VALIDATE_MARKDOWN_PRETTIER: false - VALIDATE_YAML_PRETTIER: false - VALIDATE_GITLEAKS: false - - - uses: actions/configure-pages@v5 - - - name: Install mkdoks-material - shell: pwsh - run: | - pip install mkdocs-material - pip install mkdocs-git-authors-plugin - pip install mkdocs-git-revision-date-localized-plugin - pip install mkdocs-git-committers-plugin-2 - - - name: Structure site - uses: PSModule/GitHub-Script@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - Script: | - New-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.DocsOutputPath }}/*" -Destination "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -Recurse -Force - $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' - $SiteOutputPath = Join-Path $PWD -ChildPath '${{ inputs.SiteOutputPath }}' - - LogGroup "Get folderstructure" { - Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - } - - $functionDocsFolder = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Functions' | Get-Item - Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { - $fileName = $_.Name - $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash - LogGroup " - [$fileName] - [$hash]" { - Show-FileContent -Path $_ - } - } - - LogGroup 'Build docs - Process about topics' { - $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' - $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force - $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } - Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | - Rename-Item -NewName { $_.Name -replace '.txt', '.md' } - } - - LogGroup 'Build docs - Copy icon to assets' { - $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' - $null = New-Item -Path $assetsFolderPath -ItemType Directory -Force - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $iconPath = Join-Path -Path $rootPath -ChildPath 'icon\icon.png' - Copy-Item -Path $iconPath -Destination $assetsFolderPath -Force -Verbose - } - - LogGroup 'Build docs - Copy readme.md' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $readmePath = Join-Path -Path $rootPath -ChildPath 'README.md' - $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' - Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose - } - - LogGroup 'Build docs - Create mkdocs.yml' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - # This should be moved to an action so that we can use a default one, and not have to copy it from the repo. - $mkdocsSourcePath = Join-Path -Path $rootPath -ChildPath 'mkdocs.yml' - $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' - $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) - $mkdocsContent | Set-Content -Path $mkdocsTargetPath -Force - Show-FileContent -Path $mkdocsTargetPath - } - - - name: Debug File system - shell: pwsh - run: | - Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - - - name: Build mkdocs-material project - working-directory: ${{ inputs.SiteOutputPath }} - shell: pwsh - run: | - Start-LogGroup 'Build docs - mkdocs build - content' - Show-FileContent -Path mkdocs.yml - Stop-LogGroup - Start-LogGroup 'Build docs - mkdocs build' - mkdocs build --config-file mkdocs.yml --site-dir ${{ github.workspace }}/_site - Stop-LogGroup - - - uses: actions/upload-pages-artifact@v3 + uses: ./.github/workflows/Build-Docs.yml + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + ModulesOutputPath: ${{ inputs.ModulesOutputPath }} + DocsOutputPath: ${{ inputs.DocsOutputPath }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + SiteOutputPath: ${{ inputs.SiteOutputPath }} # This is necessary as there is no way to get output from a matrix job TestModule-pwsh-ubuntu-latest: diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 3a5c71cd..4e240d0f 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -139,162 +139,20 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - BuildDocs: - name: Build docs + Build-Docs: needs: - Build-Module - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Document module - uses: PSModule/Document-PSModule@v0 - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} - DocsOutputPath: ${{ inputs.DocsOutputPath }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Commit all changes - continue-on-error: true - shell: pwsh - run: | - # Rename the gitignore file to .gitignore.bak - 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 - Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force - - - name: Lint documentation - uses: super-linter/super-linter/slim@latest - env: - FILTER_REGEX_INCLUDE: '${{ inputs.DocsOutputPath }}/**' - DEFAULT_BRANCH: main - DEFAULT_WORKSPACE: ${{ github.workspace }} - ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true - GITHUB_TOKEN: ${{ github.token }} - RUN_LOCAL: true - VALIDATE_ALL_CODEBASE: true - VALIDATE_JSON_PRETTIER: false - VALIDATE_MARKDOWN_PRETTIER: false - VALIDATE_YAML_PRETTIER: false - VALIDATE_GITLEAKS: false - - - uses: actions/configure-pages@v5 - - - name: Install mkdoks-material - shell: pwsh - run: | - pip install mkdocs-material - pip install mkdocs-git-authors-plugin - pip install mkdocs-git-revision-date-localized-plugin - pip install mkdocs-git-committers-plugin-2 - - - name: Structure site - uses: PSModule/GitHub-Script@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - Script: | - New-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.DocsOutputPath }}/*" -Destination "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -Recurse -Force - $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' - $SiteOutputPath = Join-Path $PWD -ChildPath '${{ inputs.SiteOutputPath }}' - - LogGroup "Get folder structure" { - Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List - } - - $functionDocsFolder = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Functions' | Get-Item - Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { - $fileName = $_.Name - LogGroup " - $fileName" { - Show-FileContent -Path $_ - } - } - - LogGroup 'Build docs - Process about topics' { - $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' - $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force - $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } - Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | - Rename-Item -NewName { $_.Name -replace '.txt', '.md' } - } - - LogGroup 'Build docs - Copy icon to assets' { - $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' - $null = New-Item -Path $assetsFolderPath -ItemType Directory -Force - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $iconPath = Join-Path -Path $rootPath -ChildPath 'icon\icon.png' - Copy-Item -Path $iconPath -Destination $assetsFolderPath -Force -Verbose - } - - LogGroup 'Build docs - Copy readme.md' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $readmePath = Join-Path -Path $rootPath -ChildPath 'README.md' - $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' - Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose - } - - LogGroup 'Build docs - Create mkdocs.yml' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - # This should be moved to an action so that we can use a default one, and not have to copy it from the repo. - $mkdocsSourcePath = Join-Path -Path $rootPath -ChildPath 'mkdocs.yml' - $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' - $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) - $mkdocsContent | Set-Content -Path $mkdocsTargetPath -Force - Show-FileContent -Path $mkdocsTargetPath - } - - - name: Debug File system - shell: pwsh - run: | - Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - - - name: Build mkdocs-material project - working-directory: ${{ inputs.SiteOutputPath }} - shell: pwsh - run: | - Start-LogGroup 'Build docs - mkdocs build - content' - Show-FileContent -Path mkdocs.yml - Stop-LogGroup - Start-LogGroup 'Build docs - mkdocs build' - mkdocs build --config-file mkdocs.yml --site-dir ${{ github.workspace }}/_site - Stop-LogGroup - - - uses: actions/upload-pages-artifact@v3 + uses: ./.github/workflows/Build-Docs.yml + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + ModulesOutputPath: ${{ inputs.ModulesOutputPath }} + DocsOutputPath: ${{ inputs.DocsOutputPath }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + SiteOutputPath: ${{ inputs.SiteOutputPath }} #This is necessary as there is no way to get output from a matrix job TestModule-pwsh-ubuntu-latest: @@ -595,7 +453,7 @@ jobs: if: ${{ needs.TestModuleStatus.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} needs: - TestModuleStatus - - BuildDocs + - Build-Docs runs-on: ubuntu-latest steps: - name: Checkout Code @@ -633,10 +491,10 @@ jobs: PublishSite: name: Publish documentation - if: ${{ inputs.PublishDocs && needs.BuildDocs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} + if: ${{ inputs.PublishDocs && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} needs: - TestModuleStatus - - BuildDocs + - Build-Docs permissions: pages: write # to deploy to Pages id-token: write # to verify the deployment originates from an appropriate source From efb70a2ccdd0a6677cacd832b060b6a44ba66d72 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 21:39:37 +0100 Subject: [PATCH 014/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Update=20DEFAUL?= =?UTF-8?q?T=5FWORKSPACE=20path=20in=20Build-Docs=20workflow=20to=20includ?= =?UTF-8?q?e=20DocsOutputPath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index d7b5980d..e6e9237b 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -106,9 +106,8 @@ jobs: - name: Lint documentation uses: super-linter/super-linter/slim@latest env: - FILTER_REGEX_INCLUDE: ${{ inputs.DocsOutputPath }} DEFAULT_BRANCH: main - DEFAULT_WORKSPACE: ${{ github.workspace }} + DEFAULT_WORKSPACE: ${{ github.workspace }}/${{ inputs.DocsOutputPath }} ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true GITHUB_TOKEN: ${{ github.token }} RUN_LOCAL: true From 62ad73ab52b107bbba9c481f3c1ce7b71cf4b9f6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 22:09:45 +0100 Subject: [PATCH 015/324] =?UTF-8?q?=F0=9F=A9=B9=20[Update]:=20Upgrade=20Do?= =?UTF-8?q?cument-PSModule=20action=20to=20v1=20and=20remove=20unused=20co?= =?UTF-8?q?mmit=20steps=20in=20Build-Docs=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 124 +------------------------------ 1 file changed, 1 insertion(+), 123 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index e6e9237b..873f4be2 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -74,7 +74,7 @@ jobs: Version: ${{ inputs.Version }} - name: Document module - uses: PSModule/Document-PSModule@v0 + uses: PSModule/Document-PSModule@v1 with: Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} @@ -84,125 +84,3 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - - - name: Commit all changes - continue-on-error: true - shell: pwsh - run: | - # Rename the gitignore file to .gitignore.bak - 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 - Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force - - - name: Lint documentation - uses: super-linter/super-linter/slim@latest - env: - DEFAULT_BRANCH: main - DEFAULT_WORKSPACE: ${{ github.workspace }}/${{ inputs.DocsOutputPath }} - ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true - GITHUB_TOKEN: ${{ github.token }} - RUN_LOCAL: true - VALIDATE_ALL_CODEBASE: true - VALIDATE_JSON_PRETTIER: false - VALIDATE_MARKDOWN_PRETTIER: false - VALIDATE_YAML_PRETTIER: false - VALIDATE_GITLEAKS: false - - - uses: actions/configure-pages@v5 - - - name: Install mkdoks-material - shell: pwsh - run: | - pip install mkdocs-material - pip install mkdocs-git-authors-plugin - pip install mkdocs-git-revision-date-localized-plugin - pip install mkdocs-git-committers-plugin-2 - - - name: Structure site - uses: PSModule/GitHub-Script@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - Script: | - New-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.DocsOutputPath }}/*" -Destination "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -Recurse -Force - $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' - $SiteOutputPath = Join-Path $PWD -ChildPath '${{ inputs.SiteOutputPath }}' - - LogGroup "Get folder structure" { - Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List - } - - $functionDocsFolder = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Functions' | Get-Item - Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { - $fileName = $_.Name - LogGroup " - $fileName" { - Show-FileContent -Path $_ - } - } - - LogGroup 'Build docs - Process about topics' { - $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' - $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force - $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } - Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | - Rename-Item -NewName { $_.Name -replace '.txt', '.md' } - } - - LogGroup 'Build docs - Copy icon to assets' { - $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' - $null = New-Item -Path $assetsFolderPath -ItemType Directory -Force - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $iconPath = Join-Path -Path $rootPath -ChildPath 'icon\icon.png' - Copy-Item -Path $iconPath -Destination $assetsFolderPath -Force -Verbose - } - - LogGroup 'Build docs - Copy readme.md' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $readmePath = Join-Path -Path $rootPath -ChildPath 'README.md' - $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' - Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose - } - - LogGroup 'Build docs - Create mkdocs.yml' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - # This should be moved to an action so that we can use a default one, and not have to copy it from the repo. - $mkdocsSourcePath = Join-Path -Path $rootPath -ChildPath 'mkdocs.yml' - $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' - $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) - $mkdocsContent | Set-Content -Path $mkdocsTargetPath -Force - Show-FileContent -Path $mkdocsTargetPath - } - - - name: Debug File system - shell: pwsh - run: | - Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - - - name: Build mkdocs-material project - working-directory: ${{ inputs.SiteOutputPath }} - shell: pwsh - run: | - Start-LogGroup 'Build docs - mkdocs build - content' - Show-FileContent -Path mkdocs.yml - Stop-LogGroup - Start-LogGroup 'Build docs - mkdocs build' - mkdocs build --config-file mkdocs.yml --site-dir ${{ github.workspace }}/_site - Stop-LogGroup - - - uses: actions/upload-pages-artifact@v3 - From 50e0d33f5a1d5ee2a819d8c25c3a002d83aa0f5e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Feb 2025 22:44:41 +0100 Subject: [PATCH 016/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Add=20i?= =?UTF-8?q?nputs=20for=20module=20and=20docs=20artifact=20names,=20and=20i?= =?UTF-8?q?mplement=20artifact=20download=20and=20upload=20steps=20in=20Bu?= =?UTF-8?q?ild-Docs=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 148 +++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 873f4be2..0b038aea 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -17,11 +17,21 @@ on: description: The path to the output directory for the modules. required: false default: outputs/modules + ModuleArtifactName: + type: string + description: Name of the module artifact to upload. + required: false + default: module DocsOutputPath: type: string description: The path to the output directory for the documentation. required: false default: outputs/docs + DocsArtifactName: + type: string + description: Name of the docs artifact to upload. + required: false + default: docs SiteOutputPath: type: string description: The path to the output directory for the site. @@ -73,6 +83,12 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + - name: Download module artifact + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.ModuleArtifactName }} + path: ${{ inputs.ModulesOutputPath }} + - name: Document module uses: PSModule/Document-PSModule@v1 with: @@ -84,3 +100,135 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + + - name: Upload docs artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.DocsArtifactName }} + path: ${{ inputs.DocsOutputPath }} + if-no-files-found: error + retention-days: 1 + + - name: Commit all changes + continue-on-error: true + shell: pwsh + run: | + # Rename the gitignore file to .gitignore.bak + 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 + Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force + + - name: Lint documentation + uses: super-linter/super-linter/slim@latest + env: + FILTER_REGEX_INCLUDE: ${{ inputs.DocsOutputPath }} + DEFAULT_BRANCH: main + DEFAULT_WORKSPACE: ${{ github.workspace }} + ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true + GITHUB_TOKEN: ${{ github.token }} + RUN_LOCAL: true + VALIDATE_ALL_CODEBASE: true + VALIDATE_JSON_PRETTIER: false + VALIDATE_MARKDOWN_PRETTIER: false + VALIDATE_YAML_PRETTIER: false + VALIDATE_JSCPD: false + VALIDATE_GITLEAKS: false + + - uses: actions/configure-pages@v5 + + - name: Install mkdoks-material + shell: pwsh + run: | + pip install mkdocs-material + pip install mkdocs-git-authors-plugin + pip install mkdocs-git-revision-date-localized-plugin + pip install mkdocs-git-committers-plugin-2 + + - name: Structure site + uses: PSModule/GitHub-Script@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + Script: | + New-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -ItemType Directory -Force + Copy-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.DocsOutputPath }}/*" -Destination "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -Recurse -Force + $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' + $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' + $SiteOutputPath = Join-Path $PWD -ChildPath '${{ inputs.SiteOutputPath }}' + + LogGroup "Get folder structure" { + Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List + } + + $functionDocsFolder = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Functions' | Get-Item + Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { + $fileName = $_.Name + LogGroup " - $fileName" { + Show-FileContent -Path $_ + } + } + + LogGroup 'Build docs - Process about topics' { + $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' + $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force + $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } + Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | + Rename-Item -NewName { $_.Name -replace '.txt', '.md' } + } + + LogGroup 'Build docs - Copy icon to assets' { + $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' + $null = New-Item -Path $assetsFolderPath -ItemType Directory -Force + $rootPath = Split-Path -Path $ModuleSourcePath -Parent + $iconPath = Join-Path -Path $rootPath -ChildPath 'icon\icon.png' + Copy-Item -Path $iconPath -Destination $assetsFolderPath -Force -Verbose + } + + LogGroup 'Build docs - Copy readme.md' { + $rootPath = Split-Path -Path $ModuleSourcePath -Parent + $readmePath = Join-Path -Path $rootPath -ChildPath 'README.md' + $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' + Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose + } + + LogGroup 'Build docs - Create mkdocs.yml' { + $rootPath = Split-Path -Path $ModuleSourcePath -Parent + # This should be moved to an action so that we can use a default one, and not have to copy it from the repo. + $mkdocsSourcePath = Join-Path -Path $rootPath -ChildPath 'mkdocs.yml' + $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' + $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw + $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) + $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) + $mkdocsContent | Set-Content -Path $mkdocsTargetPath -Force + Show-FileContent -Path $mkdocsTargetPath + } + + - name: Debug File system + shell: pwsh + run: | + Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse | Select-Object -ExpandProperty FullName | Sort-Object + + - name: Build mkdocs-material project + working-directory: ${{ inputs.SiteOutputPath }} + shell: pwsh + run: | + LogGroup 'Build docs - mkdocs build - content' { + Show-FileContent -Path mkdocs.yml + } + + LogGroup 'Build docs - mkdocs build' { + mkdocs build --config-file mkdocs.yml --site-dir ${{ github.workspace }}/_site + } + + - uses: actions/upload-pages-artifact@v3 From 74d93c3dae58f8ad22d6d0fe674af8f4c09a8d8e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 17 Feb 2025 00:43:21 +0100 Subject: [PATCH 017/324] =?UTF-8?q?=F0=9F=A9=B9=20[Add]:=20Create=20Gather?= =?UTF-8?q?-Tests=20workflow=20to=20gather=20test=20suites=20and=20enable?= =?UTF-8?q?=20debug=20and=20verbose=20options?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 568 ++++++++++++----------- .github/workflows/Gather-Tests.yml | 57 +++ .github/workflows/workflow.yml | 716 +++++++++++++++-------------- 3 files changed, 705 insertions(+), 636 deletions(-) create mode 100644 .github/workflows/Gather-Tests.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 88c8f69a..70089f97 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -147,285 +147,291 @@ jobs: Version: ${{ inputs.Version }} SiteOutputPath: ${{ inputs.SiteOutputPath }} - # This is necessary as there is no way to get output from a matrix job - TestModule-pwsh-ubuntu-latest: - name: Test module (pwsh, ubuntu-latest) - if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} - needs: Build-Module - runs-on: ubuntu-latest - outputs: - passed: ${{ steps.test.outputs.passed }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Test built module - id: test - uses: PSModule/Test-PSModule@v2 - continue-on-error: true - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.ModulesOutputPath }} - TestType: Module - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Status - shell: pwsh - run: | - Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - - name: Failed test - if: steps.test.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" - - TestModule-pwsh-macos-latest: - name: Test module (pwsh, macos-latest) - if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} - needs: Build-Module - runs-on: macos-latest - outputs: - passed: ${{ steps.test.outputs.passed }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Test built module - id: test - uses: PSModule/Test-PSModule@v2 - continue-on-error: true - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.ModulesOutputPath }} - TestType: Module - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Status - shell: pwsh - run: | - Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - - name: Failed test - if: steps.test.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" - - TestModule-pwsh-windows-latest: - name: Test module (pwsh, windows-latest) - if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} - needs: Build-Module - runs-on: windows-latest - outputs: - passed: ${{ steps.test.outputs.passed }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Test built module - id: test - uses: PSModule/Test-PSModule@v2 - continue-on-error: true - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.ModulesOutputPath }} - TestType: Module - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Status - shell: pwsh - run: | - Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - - name: Failed test - if: steps.test.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" - - TestModuleStatus: - name: Test module status - if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} + Gather-Tests: + if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} needs: - - TestModule-pwsh-ubuntu-latest - - TestModule-pwsh-macos-latest - - TestModule-pwsh-windows-latest - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Summerize tests - uses: PSModule/GitHub-Script@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - Script: | - LogGroup -Name 'Test analysis' { - - $linuxPassed = '${{ needs.TestModule-pwsh-ubuntu-latest.outputs.passed }}' -eq 'true' - $linuxSkipped = '${{ needs.TestModule-pwsh-ubuntu-latest.result }}' -eq 'skipped' - $macOSPassed = '${{ needs.TestModule-pwsh-macos-latest.outputs.passed }}' -eq 'true' - $macOSSkipped = '${{ needs.TestModule-pwsh-macos-latest.result }}' -eq 'skipped' - $windowsPassed = '${{ needs.TestModule-pwsh-windows-latest.outputs.passed }}' -eq 'true' - $windowsSkipped = '${{ needs.TestModule-pwsh-windows-latest.result }}' -eq 'skipped' - $anyPassed = $linuxPassed -or $macOSPassed -or $windowsPassed - $allSkipped = $linuxSkipped -and $macOSSkipped -and $windowsSkipped - - $Status = @( - [pscustomobject]@{ - Name = 'Linux' - Icon = $linuxSkipped ? '⚠️' : $linuxPassed ? '✅' : '❌' - Status = $linuxSkipped ? 'Skipped' : $linuxPassed ? 'Passed' : 'Failed' - } - [pscustomobject]@{ - Name = 'MacOS' - Icon = $macOSSkipped ? '⚠️' : $macOSPassed ? '✅' : '❌' - Status = $macOSSkipped ? 'Skipped' : $macOSPassed ? 'Passed' : 'Failed' - } - [pscustomobject]@{ - Name = 'Windows' - Icon = $windowsSkipped ? '⚠️' : $windowsPassed ? '✅' : '❌' - Status = $windowsSkipped ? 'Skipped' : $windowsPassed ? 'Passed' : 'Failed' - } - [pscustomobject]@{ - Name = 'Result' - Icon = $allSkipped ? '⚠️' : $anyPassed ? '✅' : '❌' - Status = $allSkipped ? 'Skipped' : $anyPassed ? 'Passed' : 'Failed' - } - ) - - Write-Host ($Status | Format-Table | Out-String) - ($Status | New-MDTable) | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append - - if (-not $anyPassed -and -not $allSkipped) { - Write-Host "::[error]::No tests passed" - exit 1 - } - } - - LogGroup 'Data' { - $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}\$moduleName" - $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" - - $data = [pscustomobject]@{ - ModuleName = $moduleName - Path = $path - ModuleManifestPath = $moduleManifestPath - } - Write-Verbose ($data | Format-List | Out-String) -Verbose - - Set-ModuleManifest -Path $moduleManifestPath -PowerShellVersion '7.4' - - Add-ModuleManifestData -Path $moduleManifestPath -CompatiblePSEditions 'Core' - Add-ModuleManifestData -Path $moduleManifestPath -Tags 'PSEdition_Core' - - if ($linuxPassed) { - Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Linux' - } - - if ($macOSPassed) { - Add-ModuleManifestData -Path $moduleManifestPath -Tags 'MacOS' - } - - if ($windowsPassed) { - Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Windows' - } - } - - LogGroup 'Module Manifest' { - Show-FileContent -Path $moduleManifestPath - } - - - name: Upload module artifact - uses: actions/upload-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - if-no-files-found: error - retention-days: 1 - overwrite: true + - Build-Module + uses: ./.github/workflows/Gather-Tests.yml + + # # This is necessary as there is no way to get output from a matrix job + # TestModule-pwsh-ubuntu-latest: + # name: Test module (pwsh, ubuntu-latest) + # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} + # needs: Build-Module + # runs-on: ubuntu-latest + # outputs: + # passed: ${{ steps.test.outputs.passed }} + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + # with: + # fetch-depth: 0 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Test built module + # id: test + # uses: PSModule/Test-PSModule@v2 + # continue-on-error: true + # with: + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.ModulesOutputPath }} + # TestType: Module + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Status + # shell: pwsh + # run: | + # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" + + # - name: Failed test + # if: steps.test.outcome != 'success' + # shell: pwsh + # run: Write-Host "Complete successfully" + + # TestModule-pwsh-macos-latest: + # name: Test module (pwsh, macos-latest) + # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} + # needs: Build-Module + # runs-on: macos-latest + # outputs: + # passed: ${{ steps.test.outputs.passed }} + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Test built module + # id: test + # uses: PSModule/Test-PSModule@v2 + # continue-on-error: true + # with: + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.ModulesOutputPath }} + # TestType: Module + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Status + # shell: pwsh + # run: | + # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" + + # - name: Failed test + # if: steps.test.outcome != 'success' + # shell: pwsh + # run: Write-Host "Complete successfully" + + # TestModule-pwsh-windows-latest: + # name: Test module (pwsh, windows-latest) + # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} + # needs: Build-Module + # runs-on: windows-latest + # outputs: + # passed: ${{ steps.test.outputs.passed }} + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Test built module + # id: test + # uses: PSModule/Test-PSModule@v2 + # continue-on-error: true + # with: + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.ModulesOutputPath }} + # TestType: Module + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Status + # shell: pwsh + # run: | + # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" + + # - name: Failed test + # if: steps.test.outcome != 'success' + # shell: pwsh + # run: Write-Host "Complete successfully" + + # TestModuleStatus: + # name: Test module status + # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} + # needs: + # - TestModule-pwsh-ubuntu-latest + # - TestModule-pwsh-macos-latest + # - TestModule-pwsh-windows-latest + # runs-on: ubuntu-latest + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Summerize tests + # uses: PSModule/GitHub-Script@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + # Script: | + # LogGroup -Name 'Test analysis' { + + # $linuxPassed = '${{ needs.TestModule-pwsh-ubuntu-latest.outputs.passed }}' -eq 'true' + # $linuxSkipped = '${{ needs.TestModule-pwsh-ubuntu-latest.result }}' -eq 'skipped' + # $macOSPassed = '${{ needs.TestModule-pwsh-macos-latest.outputs.passed }}' -eq 'true' + # $macOSSkipped = '${{ needs.TestModule-pwsh-macos-latest.result }}' -eq 'skipped' + # $windowsPassed = '${{ needs.TestModule-pwsh-windows-latest.outputs.passed }}' -eq 'true' + # $windowsSkipped = '${{ needs.TestModule-pwsh-windows-latest.result }}' -eq 'skipped' + # $anyPassed = $linuxPassed -or $macOSPassed -or $windowsPassed + # $allSkipped = $linuxSkipped -and $macOSSkipped -and $windowsSkipped + + # $Status = @( + # [pscustomobject]@{ + # Name = 'Linux' + # Icon = $linuxSkipped ? '⚠️' : $linuxPassed ? '✅' : '❌' + # Status = $linuxSkipped ? 'Skipped' : $linuxPassed ? 'Passed' : 'Failed' + # } + # [pscustomobject]@{ + # Name = 'MacOS' + # Icon = $macOSSkipped ? '⚠️' : $macOSPassed ? '✅' : '❌' + # Status = $macOSSkipped ? 'Skipped' : $macOSPassed ? 'Passed' : 'Failed' + # } + # [pscustomobject]@{ + # Name = 'Windows' + # Icon = $windowsSkipped ? '⚠️' : $windowsPassed ? '✅' : '❌' + # Status = $windowsSkipped ? 'Skipped' : $windowsPassed ? 'Passed' : 'Failed' + # } + # [pscustomobject]@{ + # Name = 'Result' + # Icon = $allSkipped ? '⚠️' : $anyPassed ? '✅' : '❌' + # Status = $allSkipped ? 'Skipped' : $anyPassed ? 'Passed' : 'Failed' + # } + # ) + + # Write-Host ($Status | Format-Table | Out-String) + # ($Status | New-MDTable) | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append + + # if (-not $anyPassed -and -not $allSkipped) { + # Write-Host "::[error]::No tests passed" + # exit 1 + # } + # } + + # LogGroup 'Data' { + # $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' + # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}\$moduleName" + # $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" + + # $data = [pscustomobject]@{ + # ModuleName = $moduleName + # Path = $path + # ModuleManifestPath = $moduleManifestPath + # } + # Write-Verbose ($data | Format-List | Out-String) -Verbose + + # Set-ModuleManifest -Path $moduleManifestPath -PowerShellVersion '7.4' + + # Add-ModuleManifestData -Path $moduleManifestPath -CompatiblePSEditions 'Core' + # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'PSEdition_Core' + + # if ($linuxPassed) { + # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Linux' + # } + + # if ($macOSPassed) { + # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'MacOS' + # } + + # if ($windowsPassed) { + # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Windows' + # } + # } + + # LogGroup 'Module Manifest' { + # Show-FileContent -Path $moduleManifestPath + # } + + # - name: Upload module artifact + # uses: actions/upload-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + # if-no-files-found: error + # retention-days: 1 + # overwrite: true diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml new file mode 100644 index 00000000..f984dbb2 --- /dev/null +++ b/.github/workflows/Gather-Tests.yml @@ -0,0 +1,57 @@ +name: Gather-Tests + +on: + workflow_call: + inputs: + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + +permissions: + contents: read # to checkout the repo + +jobs: + Gather-Tests: + name: Gather-Tests + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Debug + if: ${{ inputs.Debug }} + uses: PSModule/Debug@v0 + + - name: Gether-Tests + shell: pwsh + run: | + $testsPath = Join-Path -Path '${{ github.workspace }}' -ChildPath 'tests' + if (-not (Test-Path -Path $testsPath)) { + Write-Host "No tests found" + exit 0 + } + + $testSuites = @() + $testSuites += Get-ChildItem -Path testsPath -Directory + if (-not $testSuites) { + $testSuites += @($testsPath) + } + + Write-Output $testSuites diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 4e240d0f..8b8d0248 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -154,359 +154,365 @@ jobs: Version: ${{ inputs.Version }} SiteOutputPath: ${{ inputs.SiteOutputPath }} - #This is necessary as there is no way to get output from a matrix job - TestModule-pwsh-ubuntu-latest: - name: Test module (pwsh, ubuntu-latest) - if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} - needs: Build-Module - runs-on: ubuntu-latest - outputs: - passed: ${{ steps.test.outputs.passed }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Test built module - id: test - uses: PSModule/Test-PSModule@v2 - continue-on-error: true - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.ModulesOutputPath }} - TestType: Module - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Status - shell: pwsh - run: | - Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - - name: Failed test - if: steps.test.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" - - TestModule-pwsh-macos-latest: - name: Test module (pwsh, macos-latest) - if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} - needs: Build-Module - runs-on: macos-latest - outputs: - passed: ${{ steps.test.outputs.passed }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Test built module - id: test - uses: PSModule/Test-PSModule@v2 - continue-on-error: true - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.ModulesOutputPath }} - TestType: Module - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Status - shell: pwsh - run: | - Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - - name: Failed test - if: steps.test.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" - - TestModule-pwsh-windows-latest: - name: Test module (pwsh, windows-latest) - if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} - needs: Build-Module - runs-on: windows-latest - outputs: - passed: ${{ steps.test.outputs.passed }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Test built module - id: test - uses: PSModule/Test-PSModule@v2 - continue-on-error: true - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.ModulesOutputPath }} - TestType: Module - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Status - shell: pwsh - run: | - Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - - name: Failed test - if: steps.test.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" - - TestModuleStatus: - name: Test module status - if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} + Gather-Tests: + if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} needs: - - TestModule-pwsh-ubuntu-latest - - TestModule-pwsh-macos-latest - - TestModule-pwsh-windows-latest - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Summerize tests - uses: PSModule/GitHub-Script@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - Script: | - LogGroup -Name 'Test analysis' { - - $linuxPassed = '${{ needs.TestModule-pwsh-ubuntu-latest.outputs.passed }}' -eq 'true' - $linuxSkipped = '${{ needs.TestModule-pwsh-ubuntu-latest.result }}' -eq 'skipped' - $macOSPassed = '${{ needs.TestModule-pwsh-macos-latest.outputs.passed }}' -eq 'true' - $macOSSkipped = '${{ needs.TestModule-pwsh-macos-latest.result }}' -eq 'skipped' - $windowsPassed = '${{ needs.TestModule-pwsh-windows-latest.outputs.passed }}' -eq 'true' - $windowsSkipped = '${{ needs.TestModule-pwsh-windows-latest.result }}' -eq 'skipped' - $anyPassed = $linuxPassed -or $macOSPassed -or $windowsPassed - $allSkipped = $linuxSkipped -and $macOSSkipped -and $windowsSkipped - - $Status = @( - [pscustomobject]@{ - Name = 'Linux' - Icon = $linuxSkipped ? '⚠️' : $linuxPassed ? '✅' : '❌' - Status = $linuxSkipped ? 'Skipped' : $linuxPassed ? 'Passed' : 'Failed' - } - [pscustomobject]@{ - Name = 'MacOS' - Icon = $macOSSkipped ? '⚠️' : $macOSPassed ? '✅' : '❌' - Status = $macOSSkipped ? 'Skipped' : $macOSPassed ? 'Passed' : 'Failed' - } - [pscustomobject]@{ - Name = 'Windows' - Icon = $windowsSkipped ? '⚠️' : $windowsPassed ? '✅' : '❌' - Status = $windowsSkipped ? 'Skipped' : $windowsPassed ? 'Passed' : 'Failed' - } - [pscustomobject]@{ - Name = 'Result' - Icon = $allSkipped ? '⚠️' : $anyPassed ? '✅' : '❌' - Status = $allSkipped ? 'Skipped' : $anyPassed ? 'Passed' : 'Failed' - } - ) - - Write-Host ($Status | Format-Table | Out-String) - ($Status | New-MDTable) | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append - - if (-not $anyPassed -and -not $allSkipped) { - Write-Host "::[error]::No tests passed" - exit 1 - } - } - - LogGroup 'Data' { - $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}\$moduleName" - $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" - - # Obay module manifest overrides - $sourcePath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.Path }}" - $sourceModuleManifestPath = Join-Path -Path $sourcePath -ChildPath "manifest.psd1" - if (Test-Path -Path $sourceModuleManifestPath) { - $sourceManifest = Import-PowerShellDataFile -Path $sourceModuleManifestPath - } - - $data = [pscustomobject]@{ - ModuleName = $moduleName - Path = $path - ModuleManifestPath = $moduleManifestPath - } - Write-Verbose ($data | Format-List | Out-String) -Verbose - - # If the source module manifest has a PowerShellVersion, use that, otherwise use the latest version. - $powerShellVersion = $sourceManifest.PowerShellVersion ?? '7.4' - Set-ModuleManifest -Path $moduleManifestPath -PowerShellVersion $powerShellVersion - - Add-ModuleManifestData -Path $moduleManifestPath -CompatiblePSEditions 'Core' - Add-ModuleManifestData -Path $moduleManifestPath -Tags 'PSEdition_Core' - - if ($linuxPassed) { - Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Linux' - } - - if ($macOSPassed) { - Add-ModuleManifestData -Path $moduleManifestPath -Tags 'MacOS' - } - - if ($windowsPassed) { - Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Windows' - } - } - - LogGroup 'Module Manifest - Source' { - Show-FileContent -Path $moduleManifestPath - } - - LogGroup 'Module Manifest' { - Show-FileContent -Path $moduleManifestPath - } - - - name: Upload module artifact - uses: actions/upload-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - if-no-files-found: error - retention-days: 1 - overwrite: true - - PublishModule: - name: Publish module - if: ${{ needs.TestModuleStatus.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} - needs: - - TestModuleStatus - - Build-Docs - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: ${{ inputs.ModulesOutputPath }} - - - name: Publish module - uses: PSModule/Publish-PSModule@v1 - with: - Name: ${{ inputs.Name }} - ModulePath: ${{ inputs.ModulesOutputPath }} - APIKey: ${{ secrets.APIKEY }} - WhatIf: ${{ inputs.TestProcess }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - PublishSite: - name: Publish documentation - if: ${{ inputs.PublishDocs && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} - needs: - - TestModuleStatus - - Build-Docs - permissions: - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 + - Build-Module + uses: ./.github/workflows/Gather-Tests.yml + + # #This is necessary as there is no way to get output from a matrix job + # TestModule-pwsh-ubuntu-latest: + # name: Test module (pwsh, ubuntu-latest) + # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} + # needs: Build-Module + # runs-on: ubuntu-latest + # outputs: + # passed: ${{ steps.test.outputs.passed }} + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Test built module + # id: test + # uses: PSModule/Test-PSModule@v2 + # continue-on-error: true + # with: + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.ModulesOutputPath }} + # TestType: Module + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Status + # shell: pwsh + # run: | + # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" + + # - name: Failed test + # if: steps.test.outcome != 'success' + # shell: pwsh + # run: Write-Host "Complete successfully" + + # TestModule-pwsh-macos-latest: + # name: Test module (pwsh, macos-latest) + # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} + # needs: Build-Module + # runs-on: macos-latest + # outputs: + # passed: ${{ steps.test.outputs.passed }} + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Test built module + # id: test + # uses: PSModule/Test-PSModule@v2 + # continue-on-error: true + # with: + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.ModulesOutputPath }} + # TestType: Module + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Status + # shell: pwsh + # run: | + # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" + + # - name: Failed test + # if: steps.test.outcome != 'success' + # shell: pwsh + # run: Write-Host "Complete successfully" + + # TestModule-pwsh-windows-latest: + # name: Test module (pwsh, windows-latest) + # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} + # needs: Build-Module + # runs-on: windows-latest + # outputs: + # passed: ${{ steps.test.outputs.passed }} + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Test built module + # id: test + # uses: PSModule/Test-PSModule@v2 + # continue-on-error: true + # with: + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.ModulesOutputPath }} + # TestType: Module + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Status + # shell: pwsh + # run: | + # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" + + # - name: Failed test + # if: steps.test.outcome != 'success' + # shell: pwsh + # run: Write-Host "Complete successfully" + + # TestModuleStatus: + # name: Test module status + # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} + # needs: + # - TestModule-pwsh-ubuntu-latest + # - TestModule-pwsh-macos-latest + # - TestModule-pwsh-windows-latest + # runs-on: ubuntu-latest + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Summerize tests + # uses: PSModule/GitHub-Script@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + # Script: | + # LogGroup -Name 'Test analysis' { + + # $linuxPassed = '${{ needs.TestModule-pwsh-ubuntu-latest.outputs.passed }}' -eq 'true' + # $linuxSkipped = '${{ needs.TestModule-pwsh-ubuntu-latest.result }}' -eq 'skipped' + # $macOSPassed = '${{ needs.TestModule-pwsh-macos-latest.outputs.passed }}' -eq 'true' + # $macOSSkipped = '${{ needs.TestModule-pwsh-macos-latest.result }}' -eq 'skipped' + # $windowsPassed = '${{ needs.TestModule-pwsh-windows-latest.outputs.passed }}' -eq 'true' + # $windowsSkipped = '${{ needs.TestModule-pwsh-windows-latest.result }}' -eq 'skipped' + # $anyPassed = $linuxPassed -or $macOSPassed -or $windowsPassed + # $allSkipped = $linuxSkipped -and $macOSSkipped -and $windowsSkipped + + # $Status = @( + # [pscustomobject]@{ + # Name = 'Linux' + # Icon = $linuxSkipped ? '⚠️' : $linuxPassed ? '✅' : '❌' + # Status = $linuxSkipped ? 'Skipped' : $linuxPassed ? 'Passed' : 'Failed' + # } + # [pscustomobject]@{ + # Name = 'MacOS' + # Icon = $macOSSkipped ? '⚠️' : $macOSPassed ? '✅' : '❌' + # Status = $macOSSkipped ? 'Skipped' : $macOSPassed ? 'Passed' : 'Failed' + # } + # [pscustomobject]@{ + # Name = 'Windows' + # Icon = $windowsSkipped ? '⚠️' : $windowsPassed ? '✅' : '❌' + # Status = $windowsSkipped ? 'Skipped' : $windowsPassed ? 'Passed' : 'Failed' + # } + # [pscustomobject]@{ + # Name = 'Result' + # Icon = $allSkipped ? '⚠️' : $anyPassed ? '✅' : '❌' + # Status = $allSkipped ? 'Skipped' : $anyPassed ? 'Passed' : 'Failed' + # } + # ) + + # Write-Host ($Status | Format-Table | Out-String) + # ($Status | New-MDTable) | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append + + # if (-not $anyPassed -and -not $allSkipped) { + # Write-Host "::[error]::No tests passed" + # exit 1 + # } + # } + + # LogGroup 'Data' { + # $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' + # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}\$moduleName" + # $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" + + # # Obay module manifest overrides + # $sourcePath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.Path }}" + # $sourceModuleManifestPath = Join-Path -Path $sourcePath -ChildPath "manifest.psd1" + # if (Test-Path -Path $sourceModuleManifestPath) { + # $sourceManifest = Import-PowerShellDataFile -Path $sourceModuleManifestPath + # } + + # $data = [pscustomobject]@{ + # ModuleName = $moduleName + # Path = $path + # ModuleManifestPath = $moduleManifestPath + # } + # Write-Verbose ($data | Format-List | Out-String) -Verbose + + # # If the source module manifest has a PowerShellVersion, use that, otherwise use the latest version. + # $powerShellVersion = $sourceManifest.PowerShellVersion ?? '7.4' + # Set-ModuleManifest -Path $moduleManifestPath -PowerShellVersion $powerShellVersion + + # Add-ModuleManifestData -Path $moduleManifestPath -CompatiblePSEditions 'Core' + # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'PSEdition_Core' + + # if ($linuxPassed) { + # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Linux' + # } + + # if ($macOSPassed) { + # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'MacOS' + # } + + # if ($windowsPassed) { + # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Windows' + # } + # } + + # LogGroup 'Module Manifest - Source' { + # Show-FileContent -Path $moduleManifestPath + # } + + # LogGroup 'Module Manifest' { + # Show-FileContent -Path $moduleManifestPath + # } + + # - name: Upload module artifact + # uses: actions/upload-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + # if-no-files-found: error + # retention-days: 1 + # overwrite: true + + # PublishModule: + # name: Publish module + # if: ${{ needs.TestModuleStatus.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} + # needs: + # - TestModuleStatus + # - Build-Docs + # runs-on: ubuntu-latest + # steps: + # - name: Checkout Code + # uses: actions/checkout@v4 + + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # - name: Download module artifact + # uses: actions/download-artifact@v4 + # with: + # name: module + # path: ${{ inputs.ModulesOutputPath }} + + # - name: Publish module + # uses: PSModule/Publish-PSModule@v1 + # with: + # Name: ${{ inputs.Name }} + # ModulePath: ${{ inputs.ModulesOutputPath }} + # APIKey: ${{ secrets.APIKEY }} + # WhatIf: ${{ inputs.TestProcess }} + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # PublishSite: + # name: Publish documentation + # if: ${{ inputs.PublishDocs && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} + # needs: + # - TestModuleStatus + # - Build-Docs + # permissions: + # pages: write # to deploy to Pages + # id-token: write # to verify the deployment originates from an appropriate source + # environment: + # name: github-pages + # url: ${{ steps.deployment.outputs.page_url }} + # runs-on: ubuntu-latest + # steps: + # - name: Debug + # if: ${{ inputs.Debug }} + # uses: PSModule/Debug@v0 + + # - name: Deploy to GitHub Pages + # id: deployment + # uses: actions/deploy-pages@v4 From 4d70970285f04a8ae467af3f104911d82ebc71b3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 17 Feb 2025 00:46:38 +0100 Subject: [PATCH 018/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Correct=20varia?= =?UTF-8?q?ble=20reference=20for=20testsPath=20in=20Gather-Tests=20workflo?= =?UTF-8?q?w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index f984dbb2..d84cb3bf 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -49,7 +49,7 @@ jobs: } $testSuites = @() - $testSuites += Get-ChildItem -Path testsPath -Directory + $testSuites += Get-ChildItem -Path $testsPath -Directory if (-not $testSuites) { $testSuites += @($testsPath) } From 3c10be459642bc61db7cfc9551bd2bc0697b0cc5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 17 Feb 2025 00:59:26 +0100 Subject: [PATCH 019/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Add=20W?= =?UTF-8?q?orkspace=20input=20to=20workflows=20for=20customizable=20worksp?= =?UTF-8?q?ace=20paths?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 7 +++++++ .github/workflows/Gather-Tests.yml | 7 ++++++- .github/workflows/Workflow-Test-Default-CI.yml | 1 + .github/workflows/Workflow-Test-Default.yml | 1 + .github/workflows/Workflow-Test-WithManifest-CI.yml | 1 + .github/workflows/Workflow-Test-WithManifest.yml | 1 + .github/workflows/workflow.yml | 7 +++++++ 7 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 70089f97..a0344057 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -37,6 +37,11 @@ on: description: The path to the source code of the module. required: false default: src + Workspace: + type: string + description: The path to the workspace. + required: false + default: ${{ github.workspace }} ModulesOutputPath: type: string description: The path to the output directory for the modules. @@ -152,6 +157,8 @@ jobs: needs: - Build-Module uses: ./.github/workflows/Gather-Tests.yml + with: + Workspace: ${{ inputs.Workspace }} # # This is necessary as there is no way to get output from a matrix job # TestModule-pwsh-ubuntu-latest: diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index d84cb3bf..81fcd228 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -3,6 +3,11 @@ name: Gather-Tests on: workflow_call: inputs: + Workspace: + type: string + description: The path to the workspace. + required: false + default: ${{ github.workspace }} Debug: type: boolean description: Enable debug output. @@ -42,7 +47,7 @@ jobs: - name: Gether-Tests shell: pwsh run: | - $testsPath = Join-Path -Path '${{ github.workspace }}' -ChildPath 'tests' + $testsPath = Join-Path -Path '${{ inputs.Workspace }}' -ChildPath 'tests' if (-not (Test-Path -Path $testsPath)) { Write-Host "No tests found" exit 0 diff --git a/.github/workflows/Workflow-Test-Default-CI.yml b/.github/workflows/Workflow-Test-Default-CI.yml index 7f91a079..6d1a6932 100644 --- a/.github/workflows/Workflow-Test-Default-CI.yml +++ b/.github/workflows/Workflow-Test-Default-CI.yml @@ -27,3 +27,4 @@ jobs: ModulesOutputPath: tests/srcTestRepo/outputs/modules DocsOutputPath: tests/srcTestRepo/outputs/docs SkipTests: Module + Workspace: tests/srcTestRepo diff --git a/.github/workflows/Workflow-Test-Default.yml b/.github/workflows/Workflow-Test-Default.yml index 3ae91ac9..47e64651 100644 --- a/.github/workflows/Workflow-Test-Default.yml +++ b/.github/workflows/Workflow-Test-Default.yml @@ -30,3 +30,4 @@ jobs: DocsOutputPath: tests/srcTestRepo/outputs/docs TestProcess: true SkipTests: Module + Workspace: tests/srcTestRepo diff --git a/.github/workflows/Workflow-Test-WithManifest-CI.yml b/.github/workflows/Workflow-Test-WithManifest-CI.yml index 663c7e5e..9ff8d8b1 100644 --- a/.github/workflows/Workflow-Test-WithManifest-CI.yml +++ b/.github/workflows/Workflow-Test-WithManifest-CI.yml @@ -27,3 +27,4 @@ jobs: ModulesOutputPath: tests/srcWithManifestTestRepo/outputs/modules DocsOutputPath: tests/srcWithManifestTestRepo/outputs/docs SkipTests: Linux + Workspace: tests/srcWithManifestTestRepo diff --git a/.github/workflows/Workflow-Test-WithManifest.yml b/.github/workflows/Workflow-Test-WithManifest.yml index 40034ff2..f7ae3718 100644 --- a/.github/workflows/Workflow-Test-WithManifest.yml +++ b/.github/workflows/Workflow-Test-WithManifest.yml @@ -30,3 +30,4 @@ jobs: DocsOutputPath: tests/srcWithManifestTestRepo/outputs/docs TestProcess: true SkipTests: Linux + Workspace: tests/srcWithManifestTestRepo diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 8b8d0248..a4432360 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -37,6 +37,11 @@ on: description: The path to the source code of the module. required: false default: src + Workspace: + type: string + description: The path to the workspace. + required: false + default: ${{ github.workspace }} ModulesOutputPath: type: string description: The path to the output directory for the modules. @@ -159,6 +164,8 @@ jobs: needs: - Build-Module uses: ./.github/workflows/Gather-Tests.yml + with: + Workspace: ${{ inputs.Workspace }} # #This is necessary as there is no way to get output from a matrix job # TestModule-pwsh-ubuntu-latest: From c29361a4e50fce6008f9a8505ca0f9d6eb3182b4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 17 Feb 2025 01:07:38 +0100 Subject: [PATCH 020/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Resolve=20path?= =?UTF-8?q?=20for=20tests=20directory=20in=20Gather-Tests=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 81fcd228..0c58ff9e 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -47,7 +47,8 @@ jobs: - name: Gether-Tests shell: pwsh run: | - $testsPath = Join-Path -Path '${{ inputs.Workspace }}' -ChildPath 'tests' + $rootPath = Resolve-Path -Path '${{ inputs.Workspace }}' + $testsPath = Join-Path -Path $rootPath -ChildPath 'tests' if (-not (Test-Path -Path $testsPath)) { Write-Host "No tests found" exit 0 From cb63fbe09866ad5dc64ec5c19926ea75254ceee9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 17 Feb 2025 09:49:53 +0100 Subject: [PATCH 021/324] =?UTF-8?q?=F0=9F=A9=B9=20[Add]:=20Implement=20env?= =?UTF-8?q?ironment=20variable=20tests=20and=20correct=20Gather-Tests=20wo?= =?UTF-8?q?rkflow=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 2 +- media/Flow.drawio | 120 ++++++++++++++++++ tests/srcTestRepo/tests/Environment.Tests.ps1 | 15 +++ .../srcTestRepo/tests/PSModuleTest.Tests.ps1 | 16 --- .../tests/Environments/Environment.Tests.ps1 | 15 +++ .../{ => MyTests}/PSModuleTest.Tests.ps1 | 16 --- 6 files changed, 151 insertions(+), 33 deletions(-) create mode 100644 media/Flow.drawio create mode 100644 tests/srcTestRepo/tests/Environment.Tests.ps1 create mode 100644 tests/srcWithManifestTestRepo/tests/Environments/Environment.Tests.ps1 rename tests/srcWithManifestTestRepo/tests/{ => MyTests}/PSModuleTest.Tests.ps1 (74%) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 0c58ff9e..806c490c 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -44,7 +44,7 @@ jobs: if: ${{ inputs.Debug }} uses: PSModule/Debug@v0 - - name: Gether-Tests + - name: Gather-Tests shell: pwsh run: | $rootPath = Resolve-Path -Path '${{ inputs.Workspace }}' diff --git a/media/Flow.drawio b/media/Flow.drawio new file mode 100644 index 00000000..95b111d1 --- /dev/null +++ b/media/Flow.drawio @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/srcTestRepo/tests/Environment.Tests.ps1 b/tests/srcTestRepo/tests/Environment.Tests.ps1 new file mode 100644 index 00000000..211be946 --- /dev/null +++ b/tests/srcTestRepo/tests/Environment.Tests.ps1 @@ -0,0 +1,15 @@ +Describe 'Environment Variables are available' { + It 'Should be available [<_>]' -ForEach @( + 'TEST_APP_ENT_CLIENT_ID', + 'TEST_APP_ENT_PRIVATE_KEY', + 'TEST_APP_ORG_CLIENT_ID', + 'TEST_APP_ORG_PRIVATE_KEY', + 'TEST_USER_ORG_FG_PAT', + 'TEST_USER_USER_FG_PAT', + 'TEST_USER_PAT' + ) { + $name = $_ + Write-Verbose "Environment variable: [$name]" -Verbose + Get-ChildItem env: | Where-Object { $_.Name -eq $name } | Should -Not -BeNullOrEmpty + } +} diff --git a/tests/srcTestRepo/tests/PSModuleTest.Tests.ps1 b/tests/srcTestRepo/tests/PSModuleTest.Tests.ps1 index 2be65edb..9bf1bb64 100644 --- a/tests/srcTestRepo/tests/PSModuleTest.Tests.ps1 +++ b/tests/srcTestRepo/tests/PSModuleTest.Tests.ps1 @@ -6,22 +6,6 @@ Param( ) Write-Verbose "Path to the module: [$Path]" -Verbose -Describe 'Environment Variables are available' { - It 'Should be available [<_>]' -ForEach @( - 'TEST_APP_ENT_CLIENT_ID', - 'TEST_APP_ENT_PRIVATE_KEY', - 'TEST_APP_ORG_CLIENT_ID', - 'TEST_APP_ORG_PRIVATE_KEY', - 'TEST_USER_ORG_FG_PAT', - 'TEST_USER_USER_FG_PAT', - 'TEST_USER_PAT' - ) { - $name = $_ - Write-Verbose "Environment variable: [$name]" -Verbose - Get-ChildItem env: | Where-Object { $_.Name -eq $name } | Should -Not -BeNullOrEmpty - } -} - Describe 'PSModuleTest.Tests.ps1' { Context 'Function: Test-PSModuleTest' { It 'Should be able to call the function' { diff --git a/tests/srcWithManifestTestRepo/tests/Environments/Environment.Tests.ps1 b/tests/srcWithManifestTestRepo/tests/Environments/Environment.Tests.ps1 new file mode 100644 index 00000000..211be946 --- /dev/null +++ b/tests/srcWithManifestTestRepo/tests/Environments/Environment.Tests.ps1 @@ -0,0 +1,15 @@ +Describe 'Environment Variables are available' { + It 'Should be available [<_>]' -ForEach @( + 'TEST_APP_ENT_CLIENT_ID', + 'TEST_APP_ENT_PRIVATE_KEY', + 'TEST_APP_ORG_CLIENT_ID', + 'TEST_APP_ORG_PRIVATE_KEY', + 'TEST_USER_ORG_FG_PAT', + 'TEST_USER_USER_FG_PAT', + 'TEST_USER_PAT' + ) { + $name = $_ + Write-Verbose "Environment variable: [$name]" -Verbose + Get-ChildItem env: | Where-Object { $_.Name -eq $name } | Should -Not -BeNullOrEmpty + } +} diff --git a/tests/srcWithManifestTestRepo/tests/PSModuleTest.Tests.ps1 b/tests/srcWithManifestTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 similarity index 74% rename from tests/srcWithManifestTestRepo/tests/PSModuleTest.Tests.ps1 rename to tests/srcWithManifestTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 index 2be65edb..9bf1bb64 100644 --- a/tests/srcWithManifestTestRepo/tests/PSModuleTest.Tests.ps1 +++ b/tests/srcWithManifestTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 @@ -6,22 +6,6 @@ Param( ) Write-Verbose "Path to the module: [$Path]" -Verbose -Describe 'Environment Variables are available' { - It 'Should be available [<_>]' -ForEach @( - 'TEST_APP_ENT_CLIENT_ID', - 'TEST_APP_ENT_PRIVATE_KEY', - 'TEST_APP_ORG_CLIENT_ID', - 'TEST_APP_ORG_PRIVATE_KEY', - 'TEST_USER_ORG_FG_PAT', - 'TEST_USER_USER_FG_PAT', - 'TEST_USER_PAT' - ) { - $name = $_ - Write-Verbose "Environment variable: [$name]" -Verbose - Get-ChildItem env: | Where-Object { $_.Name -eq $name } | Should -Not -BeNullOrEmpty - } -} - Describe 'PSModuleTest.Tests.ps1' { Context 'Function: Test-PSModuleTest' { It 'Should be able to call the function' { From a8fc638d67bdcf4d0b7c72655c4b5b2c3785d661 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 17 Feb 2025 22:16:47 +0100 Subject: [PATCH 022/324] =?UTF-8?q?=F0=9F=A9=B9=20[Add]:=20Add=20backup=20?= =?UTF-8?q?diagram=20file=20for=20workflow=20visualization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- media/.$Flow.drawio.bkp | 120 ++++++++++++++++++++ media/Flow.drawio | 238 ++++++++++++++++++++-------------------- 2 files changed, 239 insertions(+), 119 deletions(-) create mode 100644 media/.$Flow.drawio.bkp diff --git a/media/.$Flow.drawio.bkp b/media/.$Flow.drawio.bkp new file mode 100644 index 00000000..95b111d1 --- /dev/null +++ b/media/.$Flow.drawio.bkp @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/media/Flow.drawio b/media/Flow.drawio index 95b111d1..cc6b9cc4 100644 --- a/media/Flow.drawio +++ b/media/Flow.drawio @@ -1,120 +1,120 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b7adaca88a1c0e813344f563427a47d5cae483c7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 19 Feb 2025 14:16:26 +0100 Subject: [PATCH 023/324] =?UTF-8?q?=F0=9F=A9=B9=20[Add]:=20Create=20Test-M?= =?UTF-8?q?odule=20workflow=20for=20modular=20source=20code=20testing=20ac?= =?UTF-8?q?ross=20multiple=20OS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 107 +++++++++++++++++ .github/workflows/workflow.yml | 183 +++++------------------------- 2 files changed, 133 insertions(+), 157 deletions(-) create mode 100644 .github/workflows/Test-Module.yml diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml new file mode 100644 index 00000000..6bfe0566 --- /dev/null +++ b/.github/workflows/Test-Module.yml @@ -0,0 +1,107 @@ +name: Test-SourceCode + +on: + workflow_call: + inputs: + RunsOn: + type: string + description: The type of runner to use for the job. + required: true + OS: + type: string + description: The operating system name. + required: true + Name: + type: string + description: The name of the module to process. Scripts default to the repository name if nothing is specified. + required: false + Path: + type: string + description: The path to the source code of the module. + required: false + default: src + ModulesOutputPath: + type: string + description: The path to the output directory for the modules. + required: false + default: outputs/modules + SkipTests: + type: string + description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. + required: false + default: None + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + +permissions: + contents: read # to checkout the repo and create releases on the repo + +jobs: + Test-SourceCode: + name: Test source code (${{ inputs.RunsOn }}) + if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} + runs-on: ${{ inputs.RunsOn }} + outputs: + passed: ${{ steps.test.outputs.passed }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Debug + if: ${{ inputs.Debug }} + uses: PSModule/Debug@v0 + + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + - name: Download module artifact + uses: actions/download-artifact@v4 + with: + name: module + path: ${{ inputs.ModulesOutputPath }} + + - name: Test built module + id: test + uses: PSModule/Test-PSModule@v2 + continue-on-error: true + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.ModulesOutputPath }} + TestType: Module + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + - name: Status + shell: pwsh + run: | + Write-Host "Passed: [${{ steps.test.outputs.passed }}]" + + - name: Failed test + if: steps.test.outcome != 'success' + shell: pwsh + run: Write-Host "Complete successfully" diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index a4432360..d86263a6 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -159,6 +159,32 @@ jobs: Version: ${{ inputs.Version }} SiteOutputPath: ${{ inputs.SiteOutputPath }} + TestModule: + if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + needs: + - Build-Module + strategy: + matrix: + include: + - OSName: Linux + RunsOn: ubuntu-latest + - OSName: macOS + RunsOn: macos-latest + - OSName: Windows + RunsOn: windows-latest + uses: ./.github/workflows/Test-Module.yml + with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + ModulesOutputPath: ${{ inputs.ModulesOutputPath }} + SkipTests: ${{ inputs.SkipTests }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + Gather-Tests: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} needs: @@ -167,163 +193,6 @@ jobs: with: Workspace: ${{ inputs.Workspace }} - # #This is necessary as there is no way to get output from a matrix job - # TestModule-pwsh-ubuntu-latest: - # name: Test module (pwsh, ubuntu-latest) - # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} - # needs: Build-Module - # runs-on: ubuntu-latest - # outputs: - # passed: ${{ steps.test.outputs.passed }} - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Test built module - # id: test - # uses: PSModule/Test-PSModule@v2 - # continue-on-error: true - # with: - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.ModulesOutputPath }} - # TestType: Module - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Status - # shell: pwsh - # run: | - # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - # - name: Failed test - # if: steps.test.outcome != 'success' - # shell: pwsh - # run: Write-Host "Complete successfully" - - # TestModule-pwsh-macos-latest: - # name: Test module (pwsh, macos-latest) - # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} - # needs: Build-Module - # runs-on: macos-latest - # outputs: - # passed: ${{ steps.test.outputs.passed }} - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Test built module - # id: test - # uses: PSModule/Test-PSModule@v2 - # continue-on-error: true - # with: - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.ModulesOutputPath }} - # TestType: Module - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Status - # shell: pwsh - # run: | - # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - # - name: Failed test - # if: steps.test.outcome != 'success' - # shell: pwsh - # run: Write-Host "Complete successfully" - - # TestModule-pwsh-windows-latest: - # name: Test module (pwsh, windows-latest) - # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} - # needs: Build-Module - # runs-on: windows-latest - # outputs: - # passed: ${{ steps.test.outputs.passed }} - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Test built module - # id: test - # uses: PSModule/Test-PSModule@v2 - # continue-on-error: true - # with: - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.ModulesOutputPath }} - # TestType: Module - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Status - # shell: pwsh - # run: | - # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - # - name: Failed test - # if: steps.test.outcome != 'success' - # shell: pwsh - # run: Write-Host "Complete successfully" - # TestModuleStatus: # name: Test module status # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} From 7dd7b59fb620b428dcbe736a6e19d18bc5e8c272 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 19 Feb 2025 14:20:06 +0100 Subject: [PATCH 024/324] =?UTF-8?q?=F0=9F=A9=B9=20[Add]:=20Implement=20Tes?= =?UTF-8?q?tModule=20job=20in=20CI=20workflow=20for=20cross-platform=20tes?= =?UTF-8?q?ting=20and=20enhance=20Test-Module=20workflow=20with=20addition?= =?UTF-8?q?al=20secret=20inputs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 26 ++++++++++++++++++++++++++ .github/workflows/Test-Module.yml | 25 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a0344057..8a6dff61 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -152,6 +152,32 @@ jobs: Version: ${{ inputs.Version }} SiteOutputPath: ${{ inputs.SiteOutputPath }} + TestModule: + if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + needs: + - Build-Module + strategy: + matrix: + include: + - OSName: Linux + RunsOn: ubuntu-latest + - OSName: macOS + RunsOn: macos-latest + - OSName: Windows + RunsOn: windows-latest + uses: ./.github/workflows/Test-Module.yml + with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + ModulesOutputPath: ${{ inputs.ModulesOutputPath }} + SkipTests: ${{ inputs.SkipTests }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + Gather-Tests: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} needs: diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 6bfe0566..7ef3ed43 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -2,6 +2,31 @@ name: Test-SourceCode on: workflow_call: + secrets: + APIKey: + description: The API key for the PowerShell Gallery. + required: true + TEST_APP_ENT_CLIENT_ID: + description: The client ID of an Enterprise GitHub App for running tests. + required: false + TEST_APP_ENT_PRIVATE_KEY: + description: The private key of an Enterprise GitHub App for running tests. + required: false + TEST_APP_ORG_CLIENT_ID: + description: The client ID of an Organization GitHub App for running tests. + required: false + TEST_APP_ORG_PRIVATE_KEY: + description: The private key of an Organization GitHub App for running tests. + required: false + TEST_USER_ORG_FG_PAT: + description: The fine-grained personal access token with org access for running tests. + required: false + TEST_USER_USER_FG_PAT: + description: The fine-grained personal access token with user account access for running tests. + required: false + TEST_USER_PAT: + description: The classic personal access token for running tests. + required: false inputs: RunsOn: type: string From 065e68078d808f1a089aee9a20d59f9198984b71 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 19 Feb 2025 14:25:57 +0100 Subject: [PATCH 025/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Remove=20unnece?= =?UTF-8?q?ssary=20APIKey=20secret=20from=20Test-Module=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 7ef3ed43..7e221e40 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -3,9 +3,6 @@ name: Test-SourceCode on: workflow_call: secrets: - APIKey: - description: The API key for the PowerShell Gallery. - required: true TEST_APP_ENT_CLIENT_ID: description: The client ID of an Enterprise GitHub App for running tests. required: false From da55a46d9421cc84a5c90a15fe0a15dd54f95fdc Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 19 Feb 2025 14:30:34 +0100 Subject: [PATCH 026/324] =?UTF-8?q?=F0=9F=A9=B9=20[Update]:=20Exclude=20wo?= =?UTF-8?q?rkflows=20from=20jscpd=20checks=20and=20inherit=20secrets=20in?= =?UTF-8?q?=20workflow=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/linters/.jscpd.json | 3 ++- .github/workflows/workflow.yml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/linters/.jscpd.json b/.github/linters/.jscpd.json index 23970e85..15d4513d 100644 --- a/.github/linters/.jscpd.json +++ b/.github/linters/.jscpd.json @@ -4,7 +4,8 @@ "consoleFull" ], "ignore": [ - "**/tests/**" + "**/tests/**", + "**/workflows/**" ], "absolute": true } diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index d86263a6..76ad22e1 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -173,6 +173,7 @@ jobs: - OSName: Windows RunsOn: windows-latest uses: ./.github/workflows/Test-Module.yml + secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} From 78323038f42ff484b2d35d561694520147095c37 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 19 Feb 2025 14:36:07 +0100 Subject: [PATCH 027/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Inherit=20?= =?UTF-8?q?secrets=20in=20CI=20workflow=20and=20move=20environment=20varia?= =?UTF-8?q?bles=20to=20Test-Module=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 11 +---------- .github/workflows/Test-Module.yml | 9 +++++++++ .github/workflows/workflow.yml | 10 ---------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8a6dff61..2503d7b6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -88,16 +88,6 @@ on: required: false default: false -env: - GITHUB_TOKEN: ${{ github.token }} # Used for GitHub CLI authentication - TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} - TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} - TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }} - TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }} - TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} - TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} - TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} - permissions: contents: read # to checkout the repository pull-requests: write # to write comments to PRs @@ -166,6 +156,7 @@ jobs: - OSName: Windows RunsOn: windows-latest uses: ./.github/workflows/Test-Module.yml + secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 7e221e40..8e0080cf 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -73,6 +73,15 @@ on: required: false default: false +env: + TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} + TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} + TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }} + TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }} + TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} + TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} + TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} + permissions: contents: read # to checkout the repo and create releases on the repo diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 76ad22e1..0551445d 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -93,16 +93,6 @@ on: required: false default: false -env: - GITHUB_TOKEN: ${{ github.token }} # Used for GitHub CLI authentication - TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} - TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} - TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }} - TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }} - TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} - TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} - TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} - permissions: contents: write # to checkout the repo and create releases on the repo pull-requests: write # to write comments to PRs From 32b6dc2ba70e27c8ef22bf459167d1f9e3abf5b2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 00:22:21 +0100 Subject: [PATCH 028/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20a?= =?UTF-8?q?nd=20restructure=20Test-SourceCode=20job=20to=20Test-PSModule-S?= =?UTF-8?q?ourceCode=20and=20add=20Invoke-ScriptAnalyzer=20job=20for=20imp?= =?UTF-8?q?roved=20linting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-SourceCode.yml | 30 ++++++++++++++++----------- .github/workflows/workflow.yml | 3 ++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 97969099..852f9906 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -50,7 +50,7 @@ permissions: contents: read # to checkout the repo and create releases on the repo jobs: - Test-SourceCode: + Test-PSModule-SourceCode: name: Test source code (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} @@ -58,26 +58,32 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 + - name: Test source code + id: test + uses: PSModule/Test-PSModule@v3 with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + Path: ${{ inputs.Path }} + Settings: SourceCode - - name: Test source code + Invoke-ScriptAnalyzer-SourceCode: + name: Lint source code (${{ inputs.RunsOn }}) + if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, inputs.OS)) }} + runs-on: ${{ inputs.RunsOn }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Lint source code id: test - uses: PSModule/Test-PSModule@v2 + uses: PSModule/Invoke-ScriptAnalyzer@v2 with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - TestType: SourceCode Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + Path: ${{ inputs.Path }} + Settings: SourceCode diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 0551445d..9782ea43 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -102,6 +102,7 @@ permissions: jobs: TestSourceCode: + name: Test source code strategy: matrix: include: @@ -143,11 +144,11 @@ jobs: Path: ${{ inputs.Path }} ModulesOutputPath: ${{ inputs.ModulesOutputPath }} DocsOutputPath: ${{ inputs.DocsOutputPath }} + SiteOutputPath: ${{ inputs.SiteOutputPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - SiteOutputPath: ${{ inputs.SiteOutputPath }} TestModule: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} From 4f3b4159bf08c8362a11afb5c61c200890bf8a40 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 00:30:58 +0100 Subject: [PATCH 029/324] =?UTF-8?q?=F0=9F=A9=B9=20[Update]:=20Disable=20fa?= =?UTF-8?q?il-fast=20strategy=20in=20TestSourceCode=20job=20for=20improved?= =?UTF-8?q?=20job=20execution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9782ea43..bd1d1686 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -104,6 +104,7 @@ jobs: TestSourceCode: name: Test source code strategy: + fail-fast: false matrix: include: - OSName: Linux From 2be3c3d984a15731c4459c4afccd036fd5b8dad9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 00:40:03 +0100 Subject: [PATCH 030/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20T?= =?UTF-8?q?est-SourceCode=20job=20to=20TestSourceCode,=20update=20job=20na?= =?UTF-8?q?me=20for=20clarity,=20and=20disable=20fail-fast=20strategy=20fo?= =?UTF-8?q?r=20improved=20execution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 4 +++- .github/workflows/Test-SourceCode.yml | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2503d7b6..df5b9b74 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -94,8 +94,10 @@ permissions: statuses: write # to update the status of the workflow from linter jobs: - Test-SourceCode: + TestSourceCode: + name: Test source code strategy: + fail-fast: false matrix: include: - OSName: Linux diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 852f9906..f8a30849 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -59,7 +59,6 @@ jobs: uses: actions/checkout@v4 - name: Test source code - id: test uses: PSModule/Test-PSModule@v3 with: Debug: ${{ inputs.Debug }} @@ -78,7 +77,6 @@ jobs: uses: actions/checkout@v4 - name: Lint source code - id: test uses: PSModule/Invoke-ScriptAnalyzer@v2 with: Debug: ${{ inputs.Debug }} From 882a5b4f961b381b6b1132a33ee52a2f87487160 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 03:42:48 +0100 Subject: [PATCH 031/324] =?UTF-8?q?=F0=9F=A9=B9=20[Add]:=20Create=20PSModu?= =?UTF-8?q?le.yml=20files=20for=20srcTestRepo=20and=20srcWithManifestTestR?= =?UTF-8?q?epo=20to=20support=20CI=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- media/Flow.drawio | 246 +++++++++--------- tests/srcTestRepo/.github/PSModule.yml | 0 .../.github/PSModule.yml | 0 3 files changed, 127 insertions(+), 119 deletions(-) create mode 100644 tests/srcTestRepo/.github/PSModule.yml create mode 100644 tests/srcWithManifestTestRepo/.github/PSModule.yml diff --git a/media/Flow.drawio b/media/Flow.drawio index cc6b9cc4..8a74a5e2 100644 --- a/media/Flow.drawio +++ b/media/Flow.drawio @@ -1,120 +1,128 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/srcTestRepo/.github/PSModule.yml b/tests/srcTestRepo/.github/PSModule.yml new file mode 100644 index 00000000..e69de29b diff --git a/tests/srcWithManifestTestRepo/.github/PSModule.yml b/tests/srcWithManifestTestRepo/.github/PSModule.yml new file mode 100644 index 00000000..e69de29b From 0dfb23433cb00ee8f24fca4b488621d37b97355a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 03:45:44 +0100 Subject: [PATCH 032/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20CI=20workflow=20inputs=20by=20removing=20unnecessary=20param?= =?UTF-8?q?eters=20and=20updating=20descriptions=20for=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 34 ++----------------- .../workflows/Workflow-Test-Default-CI.yml | 5 +-- .github/workflows/Workflow-Test-Default.yml | 5 +-- .../Workflow-Test-WithManifest-CI.yml | 5 +-- .../workflows/Workflow-Test-WithManifest.yml | 5 +-- .github/workflows/workflow.yml | 32 +---------------- 6 files changed, 7 insertions(+), 79 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index df5b9b74..48e78d3f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -34,39 +34,14 @@ on: required: false Path: type: string - description: The path to the source code of the module. - required: false - default: src - Workspace: - type: string - description: The path to the workspace. + description: The path to the root of the repo. required: false default: ${{ github.workspace }} - ModulesOutputPath: - type: string - description: The path to the output directory for the modules. - required: false - default: outputs/modules - DocsOutputPath: - type: string - description: The path to the output directory for the documentation. - required: false - default: outputs/docs - SiteOutputPath: - type: string - description: The path to the output directory for the site. - required: false - default: outputs/site SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. required: false default: None - PublishDocs: - type: boolean - description: Whether to publish the documentation using MkDocs and GitHub Pages. - required: false - default: true Debug: type: boolean description: Enable debug output. @@ -123,7 +98,6 @@ jobs: with: Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -136,13 +110,10 @@ jobs: with: Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} - DocsOutputPath: ${{ inputs.DocsOutputPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - SiteOutputPath: ${{ inputs.SiteOutputPath }} TestModule: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} @@ -164,7 +135,6 @@ jobs: OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -177,7 +147,7 @@ jobs: - Build-Module uses: ./.github/workflows/Gather-Tests.yml with: - Workspace: ${{ inputs.Workspace }} + Path: ${{ inputs.Path }} # # This is necessary as there is no way to get output from a matrix job # TestModule-pwsh-ubuntu-latest: diff --git a/.github/workflows/Workflow-Test-Default-CI.yml b/.github/workflows/Workflow-Test-Default-CI.yml index 6d1a6932..8db335cd 100644 --- a/.github/workflows/Workflow-Test-Default-CI.yml +++ b/.github/workflows/Workflow-Test-Default-CI.yml @@ -23,8 +23,5 @@ jobs: secrets: inherit with: Name: PSModuleTest - Path: tests/srcTestRepo/src - ModulesOutputPath: tests/srcTestRepo/outputs/modules - DocsOutputPath: tests/srcTestRepo/outputs/docs + Path: tests/srcTestRepo SkipTests: Module - Workspace: tests/srcTestRepo diff --git a/.github/workflows/Workflow-Test-Default.yml b/.github/workflows/Workflow-Test-Default.yml index 47e64651..feefca89 100644 --- a/.github/workflows/Workflow-Test-Default.yml +++ b/.github/workflows/Workflow-Test-Default.yml @@ -25,9 +25,6 @@ jobs: secrets: inherit with: Name: PSModuleTest - Path: tests/srcTestRepo/src - ModulesOutputPath: tests/srcTestRepo/outputs/modules - DocsOutputPath: tests/srcTestRepo/outputs/docs + Path: tests/srcTestRepo TestProcess: true SkipTests: Module - Workspace: tests/srcTestRepo diff --git a/.github/workflows/Workflow-Test-WithManifest-CI.yml b/.github/workflows/Workflow-Test-WithManifest-CI.yml index 9ff8d8b1..06fa2780 100644 --- a/.github/workflows/Workflow-Test-WithManifest-CI.yml +++ b/.github/workflows/Workflow-Test-WithManifest-CI.yml @@ -23,8 +23,5 @@ jobs: secrets: inherit with: Name: PSModuleTest - Path: tests/srcWithManifestTestRepo/src - ModulesOutputPath: tests/srcWithManifestTestRepo/outputs/modules - DocsOutputPath: tests/srcWithManifestTestRepo/outputs/docs + Path: tests/srcWithManifestTestRepo SkipTests: Linux - Workspace: tests/srcWithManifestTestRepo diff --git a/.github/workflows/Workflow-Test-WithManifest.yml b/.github/workflows/Workflow-Test-WithManifest.yml index f7ae3718..39e1082b 100644 --- a/.github/workflows/Workflow-Test-WithManifest.yml +++ b/.github/workflows/Workflow-Test-WithManifest.yml @@ -25,9 +25,6 @@ jobs: secrets: inherit with: Name: PSModuleTest - Path: tests/srcWithManifestTestRepo/src - ModulesOutputPath: tests/srcWithManifestTestRepo/outputs/modules - DocsOutputPath: tests/srcWithManifestTestRepo/outputs/docs + Path: tests/srcWithManifestTestRepo TestProcess: true SkipTests: Linux - Workspace: tests/srcWithManifestTestRepo diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index bd1d1686..34525049 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -34,29 +34,9 @@ on: required: false Path: type: string - description: The path to the source code of the module. - required: false - default: src - Workspace: - type: string - description: The path to the workspace. + description: The path to the root of the repo. required: false default: ${{ github.workspace }} - ModulesOutputPath: - type: string - description: The path to the output directory for the modules. - required: false - default: outputs/modules - DocsOutputPath: - type: string - description: The path to the output directory for the documentation. - required: false - default: outputs/docs - SiteOutputPath: - type: string - description: The path to the output directory for the site. - required: false - default: outputs/site SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. @@ -67,11 +47,6 @@ on: description: Whether to test the process. required: false default: false - PublishDocs: - type: boolean - description: Whether to publish the documentation using MkDocs and GitHub Pages. - required: false - default: true Debug: type: boolean description: Enable debug output. @@ -130,7 +105,6 @@ jobs: with: Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -143,9 +117,6 @@ jobs: with: Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} - DocsOutputPath: ${{ inputs.DocsOutputPath }} - SiteOutputPath: ${{ inputs.SiteOutputPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -171,7 +142,6 @@ jobs: OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From 96933ada4a039efd6254e9a6741ed7cb1012ac45 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 12:24:32 +0100 Subject: [PATCH 033/324] =?UTF-8?q?=F0=9F=A9=B9=20[Update]:=20Modify=20inp?= =?UTF-8?q?ut=20defaults=20in=20Build-Module=20and=20Test-SourceCode=20wor?= =?UTF-8?q?kflows=20for=20improved=20clarity=20and=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Module.yml | 21 +++------------------ .github/workflows/Test-SourceCode.yml | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.github/workflows/Build-Module.yml b/.github/workflows/Build-Module.yml index 567eebec..066be907 100644 --- a/.github/workflows/Build-Module.yml +++ b/.github/workflows/Build-Module.yml @@ -11,17 +11,7 @@ on: type: string description: The path to the source code of the module. required: false - default: src - ModulesOutputPath: - type: string - description: The path to the output directory for the modules. - required: false - default: outputs/modules - ModuleArtifactName: - type: string - description: Name of the module artifact to upload. - required: false - default: module + default: ${{ github.workspace }} Debug: type: boolean description: Enable debug output. @@ -54,10 +44,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - name: Initialize environment uses: PSModule/Initialize-PSModule@v1 with: @@ -71,7 +57,6 @@ jobs: with: Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -80,7 +65,7 @@ jobs: - name: Upload module artifact uses: actions/upload-artifact@v4 with: - name: ${{ inputs.ModuleArtifactName }} - path: ${{ inputs.ModulesOutputPath }} + name: module + path: outputs/module if-no-files-found: error retention-days: 1 diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index f8a30849..6de781a1 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -17,9 +17,9 @@ on: required: false Path: type: string - description: The path to the source code of the module. + description: The path to the root of the repo. required: false - default: src + default: ${{ github.workspace }} SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. @@ -58,6 +58,14 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + - name: Test source code uses: PSModule/Test-PSModule@v3 with: @@ -76,6 +84,14 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + - name: Lint source code uses: PSModule/Invoke-ScriptAnalyzer@v2 with: @@ -83,5 +99,5 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - Path: ${{ inputs.Path }} + Path: ${{ inputs.Path }}/src Settings: SourceCode From c33b2527612703acbf713b7a30abbb5d198c1783 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 12:47:35 +0100 Subject: [PATCH 034/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nused=20artifact=20upload=20step=20and=20clean=20up=20parameter?= =?UTF-8?q?s=20in=20Build-Module=20and=20Test-Module=20workflows=20for=20i?= =?UTF-8?q?mproved=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Module.yml | 8 -------- .github/workflows/Test-Module.yml | 5 ----- 2 files changed, 13 deletions(-) diff --git a/.github/workflows/Build-Module.yml b/.github/workflows/Build-Module.yml index 066be907..73e3f482 100644 --- a/.github/workflows/Build-Module.yml +++ b/.github/workflows/Build-Module.yml @@ -61,11 +61,3 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - - - name: Upload module artifact - uses: actions/upload-artifact@v4 - with: - name: module - path: outputs/module - if-no-files-found: error - retention-days: 1 diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 8e0080cf..f8a2174e 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -42,11 +42,6 @@ on: description: The path to the source code of the module. required: false default: src - ModulesOutputPath: - type: string - description: The path to the output directory for the modules. - required: false - default: outputs/modules SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. From 1764828f03858094890856dd8d42e01962a0eacb Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 12:54:42 +0100 Subject: [PATCH 035/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20i?= =?UTF-8?q?nput=20parameter=20names=20and=20descriptions=20in=20Gather-Tes?= =?UTF-8?q?ts,=20Test-Module,=20and=20workflow=20files=20for=20improved=20?= =?UTF-8?q?clarity=20and=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 8 ++------ .github/workflows/Test-Module.yml | 8 ++++---- .github/workflows/workflow.yml | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 806c490c..2cbb18ec 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -3,9 +3,9 @@ name: Gather-Tests on: workflow_call: inputs: - Workspace: + Path: type: string - description: The path to the workspace. + description: The path to the root of the repo. required: false default: ${{ github.workspace }} Debug: @@ -40,10 +40,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - name: Gather-Tests shell: pwsh run: | diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index f8a2174e..68ef5fdf 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -39,9 +39,9 @@ on: required: false Path: type: string - description: The path to the source code of the module. + description: The path to the root of the repo. required: false - default: src + default: ${{ github.workspace }} SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. @@ -107,7 +107,7 @@ jobs: uses: actions/download-artifact@v4 with: name: module - path: ${{ inputs.ModulesOutputPath }} + path: outputs/module - name: Test built module id: test @@ -115,7 +115,7 @@ jobs: continue-on-error: true with: Name: ${{ inputs.Name }} - Path: ${{ inputs.ModulesOutputPath }} + Path: outputs/module TestType: Module Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 34525049..59eace98 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -154,7 +154,7 @@ jobs: - Build-Module uses: ./.github/workflows/Gather-Tests.yml with: - Workspace: ${{ inputs.Workspace }} + Path: ${{ inputs.Path }} # TestModuleStatus: # name: Test module status From 88426be7dab96c07803b694b9ae7280543cef45c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 13:51:11 +0100 Subject: [PATCH 036/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20Build-Docs=20workflow=20by=20removing=20unused=20input=20par?= =?UTF-8?q?ameters=20and=20updating=20paths=20for=20clarity=20and=20consis?= =?UTF-8?q?tency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 51 +++++++------------------------- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 0b038aea..865008a4 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -12,31 +12,6 @@ on: description: The path to the source code of the module. required: false default: src - ModulesOutputPath: - type: string - description: The path to the output directory for the modules. - required: false - default: outputs/modules - ModuleArtifactName: - type: string - description: Name of the module artifact to upload. - required: false - default: module - DocsOutputPath: - type: string - description: The path to the output directory for the documentation. - required: false - default: outputs/docs - DocsArtifactName: - type: string - description: Name of the docs artifact to upload. - required: false - default: docs - SiteOutputPath: - type: string - description: The path to the output directory for the site. - required: false - default: outputs/site Debug: type: boolean description: Enable debug output. @@ -71,10 +46,6 @@ jobs: with: fetch-depth: 0 - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - name: Initialize environment uses: PSModule/Initialize-PSModule@v1 with: @@ -86,16 +57,14 @@ jobs: - name: Download module artifact uses: actions/download-artifact@v4 with: - name: ${{ inputs.ModuleArtifactName }} - path: ${{ inputs.ModulesOutputPath }} + name: module + path: outputs/module - name: Document module uses: PSModule/Document-PSModule@v1 with: Name: ${{ inputs.Name }} Path: ${{ inputs.Path }} - ModulesOutputPath: ${{ inputs.ModulesOutputPath }} - DocsOutputPath: ${{ inputs.DocsOutputPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -104,8 +73,8 @@ jobs: - name: Upload docs artifact uses: actions/upload-artifact@v4 with: - name: ${{ inputs.DocsArtifactName }} - path: ${{ inputs.DocsOutputPath }} + name: docs + path: outputs/docs if-no-files-found: error retention-days: 1 @@ -130,7 +99,7 @@ jobs: - name: Lint documentation uses: super-linter/super-linter/slim@latest env: - FILTER_REGEX_INCLUDE: ${{ inputs.DocsOutputPath }} + FILTER_REGEX_INCLUDE: outputs/docs DEFAULT_BRANCH: main DEFAULT_WORKSPACE: ${{ github.workspace }} ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true @@ -161,11 +130,11 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Script: | - New-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "$env:GITHUB_WORKSPACE/${{ inputs.DocsOutputPath }}/*" -Destination "$env:GITHUB_WORKSPACE/${{ inputs.SiteOutputPath }}/docs/Functions" -Recurse -Force + New-Item -Path "$env:GITHUB_WORKSPACE/outputs/site/docs/Functions" -ItemType Directory -Force + Copy-Item -Path "$env:GITHUB_WORKSPACE/outputs/docs/*" -Destination "$env:GITHUB_WORKSPACE/outputs/site/docs/Functions" -Recurse -Force $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' - $SiteOutputPath = Join-Path $PWD -ChildPath '${{ inputs.SiteOutputPath }}' + $SiteOutputPath = Join-Path $PWD -ChildPath 'outputs/site' LogGroup "Get folder structure" { Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List @@ -220,7 +189,7 @@ jobs: Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - name: Build mkdocs-material project - working-directory: ${{ inputs.SiteOutputPath }} + working-directory: outputs/site shell: pwsh run: | LogGroup 'Build docs - mkdocs build - content' { @@ -228,7 +197,7 @@ jobs: } LogGroup 'Build docs - mkdocs build' { - mkdocs build --config-file mkdocs.yml --site-dir ${{ github.workspace }}/_site + mkdocs build --config-file mkdocs.yml --site-dir ${{ inputs.Path }}/_site } - uses: actions/upload-pages-artifact@v3 From 2dca71fe6a75fa874c54db73c69ecaf5881aa02b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 13:56:10 +0100 Subject: [PATCH 037/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20o?= =?UTF-8?q?utput=20paths=20in=20Build-Docs=20workflow=20to=20use=20input?= =?UTF-8?q?=20parameters=20for=20improved=20flexibility=20and=20consistenc?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 865008a4..33881510 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -58,7 +58,7 @@ jobs: uses: actions/download-artifact@v4 with: name: module - path: outputs/module + path: ${{ inputs.Path }}/outputs/module - name: Document module uses: PSModule/Document-PSModule@v1 @@ -74,7 +74,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: docs - path: outputs/docs + path: ${{ inputs.Path }}/outputs/docs if-no-files-found: error retention-days: 1 @@ -101,7 +101,7 @@ jobs: env: FILTER_REGEX_INCLUDE: outputs/docs DEFAULT_BRANCH: main - DEFAULT_WORKSPACE: ${{ github.workspace }} + DEFAULT_WORKSPACE: ${{ inputs.Path }} ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true GITHUB_TOKEN: ${{ github.token }} RUN_LOCAL: true From 1adb45ef0fa7e8a4b9c6966b0674e273d1984855 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 14:04:10 +0100 Subject: [PATCH 038/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?Gather-Tests=20workflow=20by=20adding=20output=20for=20test=20s?= =?UTF-8?q?uites=20and=20updating=20input=20parameters=20for=20improved=20?= =?UTF-8?q?clarity=20and=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 39 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 2cbb18ec..049406ef 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -28,6 +28,10 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + outputs: + TestSuites: + description: The test suites to run. + value: ${{ fromJson(jobs.Gather-Tests.outputs.TestSuites) }} permissions: contents: read # to checkout the repo @@ -36,24 +40,31 @@ jobs: Gather-Tests: name: Gather-Tests runs-on: ubuntu-latest + outputs: + TestSuites: ${{ steps.Gather-Tests.outputs.result }} steps: - name: Checkout Code uses: actions/checkout@v4 - name: Gather-Tests - shell: pwsh - run: | - $rootPath = Resolve-Path -Path '${{ inputs.Workspace }}' - $testsPath = Join-Path -Path $rootPath -ChildPath 'tests' - if (-not (Test-Path -Path $testsPath)) { - Write-Host "No tests found" - exit 0 - } + uses: PSModule/GitHub-Script@v1 + id: Gather-Tests + with: + ShowOutput: true + Script: | + $rootPath = Resolve-Path -Path '${{ inputs.Path }}' + $testsPath = Join-Path -Path $rootPath -ChildPath 'tests' + if (-not (Test-Path -Path $testsPath)) { + Write-Host "No tests found" + exit 0 + } - $testSuites = @() - $testSuites += Get-ChildItem -Path $testsPath -Directory - if (-not $testSuites) { - $testSuites += @($testsPath) - } + $testSuites = @() + $testSuites += Get-ChildItem -Path $testsPath -Directory + if (-not $testSuites) { + $testSuites += @($testsPath) + } - Write-Output $testSuites + Write-Output $testSuites + + Set-GitHubOutput -Name TestSuites -Value $testSuites From 91bf5f2cbdcde405e299f7cd8fbf0cd4a0034182 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 19:07:21 +0100 Subject: [PATCH 039/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Reinsta?= =?UTF-8?q?ll=20GitHub=20module=20in=20Build-Docs=20workflow=20for=20impro?= =?UTF-8?q?ved=20module=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 33881510..43e60c6a 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -122,6 +122,11 @@ jobs: pip install mkdocs-git-revision-date-localized-plugin pip install mkdocs-git-committers-plugin-2 + - name: Reinstall GitHub module + shell: pwsh + run: | + Install-PSResource -Name GitHub -TrustRepository -Reinstall + - name: Structure site uses: PSModule/GitHub-Script@v1 with: From e8cb4a2648de4faed26ce3fb2f0e97236a17f24d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 19:15:41 +0100 Subject: [PATCH 040/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20B?= =?UTF-8?q?uild-Docs=20workflow=20to=20use=20input=20parameters=20for=20ou?= =?UTF-8?q?tput=20paths,=20enhancing=20flexibility=20and=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 43e60c6a..d8e4a8dc 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -135,8 +135,8 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Script: | - New-Item -Path "$env:GITHUB_WORKSPACE/outputs/site/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "$env:GITHUB_WORKSPACE/outputs/docs/*" -Destination "$env:GITHUB_WORKSPACE/outputs/site/docs/Functions" -Recurse -Force + New-Item -Path "${{ inputs.Path }}/outputs/site/docs/Functions" -ItemType Directory -Force + Copy-Item -Path "${{ inputs.Path }}/outputs/docs/*" -Destination "${{ inputs.Path }}/outputs/site/docs/Functions" -Recurse -Force $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' $SiteOutputPath = Join-Path $PWD -ChildPath 'outputs/site' @@ -191,7 +191,7 @@ jobs: - name: Debug File system shell: pwsh run: | - Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse | Select-Object -ExpandProperty FullName | Sort-Object + Get-ChildItem -Path ${{ inputs.Path }} -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - name: Build mkdocs-material project working-directory: outputs/site From 1a59245e8638b6693ccaec0c284f532bc33a7287 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 19:23:35 +0100 Subject: [PATCH 041/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20B?= =?UTF-8?q?uild-Docs=20workflow=20to=20use=20variables=20for=20directory?= =?UTF-8?q?=20paths,=20improving=20clarity=20and=20maintainability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index d8e4a8dc..f36ae5ba 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -135,7 +135,7 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Script: | - New-Item -Path "${{ inputs.Path }}/outputs/site/docs/Functions" -ItemType Directory -Force + $functionDocsFolder = New-Item -Path "${{ inputs.Path }}/outputs/site/docs/Functions" -ItemType Directory -Force Copy-Item -Path "${{ inputs.Path }}/outputs/docs/*" -Destination "${{ inputs.Path }}/outputs/site/docs/Functions" -Recurse -Force $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' @@ -145,7 +145,6 @@ jobs: Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List } - $functionDocsFolder = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Functions' | Get-Item Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { $fileName = $_.Name LogGroup " - $fileName" { @@ -163,10 +162,10 @@ jobs: LogGroup 'Build docs - Copy icon to assets' { $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' - $null = New-Item -Path $assetsFolderPath -ItemType Directory -Force + $assetsFolder = New-Item -Path $assetsFolderPath -ItemType Directory -Force $rootPath = Split-Path -Path $ModuleSourcePath -Parent $iconPath = Join-Path -Path $rootPath -ChildPath 'icon\icon.png' - Copy-Item -Path $iconPath -Destination $assetsFolderPath -Force -Verbose + Copy-Item -Path $iconPath -Destination $assetsFolder -Force -Verbose } LogGroup 'Build docs - Copy readme.md' { @@ -194,7 +193,7 @@ jobs: Get-ChildItem -Path ${{ inputs.Path }} -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - name: Build mkdocs-material project - working-directory: outputs/site + working-directory: ${{ inputs.Path }}/outputs/site shell: pwsh run: | LogGroup 'Build docs - mkdocs build - content' { From e69630aa63611ec2139df5e19a2dec57b1bf7833 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 19:34:53 +0100 Subject: [PATCH 042/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Improve=20?= =?UTF-8?q?Gather-Tests=20workflow=20by=20enhancing=20test=20suite=20colle?= =?UTF-8?q?ction=20and=20output=20formatting=20for=20better=20clarity=20an?= =?UTF-8?q?d=20usability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 049406ef..3bc62a4b 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -60,11 +60,19 @@ jobs: } $testSuites = @() - $testSuites += Get-ChildItem -Path $testsPath -Directory + Get-ChildItem -Path $testsPath -Directory | ForEach-Object { + $filePath = $_.FullName + 'ubuntu-latest', 'macos-latest', 'windows-latest' | ForEach-Object { + $testSuites = @{ + RunsOn = $_ + FullName = $filePath + } + } + } if (-not $testSuites) { $testSuites += @($testsPath) } - Write-Output $testSuites + Write-Output ($testSuites | ConvertTo-Json -Depth 10) - Set-GitHubOutput -Name TestSuites -Value $testSuites + Set-GitHubOutput -Name TestSuites -Value ($testSuites | ConvertTo-Json -Depth 10) From d82ce5b29c33901dd5156038bfb4090b1f8a5ed3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 19:52:08 +0100 Subject: [PATCH 043/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?Build-Docs=20workflow=20by=20improving=20path=20resolution=20an?= =?UTF-8?q?d=20adding=20logging=20for=20better=20debugging=20and=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 36 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index f36ae5ba..19c31045 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -134,12 +134,20 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.Path }} Script: | - $functionDocsFolder = New-Item -Path "${{ inputs.Path }}/outputs/site/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "${{ inputs.Path }}/outputs/docs/*" -Destination "${{ inputs.Path }}/outputs/site/docs/Functions" -Recurse -Force - $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - $ModuleSourcePath = Join-Path $PWD -ChildPath '${{ inputs.Path }}' - $SiteOutputPath = Join-Path $PWD -ChildPath 'outputs/site' + LogGroup "Get folder structure" { + $functionDocsFolder = New-Item -Path "/outputs/site/docs/Functions" -ItemType Directory -Force + Copy-Item -Path "/outputs/docs/*" -Destination "/outputs/site/docs/Functions" -Recurse -Force + $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' + $ModuleSourcePath = Resolve-Path 'src' | Select-Object -ExpandProperty Path + $SiteOutputPath = Resolve-Path 'outputs/site' | Select-Object -ExpandProperty Path + + Write-Host "Function Docs Folder: $functionDocsFolder" + Write-Host "Module Name: $moduleName" + Write-Host "Module Source Path: $ModuleSourcePath" + Write-Host "Site Output Path: $SiteOutputPath" + } LogGroup "Get folder structure" { Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List @@ -158,21 +166,29 @@ jobs: $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | Rename-Item -NewName { $_.Name -replace '.txt', '.md' } + + Write-Host "About Docs Folder: $aboutDocsFolder" + Write-Host "About Source Folder: $aboutSourceFolder" } LogGroup 'Build docs - Copy icon to assets' { $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' $assetsFolder = New-Item -Path $assetsFolderPath -ItemType Directory -Force $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $iconPath = Join-Path -Path $rootPath -ChildPath 'icon\icon.png' + $iconPath = Resolve-Path 'icon\icon.png' | Select-Object -ExpandProperty Path Copy-Item -Path $iconPath -Destination $assetsFolder -Force -Verbose + + Write-Host "Assets Folder: $assetsFolder" + Write-Host "Icon Path: $iconPath" } LogGroup 'Build docs - Copy readme.md' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $readmePath = Join-Path -Path $rootPath -ChildPath 'README.md' + $readmePath = Resolve-Path 'README.md' | Select-Object -ExpandProperty Path $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose + + Write-Host "Readme Path: $readmePath" + Write-Host "Readme Target Path: $readmeTargetPath" } LogGroup 'Build docs - Create mkdocs.yml' { @@ -180,6 +196,10 @@ jobs: # This should be moved to an action so that we can use a default one, and not have to copy it from the repo. $mkdocsSourcePath = Join-Path -Path $rootPath -ChildPath 'mkdocs.yml' $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' + + Write-Host "Mkdocs Source Path: $mkdocsSourcePath" + Write-Host "Mkdocs Target Path: $mkdocsTargetPath" + $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) From 89d8b30052b58c28d9f76c60ef2403d54ca2623c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 19:57:45 +0100 Subject: [PATCH 044/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20B?= =?UTF-8?q?uild-Docs=20workflow=20to=20use=20relative=20paths=20for=20impr?= =?UTF-8?q?oved=20portability=20and=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 19c31045..692d8cae 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -137,8 +137,8 @@ jobs: WorkingDirectory: ${{ inputs.Path }} Script: | LogGroup "Get folder structure" { - $functionDocsFolder = New-Item -Path "/outputs/site/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "/outputs/docs/*" -Destination "/outputs/site/docs/Functions" -Recurse -Force + $functionDocsFolder = New-Item -Path "outputs/site/docs/Functions" -ItemType Directory -Force + Copy-Item -Path "outputs/docs/*" -Destination "outputs/site/docs/Functions" -Recurse -Force $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' $ModuleSourcePath = Resolve-Path 'src' | Select-Object -ExpandProperty Path $SiteOutputPath = Resolve-Path 'outputs/site' | Select-Object -ExpandProperty Path From 0d61aea96c00a0c7cac0484217fa248e463f8484 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 20:07:56 +0100 Subject: [PATCH 045/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20B?= =?UTF-8?q?uild-Docs=20workflow=20to=20include=20artifact=20upload=20confi?= =?UTF-8?q?guration=20and=20enhance=20Gather-Tests=20workflow=20for=20impr?= =?UTF-8?q?oved=20test=20suite=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 4 ++++ .github/workflows/Gather-Tests.yml | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 692d8cae..ba0ab0ec 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -225,3 +225,7 @@ jobs: } - uses: actions/upload-pages-artifact@v3 + with: + name: github-pages + path: ${{ inputs.Path }}/_site + retention-days: 1 diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 3bc62a4b..061757f8 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -62,16 +62,18 @@ jobs: $testSuites = @() Get-ChildItem -Path $testsPath -Directory | ForEach-Object { $filePath = $_.FullName - 'ubuntu-latest', 'macos-latest', 'windows-latest' | ForEach-Object { + } + if (-not $testSuites) { + $testSuites += @($testsPath) + } + + 'ubuntu-latest', 'macos-latest', 'windows-latest' | ForEach-Object { $testSuites = @{ RunsOn = $_ FullName = $filePath } } - } - if (-not $testSuites) { - $testSuites += @($testsPath) - } + Write-Output ($testSuites | ConvertTo-Json -Depth 10) From c16bf80590fc703279ba50c797943e5f0517fd77 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 20:14:30 +0100 Subject: [PATCH 046/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20B?= =?UTF-8?q?uild-Docs=20workflow=20to=20use=20relative=20paths=20for=20file?= =?UTF-8?q?=20system=20operations,=20enhancing=20portability=20and=20clari?= =?UTF-8?q?ty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index ba0ab0ec..5e11f526 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -210,7 +210,10 @@ jobs: - name: Debug File system shell: pwsh run: | - Get-ChildItem -Path ${{ inputs.Path }} -Recurse | Select-Object -ExpandProperty FullName | Sort-Object + $basePath = '${{ inputs.Path }}' + Get-ChildItem -Path $basePath -Recurse | ForEach-Object { + [System.IO.Path]::GetRelativePath($basePath, $_.FullName) + } | Sort-Object - name: Build mkdocs-material project working-directory: ${{ inputs.Path }}/outputs/site @@ -221,7 +224,7 @@ jobs: } LogGroup 'Build docs - mkdocs build' { - mkdocs build --config-file mkdocs.yml --site-dir ${{ inputs.Path }}/_site + mkdocs build --config-file mkdocs.yml --site-dir ../../_site } - uses: actions/upload-pages-artifact@v3 From 2c6fba2d868d80b62cf8c24c715fa39f9a86e197 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 20:25:46 +0100 Subject: [PATCH 047/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?Gather-Tests=20workflow=20by=20improving=20test=20suite=20colle?= =?UTF-8?q?ction=20and=20output=20formatting=20for=20better=20clarity=20an?= =?UTF-8?q?d=20usability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 35 ++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 061757f8..4b6304b3 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -51,30 +51,43 @@ jobs: id: Gather-Tests with: ShowOutput: true + WorkingDirectory: ${{ inputs.Path }} Script: | - $rootPath = Resolve-Path -Path '${{ inputs.Path }}' - $testsPath = Join-Path -Path $rootPath -ChildPath 'tests' + $shellsToTest = @('pwsh') + $OSsToTest = @('ubuntu-latest', 'macos-latest', 'windows-latest') + + $testsPath = Resolve-Path 'tests' | Select-Object -ExpandProperty Path if (-not (Test-Path -Path $testsPath)) { Write-Host "No tests found" exit 0 } $testSuites = @() - Get-ChildItem -Path $testsPath -Directory | ForEach-Object { - $filePath = $_.FullName - } + Get-ChildItem -Path $testsPath -Directory if (-not $testSuites) { $testSuites += @($testsPath) } - 'ubuntu-latest', 'macos-latest', 'windows-latest' | ForEach-Object { - $testSuites = @{ - RunsOn = $_ - FullName = $filePath + $tests = @() + $OSsToTest | ForEach-Object { + $os = $_ + $testSuites | ForEach-Object { + $testSuite = $_ + $shellsToTest | ForEach-Object { + $shell = $_ + $testPath = Resolve-Path -Path $testSuite | Select-Object -ExpandProperty Path + $test = @{} + $test += @{ + OS = $os + Path = $testPath + Shell = $shell + } + $tests += @($test) } } + } - Write-Output ($testSuites | ConvertTo-Json -Depth 10) + Write-Output ($tests | ConvertTo-Json -Depth 10) - Set-GitHubOutput -Name TestSuites -Value ($testSuites | ConvertTo-Json -Depth 10) + Set-GitHubOutput -Name Tests -Value ($tests | ConvertTo-Json -Depth 10 -Compress) From a89e3b929409a88080eaecf336b3d94b7e48bba1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 20:27:20 +0100 Subject: [PATCH 048/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Improve=20?= =?UTF-8?q?Gather-Tests=20workflow=20by=20enhancing=20test=20suite=20colle?= =?UTF-8?q?ction=20and=20ensuring=20proper=20path=20resolution=20for=20bet?= =?UTF-8?q?ter=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 4b6304b3..05872cd0 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -63,7 +63,9 @@ jobs: } $testSuites = @() - Get-ChildItem -Path $testsPath -Directory + Get-ChildItem -Path $testsPath -Directory | ForEach-Object { + $testSuites += $_.FullName + } if (-not $testSuites) { $testSuites += @($testsPath) } @@ -76,10 +78,9 @@ jobs: $shellsToTest | ForEach-Object { $shell = $_ $testPath = Resolve-Path -Path $testSuite | Select-Object -ExpandProperty Path - $test = @{} $test += @{ - OS = $os - Path = $testPath + OS = $os + Path = $testPath Shell = $shell } $tests += @($test) From 9abd0af0b618309b7a5c99dd70881333062a3cbc Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 20:34:59 +0100 Subject: [PATCH 049/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?Gather-Tests=20workflow=20by=20adding=20output=20for=20found=20?= =?UTF-8?q?test=20paths=20and=20improving=20test=20suite=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 05872cd0..bfea113f 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -62,6 +62,8 @@ jobs: exit 0 } + Write-Host "Tests found at [$testsPath]" + $testSuites = @() Get-ChildItem -Path $testsPath -Directory | ForEach-Object { $testSuites += $_.FullName @@ -70,7 +72,9 @@ jobs: $testSuites += @($testsPath) } - $tests = @() + $testSuites | Format-List + + $tests = [System.Collections.Generic.List[pscustomobject]]::new() $OSsToTest | ForEach-Object { $os = $_ $testSuites | ForEach-Object { @@ -78,12 +82,11 @@ jobs: $shellsToTest | ForEach-Object { $shell = $_ $testPath = Resolve-Path -Path $testSuite | Select-Object -ExpandProperty Path - $test += @{ + $tests.Add([pscustomobject]@{ OS = $os Path = $testPath Shell = $shell - } - $tests += @($test) + }) } } } From 3a79e73a9241a379634a9aea0af1189c44c783f4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 20:44:51 +0100 Subject: [PATCH 050/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?Gather-Tests=20workflow=20by=20adding=20output=20summary=20for?= =?UTF-8?q?=20improved=20visibility=20of=20test=20results?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index bfea113f..cf4ae835 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -95,3 +95,5 @@ jobs: Write-Output ($tests | ConvertTo-Json -Depth 10) Set-GitHubOutput -Name Tests -Value ($tests | ConvertTo-Json -Depth 10 -Compress) + Get-Content $env:GITHUB_OUTPUT + Set-GithubStepSummary -Summary (Get-Content $env:GITHUB_OUTPUT) From 04e5d17f8f98eb32e326dfce944226b65c977167 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 20:57:51 +0100 Subject: [PATCH 051/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20output=20handling=20in=20Gather-Tests=20workflow=20by=20remo?= =?UTF-8?q?ving=20unnecessary=20JSON=20conversion=20for=20test=20results?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index cf4ae835..9f149a42 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -94,6 +94,4 @@ jobs: Write-Output ($tests | ConvertTo-Json -Depth 10) - Set-GitHubOutput -Name Tests -Value ($tests | ConvertTo-Json -Depth 10 -Compress) - Get-Content $env:GITHUB_OUTPUT - Set-GithubStepSummary -Summary (Get-Content $env:GITHUB_OUTPUT) + Set-GitHubOutput -Name Tests -Value $tests From 652b997337a67ea31dc4d04234c613ff949e0ebf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 21:03:55 +0100 Subject: [PATCH 052/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Improve=20?= =?UTF-8?q?Gather-Tests=20workflow=20by=20updating=20output=20handling=20t?= =?UTF-8?q?o=20read=20from=20GITHUB=5FOUTPUT=20for=20enhanced=20test=20res?= =?UTF-8?q?ult=20visibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 9f149a42..2172b9f4 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -91,7 +91,9 @@ jobs: } } - Write-Output ($tests | ConvertTo-Json -Depth 10) Set-GitHubOutput -Name Tests -Value $tests + $output = Get-Content $env:GITHUB_OUTPUT -Raw + Write-Output $output + Set-GitHubOutput -Name Tests -Value $output From 76a764525df6f9a9958e9f810b43897302c02b6e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 21:05:31 +0100 Subject: [PATCH 053/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?Gather-Tests=20workflow=20by=20adding=20verbose=20and=20debug?= =?UTF-8?q?=20options=20to=20output=20handling=20for=20improved=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 2172b9f4..23c103d8 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -93,7 +93,7 @@ jobs: Write-Output ($tests | ConvertTo-Json -Depth 10) - Set-GitHubOutput -Name Tests -Value $tests + Set-GitHubOutput -Name Tests -Value $tests -Verbose -Debug -Confirm:$false $output = Get-Content $env:GITHUB_OUTPUT -Raw Write-Output $output - Set-GitHubOutput -Name Tests -Value $output + Set-GitHubStepSummary -Summary $output From 1e892d052cb74d1db0e75846a314a3b48ddc5a36 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Feb 2025 21:20:56 +0100 Subject: [PATCH 054/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20G?= =?UTF-8?q?ather-Tests=20workflow=20to=20compress=20JSON=20output=20and=20?= =?UTF-8?q?improve=20handling=20of=20GitHub=20output=20for=20enhanced=20cl?= =?UTF-8?q?arity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 23c103d8..f43d372d 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -91,9 +91,11 @@ jobs: } } - Write-Output ($tests | ConvertTo-Json -Depth 10) + $testsJson = $tests | ConvertTo-Json -Depth 10 -Compress - Set-GitHubOutput -Name Tests -Value $tests -Verbose -Debug -Confirm:$false + Write-Output $testsJson + + Set-GitHubOutput -Name Tests -Value $testsJson -Verbose -Debug -Confirm:$false $output = Get-Content $env:GITHUB_OUTPUT -Raw Write-Output $output Set-GitHubStepSummary -Summary $output From e2fae4b4b469892ee8c7c13237093a8be7657189 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 10:46:30 +0100 Subject: [PATCH 055/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20G?= =?UTF-8?q?ather-Tests=20workflow=20to=20use=20raw=20test=20results=20for?= =?UTF-8?q?=20GitHub=20output=20and=20adjust=20diagram=20layout=20for=20im?= =?UTF-8?q?proved=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 2 +- media/Flow.drawio | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index f43d372d..56460f22 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -95,7 +95,7 @@ jobs: Write-Output $testsJson - Set-GitHubOutput -Name Tests -Value $testsJson -Verbose -Debug -Confirm:$false + Set-GitHubOutput -Name Tests -Value $tests -Verbose -Debug -Confirm:$false $output = Get-Content $env:GITHUB_OUTPUT -Raw Write-Output $output Set-GitHubStepSummary -Summary $output diff --git a/media/Flow.drawio b/media/Flow.drawio index 8a74a5e2..29afd76c 100644 --- a/media/Flow.drawio +++ b/media/Flow.drawio @@ -1,6 +1,6 @@ - + @@ -20,7 +20,7 @@ - + @@ -58,7 +58,7 @@ - + @@ -67,10 +67,10 @@ - + - + @@ -119,7 +119,7 @@ - + From 0147c13947d55afa5ba2a64a360bed82eaea538b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 11:00:31 +0100 Subject: [PATCH 056/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20G?= =?UTF-8?q?ather-Tests=20workflow=20to=20simplify=20output=20handling=20by?= =?UTF-8?q?=20removing=20unnecessary=20JSON=20parsing=20for=20TestSuites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 56460f22..946e0062 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -31,7 +31,7 @@ on: outputs: TestSuites: description: The test suites to run. - value: ${{ fromJson(jobs.Gather-Tests.outputs.TestSuites) }} + value: ${{ jobs.Gather-Tests.outputs.TestSuites }} permissions: contents: read # to checkout the repo @@ -41,7 +41,7 @@ jobs: name: Gather-Tests runs-on: ubuntu-latest outputs: - TestSuites: ${{ steps.Gather-Tests.outputs.result }} + TestSuites: ${{ fromJson(steps.Gather-Tests.outputs.result).TestSuites }} steps: - name: Checkout Code uses: actions/checkout@v4 From 089378e58f471501887d826b26b396e39cc39eda Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 11:03:10 +0100 Subject: [PATCH 057/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Improve=20?= =?UTF-8?q?formatting=20in=20Gather-Tests=20workflow=20by=20adjusting=20ob?= =?UTF-8?q?ject=20creation=20for=20better=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 946e0062..51acad25 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -82,11 +82,13 @@ jobs: $shellsToTest | ForEach-Object { $shell = $_ $testPath = Resolve-Path -Path $testSuite | Select-Object -ExpandProperty Path - $tests.Add([pscustomobject]@{ - OS = $os - Path = $testPath - Shell = $shell - }) + $tests.Add( + [pscustomobject]@{ + OS = $os + Path = $testPath + Shell = $shell + } + ) } } } From 3656a9d3e26bb2b2712fb905e6f7d000d8673a37 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 11:21:08 +0100 Subject: [PATCH 058/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Add=20T?= =?UTF-8?q?estModuleLocal=20job=20to=20execute=20test=20suites=20based=20o?= =?UTF-8?q?n=20Gather-Tests=20results=20for=20improved=20testing=20workflo?= =?UTF-8?q?w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 59eace98..a01c5bb5 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -156,6 +156,20 @@ jobs: with: Path: ${{ inputs.Path }} + TestModuleLocal: + if: ${{ needs.Gather-Tests.result == 'success' && !cancelled() }} + needs: + - Gather-Tests + strategy: + matrix: ${{ fromJson(needs.Gather-Tests.outputs.TestSuites) }} + runs-on: ${{ matrix.OS }} + steps: + - name: Test + shell: pwsh + run: | + $suite = '${{ matrix.Path }}' + Write-Host "Running test suite: $suite" + # TestModuleStatus: # name: Test module status # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} From 7782f20366981c3e65fd86adf0e557e74823bd95 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 11:51:24 +0100 Subject: [PATCH 059/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20test=20suite=20preparation=20in=20Gather-Tests=20workflow=20?= =?UTF-8?q?by=20consolidating=20OS=20and=20Path=20assignments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 41 +++++++++++++++++------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 51acad25..11a4fbb4 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -74,24 +74,29 @@ jobs: $testSuites | Format-List - $tests = [System.Collections.Generic.List[pscustomobject]]::new() - $OSsToTest | ForEach-Object { - $os = $_ - $testSuites | ForEach-Object { - $testSuite = $_ - $shellsToTest | ForEach-Object { - $shell = $_ - $testPath = Resolve-Path -Path $testSuite | Select-Object -ExpandProperty Path - $tests.Add( - [pscustomobject]@{ - OS = $os - Path = $testPath - Shell = $shell - } - ) - } - } - } + $tests = @( + OS = $OSsToTest + Path = $testSuites + ) + + + # $OSsToTest | ForEach-Object { + # $os = $_ + # $testSuites | ForEach-Object { + # $testSuite = $_ + # $shellsToTest | ForEach-Object { + # $shell = $_ + # $testPath = Resolve-Path -Path $testSuite | Select-Object -ExpandProperty Path + # $tests.Add( + # [pscustomobject]@{ + # OS = $os + # Path = $testPath + # Shell = $shell + # } + # ) + # } + # } + # } $testsJson = $tests | ConvertTo-Json -Depth 10 -Compress From ba029510142935e80dc1b3089431dc871589eb82 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 11:54:43 +0100 Subject: [PATCH 060/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Add=20S?= =?UTF-8?q?tatus=20job=20to=20workflow=20for=20summarizing=20outcomes=20of?= =?UTF-8?q?=20TestModule=20and=20TestModuleLocal=20jobs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index a01c5bb5..fe565beb 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -170,6 +170,27 @@ jobs: $suite = '${{ matrix.Path }}' Write-Host "Running test suite: $suite" + Status: + name: Status + runs-on: ubuntu-latest + needs: + - TestModule + - TestModuleLocal + steps: + - name: Status + shell: pwsh + run: | + [pscustomobject]@{ + TestModule = @{ + Outcome = ${{ needs.TestModule.outcome }}" + Conclusion = ${{ needs.TestModule.conclusion }}" + } + TestModuleLocal = @{ + Outcome = ${{ needs.TestModuleLocal.outcome }}" + Conclusion = ${{ needs.TestModuleLocal.conclusion }}" + } + } + # TestModuleStatus: # name: Test module status # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} From 17de2d769012f630ecb8e004eff14fb6c7576f70 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 11:59:53 +0100 Subject: [PATCH 061/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Change=20t?= =?UTF-8?q?ests=20variable=20from=20array=20to=20hashtable=20for=20improve?= =?UTF-8?q?d=20data=20structure=20in=20Gather-Tests=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 11a4fbb4..3d5f00a3 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -74,10 +74,10 @@ jobs: $testSuites | Format-List - $tests = @( + $tests = @{ OS = $OSsToTest Path = $testSuites - ) + } # $OSsToTest | ForEach-Object { From 751c5bfd217a09d9790cc3271f6ae6889c070a33 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 17:04:27 +0100 Subject: [PATCH 062/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Parse=20TestSui?= =?UTF-8?q?tes=20output=20as=20JSON=20in=20Gather-Tests=20workflow=20for?= =?UTF-8?q?=20correct=20data=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 3d5f00a3..43c1e210 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -31,7 +31,7 @@ on: outputs: TestSuites: description: The test suites to run. - value: ${{ jobs.Gather-Tests.outputs.TestSuites }} + value: ${{ fromJson(jobs.Gather-Tests.outputs.TestSuites) }} permissions: contents: read # to checkout the repo From 2e67805c6cdb6c18c58ef59c38d01b7f826f11f1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 17:13:33 +0100 Subject: [PATCH 063/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20c?= =?UTF-8?q?onditional=20check=20for=20TestModuleLocal=20job=20execution=20?= =?UTF-8?q?in=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index fe565beb..84ad09a2 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -157,7 +157,6 @@ jobs: Path: ${{ inputs.Path }} TestModuleLocal: - if: ${{ needs.Gather-Tests.result == 'success' && !cancelled() }} needs: - Gather-Tests strategy: From 90726f4ab4cdd50b3b324a000283feb380d32bb1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 17:21:08 +0100 Subject: [PATCH 064/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20outcome=20retrieval=20for=20TestModule=20and=20TestModuleLoc?= =?UTF-8?q?al=20in=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 84ad09a2..80abaf88 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -180,14 +180,8 @@ jobs: shell: pwsh run: | [pscustomobject]@{ - TestModule = @{ - Outcome = ${{ needs.TestModule.outcome }}" - Conclusion = ${{ needs.TestModule.conclusion }}" - } - TestModuleLocal = @{ - Outcome = ${{ needs.TestModuleLocal.outcome }}" - Conclusion = ${{ needs.TestModuleLocal.conclusion }}" - } + TestModule = '${{ needs.TestModule.result }}' + TestModuleLocal = '${{ needs.TestModuleLocal.result }}' } # TestModuleStatus: From 4097deace854b9189bc777a218c50e8599d7465f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 17:30:09 +0100 Subject: [PATCH 065/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Correct=20outpu?= =?UTF-8?q?t=20value=20retrieval=20for=20TestSuites=20in=20Gather-Tests=20?= =?UTF-8?q?workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 43c1e210..3d5f00a3 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -31,7 +31,7 @@ on: outputs: TestSuites: description: The test suites to run. - value: ${{ fromJson(jobs.Gather-Tests.outputs.TestSuites) }} + value: ${{ jobs.Gather-Tests.outputs.TestSuites }} permissions: contents: read # to checkout the repo From 563fd27963ad0c720f057275052ae5fa73dc96d3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 17:54:54 +0100 Subject: [PATCH 066/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Update=20matrix?= =?UTF-8?q?=20retrieval=20for=20job=20dependencies=20in=20workflow=20to=20?= =?UTF-8?q?ensure=20correct=20execution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 80abaf88..e4e9b303 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -160,7 +160,7 @@ jobs: needs: - Gather-Tests strategy: - matrix: ${{ fromJson(needs.Gather-Tests.outputs.TestSuites) }} + matrix: ${{ needs.Gather-Tests.outputs.TestSuites }} runs-on: ${{ matrix.OS }} steps: - name: Test From ef14b1421fc932781e40f679f3d5a81108b50fc2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:01:33 +0100 Subject: [PATCH 067/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Convert=20TestS?= =?UTF-8?q?uites=20output=20to=20JSON=20format=20for=20matrix=20strategy?= =?UTF-8?q?=20in=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index e4e9b303..4a9f5ce7 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -160,7 +160,7 @@ jobs: needs: - Gather-Tests strategy: - matrix: ${{ needs.Gather-Tests.outputs.TestSuites }} + matrix: ${{ toJson(needs.Gather-Tests.outputs.TestSuites) }} runs-on: ${{ matrix.OS }} steps: - name: Test From 154cbd0b256a89a68227afbba56243ee3f8a54ea Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:07:07 +0100 Subject: [PATCH 068/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Comment=20?= =?UTF-8?q?out=20unused=20jobs=20in=20workflow=20to=20improve=20clarity=20?= =?UTF-8?q?and=20maintainability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 150 ++++++++++++++++----------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 4a9f5ce7..56250110 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -76,82 +76,82 @@ permissions: id-token: write # to verify the deployment originates from an appropriate source jobs: - TestSourceCode: - name: Test source code - strategy: - fail-fast: false - matrix: - include: - - OSName: Linux - RunsOn: ubuntu-latest - - OSName: macOS - RunsOn: macos-latest - - OSName: Windows - RunsOn: windows-latest - uses: ./.github/workflows/Test-SourceCode.yml - with: - RunsOn: ${{ matrix.RunsOn }} - OS: ${{ matrix.OSName }} - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - SkipTests: ${{ inputs.SkipTests }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - Build-Module: - uses: ./.github/workflows/Build-Module.yml - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - Build-Docs: - needs: - - Build-Module - uses: ./.github/workflows/Build-Docs.yml - with: - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - TestModule: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} - needs: - - Build-Module - strategy: - matrix: - include: - - OSName: Linux - RunsOn: ubuntu-latest - - OSName: macOS - RunsOn: macos-latest - - OSName: Windows - RunsOn: windows-latest - uses: ./.github/workflows/Test-Module.yml - secrets: inherit - with: - RunsOn: ${{ matrix.RunsOn }} - OS: ${{ matrix.OSName }} - Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} - SkipTests: ${{ inputs.SkipTests }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + # TestSourceCode: + # name: Test source code + # strategy: + # fail-fast: false + # matrix: + # include: + # - OSName: Linux + # RunsOn: ubuntu-latest + # - OSName: macOS + # RunsOn: macos-latest + # - OSName: Windows + # RunsOn: windows-latest + # uses: ./.github/workflows/Test-SourceCode.yml + # with: + # RunsOn: ${{ matrix.RunsOn }} + # OS: ${{ matrix.OSName }} + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.Path }} + # SkipTests: ${{ inputs.SkipTests }} + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # Build-Module: + # uses: ./.github/workflows/Build-Module.yml + # with: + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.Path }} + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # Build-Docs: + # needs: + # - Build-Module + # uses: ./.github/workflows/Build-Docs.yml + # with: + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.Path }} + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + # TestModule: + # if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + # needs: + # - Build-Module + # strategy: + # matrix: + # include: + # - OSName: Linux + # RunsOn: ubuntu-latest + # - OSName: macOS + # RunsOn: macos-latest + # - OSName: Windows + # RunsOn: windows-latest + # uses: ./.github/workflows/Test-Module.yml + # secrets: inherit + # with: + # RunsOn: ${{ matrix.RunsOn }} + # OS: ${{ matrix.OSName }} + # Name: ${{ inputs.Name }} + # Path: ${{ inputs.Path }} + # SkipTests: ${{ inputs.SkipTests }} + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} Gather-Tests: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} - needs: - - Build-Module + # if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + # needs: + # - Build-Module uses: ./.github/workflows/Gather-Tests.yml with: Path: ${{ inputs.Path }} @@ -173,7 +173,7 @@ jobs: name: Status runs-on: ubuntu-latest needs: - - TestModule + # - TestModule - TestModuleLocal steps: - name: Status From 39743b61fcfef51661f4279270eb549b1f9991d4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:09:41 +0100 Subject: [PATCH 069/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Clean=20up?= =?UTF-8?q?=20Gather-Tests=20workflow=20by=20removing=20commented-out=20co?= =?UTF-8?q?de=20and=20enhancing=20output=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 19 -------- .github/workflows/workflow.yml | 70 +++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 3d5f00a3..4f76b5f4 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -79,25 +79,6 @@ jobs: Path = $testSuites } - - # $OSsToTest | ForEach-Object { - # $os = $_ - # $testSuites | ForEach-Object { - # $testSuite = $_ - # $shellsToTest | ForEach-Object { - # $shell = $_ - # $testPath = Resolve-Path -Path $testSuite | Select-Object -ExpandProperty Path - # $tests.Add( - # [pscustomobject]@{ - # OS = $os - # Path = $testPath - # Shell = $shell - # } - # ) - # } - # } - # } - $testsJson = $tests | ConvertTo-Json -Depth 10 -Compress Write-Output $testsJson diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 56250110..9f51c13d 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -148,19 +148,75 @@ jobs: # Verbose: ${{ inputs.Verbose }} # Version: ${{ inputs.Version }} + # Gather-Tests: + # # if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + # # needs: + # # - Build-Module + # uses: ./.github/workflows/Gather-Tests.yml + # with: + # Path: ${{ inputs.Path }} + Gather-Tests: - # if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} - # needs: - # - Build-Module - uses: ./.github/workflows/Gather-Tests.yml - with: - Path: ${{ inputs.Path }} + name: Gather-Tests + runs-on: ubuntu-latest + outputs: + TestSuites: ${{ fromJson(steps.Gather-Tests.outputs.result).TestSuites }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Gather-Tests + uses: PSModule/GitHub-Script@v1 + id: Gather-Tests + with: + ShowOutput: true + WorkingDirectory: ${{ inputs.Path }} + Script: | + $shellsToTest = @('pwsh') + $OSsToTest = @('ubuntu-latest', 'macos-latest', 'windows-latest') + + $testsPath = Resolve-Path 'tests' | Select-Object -ExpandProperty Path + if (-not (Test-Path -Path $testsPath)) { + Write-Host "No tests found" + exit 0 + } + + Write-Host "Tests found at [$testsPath]" + + $testSuites = @() + Get-ChildItem -Path $testsPath -Directory | ForEach-Object { + $testSuites += $_.FullName + } + if (-not $testSuites) { + $testSuites += @($testsPath) + } + + $testSuites | Format-List + + $tests = @{ + OS = $OSsToTest + Path = $testSuites + } + + $testsJson = $tests | ConvertTo-Json -Depth 10 -Compress + + Write-Output $testsJson + + Set-GitHubOutput -Name Tests -Value $tests -Verbose -Debug -Confirm:$false + $output = Get-Content $env:GITHUB_OUTPUT -Raw + Write-Output $output + Set-GitHubStepSummary -Summary $output + + + + + TestModuleLocal: needs: - Gather-Tests strategy: - matrix: ${{ toJson(needs.Gather-Tests.outputs.TestSuites) }} + matrix: ${{ fromJson(needs.Gather-Tests.outputs.TestSuites) }} runs-on: ${{ matrix.OS }} steps: - name: Test From abcf83f81c7e66743a868ad4f73c474778821721 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:12:12 +0100 Subject: [PATCH 070/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Update=20output?= =?UTF-8?q?=20variable=20name=20from=20TestSuites=20to=20Tests=20in=20Gath?= =?UTF-8?q?er-Tests=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9f51c13d..feef82fb 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -160,7 +160,7 @@ jobs: name: Gather-Tests runs-on: ubuntu-latest outputs: - TestSuites: ${{ fromJson(steps.Gather-Tests.outputs.result).TestSuites }} + Tests: ${{ fromJson(steps.Gather-Tests.outputs.result).Tests }} steps: - name: Checkout Code uses: actions/checkout@v4 @@ -207,16 +207,11 @@ jobs: Write-Output $output Set-GitHubStepSummary -Summary $output - - - - - TestModuleLocal: needs: - Gather-Tests strategy: - matrix: ${{ fromJson(needs.Gather-Tests.outputs.TestSuites) }} + matrix: ${{ needs.Gather-Tests.outputs.Tests }} runs-on: ${{ matrix.OS }} steps: - name: Test From c549253bdfaf37724297af887be2e7589bcf362d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:14:38 +0100 Subject: [PATCH 071/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Parse=20Tests?= =?UTF-8?q?=20output=20as=20JSON=20for=20matrix=20strategy=20in=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index feef82fb..269ddd09 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -211,7 +211,7 @@ jobs: needs: - Gather-Tests strategy: - matrix: ${{ needs.Gather-Tests.outputs.Tests }} + matrix: ${{ fromJson(needs.Gather-Tests.outputs.Tests) }} runs-on: ${{ matrix.OS }} steps: - name: Test From bfffb1119f1d4f8d379a61fe58efcc839b971ddf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:23:16 +0100 Subject: [PATCH 072/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20G?= =?UTF-8?q?ather-Tests=20workflow=20to=20parse=20TestSuites=20output=20as?= =?UTF-8?q?=20JSON=20and=20enhance=20job=20definitions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 2 +- .github/workflows/workflow.yml | 209 +++++++++++------------------ 2 files changed, 80 insertions(+), 131 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 4f76b5f4..1de46ca9 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -31,7 +31,7 @@ on: outputs: TestSuites: description: The test suites to run. - value: ${{ jobs.Gather-Tests.outputs.TestSuites }} + value: ${{ fromJson(jobs.Gather-Tests.outputs.TestSuites) }} permissions: contents: read # to checkout the repo diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 269ddd09..b2a14a58 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -76,142 +76,91 @@ permissions: id-token: write # to verify the deployment originates from an appropriate source jobs: - # TestSourceCode: - # name: Test source code - # strategy: - # fail-fast: false - # matrix: - # include: - # - OSName: Linux - # RunsOn: ubuntu-latest - # - OSName: macOS - # RunsOn: macos-latest - # - OSName: Windows - # RunsOn: windows-latest - # uses: ./.github/workflows/Test-SourceCode.yml - # with: - # RunsOn: ${{ matrix.RunsOn }} - # OS: ${{ matrix.OSName }} - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.Path }} - # SkipTests: ${{ inputs.SkipTests }} - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # Build-Module: - # uses: ./.github/workflows/Build-Module.yml - # with: - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.Path }} - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # Build-Docs: - # needs: - # - Build-Module - # uses: ./.github/workflows/Build-Docs.yml - # with: - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.Path }} - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # TestModule: - # if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} - # needs: - # - Build-Module - # strategy: - # matrix: - # include: - # - OSName: Linux - # RunsOn: ubuntu-latest - # - OSName: macOS - # RunsOn: macos-latest - # - OSName: Windows - # RunsOn: windows-latest - # uses: ./.github/workflows/Test-Module.yml - # secrets: inherit - # with: - # RunsOn: ${{ matrix.RunsOn }} - # OS: ${{ matrix.OSName }} - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.Path }} - # SkipTests: ${{ inputs.SkipTests }} - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # Gather-Tests: - # # if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} - # # needs: - # # - Build-Module - # uses: ./.github/workflows/Gather-Tests.yml - # with: - # Path: ${{ inputs.Path }} + TestSourceCode: + name: Test source code + strategy: + fail-fast: false + matrix: + include: + - OSName: Linux + RunsOn: ubuntu-latest + - OSName: macOS + RunsOn: macos-latest + - OSName: Windows + RunsOn: windows-latest + uses: ./.github/workflows/Test-SourceCode.yml + with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + SkipTests: ${{ inputs.SkipTests }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + Build-Module: + uses: ./.github/workflows/Build-Module.yml + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + Build-Docs: + needs: + - Build-Module + uses: ./.github/workflows/Build-Docs.yml + with: + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + TestModule: + if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + needs: + - Build-Module + strategy: + matrix: + include: + - OSName: Linux + RunsOn: ubuntu-latest + - OSName: macOS + RunsOn: macos-latest + - OSName: Windows + RunsOn: windows-latest + uses: ./.github/workflows/Test-Module.yml + secrets: inherit + with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + SkipTests: ${{ inputs.SkipTests }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} Gather-Tests: - name: Gather-Tests - runs-on: ubuntu-latest - outputs: - Tests: ${{ fromJson(steps.Gather-Tests.outputs.result).Tests }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Gather-Tests - uses: PSModule/GitHub-Script@v1 - id: Gather-Tests - with: - ShowOutput: true - WorkingDirectory: ${{ inputs.Path }} - Script: | - $shellsToTest = @('pwsh') - $OSsToTest = @('ubuntu-latest', 'macos-latest', 'windows-latest') - - $testsPath = Resolve-Path 'tests' | Select-Object -ExpandProperty Path - if (-not (Test-Path -Path $testsPath)) { - Write-Host "No tests found" - exit 0 - } - - Write-Host "Tests found at [$testsPath]" - - $testSuites = @() - Get-ChildItem -Path $testsPath -Directory | ForEach-Object { - $testSuites += $_.FullName - } - if (-not $testSuites) { - $testSuites += @($testsPath) - } - - $testSuites | Format-List - - $tests = @{ - OS = $OSsToTest - Path = $testSuites - } - - $testsJson = $tests | ConvertTo-Json -Depth 10 -Compress - - Write-Output $testsJson - - Set-GitHubOutput -Name Tests -Value $tests -Verbose -Debug -Confirm:$false - $output = Get-Content $env:GITHUB_OUTPUT -Raw - Write-Output $output - Set-GitHubStepSummary -Summary $output + # if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + # needs: + # - Build-Module + uses: ./.github/workflows/Gather-Tests.yml + with: + Path: ${{ inputs.Path }} TestModuleLocal: needs: - Gather-Tests strategy: - matrix: ${{ fromJson(needs.Gather-Tests.outputs.Tests) }} + matrix: ${{ needs.Gather-Tests.outputs.Tests }} runs-on: ${{ matrix.OS }} steps: - name: Test @@ -224,7 +173,7 @@ jobs: name: Status runs-on: ubuntu-latest needs: - # - TestModule + - TestModule - TestModuleLocal steps: - name: Status From a42d3e3a2a534aeb70ded68a85bdb63e72cdb433 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:37:00 +0100 Subject: [PATCH 073/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20G?= =?UTF-8?q?ather-Tests=20workflow=20to=20use=20TestsPaths=20instead=20of?= =?UTF-8?q?=20TestSuites=20and=20clean=20up=20unused=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 23 ++++++++--------------- .github/workflows/workflow.yml | 3 --- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index 1de46ca9..c23dee54 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -64,26 +64,19 @@ jobs: Write-Host "Tests found at [$testsPath]" - $testSuites = @() + $testsPaths = @() Get-ChildItem -Path $testsPath -Directory | ForEach-Object { - $testSuites += $_.FullName + $testsPaths += $_.FullName } - if (-not $testSuites) { - $testSuites += @($testsPath) + if (-not $testsPaths) { + $testsPaths += @($testsPath) } - $testSuites | Format-List + $testsPaths | Format-List - $tests = @{ + $testSuites = @{ OS = $OSsToTest - Path = $testSuites + Path = $testsPaths } - $testsJson = $tests | ConvertTo-Json -Depth 10 -Compress - - Write-Output $testsJson - - Set-GitHubOutput -Name Tests -Value $tests -Verbose -Debug -Confirm:$false - $output = Get-Content $env:GITHUB_OUTPUT -Raw - Write-Output $output - Set-GitHubStepSummary -Summary $output + Set-GitHubOutput -Name TestSuites -Value $testSuites -Verbose -Debug -Confirm:$false diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index b2a14a58..d5efd2ed 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -149,9 +149,6 @@ jobs: Version: ${{ inputs.Version }} Gather-Tests: - # if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} - # needs: - # - Build-Module uses: ./.github/workflows/Gather-Tests.yml with: Path: ${{ inputs.Path }} From b1c6b923264e91749aff0ba7d14b6e378db0847a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:37:14 +0100 Subject: [PATCH 074/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20G?= =?UTF-8?q?ather-Tests=20job=20to=20Gather-TestSuites=20and=20update=20dep?= =?UTF-8?q?endencies=20in=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index d5efd2ed..b3b2ca5a 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -148,22 +148,25 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - Gather-Tests: + Gather-TestSuites: uses: ./.github/workflows/Gather-Tests.yml with: Path: ${{ inputs.Path }} TestModuleLocal: needs: - - Gather-Tests + - Gather-TestSuites strategy: - matrix: ${{ needs.Gather-Tests.outputs.Tests }} + matrix: ${{ needs.Gather-Tests.outputs.TestSuites }} runs-on: ${{ matrix.OS }} steps: - name: Test shell: pwsh run: | $suite = '${{ matrix.Path }}' + if ($IsLinux) { + throw "Linux is not supported" + } Write-Host "Running test suite: $suite" Status: From 4fc3b856ebb8546457b5eb8994eda9809623f0a1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:46:32 +0100 Subject: [PATCH 075/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Correct=20outpu?= =?UTF-8?q?t=20value=20reference=20for=20TestSuites=20in=20Gather-Tests=20?= =?UTF-8?q?workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Gather-Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Gather-Tests.yml index c23dee54..7c8f3493 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Gather-Tests.yml @@ -31,7 +31,7 @@ on: outputs: TestSuites: description: The test suites to run. - value: ${{ fromJson(jobs.Gather-Tests.outputs.TestSuites) }} + value: ${{ jobs.Gather-Tests.outputs.TestSuites }} permissions: contents: read # to checkout the repo From 9a56154fd375839406c61e0cb2757512b1570c2e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:47:21 +0100 Subject: [PATCH 076/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Correct=20refer?= =?UTF-8?q?ence=20to=20Gather-TestSuites=20output=20in=20workflow=20matrix?= =?UTF-8?q?=20strategy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index b3b2ca5a..3bd5d36d 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -157,7 +157,7 @@ jobs: needs: - Gather-TestSuites strategy: - matrix: ${{ needs.Gather-Tests.outputs.TestSuites }} + matrix: ${{ needs.Gather-TestSuites.outputs.TestSuites }} runs-on: ${{ matrix.OS }} steps: - name: Test From f3294b729330189a701e2f43b833cb6762b12c0c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:53:06 +0100 Subject: [PATCH 077/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20G?= =?UTF-8?q?ather-Tests=20workflow=20to=20Get-TestSuites=20and=20update=20j?= =?UTF-8?q?ob=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 38 ++++++++++++++++--- .../{Gather-Tests.yml => Get-TestSuites.yml} | 14 +++---- .github/workflows/workflow.yml | 8 ++-- 3 files changed, 44 insertions(+), 16 deletions(-) rename .github/workflows/{Gather-Tests.yml => Get-TestSuites.yml} (88%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 48e78d3f..b376f1dc 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -141,14 +141,42 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - Gather-Tests: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} - needs: - - Build-Module - uses: ./.github/workflows/Gather-Tests.yml + Get-TestSuites: + uses: ./.github/workflows/Get-TestSuites.yml with: Path: ${{ inputs.Path }} + TestModuleLocal: + needs: + - Get-TestSuites + strategy: + matrix: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} + runs-on: ${{ matrix.OS }} + steps: + - name: Test + shell: pwsh + run: | + $suite = '${{ matrix.Path }}' + if ($IsLinux) { + throw "Linux is not supported" + } + Write-Host "Running test suite: $suite" + + Status: + name: Status + runs-on: ubuntu-latest + needs: + - TestModule + - TestModuleLocal + steps: + - name: Status + shell: pwsh + run: | + [pscustomobject]@{ + TestModule = '${{ needs.TestModule.result }}' + TestModuleLocal = '${{ needs.TestModuleLocal.result }}' + } + # # This is necessary as there is no way to get output from a matrix job # TestModule-pwsh-ubuntu-latest: # name: Test module (pwsh, ubuntu-latest) diff --git a/.github/workflows/Gather-Tests.yml b/.github/workflows/Get-TestSuites.yml similarity index 88% rename from .github/workflows/Gather-Tests.yml rename to .github/workflows/Get-TestSuites.yml index 7c8f3493..75c7549a 100644 --- a/.github/workflows/Gather-Tests.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -1,4 +1,4 @@ -name: Gather-Tests +name: Get-TestSuites on: workflow_call: @@ -31,24 +31,24 @@ on: outputs: TestSuites: description: The test suites to run. - value: ${{ jobs.Gather-Tests.outputs.TestSuites }} + value: ${{ jobs.Get-TestSuites.outputs.TestSuites }} permissions: contents: read # to checkout the repo jobs: - Gather-Tests: - name: Gather-Tests + Get-TestSuites: + name: Get-TestSuites runs-on: ubuntu-latest outputs: - TestSuites: ${{ fromJson(steps.Gather-Tests.outputs.result).TestSuites }} + TestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).TestSuites }} steps: - name: Checkout Code uses: actions/checkout@v4 - - name: Gather-Tests + - name: Get-TestSuites uses: PSModule/GitHub-Script@v1 - id: Gather-Tests + id: Get-TestSuites with: ShowOutput: true WorkingDirectory: ${{ inputs.Path }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 3bd5d36d..bc68784a 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -148,16 +148,16 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - Gather-TestSuites: - uses: ./.github/workflows/Gather-Tests.yml + Get-TestSuites: + uses: ./.github/workflows/Get-TestSuites.yml with: Path: ${{ inputs.Path }} TestModuleLocal: needs: - - Gather-TestSuites + - Get-TestSuites strategy: - matrix: ${{ needs.Gather-TestSuites.outputs.TestSuites }} + matrix: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} runs-on: ${{ matrix.OS }} steps: - name: Test From f403d6e8b4767596cace22092ad2f2a80db968bd Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 18:55:14 +0100 Subject: [PATCH 078/324] =?UTF-8?q?=F0=9F=A9=B9=20[Fix]:=20Disable=20fail-?= =?UTF-8?q?fast=20in=20workflow=20matrix=20strategy=20for=20improved=20job?= =?UTF-8?q?=20execution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index bc68784a..ca75d87e 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -157,6 +157,7 @@ jobs: needs: - Get-TestSuites strategy: + fail-fast: false matrix: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} runs-on: ${{ matrix.OS }} steps: From 0b061de2232fe4e6cfea99b07c51f10a9d1a1658 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 19:08:27 +0100 Subject: [PATCH 079/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Update?= =?UTF-8?q?=20CI=20workflows=20to=20include=20detailed=20test=20outcomes?= =?UTF-8?q?=20and=20disable=20fail-fast=20for=20improved=20job=20reliabili?= =?UTF-8?q?ty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 11 +++++++++++ .github/workflows/Test-Module.yml | 4 ++-- .github/workflows/workflow.yml | 12 +++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b376f1dc..e5fdc5bd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -150,11 +150,16 @@ jobs: needs: - Get-TestSuites strategy: + fail-fast: false matrix: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} runs-on: ${{ matrix.OS }} + outputs: + Passed: ${{ steps.action-test.outcome }} steps: - name: Test shell: pwsh + id: action-test + continue-on-error: true run: | $suite = '${{ matrix.Path }}' if ($IsLinux) { @@ -162,6 +167,12 @@ jobs: } Write-Host "Running test suite: $suite" + - name: Status + shell: pwsh + run: | + Write-Host 'outcome: ${{ steps.action-test.outcome }}' + Write-Host 'conclusion: ${{ steps.action-test.conclusion }}' + Status: name: Status runs-on: ubuntu-latest diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 68ef5fdf..8252a606 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -86,7 +86,7 @@ jobs: if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} outputs: - passed: ${{ steps.test.outputs.passed }} + Passed: ${{ steps.action-test.outcome }} steps: - name: Checkout Code uses: actions/checkout@v4 @@ -125,7 +125,7 @@ jobs: - name: Status shell: pwsh run: | - Write-Host "Passed: [${{ steps.test.outputs.passed }}]" + Write-Host '${{ steps.action-test.outcome }}' - name: Failed test if: steps.test.outcome != 'success' diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index ca75d87e..f6429ac9 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -160,9 +160,13 @@ jobs: fail-fast: false matrix: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} runs-on: ${{ matrix.OS }} + outputs: + Passed: ${{ steps.action-test.outcome }} steps: - name: Test shell: pwsh + id: action-test + continue-on-error: true run: | $suite = '${{ matrix.Path }}' if ($IsLinux) { @@ -170,6 +174,12 @@ jobs: } Write-Host "Running test suite: $suite" + - name: Status + shell: pwsh + run: | + Write-Host 'outcome: ${{ steps.action-test.outcome }}' + Write-Host 'conclusion: ${{ steps.action-test.conclusion }}' + Status: name: Status runs-on: ubuntu-latest @@ -183,7 +193,7 @@ jobs: [pscustomobject]@{ TestModule = '${{ needs.TestModule.result }}' TestModuleLocal = '${{ needs.TestModuleLocal.result }}' - } + } # TestModuleStatus: # name: Test module status From e19152b9d34587ad3cb30ee47a4746291e33aa17 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 19:18:51 +0100 Subject: [PATCH 080/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Add=20j?= =?UTF-8?q?ob=20dependencies=20for=20Build-Module=20and=20TestSourceCode?= =?UTF-8?q?=20in=20CI=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e5fdc5bd..9d0358ca 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -149,6 +149,7 @@ jobs: TestModuleLocal: needs: - Get-TestSuites + - Build-Module strategy: fail-fast: false matrix: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} @@ -177,6 +178,7 @@ jobs: name: Status runs-on: ubuntu-latest needs: + - TestSourceCode - TestModule - TestModuleLocal steps: From d1c76a50282bb35e5ece9e66935a087f963a898c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 19:37:25 +0100 Subject: [PATCH 081/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20T?= =?UTF-8?q?est-SourceCode=20workflow=20to=20Test-Module=20and=20remove=20r?= =?UTF-8?q?edundant=20environment=20initialization=20steps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 29 +++++++++------------------ .github/workflows/Test-SourceCode.yml | 28 +++++++++++++------------- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 8252a606..70f3d2ae 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -1,4 +1,4 @@ -name: Test-SourceCode +name: Test-Module on: workflow_call: @@ -85,29 +85,25 @@ jobs: name: Test source code (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} - outputs: - Passed: ${{ steps.action-test.outcome }} steps: - name: Checkout Code uses: actions/checkout@v4 - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 + - name: Download module artifact + uses: actions/download-artifact@v4 + with: + name: module + path: outputs/module - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 + - name: Test source code + uses: PSModule/Test-PSModule@v3 with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - - - name: Download module artifact - uses: actions/download-artifact@v4 - with: - name: module - path: outputs/module + Path: ${{ inputs.Path }} + Settings: Module - name: Test built module id: test @@ -122,11 +118,6 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - - name: Status - shell: pwsh - run: | - Write-Host '${{ steps.action-test.outcome }}' - - name: Failed test if: steps.test.outcome != 'success' shell: pwsh diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 6de781a1..2ddf998c 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -58,13 +58,13 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} - name: Test source code uses: PSModule/Test-PSModule@v3 @@ -84,13 +84,13 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} - name: Lint source code uses: PSModule/Invoke-ScriptAnalyzer@v2 From e33341f2d74ec3d44771e054410451fd74250510 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 20:00:41 +0100 Subject: [PATCH 082/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Standardiz?= =?UTF-8?q?e=20job=20names=20in=20CI=20workflows=20for=20consistency=20and?= =?UTF-8?q?=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 23 +++-- .github/workflows/Get-TestSuites.yml | 60 +++++++++--- .github/workflows/Test-Module.yml | 28 +++--- .github/workflows/Test-ModuleLocal.yml | 121 +++++++++++++++++++++++++ .github/workflows/Test-SourceCode.yml | 12 +-- .github/workflows/workflow.yml | 23 +++-- 6 files changed, 214 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/Test-ModuleLocal.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9d0358ca..c8aa25d6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -69,8 +69,8 @@ permissions: statuses: write # to update the status of the workflow from linter jobs: - TestSourceCode: - name: Test source code + Test-SourceCode: + name: Test-SourceCode strategy: fail-fast: false matrix: @@ -115,8 +115,9 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - TestModule: + Test-Module: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + name: Test-Module needs: - Build-Module strategy: @@ -142,17 +143,21 @@ jobs: Version: ${{ inputs.Version }} Get-TestSuites: + name: Get-TestSuites uses: ./.github/workflows/Get-TestSuites.yml with: Path: ${{ inputs.Path }} - TestModuleLocal: + Test-ModuleLocal: + name: Test-ModuleLocal + if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} needs: - - Get-TestSuites - Build-Module + - Get-TestSuites strategy: fail-fast: false - matrix: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} + matrix: + include: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} runs-on: ${{ matrix.OS }} outputs: Passed: ${{ steps.action-test.outcome }} @@ -178,9 +183,9 @@ jobs: name: Status runs-on: ubuntu-latest needs: - - TestSourceCode - - TestModule - - TestModuleLocal + - Test-SourceCode + - Test-Module + - Test-ModuleLocal steps: - name: Status shell: pwsh diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 75c7549a..3e7369eb 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -53,30 +53,62 @@ jobs: ShowOutput: true WorkingDirectory: ${{ inputs.Path }} Script: | - $shellsToTest = @('pwsh') - $OSsToTest = @('ubuntu-latest', 'macos-latest', 'windows-latest') + # Define your test configurations + $testConfigs = @( + @{ + OS = 'ubuntu-latest' + Shells = 'pwsh' + Path = '' # to be filled later + }, + @{ + OS = 'macos-latest' + Shells = 'pwsh' + Path = '' + }, + @{ + OS = 'windows-latest' + Shells = 'pwsh' + Path = '' + }, + @{ + OS = 'windows-latest' + Shells = 'powershell' + Path = '' + } + ) + # Locate the tests directory $testsPath = Resolve-Path 'tests' | Select-Object -ExpandProperty Path if (-not (Test-Path -Path $testsPath)) { - Write-Host "No tests found" + Write-Host 'No tests found' exit 0 } - Write-Host "Tests found at [$testsPath]" - $testsPaths = @() - Get-ChildItem -Path $testsPath -Directory | ForEach-Object { - $testsPaths += $_.FullName - } + # Get all directories inside the tests folder. + $testsPaths = Get-ChildItem -Path $testsPath -Directory | ForEach-Object { $_.FullName } if (-not $testsPaths) { - $testsPaths += @($testsPath) + # If no subdirectories, use the tests folder itself. + $testsPaths = , $testsPath } - $testsPaths | Format-List - - $testSuites = @{ - OS = $OSsToTest - Path = $testsPaths + # Build the test suites matrix + $testSuites = @() + foreach ($folder in $testsPaths) { + foreach ($config in $testConfigs) { + # For each folder and config, produce a new object with the proper values. + $testSuite = @{ + OS = $config.OS + Shells = $config.Shells + Path = $folder + } + $testSuites += $testSuite + } } + # (Optional) Display the generated matrix in a table for verification. + $testSuites | Format-Table -AutoSize + + # Pass the final object to GitHub Actions output Set-GitHubOutput -Name TestSuites -Value $testSuites -Verbose -Debug -Confirm:$false + diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 70f3d2ae..c1623839 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -81,21 +81,30 @@ permissions: contents: read # to checkout the repo and create releases on the repo jobs: - Test-SourceCode: - name: Test source code (${{ inputs.RunsOn }}) + Test-Module: + name: Test-Module (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - name: Checkout Code uses: actions/checkout@v4 + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + - name: Download module artifact uses: actions/download-artifact@v4 with: name: module path: outputs/module - - name: Test source code + - name: Test-Module + id: test uses: PSModule/Test-PSModule@v3 with: Debug: ${{ inputs.Debug }} @@ -105,19 +114,6 @@ jobs: Path: ${{ inputs.Path }} Settings: Module - - name: Test built module - id: test - uses: PSModule/Test-PSModule@v2 - continue-on-error: true - with: - Name: ${{ inputs.Name }} - Path: outputs/module - TestType: Module - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - - name: Failed test if: steps.test.outcome != 'success' shell: pwsh diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml new file mode 100644 index 00000000..a9e1365b --- /dev/null +++ b/.github/workflows/Test-ModuleLocal.yml @@ -0,0 +1,121 @@ +name: Test-ModuleLocal + +on: + workflow_call: + secrets: + TEST_APP_ENT_CLIENT_ID: + description: The client ID of an Enterprise GitHub App for running tests. + required: false + TEST_APP_ENT_PRIVATE_KEY: + description: The private key of an Enterprise GitHub App for running tests. + required: false + TEST_APP_ORG_CLIENT_ID: + description: The client ID of an Organization GitHub App for running tests. + required: false + TEST_APP_ORG_PRIVATE_KEY: + description: The private key of an Organization GitHub App for running tests. + required: false + TEST_USER_ORG_FG_PAT: + description: The fine-grained personal access token with org access for running tests. + required: false + TEST_USER_USER_FG_PAT: + description: The fine-grained personal access token with user account access for running tests. + required: false + TEST_USER_PAT: + description: The classic personal access token for running tests. + required: false + inputs: + RunsOn: + type: string + description: The type of runner to use for the job. + required: true + OS: + type: string + description: The operating system name. + required: true + Name: + type: string + description: The name of the module to process. Scripts default to the repository name if nothing is specified. + required: false + Path: + type: string + description: The path to the root of the repo. + required: false + default: ${{ github.workspace }} + SkipTests: + type: string + description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. + required: false + default: None + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + +env: + TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} + TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} + TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }} + TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }} + TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} + TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} + TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} + +permissions: + contents: read # to checkout the repo and create releases on the repo + +jobs: + Test-ModuleLocal: + name: Test-ModuleLocal (${{ inputs.RunsOn }}) + if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} + runs-on: ${{ inputs.RunsOn }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + + - name: Download module artifact + uses: actions/download-artifact@v4 + with: + name: module + path: outputs/module + + - name: Test-ModuleLocal + uses: PSModule/Invoke-Pester@v3 + id: test + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + TestResult_TestSuiteName: ${{ inputs.Settings }}-${{ runner.os }} + Path: + Run_Path: ${{ inputs.Path }}/module/output + + - name: Failed test + if: steps.test.outcome != 'success' + shell: pwsh + run: Write-Host "Complete successfully" diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 2ddf998c..b956ec05 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -50,8 +50,8 @@ permissions: contents: read # to checkout the repo and create releases on the repo jobs: - Test-PSModule-SourceCode: - name: Test source code (${{ inputs.RunsOn }}) + Test-SourceCode: + name: Test-SourceCode (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: @@ -66,7 +66,7 @@ jobs: # Verbose: ${{ inputs.Verbose }} # Version: ${{ inputs.Version }} - - name: Test source code + - name: Test-SourceCode uses: PSModule/Test-PSModule@v3 with: Debug: ${{ inputs.Debug }} @@ -76,8 +76,8 @@ jobs: Path: ${{ inputs.Path }} Settings: SourceCode - Invoke-ScriptAnalyzer-SourceCode: - name: Lint source code (${{ inputs.RunsOn }}) + Lint-SourceCode: + name: Lint-SourceCode (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: @@ -92,7 +92,7 @@ jobs: # Verbose: ${{ inputs.Verbose }} # Version: ${{ inputs.Version }} - - name: Lint source code + - name: Lint-SourceCode uses: PSModule/Invoke-ScriptAnalyzer@v2 with: Debug: ${{ inputs.Debug }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index f6429ac9..33408d42 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -76,8 +76,8 @@ permissions: id-token: write # to verify the deployment originates from an appropriate source jobs: - TestSourceCode: - name: Test source code + Test-SourceCode: + name: Test-SourceCode strategy: fail-fast: false matrix: @@ -122,8 +122,9 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - TestModule: + Test-Module: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + name: Test-Module needs: - Build-Module strategy: @@ -149,16 +150,21 @@ jobs: Version: ${{ inputs.Version }} Get-TestSuites: + name: Get-TestSuites uses: ./.github/workflows/Get-TestSuites.yml with: Path: ${{ inputs.Path }} - TestModuleLocal: + Test-ModuleLocal: + name: Test-ModuleLocal + if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} needs: + - Build-Module - Get-TestSuites strategy: fail-fast: false - matrix: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} + matrix: + include: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} runs-on: ${{ matrix.OS }} outputs: Passed: ${{ steps.action-test.outcome }} @@ -184,8 +190,9 @@ jobs: name: Status runs-on: ubuntu-latest needs: - - TestModule - - TestModuleLocal + - Test-SourceCode + - Test-Module + - Test-ModuleLocal steps: - name: Status shell: pwsh @@ -193,7 +200,7 @@ jobs: [pscustomobject]@{ TestModule = '${{ needs.TestModule.result }}' TestModuleLocal = '${{ needs.TestModuleLocal.result }}' - } + } # TestModuleStatus: # name: Test module status From c5f335b194b8a10f1713b1c4256ccc1be11fe781 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 20:09:54 +0100 Subject: [PATCH 083/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Pass=20?= =?UTF-8?q?job=20name=20as=20input=20to=20Test-Module=20and=20ensure=20fai?= =?UTF-8?q?l-fast=20is=20disabled=20in=20workflow=20strategy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 1 + .github/workflows/workflow.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index c1623839..f02b2af3 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -107,6 +107,7 @@ jobs: id: test uses: PSModule/Test-PSModule@v3 with: + Name: ${{ inputs.Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 33408d42..c3900875 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -128,6 +128,7 @@ jobs: needs: - Build-Module strategy: + fail-fast: false matrix: include: - OSName: Linux From 26b954d9cdc5d3fe21385172189e6bceadcd0100 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 20:16:16 +0100 Subject: [PATCH 084/324] =?UTF-8?q?=F0=9F=A9=B9=20[Enhancement]:=20Add=20a?= =?UTF-8?q?=20new=20Test=20job=20to=20list=20all=20files=20recursively=20i?= =?UTF-8?q?n=20the=20Test-Module=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index f02b2af3..9b783a42 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -103,6 +103,11 @@ jobs: name: module path: outputs/module + - name: Test + shell: pwsh + run: | + Get-ChildItem . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object + - name: Test-Module id: test uses: PSModule/Test-PSModule@v3 From f1259fca18f59fe7e6d66eea0a2fe7c0f4923a2c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 20:39:07 +0100 Subject: [PATCH 085/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20p?= =?UTF-8?q?aths=20in=20Test-ModuleLocal=20workflow=20to=20use=20dynamic=20?= =?UTF-8?q?input=20for=20output=20directories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index a9e1365b..1c5ed662 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -101,7 +101,7 @@ jobs: uses: actions/download-artifact@v4 with: name: module - path: outputs/module + path: ${{ inputs.Path }}/outputs/module - name: Test-ModuleLocal uses: PSModule/Invoke-Pester@v3 @@ -113,7 +113,7 @@ jobs: Version: ${{ inputs.Version }} TestResult_TestSuiteName: ${{ inputs.Settings }}-${{ runner.os }} Path: - Run_Path: ${{ inputs.Path }}/module/output + Run_Path: ${{ inputs.Path }}/outputs/module - name: Failed test if: steps.test.outcome != 'success' From 38e545b54ab2c843b4731fd01d7932d62f522846 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 20:46:59 +0100 Subject: [PATCH 086/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20o?= =?UTF-8?q?utput=20path=20in=20Test-Module=20workflow=20to=20use=20dynamic?= =?UTF-8?q?=20input?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 9b783a42..8b2d7844 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -101,7 +101,7 @@ jobs: uses: actions/download-artifact@v4 with: name: module - path: outputs/module + path: ${{ inputs.Path }}/outputs/module - name: Test shell: pwsh From 524cc4a0703f765a1c14f6017b87861a0f6871cf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 21:06:15 +0100 Subject: [PATCH 087/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Comment=20?= =?UTF-8?q?out=20environment=20initialization=20steps=20in=20multiple=20wo?= =?UTF-8?q?rkflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 14 +++++++------- .github/workflows/Build-Module.yml | 14 +++++++------- .github/workflows/CI.yml | 1 + .github/workflows/Test-Module.yml | 8 -------- .github/workflows/Test-ModuleLocal.yml | 8 -------- 5 files changed, 15 insertions(+), 30 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 5e11f526..2afcb25d 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -46,13 +46,13 @@ jobs: with: fetch-depth: 0 - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} - name: Download module artifact uses: actions/download-artifact@v4 diff --git a/.github/workflows/Build-Module.yml b/.github/workflows/Build-Module.yml index 73e3f482..5d3fe3e5 100644 --- a/.github/workflows/Build-Module.yml +++ b/.github/workflows/Build-Module.yml @@ -44,13 +44,13 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + # - name: Initialize environment + # uses: PSModule/Initialize-PSModule@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} - name: Build module uses: PSModule/Build-PSModule@v4 diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c8aa25d6..73c646d1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -121,6 +121,7 @@ jobs: needs: - Build-Module strategy: + fail-fast: false matrix: include: - OSName: Linux diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 8b2d7844..5f23af12 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -89,14 +89,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - name: Download module artifact uses: actions/download-artifact@v4 with: diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 1c5ed662..a181618a 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -89,14 +89,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - name: Download module artifact uses: actions/download-artifact@v4 with: From db28785a8f69b9ef4499ce5d75d6f291a577bb36 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 21:16:18 +0100 Subject: [PATCH 088/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Disable=20?= =?UTF-8?q?fail-fast=20strategy=20in=20CI=20workflows=20and=20clean=20up?= =?UTF-8?q?=20commented=20code=20in=20Test=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 1 + .github/workflows/Test-Module.yml | 13 ------------- .github/workflows/Test-ModuleLocal.yml | 8 -------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c8aa25d6..73c646d1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -121,6 +121,7 @@ jobs: needs: - Build-Module strategy: + fail-fast: false matrix: include: - OSName: Linux diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 8b2d7844..e0393211 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -89,25 +89,12 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - name: Download module artifact uses: actions/download-artifact@v4 with: name: module path: ${{ inputs.Path }}/outputs/module - - name: Test - shell: pwsh - run: | - Get-ChildItem . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - - name: Test-Module id: test uses: PSModule/Test-PSModule@v3 diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 1c5ed662..a181618a 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -89,14 +89,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - name: Download module artifact uses: actions/download-artifact@v4 with: From 705cdae92bda163c692950a69819f048cdb9d86f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 21:16:43 +0100 Subject: [PATCH 089/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Uncomment?= =?UTF-8?q?=20environment=20initialization=20steps=20in=20Build-Module=20w?= =?UTF-8?q?orkflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Module.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Build-Module.yml b/.github/workflows/Build-Module.yml index 5d3fe3e5..73e3f482 100644 --- a/.github/workflows/Build-Module.yml +++ b/.github/workflows/Build-Module.yml @@ -44,13 +44,13 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} - name: Build module uses: PSModule/Build-PSModule@v4 From bc57e19418c2d605688280f9f68dc0dc927f88f2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 21:20:23 +0100 Subject: [PATCH 090/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Uncomment?= =?UTF-8?q?=20environment=20initialization=20steps=20in=20Build-Docs=20wor?= =?UTF-8?q?kflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 2afcb25d..5e11f526 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -46,13 +46,13 @@ jobs: with: fetch-depth: 0 - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} - name: Download module artifact uses: actions/download-artifact@v4 From 6c638bd109991792fa16f37723c728bac2f9cc47 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 22:51:35 +0100 Subject: [PATCH 091/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20test=20configuration=20and=20improve=20workflow=20readabilit?= =?UTF-8?q?y=20in=20Get-TestSuites=20and=20Test-ModuleLocal=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 61 +++++++++----------------- .github/workflows/Test-ModuleLocal.yml | 17 ++++++- .github/workflows/workflow.yml | 34 ++++++-------- 3 files changed, 49 insertions(+), 63 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 3e7369eb..1acd5840 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -53,62 +53,41 @@ jobs: ShowOutput: true WorkingDirectory: ${{ inputs.Path }} Script: | - # Define your test configurations - $testConfigs = @( - @{ - OS = 'ubuntu-latest' - Shells = 'pwsh' - Path = '' # to be filled later - }, - @{ - OS = 'macos-latest' - Shells = 'pwsh' - Path = '' - }, - @{ - OS = 'windows-latest' - Shells = 'pwsh' - Path = '' - }, - @{ - OS = 'windows-latest' - Shells = 'powershell' - Path = '' - } + # Define test configurations as an array of hashtables. + $osConfigs = @( + @{ runson = 'ubuntu-latest'; name = 'Linux' } + @{ runson = 'macos-latest'; name = 'macOS' } + @{ runson = 'windows-latest'; name = 'Windows' } ) - # Locate the tests directory - $testsPath = Resolve-Path 'tests' | Select-Object -ExpandProperty Path - if (-not (Test-Path -Path $testsPath)) { + # Locate the tests directory. + $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path + if (-not $testsPath -or -not (Test-Path -Path $testsPath)) { Write-Host 'No tests found' exit 0 } Write-Host "Tests found at [$testsPath]" - # Get all directories inside the tests folder. + # Get all subdirectories inside the tests folder; if none, use the tests folder itself. $testsPaths = Get-ChildItem -Path $testsPath -Directory | ForEach-Object { $_.FullName } if (-not $testsPaths) { - # If no subdirectories, use the tests folder itself. - $testsPaths = , $testsPath + $testsPaths = @($testsPath) } - # Build the test suites matrix - $testSuites = @() - foreach ($folder in $testsPaths) { - foreach ($config in $testConfigs) { - # For each folder and config, produce a new object with the proper values. - $testSuite = @{ - OS = $config.OS - Shells = $config.Shells - Path = $folder + # Build the test suites matrix. + $testSuites = foreach ($folder in $testsPaths) { + foreach ($osConfig in $osConfigs) { + [pscustomobject]@{ + RunsOn = $osConfig.runson + OSName = $osConfig.name + TestFolderPath = $folder + TestName = Split-Path -Path $folder -Leaf } - $testSuites += $testSuite } } # (Optional) Display the generated matrix in a table for verification. $testSuites | Format-Table -AutoSize - # Pass the final object to GitHub Actions output - Set-GitHubOutput -Name TestSuites -Value $testSuites -Verbose -Debug -Confirm:$false - + # Pass the final object to GitHub Actions output. + Set-GitHubOutput -Name TestSuites -Value $testSuites diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index a181618a..48e6ef89 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -37,6 +37,16 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false + TestFolderPath: + type: string + description: The path to the tests folder. + required: false + default: tests + TestName: + type: string + description: The path to the tests folder. + required: false + default: tests Path: type: string description: The path to the root of the repo. @@ -103,8 +113,11 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - TestResult_TestSuiteName: ${{ inputs.Settings }}-${{ runner.os }} - Path: + TestResult_TestSuiteName: ${{ inputs.TestName }}-${{ runner.os }} + TestResult_Enabled: true + CodeCoverage_Enabled: true + CodeCoverage_OutputFormat: JaCoCo + Path: ${{ inputs.TestFolderPath }} Run_Path: ${{ inputs.Path }}/outputs/module - name: Failed test diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index c3900875..ecfb4201 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -166,26 +166,20 @@ jobs: fail-fast: false matrix: include: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} - runs-on: ${{ matrix.OS }} - outputs: - Passed: ${{ steps.action-test.outcome }} - steps: - - name: Test - shell: pwsh - id: action-test - continue-on-error: true - run: | - $suite = '${{ matrix.Path }}' - if ($IsLinux) { - throw "Linux is not supported" - } - Write-Host "Running test suite: $suite" - - - name: Status - shell: pwsh - run: | - Write-Host 'outcome: ${{ steps.action-test.outcome }}' - Write-Host 'conclusion: ${{ steps.action-test.conclusion }}' + uses: ./.github/workflows/Test-ModuleLocal.yml + secrets: inherit + with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} + Name: ${{ inputs.Name }} + Path: ${{ inputs.Path }} + SkipTests: ${{ inputs.SkipTests }} + TestFolderPath: ${{ matrix.TestFolderPath }} + TestName: ${{ matrix.TestName }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} Status: name: Status From f621936e9e8c904a740327e24ad73e1100f17268 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 22:52:15 +0100 Subject: [PATCH 092/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20j?= =?UTF-8?q?ob=20names=20in=20Test=20workflows=20to=20use=20dynamic=20input?= =?UTF-8?q?=20variables=20for=20improved=20flexibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 +- .github/workflows/workflow.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 48e6ef89..dda4bff4 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -92,7 +92,7 @@ permissions: jobs: Test-ModuleLocal: - name: Test-ModuleLocal (${{ inputs.RunsOn }}) + name: ${{ inputs.RunsOn }} if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index ecfb4201..fb30e82a 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -157,7 +157,7 @@ jobs: Path: ${{ inputs.Path }} Test-ModuleLocal: - name: Test-ModuleLocal + name: ${{ matrix.TestName }} if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} needs: - Build-Module From 2ff24b2367b4afbb325a2c81fcbbdd2f512005bc Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Feb 2025 23:13:08 +0100 Subject: [PATCH 093/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20j?= =?UTF-8?q?ob=20names=20in=20Test-ModuleLocal=20workflow=20to=20include=20?= =?UTF-8?q?OS=20for=20better=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index dda4bff4..1e4e288b 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -92,7 +92,7 @@ permissions: jobs: Test-ModuleLocal: - name: ${{ inputs.RunsOn }} + name: ${{ inputs.TestName }}-${{ inputs.OS }} if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: @@ -113,7 +113,7 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - TestResult_TestSuiteName: ${{ inputs.TestName }}-${{ runner.os }} + TestResult_TestSuiteName: ${{ inputs.TestName }}-${{ inputs.OS }} TestResult_Enabled: true CodeCoverage_Enabled: true CodeCoverage_OutputFormat: JaCoCo From 39ba4584b2d7cae5653baec0ec1b3b29d15744a1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 27 Feb 2025 10:38:23 +0100 Subject: [PATCH 094/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20Lint?= =?UTF-8?q?-SourceCode=20job=20to=20Test=20workflows=20and=20include=20deb?= =?UTF-8?q?ug=20step=20in=20Test-ModuleLocal=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 31 ++++++++++++++++++++++++++ .github/workflows/Test-ModuleLocal.yml | 5 +++++ .github/workflows/Test-SourceCode.yml | 16 ------------- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index e0393211..4eb37d5d 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -111,3 +111,34 @@ jobs: if: steps.test.outcome != 'success' shell: pwsh run: Write-Host "Complete successfully" + + + Lint-SourceCode: + name: Lint-SourceCode (${{ inputs.RunsOn }}) + if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} + runs-on: ${{ inputs.RunsOn }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Download module artifact + uses: actions/download-artifact@v4 + with: + name: module + path: ${{ inputs.Path }}/outputs/module + + - name: Lint-SourceCode + uses: PSModule/Invoke-ScriptAnalyzer@v2 + id: lint + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + Path: ${{ inputs.Path }} + Settings: Module + + - name: Failed test + if: steps.lint.outcome != 'success' + shell: pwsh + run: Write-Host "Complete successfully" diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 1e4e288b..da215980 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -105,6 +105,11 @@ jobs: name: module path: ${{ inputs.Path }}/outputs/module + - name: Debug + shell: pwsh + run: | + Get-ChildItem . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object + - name: Test-ModuleLocal uses: PSModule/Invoke-Pester@v3 id: test diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index b956ec05..7dea4a57 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -58,14 +58,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - name: Test-SourceCode uses: PSModule/Test-PSModule@v3 with: @@ -84,14 +76,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - name: Lint-SourceCode uses: PSModule/Invoke-ScriptAnalyzer@v2 with: From 22fff4a2367243b93106d442f0571f19540276b0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 27 Feb 2025 10:57:03 +0100 Subject: [PATCH 095/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Use=20GetR?= =?UTF-8?q?elativePath=20for=20TestFolderPath=20to=20improve=20path=20hand?= =?UTF-8?q?ling=20in=20Get-TestSuites=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 1acd5840..43b49e0b 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -80,7 +80,7 @@ jobs: [pscustomobject]@{ RunsOn = $osConfig.runson OSName = $osConfig.name - TestFolderPath = $folder + TestFolderPath = [System.IO.Path]::GetRelativePath($PWD.Path, $folder) TestName = Split-Path -Path $folder -Leaf } } From 41ef8a9b845c11dc06194d44a50e3350564a652c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 27 Feb 2025 11:01:29 +0100 Subject: [PATCH 096/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Replace=20?= =?UTF-8?q?GetRelativePath=20with=20Resolve-Path=20for=20improved=20path?= =?UTF-8?q?=20resolution=20in=20Get-TestSuites=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 43b49e0b..7a6429c1 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -80,7 +80,7 @@ jobs: [pscustomobject]@{ RunsOn = $osConfig.runson OSName = $osConfig.name - TestFolderPath = [System.IO.Path]::GetRelativePath($PWD.Path, $folder) + TestFolderPath = Resolve-Path -Path $folder -Relative TestName = Split-Path -Path $folder -Leaf } } From 754a89de51b615d9a53d14db6e829597ff233d48 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 27 Feb 2025 11:02:27 +0100 Subject: [PATCH 097/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20P?= =?UTF-8?q?ath=20construction=20in=20Test-ModuleLocal=20workflow=20to=20in?= =?UTF-8?q?clude=20base=20Path=20for=20improved=20directory=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index da215980..736d9394 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -122,7 +122,7 @@ jobs: TestResult_Enabled: true CodeCoverage_Enabled: true CodeCoverage_OutputFormat: JaCoCo - Path: ${{ inputs.TestFolderPath }} + Path: ${{ inputs.Path }}/${{ inputs.TestFolderPath }} Run_Path: ${{ inputs.Path }}/outputs/module - name: Failed test From bb81184b4f797d8e83e9c2487db7bf65cb2bd058 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 28 Feb 2025 22:20:57 +0100 Subject: [PATCH 098/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20'?= =?UTF-8?q?Path'=20to=20'WorkingDirectory'=20in=20workflow=20files=20for?= =?UTF-8?q?=20improved=20clarity=20and=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 27 ++++++++++--------- .github/workflows/Build-Module.yml | 13 ++++----- .github/workflows/CI.yml | 20 +++++++------- .github/workflows/Get-TestSuites.yml | 13 ++++----- .github/workflows/Test-Module.yml | 18 ++++++------- .github/workflows/Test-ModuleLocal.yml | 18 +++++++------ .github/workflows/Test-SourceCode.yml | 15 ++++++----- .../workflows/Workflow-Test-Default-CI.yml | 2 +- .github/workflows/Workflow-Test-Default.yml | 2 +- .../Workflow-Test-WithManifest-CI.yml | 2 +- .../workflows/Workflow-Test-WithManifest.yml | 2 +- .github/workflows/workflow.yml | 2 +- 12 files changed, 70 insertions(+), 64 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 5e11f526..3f9e8573 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -7,11 +7,11 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - Path: + WorkingDirectory: type: string - description: The path to the source code of the module. + description: The working directory where the script will run from. required: false - default: src + default: ${{ github.workspace }} Debug: type: boolean description: Enable debug output. @@ -53,28 +53,29 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Download module artifact uses: actions/download-artifact@v4 with: name: module - path: ${{ inputs.Path }}/outputs/module + path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Document module uses: PSModule/Document-PSModule@v1 with: Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Upload docs artifact uses: actions/upload-artifact@v4 with: name: docs - path: ${{ inputs.Path }}/outputs/docs + path: ${{ inputs.WorkingDirectory }}/outputs/docs if-no-files-found: error retention-days: 1 @@ -101,7 +102,7 @@ jobs: env: FILTER_REGEX_INCLUDE: outputs/docs DEFAULT_BRANCH: main - DEFAULT_WORKSPACE: ${{ inputs.Path }} + DEFAULT_WORKSPACE: ${{ inputs.WorkingDirectory }} ENABLE_GITHUB_ACTIONS_GROUP_TITLE: true GITHUB_TOKEN: ${{ github.token }} RUN_LOCAL: true @@ -134,7 +135,7 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.Path }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Script: | LogGroup "Get folder structure" { $functionDocsFolder = New-Item -Path "outputs/site/docs/Functions" -ItemType Directory -Force @@ -209,14 +210,14 @@ jobs: - name: Debug File system shell: pwsh + working-directory: $${{ inputs.WorkingDirectory }} run: | - $basePath = '${{ inputs.Path }}' - Get-ChildItem -Path $basePath -Recurse | ForEach-Object { - [System.IO.Path]::GetRelativePath($basePath, $_.FullName) + Get-ChildItem -Path . -Recurse | ForEach-Object { + [System.IO.Path]::GetRelativePath(., $_.FullName) } | Sort-Object - name: Build mkdocs-material project - working-directory: ${{ inputs.Path }}/outputs/site + working-directory: ${{ inputs.WorkingDirectory }}/outputs/site shell: pwsh run: | LogGroup 'Build docs - mkdocs build - content' { @@ -230,5 +231,5 @@ jobs: - uses: actions/upload-pages-artifact@v3 with: name: github-pages - path: ${{ inputs.Path }}/_site + path: ${{ inputs.WorkingDirectory }}/_site retention-days: 1 diff --git a/.github/workflows/Build-Module.yml b/.github/workflows/Build-Module.yml index 73e3f482..7e5ae5a8 100644 --- a/.github/workflows/Build-Module.yml +++ b/.github/workflows/Build-Module.yml @@ -7,11 +7,6 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - Path: - type: string - description: The path to the source code of the module. - required: false - default: ${{ github.workspace }} Debug: type: boolean description: Enable debug output. @@ -32,6 +27,11 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} permissions: contents: read # to checkout the repository @@ -51,13 +51,14 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Build module uses: PSModule/Build-PSModule@v4 with: Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 73c646d1..e6619f81 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -32,11 +32,6 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - Path: - type: string - description: The path to the root of the repo. - required: false - default: ${{ github.workspace }} SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. @@ -62,6 +57,11 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} permissions: contents: read # to checkout the repository @@ -86,22 +86,22 @@ jobs: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Build-Module: uses: ./.github/workflows/Build-Module.yml with: Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Build-Docs: needs: @@ -109,11 +109,11 @@ jobs: uses: ./.github/workflows/Build-Docs.yml with: Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-Module: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} @@ -136,18 +136,18 @@ jobs: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestSuites: name: Get-TestSuites uses: ./.github/workflows/Get-TestSuites.yml with: - Path: ${{ inputs.Path }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-ModuleLocal: name: Test-ModuleLocal diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 7a6429c1..2e1c4d26 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -3,11 +3,6 @@ name: Get-TestSuites on: workflow_call: inputs: - Path: - type: string - description: The path to the root of the repo. - required: false - default: ${{ github.workspace }} Debug: type: boolean description: Enable debug output. @@ -28,6 +23,12 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} + outputs: TestSuites: description: The test suites to run. @@ -51,7 +52,7 @@ jobs: id: Get-TestSuites with: ShowOutput: true - WorkingDirectory: ${{ inputs.Path }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Script: | # Define test configurations as an array of hashtables. $osConfigs = @( diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 4eb37d5d..1a62a022 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -37,11 +37,6 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - Path: - type: string - description: The path to the root of the repo. - required: false - default: ${{ github.workspace }} SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. @@ -67,6 +62,11 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} env: TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} @@ -93,7 +93,7 @@ jobs: uses: actions/download-artifact@v4 with: name: module - path: ${{ inputs.Path }}/outputs/module + path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Test-Module id: test @@ -104,7 +104,7 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - Path: ${{ inputs.Path }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Settings: Module - name: Failed test @@ -125,7 +125,7 @@ jobs: uses: actions/download-artifact@v4 with: name: module - path: ${{ inputs.Path }}/outputs/module + path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Lint-SourceCode uses: PSModule/Invoke-ScriptAnalyzer@v2 @@ -135,7 +135,7 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - Path: ${{ inputs.Path }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Settings: Module - name: Failed test diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 736d9394..fc73896f 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -47,11 +47,6 @@ on: description: The path to the tests folder. required: false default: tests - Path: - type: string - description: The path to the root of the repo. - required: false - default: ${{ github.workspace }} SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. @@ -77,6 +72,11 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} env: TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} @@ -103,10 +103,11 @@ jobs: uses: actions/download-artifact@v4 with: name: module - path: ${{ inputs.Path }}/outputs/module + path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Debug shell: pwsh + working-directory: ${{ inputs.WorkingDirectory }} run: | Get-ChildItem . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object @@ -122,8 +123,9 @@ jobs: TestResult_Enabled: true CodeCoverage_Enabled: true CodeCoverage_OutputFormat: JaCoCo - Path: ${{ inputs.Path }}/${{ inputs.TestFolderPath }} - Run_Path: ${{ inputs.Path }}/outputs/module + Path: ${{ inputs.TestFolderPath }} + Run_Path: outputs/module + WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Failed test if: steps.test.outcome != 'success' diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 7dea4a57..4946f8e3 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -15,11 +15,6 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - Path: - type: string - description: The path to the root of the repo. - required: false - default: ${{ github.workspace }} SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. @@ -45,6 +40,11 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} permissions: contents: read # to checkout the repo and create releases on the repo @@ -65,7 +65,7 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - Path: ${{ inputs.Path }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Settings: SourceCode Lint-SourceCode: @@ -83,5 +83,6 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - Path: ${{ inputs.Path }}/src + Path: src Settings: SourceCode + WorkingDirectory: ${{ inputs.WorkingDirectory }} diff --git a/.github/workflows/Workflow-Test-Default-CI.yml b/.github/workflows/Workflow-Test-Default-CI.yml index 8db335cd..3ef99f04 100644 --- a/.github/workflows/Workflow-Test-Default-CI.yml +++ b/.github/workflows/Workflow-Test-Default-CI.yml @@ -23,5 +23,5 @@ jobs: secrets: inherit with: Name: PSModuleTest - Path: tests/srcTestRepo + WorkingDirectory: tests/srcTestRepo SkipTests: Module diff --git a/.github/workflows/Workflow-Test-Default.yml b/.github/workflows/Workflow-Test-Default.yml index feefca89..2fcf36a6 100644 --- a/.github/workflows/Workflow-Test-Default.yml +++ b/.github/workflows/Workflow-Test-Default.yml @@ -25,6 +25,6 @@ jobs: secrets: inherit with: Name: PSModuleTest - Path: tests/srcTestRepo + WorkingDirectory: tests/srcTestRepo TestProcess: true SkipTests: Module diff --git a/.github/workflows/Workflow-Test-WithManifest-CI.yml b/.github/workflows/Workflow-Test-WithManifest-CI.yml index 06fa2780..3c9194b8 100644 --- a/.github/workflows/Workflow-Test-WithManifest-CI.yml +++ b/.github/workflows/Workflow-Test-WithManifest-CI.yml @@ -23,5 +23,5 @@ jobs: secrets: inherit with: Name: PSModuleTest - Path: tests/srcWithManifestTestRepo + WorkingDirectory: tests/srcWithManifestTestRepo SkipTests: Linux diff --git a/.github/workflows/Workflow-Test-WithManifest.yml b/.github/workflows/Workflow-Test-WithManifest.yml index 39e1082b..bf8ed601 100644 --- a/.github/workflows/Workflow-Test-WithManifest.yml +++ b/.github/workflows/Workflow-Test-WithManifest.yml @@ -25,6 +25,6 @@ jobs: secrets: inherit with: Name: PSModuleTest - Path: tests/srcWithManifestTestRepo + WorkingDirectory: tests/srcWithManifestTestRepo TestProcess: true SkipTests: Linux diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index fb30e82a..e88e7923 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -32,7 +32,7 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - Path: + WorkingDirectory: type: string description: The path to the root of the repo. required: false From e3d2257d8d0631fa9a3584242d73084026aa3752 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 1 Mar 2025 11:00:12 +0100 Subject: [PATCH 099/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20p?= =?UTF-8?q?ath=20construction=20in=20CI=20and=20workflow=20files=20to=20us?= =?UTF-8?q?e=20forward=20slashes=20for=20improved=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 2 +- .github/workflows/workflow.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e6619f81..c53a2f37 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -438,7 +438,7 @@ jobs: # LogGroup 'Data' { # $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}\$moduleName" + # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}/$moduleName" # $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" # $data = [pscustomobject]@{ diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index e88e7923..09837307 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -280,7 +280,7 @@ jobs: # LogGroup 'Data' { # $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}\$moduleName" + # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}/$moduleName" # $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" # # Obay module manifest overrides From 6d6fb858623760fd2beba61e0c5826804b2cc1e3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 1 Mar 2025 17:57:50 +0100 Subject: [PATCH 100/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20Work?= =?UTF-8?q?ingDirectory=20input=20to=20workflows=20for=20improved=20direct?= =?UTF-8?q?ory=20handling=20and=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 12 +- .github/workflows/CI.yml | 214 +++++---------------------- .github/workflows/Get-TestSuites.yml | 4 + .github/workflows/workflow.yml | 16 +- 4 files changed, 53 insertions(+), 193 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 3f9e8573..84742e04 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -7,11 +7,6 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - WorkingDirectory: - type: string - description: The working directory where the script will run from. - required: false - default: ${{ github.workspace }} Debug: type: boolean description: Enable debug output. @@ -32,6 +27,11 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} permissions: contents: read # to checkout the repo @@ -210,7 +210,7 @@ jobs: - name: Debug File system shell: pwsh - working-directory: $${{ inputs.WorkingDirectory }} + working-directory: ${{ inputs.WorkingDirectory }} run: | Get-ChildItem -Path . -Recurse | ForEach-Object { [System.IO.Path]::GetRelativePath(., $_.FullName) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c53a2f37..e0f433dd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -147,10 +147,14 @@ jobs: name: Get-TestSuites uses: ./.github/workflows/Get-TestSuites.yml with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-ModuleLocal: - name: Test-ModuleLocal + name: ${{ matrix.TestName }} if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} needs: - Build-Module @@ -159,26 +163,20 @@ jobs: fail-fast: false matrix: include: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} - runs-on: ${{ matrix.OS }} - outputs: - Passed: ${{ steps.action-test.outcome }} - steps: - - name: Test - shell: pwsh - id: action-test - continue-on-error: true - run: | - $suite = '${{ matrix.Path }}' - if ($IsLinux) { - throw "Linux is not supported" - } - Write-Host "Running test suite: $suite" - - - name: Status - shell: pwsh - run: | - Write-Host 'outcome: ${{ steps.action-test.outcome }}' - Write-Host 'conclusion: ${{ steps.action-test.conclusion }}' + uses: ./.github/workflows/Test-ModuleLocal.yml + secrets: inherit + with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} + Name: ${{ inputs.Name }} + SkipTests: ${{ inputs.SkipTests }} + TestFolderPath: ${{ matrix.TestFolderPath }} + TestName: ${{ matrix.TestName }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Status: name: Status @@ -196,165 +194,6 @@ jobs: TestModuleLocal = '${{ needs.TestModuleLocal.result }}' } - # # This is necessary as there is no way to get output from a matrix job - # TestModule-pwsh-ubuntu-latest: - # name: Test module (pwsh, ubuntu-latest) - # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Linux')) && !cancelled() }} - # needs: Build-Module - # runs-on: ubuntu-latest - # outputs: - # passed: ${{ steps.test.outputs.passed }} - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - # with: - # fetch-depth: 0 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Test built module - # id: test - # uses: PSModule/Test-PSModule@v2 - # continue-on-error: true - # with: - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.ModulesOutputPath }} - # TestType: Module - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Status - # shell: pwsh - # run: | - # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - # - name: Failed test - # if: steps.test.outcome != 'success' - # shell: pwsh - # run: Write-Host "Complete successfully" - - # TestModule-pwsh-macos-latest: - # name: Test module (pwsh, macos-latest) - # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'macOS')) && !cancelled() }} - # needs: Build-Module - # runs-on: macos-latest - # outputs: - # passed: ${{ steps.test.outputs.passed }} - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Test built module - # id: test - # uses: PSModule/Test-PSModule@v2 - # continue-on-error: true - # with: - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.ModulesOutputPath }} - # TestType: Module - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Status - # shell: pwsh - # run: | - # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - # - name: Failed test - # if: steps.test.outcome != 'success' - # shell: pwsh - # run: Write-Host "Complete successfully" - - # TestModule-pwsh-windows-latest: - # name: Test module (pwsh, windows-latest) - # if: ${{ needs.Build-Module.result == 'success' && !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, 'Windows')) && !cancelled() }} - # needs: Build-Module - # runs-on: windows-latest - # outputs: - # passed: ${{ steps.test.outputs.passed }} - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Test built module - # id: test - # uses: PSModule/Test-PSModule@v2 - # continue-on-error: true - # with: - # Name: ${{ inputs.Name }} - # Path: ${{ inputs.ModulesOutputPath }} - # TestType: Module - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Status - # shell: pwsh - # run: | - # Write-Host "Passed: [${{ steps.test.outputs.passed }}]" - - # - name: Failed test - # if: steps.test.outcome != 'success' - # shell: pwsh - # run: Write-Host "Complete successfully" - # TestModuleStatus: # name: Test module status # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} @@ -441,6 +280,13 @@ jobs: # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}/$moduleName" # $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" + # # Obay module manifest overrides + # $sourcePath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.Path }}" + # $sourceModuleManifestPath = Join-Path -Path $sourcePath -ChildPath "manifest.psd1" + # if (Test-Path -Path $sourceModuleManifestPath) { + # $sourceManifest = Import-PowerShellDataFile -Path $sourceModuleManifestPath + # } + # $data = [pscustomobject]@{ # ModuleName = $moduleName # Path = $path @@ -448,7 +294,9 @@ jobs: # } # Write-Verbose ($data | Format-List | Out-String) -Verbose - # Set-ModuleManifest -Path $moduleManifestPath -PowerShellVersion '7.4' + # # If the source module manifest has a PowerShellVersion, use that, otherwise use the latest version. + # $powerShellVersion = $sourceManifest.PowerShellVersion ?? '7.4' + # Set-ModuleManifest -Path $moduleManifestPath -PowerShellVersion $powerShellVersion # Add-ModuleManifestData -Path $moduleManifestPath -CompatiblePSEditions 'Core' # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'PSEdition_Core' @@ -466,6 +314,10 @@ jobs: # } # } + # LogGroup 'Module Manifest - Source' { + # Show-FileContent -Path $moduleManifestPath + # } + # LogGroup 'Module Manifest' { # Show-FileContent -Path $moduleManifestPath # } diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 2e1c4d26..3ba50a3d 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -52,6 +52,10 @@ jobs: id: Get-TestSuites with: ShowOutput: true + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} Script: | # Define test configurations as an array of hashtables. diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 09837307..1c2a124c 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -93,22 +93,22 @@ jobs: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Build-Module: uses: ./.github/workflows/Build-Module.yml with: Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Build-Docs: needs: @@ -116,11 +116,11 @@ jobs: uses: ./.github/workflows/Build-Docs.yml with: Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-Module: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} @@ -143,18 +143,22 @@ jobs: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestSuites: name: Get-TestSuites uses: ./.github/workflows/Get-TestSuites.yml with: - Path: ${{ inputs.Path }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-ModuleLocal: name: ${{ matrix.TestName }} @@ -172,7 +176,6 @@ jobs: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - Path: ${{ inputs.Path }} SkipTests: ${{ inputs.SkipTests }} TestFolderPath: ${{ matrix.TestFolderPath }} TestName: ${{ matrix.TestName }} @@ -180,6 +183,7 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} Status: name: Status From 1a1451106e69852b74d3f5372432d2003e665aaf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 1 Mar 2025 18:14:00 +0100 Subject: [PATCH 101/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20G?= =?UTF-8?q?etRelativePath=20usage=20in=20Build-Docs=20workflow=20for=20imp?= =?UTF-8?q?roved=20path=20resolution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 84742e04..d214ae03 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -213,7 +213,7 @@ jobs: working-directory: ${{ inputs.WorkingDirectory }} run: | Get-ChildItem -Path . -Recurse | ForEach-Object { - [System.IO.Path]::GetRelativePath(., $_.FullName) + [System.IO.Path]::GetRelativePath($PSScriptRoot, $_.FullName) } | Sort-Object - name: Build mkdocs-material project From 583f6c7228d209509dfb09cd068ed6a1c286db51 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 12:35:48 +0100 Subject: [PATCH 102/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Correct=20?= =?UTF-8?q?TestModule=20and=20TestModuleLocal=20result=20references=20in?= =?UTF-8?q?=20CI=20workflow=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e0f433dd..411638d8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -190,8 +190,8 @@ jobs: shell: pwsh run: | [pscustomobject]@{ - TestModule = '${{ needs.TestModule.result }}' - TestModuleLocal = '${{ needs.TestModuleLocal.result }}' + TestModule = '${{ needs.Test-Module.result }}' + TestModuleLocal = '${{ needs.Test-ModuleLocal.result }}' } # TestModuleStatus: From 6ed087e0fa945410e43c8f7f34eaeb0aec14e3c0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 12:42:29 +0100 Subject: [PATCH 103/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20P?= =?UTF-8?q?ath=20input=20in=20Test-Module=20workflow=20to=20specify=20outp?= =?UTF-8?q?ut=20directory=20for=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 1a62a022..0fcac9d3 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -131,6 +131,7 @@ jobs: uses: PSModule/Invoke-ScriptAnalyzer@v2 id: lint with: + Path: outputs/module Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} From bf3a76017322079bd3f02ca8ded43f3904a397d3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 12:46:47 +0100 Subject: [PATCH 104/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20R?= =?UTF-8?q?un=5FPath=20in=20Test-ModuleLocal=20workflow=20to=20use=20Worki?= =?UTF-8?q?ngDirectory=20for=20improved=20path=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index fc73896f..6570b919 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -124,7 +124,7 @@ jobs: CodeCoverage_Enabled: true CodeCoverage_OutputFormat: JaCoCo Path: ${{ inputs.TestFolderPath }} - Run_Path: outputs/module + Run_Path: ${{ inputs.WorkingDirectory }}/outputs/module WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Failed test From 84cf60f4fc3feb756a1c4aea2434053ed91c4719 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 12:53:21 +0100 Subject: [PATCH 105/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20Run=5FPath=20in=20Test-ModuleLocal=20workflow=20by=20removin?= =?UTF-8?q?g=20WorkingDirectory=20reference?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 6570b919..fc73896f 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -124,7 +124,7 @@ jobs: CodeCoverage_Enabled: true CodeCoverage_OutputFormat: JaCoCo Path: ${{ inputs.TestFolderPath }} - Run_Path: ${{ inputs.WorkingDirectory }}/outputs/module + Run_Path: outputs/module WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Failed test From e1a07984a0cd6665184ae53c1ef8f87340f0fe44 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 13:08:47 +0100 Subject: [PATCH 106/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20p?= =?UTF-8?q?ath=20handling=20in=20Test-ModuleLocal=20workflow=20for=20consi?= =?UTF-8?q?stency=20and=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 6 +++--- .github/workflows/workflow.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index fc73896f..6f1c047a 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -123,9 +123,9 @@ jobs: TestResult_Enabled: true CodeCoverage_Enabled: true CodeCoverage_OutputFormat: JaCoCo - Path: ${{ inputs.TestFolderPath }} - Run_Path: outputs/module - WorkingDirectory: ${{ inputs.WorkingDirectory }} + Path: ${{ inputs.WorkingDirectory }}/${{ inputs.TestFolderPath }} + Run_Path: ${{ inputs.WorkingDirectory }}/outputs/module + # WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Failed test if: steps.test.outcome != 'success' diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 1c2a124c..2f4cabd2 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -197,8 +197,8 @@ jobs: shell: pwsh run: | [pscustomobject]@{ - TestModule = '${{ needs.TestModule.result }}' - TestModuleLocal = '${{ needs.TestModuleLocal.result }}' + TestModule = '${{ needs.Test-Module.result }}' + TestModuleLocal = '${{ needs.Test-ModuleLocal.result }}' } # TestModuleStatus: From 7f79b368f459a013affe15bec717ffd69236188b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 13:53:46 +0100 Subject: [PATCH 107/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20I?= =?UTF-8?q?nvoke-ScriptAnalyzer=20and=20Invoke-Pester=20actions=20to=20use?= =?UTF-8?q?=20specific=20versions=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 3 ++- .github/workflows/Test-ModuleLocal.yml | 3 ++- .github/workflows/Test-SourceCode.yml | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 0fcac9d3..6f235e7b 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -128,7 +128,8 @@ jobs: path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Lint-SourceCode - uses: PSModule/Invoke-ScriptAnalyzer@v2 + # uses: PSModule/Invoke-ScriptAnalyzer@v2 + uses: PSModule/Invoke-ScriptAnalyzer@test id: lint with: Path: outputs/module diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 6f1c047a..8886e084 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -112,7 +112,8 @@ jobs: Get-ChildItem . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - name: Test-ModuleLocal - uses: PSModule/Invoke-Pester@v3 + # uses: PSModule/Invoke-Pester@v3 + uses: PSModule/Invoke-Pester@fix id: test with: Debug: ${{ inputs.Debug }} diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 4946f8e3..3a07a8eb 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -77,7 +77,8 @@ jobs: uses: actions/checkout@v4 - name: Lint-SourceCode - uses: PSModule/Invoke-ScriptAnalyzer@v2 + # uses: PSModule/Invoke-ScriptAnalyzer@v2 + uses: PSModule/Invoke-ScriptAnalyzer@test with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From 27c839a3cc979b04538a1fe9dbfee9b7562bec24 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 13:56:19 +0100 Subject: [PATCH 108/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20p?= =?UTF-8?q?ath=20definitions=20in=20Test-ModuleLocal=20workflow=20for=20im?= =?UTF-8?q?proved=20clarity=20and=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 8886e084..a5de51e0 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -124,9 +124,9 @@ jobs: TestResult_Enabled: true CodeCoverage_Enabled: true CodeCoverage_OutputFormat: JaCoCo - Path: ${{ inputs.WorkingDirectory }}/${{ inputs.TestFolderPath }} - Run_Path: ${{ inputs.WorkingDirectory }}/outputs/module - # WorkingDirectory: ${{ inputs.WorkingDirectory }} + Path: ${{ inputs.TestFolderPath }} + Run_Path: outputs/module + WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Failed test if: steps.test.outcome != 'success' From b70411c3dad477bbc4eaa0caa0ffc4627acd93ea Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 14:04:41 +0100 Subject: [PATCH 109/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20D?= =?UTF-8?q?ebug=20and=20Verbose=20parameters=20in=20Test-ModuleLocal=20wor?= =?UTF-8?q?kflow=20to=20true=20for=20consistent=20testing=20behavior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index a5de51e0..aadebb9f 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -116,9 +116,9 @@ jobs: uses: PSModule/Invoke-Pester@fix id: test with: - Debug: ${{ inputs.Debug }} + Debug: true #${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} + Verbose: true #${{ inputs.Verbose }} Version: ${{ inputs.Version }} TestResult_TestSuiteName: ${{ inputs.TestName }}-${{ inputs.OS }} TestResult_Enabled: true From 574d56615f6cdbbb85dd29ac38f9fe8aea960239 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 14:22:20 +0100 Subject: [PATCH 110/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20blan?= =?UTF-8?q?k=20line=20for=20improved=20readability=20in=20workflow.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 2f4cabd2..04f01ddb 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -200,6 +200,7 @@ jobs: TestModule = '${{ needs.Test-Module.result }}' TestModuleLocal = '${{ needs.Test-ModuleLocal.result }}' } + # TestModuleStatus: # name: Test module status From 7d04f9760a6c49c06fa6f4811630254c20f12027 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 14:31:15 +0100 Subject: [PATCH 111/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nnecessary=20blank=20line=20in=20workflow.yml=20for=20improved?= =?UTF-8?q?=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 04f01ddb..2f4cabd2 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -200,7 +200,6 @@ jobs: TestModule = '${{ needs.Test-Module.result }}' TestModuleLocal = '${{ needs.Test-ModuleLocal.result }}' } - # TestModuleStatus: # name: Test module status From 9887d65698d4c53c061b0bde18164414ce697c64 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 14:38:23 +0100 Subject: [PATCH 112/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 9856f368c430023ad0e0d69f945326267be6335a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 14:48:33 +0100 Subject: [PATCH 113/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nnecessary=20blank=20line=20in=20README.md=20for=20improved=20r?= =?UTF-8?q?eadability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 6e6b491ee8c6b7e044e63eb65cf1c5cda65cea60 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 14:57:18 +0100 Subject: [PATCH 114/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20blan?= =?UTF-8?q?k=20line=20in=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 587da4e57a91ff9622df0fe4aef633efd1b64ebe Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 15:15:00 +0100 Subject: [PATCH 115/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nnecessary=20blank=20line=20in=20README.md=20for=20improved=20r?= =?UTF-8?q?eadability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From fb9605a1f90869bbe106a75b0047767f7b30a8c0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 15:34:27 +0100 Subject: [PATCH 116/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20blan?= =?UTF-8?q?k=20line=20in=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 910e64b2fe6831e39d17574f2bb62743c6368e2b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 15:42:41 +0100 Subject: [PATCH 117/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nnecessary=20blank=20line=20in=20README.md=20for=20improved=20r?= =?UTF-8?q?eadability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 1d484a8affdfd34c2e788bd3bbc7e4a9f105bcaf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 15:48:26 +0100 Subject: [PATCH 118/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20blan?= =?UTF-8?q?k=20line=20in=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From df74d85c009f7b66266f68df23d094c73b176500 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 16:05:08 +0100 Subject: [PATCH 119/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nnecessary=20blank=20line=20in=20README.md=20for=20improved=20r?= =?UTF-8?q?eadability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From f926b50c6e934d9770e0ad2c456eb87e74e7d1c7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 16:29:49 +0100 Subject: [PATCH 120/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20blan?= =?UTF-8?q?k=20line=20in=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From fec7b7cafc3ab6a0e5c33444aa8c82e3ab19fc11 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 18:43:37 +0100 Subject: [PATCH 121/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20w?= =?UTF-8?q?orkflow=20files=20to=20correct=20action=20versions=20and=20impr?= =?UTF-8?q?ove=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 5 ++--- .github/workflows/Test-ModuleLocal.yml | 4 ++-- .github/workflows/Test-SourceCode.yml | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 6f235e7b..3e5829a0 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -113,7 +113,7 @@ jobs: run: Write-Host "Complete successfully" - Lint-SourceCode: + Lint-Module: name: Lint-SourceCode (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} @@ -128,8 +128,7 @@ jobs: path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Lint-SourceCode - # uses: PSModule/Invoke-ScriptAnalyzer@v2 - uses: PSModule/Invoke-ScriptAnalyzer@test + uses: PSModule/Invoke-ScriptAnalyzer@v2 id: lint with: Path: outputs/module diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index aadebb9f..1ae40f51 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -112,8 +112,7 @@ jobs: Get-ChildItem . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object - name: Test-ModuleLocal - # uses: PSModule/Invoke-Pester@v3 - uses: PSModule/Invoke-Pester@fix + uses: PSModule/Invoke-Pester@v3 id: test with: Debug: true #${{ inputs.Debug }} @@ -123,6 +122,7 @@ jobs: TestResult_TestSuiteName: ${{ inputs.TestName }}-${{ inputs.OS }} TestResult_Enabled: true CodeCoverage_Enabled: true + Output_Verbosity: Detailed CodeCoverage_OutputFormat: JaCoCo Path: ${{ inputs.TestFolderPath }} Run_Path: outputs/module diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 3a07a8eb..4946f8e3 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -77,8 +77,7 @@ jobs: uses: actions/checkout@v4 - name: Lint-SourceCode - # uses: PSModule/Invoke-ScriptAnalyzer@v2 - uses: PSModule/Invoke-ScriptAnalyzer@test + uses: PSModule/Invoke-ScriptAnalyzer@v2 with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From 1c647372574fb7fe808e7809a4926a3386b554a4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 19:18:51 +0100 Subject: [PATCH 122/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nnecessary=20blank=20line=20in=20README.md=20for=20improved=20r?= =?UTF-8?q?eadability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 47b1c1df8e2d0c0f68dc4bd51a857048f1b2db91 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 19:27:51 +0100 Subject: [PATCH 123/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20w?= =?UTF-8?q?orkflow=20files=20to=20allow=20continuation=20on=20error=20for?= =?UTF-8?q?=20testing=20steps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 15 ++------------- .github/workflows/Test-ModuleLocal.yml | 7 +------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 3e5829a0..326239af 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -96,8 +96,8 @@ jobs: path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Test-Module - id: test uses: PSModule/Test-PSModule@v3 + continue-on-error: true with: Name: ${{ inputs.Name }} Debug: ${{ inputs.Debug }} @@ -107,12 +107,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Settings: Module - - name: Failed test - if: steps.test.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" - - Lint-Module: name: Lint-SourceCode (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} @@ -129,7 +123,7 @@ jobs: - name: Lint-SourceCode uses: PSModule/Invoke-ScriptAnalyzer@v2 - id: lint + continue-on-error: true with: Path: outputs/module Debug: ${{ inputs.Debug }} @@ -138,8 +132,3 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} Settings: Module - - - name: Failed test - if: steps.lint.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 1ae40f51..ccaa4920 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -113,7 +113,7 @@ jobs: - name: Test-ModuleLocal uses: PSModule/Invoke-Pester@v3 - id: test + continue-on-error: true with: Debug: true #${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -127,8 +127,3 @@ jobs: Path: ${{ inputs.TestFolderPath }} Run_Path: outputs/module WorkingDirectory: ${{ inputs.WorkingDirectory }} - - - name: Failed test - if: steps.test.outcome != 'success' - shell: pwsh - run: Write-Host "Complete successfully" From 53c7c46f535ab16c804ff5ecb801a6c5b029473a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 21:26:13 +0100 Subject: [PATCH 124/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20blan?= =?UTF-8?q?k=20line=20in=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 1a01fda0235db0e11f8aa2824eed16a8ca9aa009 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 21:48:01 +0100 Subject: [PATCH 125/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20w?= =?UTF-8?q?orkflow=20to=20download=20and=20extract=20code=20coverage=20art?= =?UTF-8?q?ifacts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 39 ++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 2f4cabd2..3ebc5b3c 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -194,12 +194,39 @@ jobs: - Test-ModuleLocal steps: - name: Status - shell: pwsh - run: | - [pscustomobject]@{ - TestModule = '${{ needs.Test-Module.result }}' - TestModuleLocal = '${{ needs.Test-ModuleLocal.result }}' - } + uses: PSModule/GitHub-Script@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Script: | + $repository = $env:GITHUB_REPOSITORY + $runId = $env:GITHUB_RUN_ID + $OutputPath = "./CodeCoverageArtifacts" + New-Item -ItemType Directory -Path $OutputPath | Out-Null + $artifactsJson = gh api "repos/$repository/actions/runs/$runId/artifacts" | ConvertFrom-Json + foreach ($artifact in $artifactsJson.artifacts) { + if ($artifact.name -like "*CodeCoverage") { + $zipPath = Join-Path $OutputPath "$($artifact.name).zip" + + Write-Host "Downloading artifact '$($artifact.name)'..." + gh api ` + --method GET ` + -H "Accept: application/vnd.github+json" ` + "/repos/$repository/actions/artifacts/$($artifact.id)/zip" ` + --output $zipPath + + # Extract the artifact + Write-Host "Extracting artifact '$($artifact.name)'..." + Expand-Archive -Path $zipPath -DestinationPath (Join-Path $OutputPath $artifact.name) -Force + + # Optionally remove the zip after extraction + Remove-Item $zipPath -Force + } + } + Get-ChildItem -Path $OutputPath -Recurse # TestModuleStatus: # name: Test module status From d0855d2dbc24f936c57eec168c66f36ff6a7225e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 21:52:51 +0100 Subject: [PATCH 126/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nused=20WorkingDirectory=20input=20from=20workflow=20configurat?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 3ebc5b3c..ccb86d5e 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -200,7 +200,6 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} Script: | $repository = $env:GITHUB_REPOSITORY $runId = $env:GITHUB_RUN_ID From fe4e1f1dd1ea58b87e0de6f5222c6766f9d8e5e9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 21:59:07 +0100 Subject: [PATCH 127/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?workflow=20script=20to=20improve=20artifact=20handling=20and=20?= =?UTF-8?q?output=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index ccb86d5e..34f18c9a 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -201,11 +201,13 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Script: | + $PSStyle.Out $repository = $env:GITHUB_REPOSITORY $runId = $env:GITHUB_RUN_ID $OutputPath = "./CodeCoverageArtifacts" - New-Item -ItemType Directory -Path $OutputPath | Out-Null + $null = New-Item -ItemType Directory -Path $OutputPath $artifactsJson = gh api "repos/$repository/actions/runs/$runId/artifacts" | ConvertFrom-Json + $artifactsJson.artifacts | Format-Table -AutoSize | Out-String foreach ($artifact in $artifactsJson.artifacts) { if ($artifact.name -like "*CodeCoverage") { $zipPath = Join-Path $OutputPath "$($artifact.name).zip" From bea918c5342c0a9568059ebe2682765ef3d2f8c3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 22:06:31 +0100 Subject: [PATCH 128/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Filter=20a?= =?UTF-8?q?nd=20sort=20code=20coverage=20artifacts=20in=20workflow=20scrip?= =?UTF-8?q?t=20for=20improved=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 34f18c9a..1dd9f909 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -207,8 +207,9 @@ jobs: $OutputPath = "./CodeCoverageArtifacts" $null = New-Item -ItemType Directory -Path $OutputPath $artifactsJson = gh api "repos/$repository/actions/runs/$runId/artifacts" | ConvertFrom-Json - $artifactsJson.artifacts | Format-Table -AutoSize | Out-String - foreach ($artifact in $artifactsJson.artifacts) { + $artifacts = $artifactsJson.artifacts | Where-Object { $_.Name -Like "*CodeCoverage"} | Sort-Object -Property name + $artifacts | Format-List | Out-String + foreach ($artifact in $artifacts) { if ($artifact.name -like "*CodeCoverage") { $zipPath = Join-Path $OutputPath "$($artifact.name).zip" From 96d6d1f1b66cb76b7534cddb00aa0112d63ad6d3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 22:17:47 +0100 Subject: [PATCH 129/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20artifact=20downloading=20in=20workflow=20script=20by=20repla?= =?UTF-8?q?cing=20manual=20download=20and=20extraction=20with=20a=20single?= =?UTF-8?q?=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 1dd9f909..ffe43661 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -201,34 +201,12 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Script: | - $PSStyle.Out - $repository = $env:GITHUB_REPOSITORY + $PSStyle.OutputRendering = 'Ansi' $runId = $env:GITHUB_RUN_ID - $OutputPath = "./CodeCoverageArtifacts" - $null = New-Item -ItemType Directory -Path $OutputPath $artifactsJson = gh api "repos/$repository/actions/runs/$runId/artifacts" | ConvertFrom-Json $artifacts = $artifactsJson.artifacts | Where-Object { $_.Name -Like "*CodeCoverage"} | Sort-Object -Property name $artifacts | Format-List | Out-String - foreach ($artifact in $artifacts) { - if ($artifact.name -like "*CodeCoverage") { - $zipPath = Join-Path $OutputPath "$($artifact.name).zip" - - Write-Host "Downloading artifact '$($artifact.name)'..." - gh api ` - --method GET ` - -H "Accept: application/vnd.github+json" ` - "/repos/$repository/actions/artifacts/$($artifact.id)/zip" ` - --output $zipPath - - # Extract the artifact - Write-Host "Extracting artifact '$($artifact.name)'..." - Expand-Archive -Path $zipPath -DestinationPath (Join-Path $OutputPath $artifact.name) -Force - - # Optionally remove the zip after extraction - Remove-Item $zipPath -Force - } - } - Get-ChildItem -Path $OutputPath -Recurse + gh run download $runId --name "*CodeCoverage" # TestModuleStatus: # name: Test module status From 6e13956e6d7e1c6395aae59f391a84a5bc62e237 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 22:24:23 +0100 Subject: [PATCH 130/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20a?= =?UTF-8?q?rtifact=20download=20command=20in=20workflow=20script=20to=20us?= =?UTF-8?q?e=20pattern=20matching=20for=20code=20coverage=20artifacts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index ffe43661..56e487ef 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -206,7 +206,7 @@ jobs: $artifactsJson = gh api "repos/$repository/actions/runs/$runId/artifacts" | ConvertFrom-Json $artifacts = $artifactsJson.artifacts | Where-Object { $_.Name -Like "*CodeCoverage"} | Sort-Object -Property name $artifacts | Format-List | Out-String - gh run download $runId --name "*CodeCoverage" + gh run download $runId --pattern "*CodeCoverage" # TestModuleStatus: # name: Test module status From 913d59e16a1a25960a5ea09d1b855ed0858000ff Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 22:30:31 +0100 Subject: [PATCH 131/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20a?= =?UTF-8?q?rtifact=20download=20command=20in=20workflow=20script=20to=20in?= =?UTF-8?q?clude=20repository=20context=20for=20code=20coverage=20artifact?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 56e487ef..15a0661a 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -202,11 +202,12 @@ jobs: Version: ${{ inputs.Version }} Script: | $PSStyle.OutputRendering = 'Ansi' + $repo = $env:GITHUB_REPOSITORY $runId = $env:GITHUB_RUN_ID $artifactsJson = gh api "repos/$repository/actions/runs/$runId/artifacts" | ConvertFrom-Json $artifacts = $artifactsJson.artifacts | Where-Object { $_.Name -Like "*CodeCoverage"} | Sort-Object -Property name $artifacts | Format-List | Out-String - gh run download $runId --pattern "*CodeCoverage" + gh run download $runId --pattern "*CodeCoverage" --repo $repo # TestModuleStatus: # name: Test module status From 3cc46e1dc263dbb2090e76872d10d4a1e5ab775c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 22:45:22 +0100 Subject: [PATCH 132/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20a?= =?UTF-8?q?rtifact=20filtering=20in=20workflow=20script=20to=20improve=20c?= =?UTF-8?q?ode=20coverage=20artifact=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 15a0661a..d25a71e6 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -205,9 +205,9 @@ jobs: $repo = $env:GITHUB_REPOSITORY $runId = $env:GITHUB_RUN_ID $artifactsJson = gh api "repos/$repository/actions/runs/$runId/artifacts" | ConvertFrom-Json - $artifacts = $artifactsJson.artifacts | Where-Object { $_.Name -Like "*CodeCoverage"} | Sort-Object -Property name + $artifacts = $artifactsJson.artifacts | Where-Object { $_.name -Like "*CodeCoverage"} | Sort-Object -Property name $artifacts | Format-List | Out-String - gh run download $runId --pattern "*CodeCoverage" --repo $repo + gh run download $runId --repo $repo # TestModuleStatus: # name: Test module status From 670b57c03364a7175246878896f86a871eae5980 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 22:50:12 +0100 Subject: [PATCH 133/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20a?= =?UTF-8?q?rtifact=20retrieval=20in=20workflow=20script=20to=20use=20repos?= =?UTF-8?q?itory=20context=20for=20code=20coverage=20artifacts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index d25a71e6..5e275fc4 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -204,7 +204,7 @@ jobs: $PSStyle.OutputRendering = 'Ansi' $repo = $env:GITHUB_REPOSITORY $runId = $env:GITHUB_RUN_ID - $artifactsJson = gh api "repos/$repository/actions/runs/$runId/artifacts" | ConvertFrom-Json + $artifactsJson = gh api "repos/$repo/actions/runs/$runId/artifacts" | ConvertFrom-Json $artifacts = $artifactsJson.artifacts | Where-Object { $_.name -Like "*CodeCoverage"} | Sort-Object -Property name $artifacts | Format-List | Out-String gh run download $runId --repo $repo From c93d57a373be121cee01c406706f6ff62ebd4a92 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 22:54:31 +0100 Subject: [PATCH 134/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?artifact=20download=20command=20in=20workflow=20script=20to=20u?= =?UTF-8?q?se=20pattern=20matching=20for=20code=20coverage=20artifacts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 5e275fc4..633af13e 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -207,7 +207,8 @@ jobs: $artifactsJson = gh api "repos/$repo/actions/runs/$runId/artifacts" | ConvertFrom-Json $artifacts = $artifactsJson.artifacts | Where-Object { $_.name -Like "*CodeCoverage"} | Sort-Object -Property name $artifacts | Format-List | Out-String - gh run download $runId --repo $repo + gh run download $runId --repo $repo --pattern *CodeCoverage + Get-ChildItem -Path . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object # TestModuleStatus: # name: Test module status From 963de209b488f8b55741acd8aba54d11d86466f7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 23:03:16 +0100 Subject: [PATCH 135/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20artifact=20download=20command=20in=20workflow=20script=20to?= =?UTF-8?q?=20directly=20download=20code=20coverage=20artifacts=20to=20the?= =?UTF-8?q?=20current=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 633af13e..82ace205 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -201,13 +201,7 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Script: | - $PSStyle.OutputRendering = 'Ansi' - $repo = $env:GITHUB_REPOSITORY - $runId = $env:GITHUB_RUN_ID - $artifactsJson = gh api "repos/$repo/actions/runs/$runId/artifacts" | ConvertFrom-Json - $artifacts = $artifactsJson.artifacts | Where-Object { $_.name -Like "*CodeCoverage"} | Sort-Object -Property name - $artifacts | Format-List | Out-String - gh run download $runId --repo $repo --pattern *CodeCoverage + gh run download $runId --repo $repo --pattern *CodeCoverage --dir . Get-ChildItem -Path . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object # TestModuleStatus: From 2508f849b0351842b1278926adf95dd05bca28de Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 23:07:18 +0100 Subject: [PATCH 136/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20w?= =?UTF-8?q?orkflow=20script=20to=20set=20output=20rendering=20and=20retrie?= =?UTF-8?q?ve=20repository=20context=20for=20code=20coverage=20artifact=20?= =?UTF-8?q?download?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 82ace205..747552de 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -201,6 +201,9 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Script: | + $PSStyle.OutputRendering = 'Ansi' + $repo = $env:GITHUB_REPOSITORY + $runId = $env:GITHUB_RUN_ID gh run download $runId --repo $repo --pattern *CodeCoverage --dir . Get-ChildItem -Path . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object From cba299082a18e431b11fee82329cd595b25fc3eb Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 23:13:22 +0100 Subject: [PATCH 137/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Improve=20?= =?UTF-8?q?file=20listing=20and=20logging=20in=20workflow=20script=20for?= =?UTF-8?q?=20better=20visibility=20of=20code=20coverage=20artifacts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 747552de..803e0798 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -205,7 +205,14 @@ jobs: $repo = $env:GITHUB_REPOSITORY $runId = $env:GITHUB_RUN_ID gh run download $runId --repo $repo --pattern *CodeCoverage --dir . - Get-ChildItem -Path . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object + $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object + $files | Out-String + $files | ForEach-Object { + $fileName = $_.Name + LogGroup " - $fileName" { + Show-FileContent -Path $_ + } + } # TestModuleStatus: # name: Test module status From 40d1337b85bffbece64f53a3c56784841ae58908 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 23:17:38 +0100 Subject: [PATCH 138/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Replace=20?= =?UTF-8?q?Show-FileContent=20with=20Get-Content=20for=20improved=20file?= =?UTF-8?q?=20content=20retrieval=20in=20workflow=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 803e0798..b91b27a3 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -210,7 +210,7 @@ jobs: $files | ForEach-Object { $fileName = $_.Name LogGroup " - $fileName" { - Show-FileContent -Path $_ + Get-Content -Path $_ } } From d197e574720ada9fedf16d6b38c22e94dcae8059 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 23:25:28 +0100 Subject: [PATCH 139/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Implement?= =?UTF-8?q?=20XML=20report=20merging=20in=20workflow=20script=20to=20conso?= =?UTF-8?q?lidate=20code=20coverage=20data=20into=20a=20single=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 60 ++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index b91b27a3..0dc6d3e0 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -206,14 +206,62 @@ jobs: $runId = $env:GITHUB_RUN_ID gh run download $runId --repo $repo --pattern *CodeCoverage --dir . $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object - $files | Out-String - $files | ForEach-Object { - $fileName = $_.Name - LogGroup " - $fileName" { - Get-Content -Path $_ - } + # Load the first XML as the base report + [xml]$mergedReport = Get-Content -Path $files[0] + + # Function to merge counters + function Merge-Counters($baseNode, $newNode) { + foreach ($newCounter in $newNode.counter) { + $baseCounter = $baseNode.counter | Where-Object { $_.type -eq $newCounter.type } + if ($baseCounter) { + $baseCounter.missed = [int]$baseCounter.missed + [int]$newCounter.missed + $baseCounter.covered = [int]$baseCounter.covered + [int]$newCounter.covered + } else { + # Import new counter if it doesn't exist + $importedCounter = $mergedReport.ImportNode($newCounter, $true) + $baseNode.AppendChild($importedCounter) | Out-Null + } + } } + # Loop through remaining reports to merge coverage data + foreach ($reportPath in $files[1..($files.Count - 1)]) { + [xml]$currentReport = Get-Content -Path $reportPath + + # Merge the top-level counters + Merge-Counters -baseNode $mergedReport.report -newNode $currentReport.report + + # Merge packages and classes + foreach ($package in $currentReport.report.package) { + $basePackage = $mergedReport.report.package | Where-Object { $_.name -eq $package.name } + + if ($basePackage) { + # Merge counters at package level + Merge-Counters -baseNode $basePackage -newNode $package + + foreach ($class in $package.class) { + $baseClass = $basePackage.class | Where-Object { $_.name -eq $class.name } + if ($baseClass) { + # Merge counters at class level + Merge-Counters -baseNode $baseClass -newNode $class + } else { + # Import new class + $importedClass = $mergedReport.ImportNode($class, $true) + $basePackage.AppendChild($importedClass) | Out-Null + } + } + } else { + # Import entire new package + $importedPackage = $mergedReport.ImportNode($package, $true) + $mergedReport.report.AppendChild($importedPackage) | Out-Null + } + } + } + + # Output the combined report + $mergedReport.Save("merged-jacoco-report.xml") + + # TestModuleStatus: # name: Test module status # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} From d276cf4bb89b09bb2b4e4ee04cb43ee07ed9ff59 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 23:36:16 +0100 Subject: [PATCH 140/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Output=20m?= =?UTF-8?q?erged=20report=20as=20string=20in=20workflow=20script=20for=20i?= =?UTF-8?q?mproved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 0dc6d3e0..423e6195 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -260,6 +260,7 @@ jobs: # Output the combined report $mergedReport.Save("merged-jacoco-report.xml") + $mergedReport | Out-String # TestModuleStatus: From 78a1ce8511fa85425fb029398e9a7acc51232df7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Mar 2025 23:41:42 +0100 Subject: [PATCH 141/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?XML=20report=20output=20formatting=20in=20workflow=20script=20f?= =?UTF-8?q?or=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 423e6195..9754345f 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -260,7 +260,22 @@ jobs: # Output the combined report $mergedReport.Save("merged-jacoco-report.xml") - $mergedReport | Out-String + + # Assuming $mergedReport is your final [xml] object: + $xmlString = $mergedReport.OuterXml + + # To format (pretty-print) the XML nicely: + $stringWriter = New-Object System.IO.StringWriter + $xmlWriter = [System.Xml.XmlTextWriter]::new($stringWriter) + $xmlWriter.Formatting = "Indented" + $mergedReport.WriteTo($xmlWriter) + $xmlWriter.Flush() + $prettyXml = $stringWriter.ToString() + + $prettyXml | Out-String + + # Output or export the XML string + # $prettyXml | Out-File -FilePath "merged-jacoco-report.xml" -Encoding UTF8 # TestModuleStatus: From ed86f24f041b546ede90fb9adecd2dee93e1f6a2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 08:32:07 +0100 Subject: [PATCH 142/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Rename=20j?= =?UTF-8?q?ob=20and=20steps=20for=20clarity=20in=20workflow=20script=20to?= =?UTF-8?q?=20improve=20readability=20and=20maintainability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 171 +++++++++++++++++++-------------- 1 file changed, 97 insertions(+), 74 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9754345f..a4eb87ef 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -185,15 +185,15 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Status: - name: Status + Get-TestResults: + name: Get-TestResults runs-on: ubuntu-latest needs: - Test-SourceCode - Test-Module - Test-ModuleLocal steps: - - name: Status + - name: Get-TestResults uses: PSModule/GitHub-Script@v1 with: Debug: ${{ inputs.Debug }} @@ -204,78 +204,101 @@ jobs: $PSStyle.OutputRendering = 'Ansi' $repo = $env:GITHUB_REPOSITORY $runId = $env:GITHUB_RUN_ID - gh run download $runId --repo $repo --pattern *CodeCoverage --dir . + gh run download $runId --repo $repo --pattern *-TestResults $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object - # Load the first XML as the base report - [xml]$mergedReport = Get-Content -Path $files[0] - - # Function to merge counters - function Merge-Counters($baseNode, $newNode) { - foreach ($newCounter in $newNode.counter) { - $baseCounter = $baseNode.counter | Where-Object { $_.type -eq $newCounter.type } - if ($baseCounter) { - $baseCounter.missed = [int]$baseCounter.missed + [int]$newCounter.missed - $baseCounter.covered = [int]$baseCounter.covered + [int]$newCounter.covered - } else { - # Import new counter if it doesn't exist - $importedCounter = $mergedReport.ImportNode($newCounter, $true) - $baseNode.AppendChild($importedCounter) | Out-Null - } - } - } - - # Loop through remaining reports to merge coverage data - foreach ($reportPath in $files[1..($files.Count - 1)]) { - [xml]$currentReport = Get-Content -Path $reportPath - - # Merge the top-level counters - Merge-Counters -baseNode $mergedReport.report -newNode $currentReport.report - - # Merge packages and classes - foreach ($package in $currentReport.report.package) { - $basePackage = $mergedReport.report.package | Where-Object { $_.name -eq $package.name } - - if ($basePackage) { - # Merge counters at package level - Merge-Counters -baseNode $basePackage -newNode $package - - foreach ($class in $package.class) { - $baseClass = $basePackage.class | Where-Object { $_.name -eq $class.name } - if ($baseClass) { - # Merge counters at class level - Merge-Counters -baseNode $baseClass -newNode $class - } else { - # Import new class - $importedClass = $mergedReport.ImportNode($class, $true) - $basePackage.AppendChild($importedClass) | Out-Null - } - } - } else { - # Import entire new package - $importedPackage = $mergedReport.ImportNode($package, $true) - $mergedReport.report.AppendChild($importedPackage) | Out-Null - } - } - } - - # Output the combined report - $mergedReport.Save("merged-jacoco-report.xml") - - # Assuming $mergedReport is your final [xml] object: - $xmlString = $mergedReport.OuterXml - - # To format (pretty-print) the XML nicely: - $stringWriter = New-Object System.IO.StringWriter - $xmlWriter = [System.Xml.XmlTextWriter]::new($stringWriter) - $xmlWriter.Formatting = "Indented" - $mergedReport.WriteTo($xmlWriter) - $xmlWriter.Flush() - $prettyXml = $stringWriter.ToString() - - $prettyXml | Out-String - - # Output or export the XML string - # $prettyXml | Out-File -FilePath "merged-jacoco-report.xml" -Encoding UTF8 + $files | Format-Table -AutoSize | Out-String + + # Get-CodeCoverage: + # name: Get-CodeCoverage + # runs-on: ubuntu-latest + # needs: + # - Test-SourceCode + # - Test-Module + # - Test-ModuleLocal + # steps: + # - name: Get-CodeCoverage + # uses: PSModule/GitHub-Script@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + # Script: | + # $PSStyle.OutputRendering = 'Ansi' + # $repo = $env:GITHUB_REPOSITORY + # $runId = $env:GITHUB_RUN_ID + # gh run download $runId --repo $repo --pattern *-CodeCoverage + # $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object + # # Load the first XML as the base report + # [xml]$mergedReport = Get-Content -Path $files[0] + + # # Function to merge counters + # function Merge-Counters($baseNode, $newNode) { + # foreach ($newCounter in $newNode.counter) { + # $baseCounter = $baseNode.counter | Where-Object { $_.type -eq $newCounter.type } + # if ($baseCounter) { + # $baseCounter.missed = [int]$baseCounter.missed + [int]$newCounter.missed + # $baseCounter.covered = [int]$baseCounter.covered + [int]$newCounter.covered + # } else { + # # Import new counter if it doesn't exist + # $importedCounter = $mergedReport.ImportNode($newCounter, $true) + # $baseNode.AppendChild($importedCounter) | Out-Null + # } + # } + # } + + # # Loop through remaining reports to merge coverage data + # foreach ($reportPath in $files[1..($files.Count - 1)]) { + # [xml]$currentReport = Get-Content -Path $reportPath + + # # Merge the top-level counters + # Merge-Counters -baseNode $mergedReport.report -newNode $currentReport.report + + # # Merge packages and classes + # foreach ($package in $currentReport.report.package) { + # $basePackage = $mergedReport.report.package | Where-Object { $_.name -eq $package.name } + + # if ($basePackage) { + # # Merge counters at package level + # Merge-Counters -baseNode $basePackage -newNode $package + + # foreach ($class in $package.class) { + # $baseClass = $basePackage.class | Where-Object { $_.name -eq $class.name } + # if ($baseClass) { + # # Merge counters at class level + # Merge-Counters -baseNode $baseClass -newNode $class + # } else { + # # Import new class + # $importedClass = $mergedReport.ImportNode($class, $true) + # $basePackage.AppendChild($importedClass) | Out-Null + # } + # } + # } else { + # # Import entire new package + # $importedPackage = $mergedReport.ImportNode($package, $true) + # $mergedReport.report.AppendChild($importedPackage) | Out-Null + # } + # } + # } + + # # Output the combined report + # $mergedReport.Save("merged-jacoco-report.xml") + + # # Assuming $mergedReport is your final [xml] object: + # $xmlString = $mergedReport.OuterXml + + # # To format (pretty-print) the XML nicely: + # $stringWriter = New-Object System.IO.StringWriter + # $xmlWriter = [System.Xml.XmlTextWriter]::new($stringWriter) + # $xmlWriter.Formatting = "Indented" + # $mergedReport.WriteTo($xmlWriter) + # $xmlWriter.Flush() + # $prettyXml = $stringWriter.ToString() + + # $prettyXml | Out-String + + # # Output or export the XML string + # # $prettyXml | Out-File -FilePath "merged-jacoco-report.xml" -Encoding UTF8 # TestModuleStatus: From b77c1ca1506e03ff4bbf81638988dbc138adeb76 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 08:42:50 +0100 Subject: [PATCH 143/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20logg?= =?UTF-8?q?ing=20for=20each=20file's=20content=20in=20workflow=20script=20?= =?UTF-8?q?to=20enhance=20output=20visibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index a4eb87ef..e094a1a5 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -208,6 +208,13 @@ jobs: $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object $files | Format-Table -AutoSize | Out-String + foreach ($file in $files) { + $fileName = $file.BaseName + LogGroup $fileName { + Get-Content -Path $file | Out-String + } + } + # Get-CodeCoverage: # name: Get-CodeCoverage # runs-on: ubuntu-latest From 4a196a75c7906be3065719edea9208f487ed4363 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 08:54:38 +0100 Subject: [PATCH 144/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Simplify?= =?UTF-8?q?=20file=20retrieval=20in=20workflow=20script=20by=20removing=20?= =?UTF-8?q?unnecessary=20sorting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index e094a1a5..80b58e27 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -205,7 +205,7 @@ jobs: $repo = $env:GITHUB_REPOSITORY $runId = $env:GITHUB_RUN_ID gh run download $runId --repo $repo --pattern *-TestResults - $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object + $files = Get-ChildItem -Path . -Recurse -File $files | Format-Table -AutoSize | Out-String foreach ($file in $files) { From 797ffb6a48633dcdb640a226adeb4f0b38ddd632 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 09:30:48 +0100 Subject: [PATCH 145/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Enhance=20?= =?UTF-8?q?XML=20processing=20in=20workflow=20script=20to=20extract=20and?= =?UTF-8?q?=20log=20test=20case=20details?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 80b58e27..8292fd86 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -208,11 +208,29 @@ jobs: $files = Get-ChildItem -Path . -Recurse -File $files | Format-Table -AutoSize | Out-String + $allCases = [System.Collections.Generic.List[psobject]]::new() foreach ($file in $files) { $fileName = $file.BaseName LogGroup $fileName { Get-Content -Path $file | Out-String } + LogGroup "$fileName - Process" { + $xmlDoc = [xml](Get-Content $_.FullName) + $cases = $xmlDoc.SelectNodes('//test-case') | ForEach-Object { + [pscustomobject]@{ + Name = $_.name + Description = $_.description + Result = $_.result + Success = [bool]($_.success -eq 'True') + Time = [float]$_.time + Executed = [bool]($_.executed -eq 'True') + FailureMessage = $_.failure.message + StackTrace = $_.failure.'stack-trace' + } + } + $cases | ForEach-Object { $allCases.Add($_) } + $cases | Format-Table -AutoSize | Out-String + } } # Get-CodeCoverage: From cd087a55dfa55f521d0832897740e50472e7256c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 09:58:44 +0100 Subject: [PATCH 146/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Update=20f?= =?UTF-8?q?ile=20path=20retrieval=20in=20workflow=20script=20for=20XML=20p?= =?UTF-8?q?rocessing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 8292fd86..5a6ac0f7 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -215,7 +215,7 @@ jobs: Get-Content -Path $file | Out-String } LogGroup "$fileName - Process" { - $xmlDoc = [xml](Get-Content $_.FullName) + $xmlDoc = [xml](Get-Content -Path $file.FullName) $cases = $xmlDoc.SelectNodes('//test-case') | ForEach-Object { [pscustomobject]@{ Name = $_.name From 1184ce09b6f335bd4fa07b23d34745b8a33ff5f6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 10:06:12 +0100 Subject: [PATCH 147/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Add=20logg?= =?UTF-8?q?ing=20for=20TestResults=20files=20and=20change=20output=20forma?= =?UTF-8?q?t=20for=20test=20cases=20in=20workflow=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 5a6ac0f7..9c1445c4 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -206,6 +206,10 @@ jobs: $runId = $env:GITHUB_RUN_ID gh run download $runId --repo $repo --pattern *-TestResults $files = Get-ChildItem -Path . -Recurse -File + + LogGroup "List TestResults files" { + $files.Name | Out-String + } $files | Format-Table -AutoSize | Out-String $allCases = [System.Collections.Generic.List[psobject]]::new() @@ -229,7 +233,7 @@ jobs: } } $cases | ForEach-Object { $allCases.Add($_) } - $cases | Format-Table -AutoSize | Out-String + $cases | Format-List | Out-String } } From 86d49bfabc693f287b366f99827b4514bc1d5106 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 11:08:02 +0100 Subject: [PATCH 148/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Modularize?= =?UTF-8?q?=20Get-TestResults=20workflow=20and=20enhance=20input=20handlin?= =?UTF-8?q?g=20in=20CI=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 114 +++++++++++++++++++++++--- .github/workflows/Get-TestResults.yml | 53 ++++++++++++ .github/workflows/workflow.yml | 53 ++---------- 3 files changed, 164 insertions(+), 56 deletions(-) create mode 100644 .github/workflows/Get-TestResults.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 411638d8..b58e3add 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -178,21 +178,113 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Status: - name: Status - runs-on: ubuntu-latest + Get-TestResults: + name: Get-TestResults needs: - Test-SourceCode - Test-Module - Test-ModuleLocal - steps: - - name: Status - shell: pwsh - run: | - [pscustomobject]@{ - TestModule = '${{ needs.Test-Module.result }}' - TestModuleLocal = '${{ needs.Test-ModuleLocal.result }}' - } + uses: ./.github/workflows/Get-TestResults.yml + secrets: inherit + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + + # Get-CodeCoverage: + # name: Get-CodeCoverage + # runs-on: ubuntu-latest + # needs: + # - Test-SourceCode + # - Test-Module + # - Test-ModuleLocal + # steps: + # - name: Get-CodeCoverage + # uses: PSModule/GitHub-Script@v1 + # with: + # Debug: ${{ inputs.Debug }} + # Prerelease: ${{ inputs.Prerelease }} + # Verbose: ${{ inputs.Verbose }} + # Version: ${{ inputs.Version }} + # Script: | + # $PSStyle.OutputRendering = 'Ansi' + # $repo = $env:GITHUB_REPOSITORY + # $runId = $env:GITHUB_RUN_ID + # gh run download $runId --repo $repo --pattern *-CodeCoverage + # $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object + # # Load the first XML as the base report + # [xml]$mergedReport = Get-Content -Path $files[0] + + # # Function to merge counters + # function Merge-Counters($baseNode, $newNode) { + # foreach ($newCounter in $newNode.counter) { + # $baseCounter = $baseNode.counter | Where-Object { $_.type -eq $newCounter.type } + # if ($baseCounter) { + # $baseCounter.missed = [int]$baseCounter.missed + [int]$newCounter.missed + # $baseCounter.covered = [int]$baseCounter.covered + [int]$newCounter.covered + # } else { + # # Import new counter if it doesn't exist + # $importedCounter = $mergedReport.ImportNode($newCounter, $true) + # $baseNode.AppendChild($importedCounter) | Out-Null + # } + # } + # } + + # # Loop through remaining reports to merge coverage data + # foreach ($reportPath in $files[1..($files.Count - 1)]) { + # [xml]$currentReport = Get-Content -Path $reportPath + + # # Merge the top-level counters + # Merge-Counters -baseNode $mergedReport.report -newNode $currentReport.report + + # # Merge packages and classes + # foreach ($package in $currentReport.report.package) { + # $basePackage = $mergedReport.report.package | Where-Object { $_.name -eq $package.name } + + # if ($basePackage) { + # # Merge counters at package level + # Merge-Counters -baseNode $basePackage -newNode $package + + # foreach ($class in $package.class) { + # $baseClass = $basePackage.class | Where-Object { $_.name -eq $class.name } + # if ($baseClass) { + # # Merge counters at class level + # Merge-Counters -baseNode $baseClass -newNode $class + # } else { + # # Import new class + # $importedClass = $mergedReport.ImportNode($class, $true) + # $basePackage.AppendChild($importedClass) | Out-Null + # } + # } + # } else { + # # Import entire new package + # $importedPackage = $mergedReport.ImportNode($package, $true) + # $mergedReport.report.AppendChild($importedPackage) | Out-Null + # } + # } + # } + + # # Output the combined report + # $mergedReport.Save("merged-jacoco-report.xml") + + # # Assuming $mergedReport is your final [xml] object: + # $xmlString = $mergedReport.OuterXml + + # # To format (pretty-print) the XML nicely: + # $stringWriter = New-Object System.IO.StringWriter + # $xmlWriter = [System.Xml.XmlTextWriter]::new($stringWriter) + # $xmlWriter.Formatting = "Indented" + # $mergedReport.WriteTo($xmlWriter) + # $xmlWriter.Flush() + # $prettyXml = $stringWriter.ToString() + + # $prettyXml | Out-String + + # # Output or export the XML string + # # $prettyXml | Out-File -FilePath "merged-jacoco-report.xml" -Encoding UTF8 + # TestModuleStatus: # name: Test module status diff --git a/.github/workflows/Get-TestResults.yml b/.github/workflows/Get-TestResults.yml new file mode 100644 index 00000000..f57b5ef0 --- /dev/null +++ b/.github/workflows/Get-TestResults.yml @@ -0,0 +1,53 @@ +name: Get-TestResults + +on: + workflow_call: + inputs: + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} + +permissions: + contents: read # to checkout the repo + +jobs: + Get-TestResults: + name: Get-TestResults + runs-on: ubuntu-latest + outputs: + TestResults: ${{ fromJson(steps.Get-TestResults.outputs.result).TestResults }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Get-TestResults + uses: PSModule/Get-PesterTestResults@v1 + id: Get-TestResults + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9c1445c4..d6c23e4b 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -187,55 +187,18 @@ jobs: Get-TestResults: name: Get-TestResults - runs-on: ubuntu-latest needs: - Test-SourceCode - Test-Module - Test-ModuleLocal - steps: - - name: Get-TestResults - uses: PSModule/GitHub-Script@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - Script: | - $PSStyle.OutputRendering = 'Ansi' - $repo = $env:GITHUB_REPOSITORY - $runId = $env:GITHUB_RUN_ID - gh run download $runId --repo $repo --pattern *-TestResults - $files = Get-ChildItem -Path . -Recurse -File - - LogGroup "List TestResults files" { - $files.Name | Out-String - } - $files | Format-Table -AutoSize | Out-String - - $allCases = [System.Collections.Generic.List[psobject]]::new() - foreach ($file in $files) { - $fileName = $file.BaseName - LogGroup $fileName { - Get-Content -Path $file | Out-String - } - LogGroup "$fileName - Process" { - $xmlDoc = [xml](Get-Content -Path $file.FullName) - $cases = $xmlDoc.SelectNodes('//test-case') | ForEach-Object { - [pscustomobject]@{ - Name = $_.name - Description = $_.description - Result = $_.result - Success = [bool]($_.success -eq 'True') - Time = [float]$_.time - Executed = [bool]($_.executed -eq 'True') - FailureMessage = $_.failure.message - StackTrace = $_.failure.'stack-trace' - } - } - $cases | ForEach-Object { $allCases.Add($_) } - $cases | Format-List | Out-String - } - } + uses: ./.github/workflows/Get-TestResults.yml + secrets: inherit + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} # Get-CodeCoverage: # name: Get-CodeCoverage From 94f5d3c9bdd6f300bf93d551c297320838fd1f98 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 11:22:57 +0100 Subject: [PATCH 149/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20u?= =?UTF-8?q?nnecessary=20output=20declaration=20in=20Get-TestResults=20work?= =?UTF-8?q?flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestResults.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/Get-TestResults.yml b/.github/workflows/Get-TestResults.yml index f57b5ef0..5fabc3b4 100644 --- a/.github/workflows/Get-TestResults.yml +++ b/.github/workflows/Get-TestResults.yml @@ -36,8 +36,6 @@ jobs: Get-TestResults: name: Get-TestResults runs-on: ubuntu-latest - outputs: - TestResults: ${{ fromJson(steps.Get-TestResults.outputs.result).TestResults }} steps: - name: Checkout Code uses: actions/checkout@v4 From b0ddbcca04cb9b5bd86675869cb4f47f3402ae84 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 12:58:46 +0100 Subject: [PATCH 150/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20r?= =?UTF-8?q?edundant=20checkout=20step=20and=20add=20Get-CodeCoverage=20wor?= =?UTF-8?q?kflow=20for=20enhanced=20test=20coverage=20analysis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-CodeCoverage.yml | 48 ++++++++++++++++++++++++++ .github/workflows/Get-TestResults.yml | 3 -- .github/workflows/workflow.yml | 15 ++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/Get-CodeCoverage.yml diff --git a/.github/workflows/Get-CodeCoverage.yml b/.github/workflows/Get-CodeCoverage.yml new file mode 100644 index 00000000..7220865d --- /dev/null +++ b/.github/workflows/Get-CodeCoverage.yml @@ -0,0 +1,48 @@ +name: Get-CodeCoverage + +on: + workflow_call: + inputs: + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: ${{ github.workspace }} + +permissions: + contents: read # to checkout the repo + +jobs: + Get-CodeCoverage: + name: Get-CodeCoverage + runs-on: ubuntu-latest + steps: + - name: Get-CodeCoverage + uses: PSModule/Get-PesterCodeCoverage@v1 + id: Get-CodeCoverage + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} diff --git a/.github/workflows/Get-TestResults.yml b/.github/workflows/Get-TestResults.yml index 5fabc3b4..1bc1a701 100644 --- a/.github/workflows/Get-TestResults.yml +++ b/.github/workflows/Get-TestResults.yml @@ -37,9 +37,6 @@ jobs: name: Get-TestResults runs-on: ubuntu-latest steps: - - name: Checkout Code - uses: actions/checkout@v4 - - name: Get-TestResults uses: PSModule/Get-PesterTestResults@v1 id: Get-TestResults diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index d6c23e4b..5002dee6 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -200,6 +200,21 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} + Get-CodeCoverage: + name: Get-CodeCoverage + needs: + - Test-SourceCode + - Test-Module + - Test-ModuleLocal + uses: ./.github/workflows/Get-CodeCoverage.yml + secrets: inherit + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + # Get-CodeCoverage: # name: Get-CodeCoverage # runs-on: ubuntu-latest From 49e39c0a8966003f3c76b8f90fc654bd909a4287 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 13:04:28 +0100 Subject: [PATCH 151/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20W?= =?UTF-8?q?orkingDirectory=20input=20from=20Get-CodeCoverage=20workflow=20?= =?UTF-8?q?for=20cleaner=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 5002dee6..73cfe35c 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -198,7 +198,6 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-CodeCoverage: name: Get-CodeCoverage @@ -213,7 +212,6 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} # Get-CodeCoverage: # name: Get-CodeCoverage From 8a30c872d0cdaf5ebe0a4da45fac3af94415c353 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 14:48:00 +0100 Subject: [PATCH 152/324] =?UTF-8?q?=F0=9F=A9=B9=20[Refactor]:=20Remove=20G?= =?UTF-8?q?et-CodeCoverage=20workflow=20to=20streamline=20CI=20configurati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 93 ---------------------------------- 1 file changed, 93 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 73cfe35c..9519ac44 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -213,99 +213,6 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - # Get-CodeCoverage: - # name: Get-CodeCoverage - # runs-on: ubuntu-latest - # needs: - # - Test-SourceCode - # - Test-Module - # - Test-ModuleLocal - # steps: - # - name: Get-CodeCoverage - # uses: PSModule/GitHub-Script@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - # Script: | - # $PSStyle.OutputRendering = 'Ansi' - # $repo = $env:GITHUB_REPOSITORY - # $runId = $env:GITHUB_RUN_ID - # gh run download $runId --repo $repo --pattern *-CodeCoverage - # $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object - # # Load the first XML as the base report - # [xml]$mergedReport = Get-Content -Path $files[0] - - # # Function to merge counters - # function Merge-Counters($baseNode, $newNode) { - # foreach ($newCounter in $newNode.counter) { - # $baseCounter = $baseNode.counter | Where-Object { $_.type -eq $newCounter.type } - # if ($baseCounter) { - # $baseCounter.missed = [int]$baseCounter.missed + [int]$newCounter.missed - # $baseCounter.covered = [int]$baseCounter.covered + [int]$newCounter.covered - # } else { - # # Import new counter if it doesn't exist - # $importedCounter = $mergedReport.ImportNode($newCounter, $true) - # $baseNode.AppendChild($importedCounter) | Out-Null - # } - # } - # } - - # # Loop through remaining reports to merge coverage data - # foreach ($reportPath in $files[1..($files.Count - 1)]) { - # [xml]$currentReport = Get-Content -Path $reportPath - - # # Merge the top-level counters - # Merge-Counters -baseNode $mergedReport.report -newNode $currentReport.report - - # # Merge packages and classes - # foreach ($package in $currentReport.report.package) { - # $basePackage = $mergedReport.report.package | Where-Object { $_.name -eq $package.name } - - # if ($basePackage) { - # # Merge counters at package level - # Merge-Counters -baseNode $basePackage -newNode $package - - # foreach ($class in $package.class) { - # $baseClass = $basePackage.class | Where-Object { $_.name -eq $class.name } - # if ($baseClass) { - # # Merge counters at class level - # Merge-Counters -baseNode $baseClass -newNode $class - # } else { - # # Import new class - # $importedClass = $mergedReport.ImportNode($class, $true) - # $basePackage.AppendChild($importedClass) | Out-Null - # } - # } - # } else { - # # Import entire new package - # $importedPackage = $mergedReport.ImportNode($package, $true) - # $mergedReport.report.AppendChild($importedPackage) | Out-Null - # } - # } - # } - - # # Output the combined report - # $mergedReport.Save("merged-jacoco-report.xml") - - # # Assuming $mergedReport is your final [xml] object: - # $xmlString = $mergedReport.OuterXml - - # # To format (pretty-print) the XML nicely: - # $stringWriter = New-Object System.IO.StringWriter - # $xmlWriter = [System.Xml.XmlTextWriter]::new($stringWriter) - # $xmlWriter.Formatting = "Indented" - # $mergedReport.WriteTo($xmlWriter) - # $xmlWriter.Flush() - # $prettyXml = $stringWriter.ToString() - - # $prettyXml | Out-String - - # # Output or export the XML string - # # $prettyXml | Out-File -FilePath "merged-jacoco-report.xml" -Encoding UTF8 - - # TestModuleStatus: # name: Test module status # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} From 6ff3216d5304d77b32f2b326d321ea4ce026788a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 22:17:08 +0100 Subject: [PATCH 153/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 73b9cabaea65fff5b2cdc1be33d5091c3bbb028a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 22:26:21 +0100 Subject: [PATCH 154/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 12ae4956fb4c02ed942ad4f8c11a9e5a9f1b3644 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 22:50:55 +0100 Subject: [PATCH 155/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 894a2288ec2491d1d425d2d88f424aea20558a44 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 23:07:01 +0100 Subject: [PATCH 156/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 28913944a6e368a9220357d0e92b360959ca49d6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 23:26:21 +0100 Subject: [PATCH 157/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From cfa7a190db05831e75f4311d3f5556f05b8fb5f2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 23:46:04 +0100 Subject: [PATCH 158/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From c8734f22113a2846ae56db478c58ff7d73acbc59 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Mar 2025 23:58:53 +0100 Subject: [PATCH 159/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 409e5ca6ef16786f297518504f2ac41bd1161b38 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 00:24:40 +0100 Subject: [PATCH 160/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 64315ac4574acbc77fc163fb8d4e84b2356b3cfa Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 00:40:40 +0100 Subject: [PATCH 161/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 476e31f15ccf6534765f25224473193adfd0ceaf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 22:11:42 +0100 Subject: [PATCH 162/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 75e822e35a7113c80755945dccff587635553c0c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 22:21:14 +0100 Subject: [PATCH 163/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 121065b46adfc89f82ef0e8deeecd1e0393fa7e9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 22:31:07 +0100 Subject: [PATCH 164/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From b646a6ad65a165fa949b8315dd10e4b9c9fc2cfb Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 22:37:23 +0100 Subject: [PATCH 165/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 70afd798c2aa3c064db4506fb714dc49f7c6485a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 22:56:26 +0100 Subject: [PATCH 166/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 4df00d448ba9bba0ee0236617665223018123ced Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 23:28:55 +0100 Subject: [PATCH 167/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 11b471150c2d5909053f2510ecf75de3565ca11a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 4 Mar 2025 23:57:33 +0100 Subject: [PATCH 168/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 350eaf11fa190d9d9fe8e726df5bbc7b48bdc834 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 00:21:02 +0100 Subject: [PATCH 169/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 89384dad34d7092adcce7512025ceb612eec55a2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 00:44:39 +0100 Subject: [PATCH 170/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 4391674efcfaca8981f0a4a78f3b1a6383400ff1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 00:56:08 +0100 Subject: [PATCH 171/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From f0f2045cc14c43b34f7883e2b4362cd707af2f8e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 01:02:24 +0100 Subject: [PATCH 172/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 39ce66ca21630cc531957a92bb4a67dbce6eece8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 01:12:25 +0100 Subject: [PATCH 173/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 5e84245bb0abdc01649edda2732fd926982400a8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 01:25:41 +0100 Subject: [PATCH 174/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From e17a803fcaf6fe9d71b4b23e1a8e9867e358abb4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 01:31:37 +0100 Subject: [PATCH 175/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From aeda89ebc1e1b8a5e45caf5663b8d37d3b669cc5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 01:43:07 +0100 Subject: [PATCH 176/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 3de78cf1d7b7a8cc3f4db52218a1e0149262cf2e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 02:02:58 +0100 Subject: [PATCH 177/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 089c33d6519ad88d31f7c9a16534b445a48c1e1f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 02:13:46 +0100 Subject: [PATCH 178/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 6fe3e3d7f992da975c24613003d61caaaa901e67 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 04:12:58 +0100 Subject: [PATCH 179/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 1275184ccf7221b74ab7c22d28cf747de1006b20 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 04:33:49 +0100 Subject: [PATCH 180/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 7d81b654113bf969af317529fc3a687bab70823c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 04:52:50 +0100 Subject: [PATCH 181/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 34b670d81525813ae5bebeaa87f5ad0851b020e2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 05:03:32 +0100 Subject: [PATCH 182/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 8971644f1d335904a9e43f48a4612f2e5109a69b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 05:08:29 +0100 Subject: [PATCH 183/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From fe58bec4d6233ef678ecda8460155d4ccb067679 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 05:12:30 +0100 Subject: [PATCH 184/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 88bb4a7ee25c22b8736fbe2f1284e9c64ba4501f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 05:19:27 +0100 Subject: [PATCH 185/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From eee504693109fdcb7cfcf7eebec873a7e3a52a6f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 05:26:21 +0100 Subject: [PATCH 186/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 27bd659d9c21e584efa3a3f112c8fbd9defc0365 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 05:32:17 +0100 Subject: [PATCH 187/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From b4121b598d0d990487398ed0e2c7dc3f6eb6ed0f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 11:02:08 +0100 Subject: [PATCH 188/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 7510ce58916f8ebf5b21912f0a01cbf1d6b81c8e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 11:08:49 +0100 Subject: [PATCH 189/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 81c86a28a1ed19afdbb1f62bae12b04c61eb002a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 11:16:45 +0100 Subject: [PATCH 190/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 5cecd33d6f33dd6a77904638a24b0102b9efeda3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 11:21:19 +0100 Subject: [PATCH 191/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From a12ff84760fd501bc8c89b490e0df62fec439678 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 11:26:50 +0100 Subject: [PATCH 192/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 429e9367a186c6b9f76b0adf87c910ea31996edc Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 11:35:17 +0100 Subject: [PATCH 193/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Remove=20unnec?= =?UTF-8?q?essary=20blank=20line=20from=20README.md=20for=20improved=20rea?= =?UTF-8?q?dability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 22d8e974a0d16e3ae7f46b9a0c4f4def4957f0ed Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 11:41:55 +0100 Subject: [PATCH 194/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Refactor=20Get-C?= =?UTF-8?q?odeCoverage=20job=20to=20use=20external=20workflow=20for=20impr?= =?UTF-8?q?oved=20maintainability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 106 +++++---------------------------------- 1 file changed, 13 insertions(+), 93 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b58e3add..14267756 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -191,100 +191,20 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - - # Get-CodeCoverage: - # name: Get-CodeCoverage - # runs-on: ubuntu-latest - # needs: - # - Test-SourceCode - # - Test-Module - # - Test-ModuleLocal - # steps: - # - name: Get-CodeCoverage - # uses: PSModule/GitHub-Script@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - # Script: | - # $PSStyle.OutputRendering = 'Ansi' - # $repo = $env:GITHUB_REPOSITORY - # $runId = $env:GITHUB_RUN_ID - # gh run download $runId --repo $repo --pattern *-CodeCoverage - # $files = Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName | Sort-Object - # # Load the first XML as the base report - # [xml]$mergedReport = Get-Content -Path $files[0] - - # # Function to merge counters - # function Merge-Counters($baseNode, $newNode) { - # foreach ($newCounter in $newNode.counter) { - # $baseCounter = $baseNode.counter | Where-Object { $_.type -eq $newCounter.type } - # if ($baseCounter) { - # $baseCounter.missed = [int]$baseCounter.missed + [int]$newCounter.missed - # $baseCounter.covered = [int]$baseCounter.covered + [int]$newCounter.covered - # } else { - # # Import new counter if it doesn't exist - # $importedCounter = $mergedReport.ImportNode($newCounter, $true) - # $baseNode.AppendChild($importedCounter) | Out-Null - # } - # } - # } - - # # Loop through remaining reports to merge coverage data - # foreach ($reportPath in $files[1..($files.Count - 1)]) { - # [xml]$currentReport = Get-Content -Path $reportPath - - # # Merge the top-level counters - # Merge-Counters -baseNode $mergedReport.report -newNode $currentReport.report - - # # Merge packages and classes - # foreach ($package in $currentReport.report.package) { - # $basePackage = $mergedReport.report.package | Where-Object { $_.name -eq $package.name } - - # if ($basePackage) { - # # Merge counters at package level - # Merge-Counters -baseNode $basePackage -newNode $package - - # foreach ($class in $package.class) { - # $baseClass = $basePackage.class | Where-Object { $_.name -eq $class.name } - # if ($baseClass) { - # # Merge counters at class level - # Merge-Counters -baseNode $baseClass -newNode $class - # } else { - # # Import new class - # $importedClass = $mergedReport.ImportNode($class, $true) - # $basePackage.AppendChild($importedClass) | Out-Null - # } - # } - # } else { - # # Import entire new package - # $importedPackage = $mergedReport.ImportNode($package, $true) - # $mergedReport.report.AppendChild($importedPackage) | Out-Null - # } - # } - # } - - # # Output the combined report - # $mergedReport.Save("merged-jacoco-report.xml") - - # # Assuming $mergedReport is your final [xml] object: - # $xmlString = $mergedReport.OuterXml - - # # To format (pretty-print) the XML nicely: - # $stringWriter = New-Object System.IO.StringWriter - # $xmlWriter = [System.Xml.XmlTextWriter]::new($stringWriter) - # $xmlWriter.Formatting = "Indented" - # $mergedReport.WriteTo($xmlWriter) - # $xmlWriter.Flush() - # $prettyXml = $stringWriter.ToString() - - # $prettyXml | Out-String - - # # Output or export the XML string - # # $prettyXml | Out-File -FilePath "merged-jacoco-report.xml" -Encoding UTF8 + Get-CodeCoverage: + name: Get-CodeCoverage + needs: + - Test-SourceCode + - Test-Module + - Test-ModuleLocal + uses: ./.github/workflows/Get-CodeCoverage.yml + secrets: inherit + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} # TestModuleStatus: # name: Test module status From c67d57d1a4551dadb7e8a31e2fc8855651faad1a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 20:40:42 +0100 Subject: [PATCH 195/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Test-Mo?= =?UTF-8?q?duleLocal=20workflow=20to=20install=20PSModuleHelpers=20and=20s?= =?UTF-8?q?treamline=20module=20installation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index ccaa4920..3e033b10 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -105,11 +105,15 @@ jobs: name: module path: ${{ inputs.WorkingDirectory }}/outputs/module - - name: Debug + - name: Install-PSModuleHelpers + uses: PSModule/Install-PSModuleHelpers@v1 + + - name: Get-ModuleName shell: pwsh working-directory: ${{ inputs.WorkingDirectory }} run: | - Get-ChildItem . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object + $name = Get-ChildItem "outputs/module" | Select-Object -ExpandProperty Name + Install-PSModule -Path "outputs/module/$name" - name: Test-ModuleLocal uses: PSModule/Invoke-Pester@v3 From 3b2d649096d335730dc1fc2a951e8ef152b8f050 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 20:48:26 +0100 Subject: [PATCH 196/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Add=20a=20blan?= =?UTF-8?q?k=20line=20to=20README.md=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From b20fe0380ea5e9470a5d3ae9ca77e83720971bd2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 20:56:18 +0100 Subject: [PATCH 197/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Test-Mo?= =?UTF-8?q?duleLocal=20workflow=20to=20import=20module=20path=20dynamicall?= =?UTF-8?q?y=20for=20improved=20flexibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 3e033b10..9d3997cd 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -108,12 +108,14 @@ jobs: - name: Install-PSModuleHelpers uses: PSModule/Install-PSModuleHelpers@v1 - - name: Get-ModuleName + - name: Import-Module + id: import-module shell: pwsh working-directory: ${{ inputs.WorkingDirectory }} run: | $name = Get-ChildItem "outputs/module" | Select-Object -ExpandProperty Name - Install-PSModule -Path "outputs/module/$name" + $path = Install-PSModule -Path "outputs/module/$name" -PassThru + "path=$path" >> $GITHUB_OUTPUT - name: Test-ModuleLocal uses: PSModule/Invoke-Pester@v3 @@ -129,5 +131,5 @@ jobs: Output_Verbosity: Detailed CodeCoverage_OutputFormat: JaCoCo Path: ${{ inputs.TestFolderPath }} - Run_Path: outputs/module + Run_Path: ${{ steps.import-module.outputs.path }} WorkingDirectory: ${{ inputs.WorkingDirectory }} From c0c8a476a63bdf9062914d0b8204f7d757cd0c9e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 5 Mar 2025 22:48:08 +0100 Subject: [PATCH 198/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20comment?= =?UTF-8?q?ed-out=20TestModuleStatus=20job=20for=20cleaner=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 137 ----------------- .github/workflows/workflow.yml | 263 ++++++++------------------------- 2 files changed, 64 insertions(+), 336 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 14267756..c5ebaa00 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -205,140 +205,3 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - - # TestModuleStatus: - # name: Test module status - # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} - # needs: - # - TestModule-pwsh-ubuntu-latest - # - TestModule-pwsh-macos-latest - # - TestModule-pwsh-windows-latest - # runs-on: ubuntu-latest - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Summerize tests - # uses: PSModule/GitHub-Script@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - # Script: | - # LogGroup -Name 'Test analysis' { - - # $linuxPassed = '${{ needs.TestModule-pwsh-ubuntu-latest.outputs.passed }}' -eq 'true' - # $linuxSkipped = '${{ needs.TestModule-pwsh-ubuntu-latest.result }}' -eq 'skipped' - # $macOSPassed = '${{ needs.TestModule-pwsh-macos-latest.outputs.passed }}' -eq 'true' - # $macOSSkipped = '${{ needs.TestModule-pwsh-macos-latest.result }}' -eq 'skipped' - # $windowsPassed = '${{ needs.TestModule-pwsh-windows-latest.outputs.passed }}' -eq 'true' - # $windowsSkipped = '${{ needs.TestModule-pwsh-windows-latest.result }}' -eq 'skipped' - # $anyPassed = $linuxPassed -or $macOSPassed -or $windowsPassed - # $allSkipped = $linuxSkipped -and $macOSSkipped -and $windowsSkipped - - # $Status = @( - # [pscustomobject]@{ - # Name = 'Linux' - # Icon = $linuxSkipped ? '⚠️' : $linuxPassed ? '✅' : '❌' - # Status = $linuxSkipped ? 'Skipped' : $linuxPassed ? 'Passed' : 'Failed' - # } - # [pscustomobject]@{ - # Name = 'MacOS' - # Icon = $macOSSkipped ? '⚠️' : $macOSPassed ? '✅' : '❌' - # Status = $macOSSkipped ? 'Skipped' : $macOSPassed ? 'Passed' : 'Failed' - # } - # [pscustomobject]@{ - # Name = 'Windows' - # Icon = $windowsSkipped ? '⚠️' : $windowsPassed ? '✅' : '❌' - # Status = $windowsSkipped ? 'Skipped' : $windowsPassed ? 'Passed' : 'Failed' - # } - # [pscustomobject]@{ - # Name = 'Result' - # Icon = $allSkipped ? '⚠️' : $anyPassed ? '✅' : '❌' - # Status = $allSkipped ? 'Skipped' : $anyPassed ? 'Passed' : 'Failed' - # } - # ) - - # Write-Host ($Status | Format-Table | Out-String) - # ($Status | New-MDTable) | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append - - # if (-not $anyPassed -and -not $allSkipped) { - # Write-Host "::[error]::No tests passed" - # exit 1 - # } - # } - - # LogGroup 'Data' { - # $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}/$moduleName" - # $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" - - # # Obay module manifest overrides - # $sourcePath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.Path }}" - # $sourceModuleManifestPath = Join-Path -Path $sourcePath -ChildPath "manifest.psd1" - # if (Test-Path -Path $sourceModuleManifestPath) { - # $sourceManifest = Import-PowerShellDataFile -Path $sourceModuleManifestPath - # } - - # $data = [pscustomobject]@{ - # ModuleName = $moduleName - # Path = $path - # ModuleManifestPath = $moduleManifestPath - # } - # Write-Verbose ($data | Format-List | Out-String) -Verbose - - # # If the source module manifest has a PowerShellVersion, use that, otherwise use the latest version. - # $powerShellVersion = $sourceManifest.PowerShellVersion ?? '7.4' - # Set-ModuleManifest -Path $moduleManifestPath -PowerShellVersion $powerShellVersion - - # Add-ModuleManifestData -Path $moduleManifestPath -CompatiblePSEditions 'Core' - # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'PSEdition_Core' - - # if ($linuxPassed) { - # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Linux' - # } - - # if ($macOSPassed) { - # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'MacOS' - # } - - # if ($windowsPassed) { - # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Windows' - # } - # } - - # LogGroup 'Module Manifest - Source' { - # Show-FileContent -Path $moduleManifestPath - # } - - # LogGroup 'Module Manifest' { - # Show-FileContent -Path $moduleManifestPath - # } - - # - name: Upload module artifact - # uses: actions/upload-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - # if-no-files-found: error - # retention-days: 1 - # overwrite: true diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9519ac44..11ee5bf4 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -213,202 +213,67 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - # TestModuleStatus: - # name: Test module status - # if: ${{ contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-ubuntu-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-macos-latest.result) && contains(fromJson('["success", "skipped"]'), needs.TestModule-pwsh-windows-latest.result) && !cancelled() }} - # needs: - # - TestModule-pwsh-ubuntu-latest - # - TestModule-pwsh-macos-latest - # - TestModule-pwsh-windows-latest - # runs-on: ubuntu-latest - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Summerize tests - # uses: PSModule/GitHub-Script@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - # Script: | - # LogGroup -Name 'Test analysis' { - - # $linuxPassed = '${{ needs.TestModule-pwsh-ubuntu-latest.outputs.passed }}' -eq 'true' - # $linuxSkipped = '${{ needs.TestModule-pwsh-ubuntu-latest.result }}' -eq 'skipped' - # $macOSPassed = '${{ needs.TestModule-pwsh-macos-latest.outputs.passed }}' -eq 'true' - # $macOSSkipped = '${{ needs.TestModule-pwsh-macos-latest.result }}' -eq 'skipped' - # $windowsPassed = '${{ needs.TestModule-pwsh-windows-latest.outputs.passed }}' -eq 'true' - # $windowsSkipped = '${{ needs.TestModule-pwsh-windows-latest.result }}' -eq 'skipped' - # $anyPassed = $linuxPassed -or $macOSPassed -or $windowsPassed - # $allSkipped = $linuxSkipped -and $macOSSkipped -and $windowsSkipped - - # $Status = @( - # [pscustomobject]@{ - # Name = 'Linux' - # Icon = $linuxSkipped ? '⚠️' : $linuxPassed ? '✅' : '❌' - # Status = $linuxSkipped ? 'Skipped' : $linuxPassed ? 'Passed' : 'Failed' - # } - # [pscustomobject]@{ - # Name = 'MacOS' - # Icon = $macOSSkipped ? '⚠️' : $macOSPassed ? '✅' : '❌' - # Status = $macOSSkipped ? 'Skipped' : $macOSPassed ? 'Passed' : 'Failed' - # } - # [pscustomobject]@{ - # Name = 'Windows' - # Icon = $windowsSkipped ? '⚠️' : $windowsPassed ? '✅' : '❌' - # Status = $windowsSkipped ? 'Skipped' : $windowsPassed ? 'Passed' : 'Failed' - # } - # [pscustomobject]@{ - # Name = 'Result' - # Icon = $allSkipped ? '⚠️' : $anyPassed ? '✅' : '❌' - # Status = $allSkipped ? 'Skipped' : $anyPassed ? 'Passed' : 'Failed' - # } - # ) - - # Write-Host ($Status | Format-Table | Out-String) - # ($Status | New-MDTable) | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append - - # if (-not $anyPassed -and -not $allSkipped) { - # Write-Host "::[error]::No tests passed" - # exit 1 - # } - # } - - # LogGroup 'Data' { - # $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - # $path = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.ModulesOutputPath }}/$moduleName" - # $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" - - # # Obay module manifest overrides - # $sourcePath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "${{ inputs.Path }}" - # $sourceModuleManifestPath = Join-Path -Path $sourcePath -ChildPath "manifest.psd1" - # if (Test-Path -Path $sourceModuleManifestPath) { - # $sourceManifest = Import-PowerShellDataFile -Path $sourceModuleManifestPath - # } - - # $data = [pscustomobject]@{ - # ModuleName = $moduleName - # Path = $path - # ModuleManifestPath = $moduleManifestPath - # } - # Write-Verbose ($data | Format-List | Out-String) -Verbose - - # # If the source module manifest has a PowerShellVersion, use that, otherwise use the latest version. - # $powerShellVersion = $sourceManifest.PowerShellVersion ?? '7.4' - # Set-ModuleManifest -Path $moduleManifestPath -PowerShellVersion $powerShellVersion - - # Add-ModuleManifestData -Path $moduleManifestPath -CompatiblePSEditions 'Core' - # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'PSEdition_Core' - - # if ($linuxPassed) { - # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Linux' - # } - - # if ($macOSPassed) { - # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'MacOS' - # } - - # if ($windowsPassed) { - # Add-ModuleManifestData -Path $moduleManifestPath -Tags 'Windows' - # } - # } - - # LogGroup 'Module Manifest - Source' { - # Show-FileContent -Path $moduleManifestPath - # } - - # LogGroup 'Module Manifest' { - # Show-FileContent -Path $moduleManifestPath - # } - - # - name: Upload module artifact - # uses: actions/upload-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - # if-no-files-found: error - # retention-days: 1 - # overwrite: true - - # PublishModule: - # name: Publish module - # if: ${{ needs.TestModuleStatus.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} - # needs: - # - TestModuleStatus - # - Build-Docs - # runs-on: ubuntu-latest - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Initialize environment - # uses: PSModule/Initialize-PSModule@v1 - # with: - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # - name: Download module artifact - # uses: actions/download-artifact@v4 - # with: - # name: module - # path: ${{ inputs.ModulesOutputPath }} - - # - name: Publish module - # uses: PSModule/Publish-PSModule@v1 - # with: - # Name: ${{ inputs.Name }} - # ModulePath: ${{ inputs.ModulesOutputPath }} - # APIKey: ${{ secrets.APIKEY }} - # WhatIf: ${{ inputs.TestProcess }} - # Debug: ${{ inputs.Debug }} - # Prerelease: ${{ inputs.Prerelease }} - # Verbose: ${{ inputs.Verbose }} - # Version: ${{ inputs.Version }} - - # PublishSite: - # name: Publish documentation - # if: ${{ inputs.PublishDocs && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} - # needs: - # - TestModuleStatus - # - Build-Docs - # permissions: - # pages: write # to deploy to Pages - # id-token: write # to verify the deployment originates from an appropriate source - # environment: - # name: github-pages - # url: ${{ steps.deployment.outputs.page_url }} - # runs-on: ubuntu-latest - # steps: - # - name: Debug - # if: ${{ inputs.Debug }} - # uses: PSModule/Debug@v0 - - # - name: Deploy to GitHub Pages - # id: deployment - # uses: actions/deploy-pages@v4 + PublishModule: + name: Publish module + if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} + needs: + - Get-TestResults + - Get-CodeCoverage + - Build-Docs + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Debug + if: ${{ inputs.Debug }} + uses: PSModule/Debug@v0 + + - name: Initialize environment + uses: PSModule/Initialize-PSModule@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + - name: Download module artifact + uses: actions/download-artifact@v4 + with: + name: module + path: ${{ inputs.ModulesOutputPath }} + + - name: Publish module + uses: PSModule/Publish-PSModule@v1 + with: + Name: ${{ inputs.Name }} + ModulePath: ${{ inputs.ModulesOutputPath }} + APIKey: ${{ secrets.APIKEY }} + WhatIf: ${{ inputs.TestProcess }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + + PublishSite: + name: Publish documentation + if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} + needs: + - Get-TestResults + - Get-CodeCoverage + - Build-Docs + permissions: + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Debug + if: ${{ inputs.Debug }} + uses: PSModule/Debug@v0 + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 From 5308e9571e599d121907c56ebbc562226cb95c42 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 10:34:15 +0100 Subject: [PATCH 199/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20default?= =?UTF-8?q?=20working=20directory=20in=20workflows=20to=20current=20direct?= =?UTF-8?q?ory=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 2 +- .github/workflows/workflow.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c5ebaa00..4516bb88 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -61,7 +61,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' permissions: contents: read # to checkout the repository diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 11ee5bf4..645ff734 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -36,7 +36,7 @@ on: type: string description: The path to the root of the repo. required: false - default: ${{ github.workspace }} + default: '.' SkipTests: type: string description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. From ea5a39e3a1df4194ff260febaf8931f710c9acd6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 13:10:32 +0100 Subject: [PATCH 200/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20CodeCovera?= =?UTF-8?q?ge=5FCoveragePercentTarget=20parameter=20to=20Test-ModuleLocal?= =?UTF-8?q?=20workflow=20for=20enhanced=20coverage=20control?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 9d3997cd..58234206 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -130,6 +130,7 @@ jobs: CodeCoverage_Enabled: true Output_Verbosity: Detailed CodeCoverage_OutputFormat: JaCoCo + CodeCoverage_CoveragePercentTarget: 20 Path: ${{ inputs.TestFolderPath }} Run_Path: ${{ steps.import-module.outputs.path }} WorkingDirectory: ${{ inputs.WorkingDirectory }} From 70bb8f9ea74645e9b1451ba1c8c49da1c8b00dd6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 13:10:50 +0100 Subject: [PATCH 201/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Set=20CodeCovera?= =?UTF-8?q?ge=5FCoveragePercentTarget=20to=200=20for=20disabling=20coverag?= =?UTF-8?q?e=20threshold?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 58234206..a1800d6b 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -130,7 +130,7 @@ jobs: CodeCoverage_Enabled: true Output_Verbosity: Detailed CodeCoverage_OutputFormat: JaCoCo - CodeCoverage_CoveragePercentTarget: 20 + CodeCoverage_CoveragePercentTarget: 0 Path: ${{ inputs.TestFolderPath }} Run_Path: ${{ steps.import-module.outputs.path }} WorkingDirectory: ${{ inputs.WorkingDirectory }} From fe1f92a68137879d82d4853bf02f22807c810afd Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 17:22:06 +0100 Subject: [PATCH 202/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20default?= =?UTF-8?q?=20working=20directory=20in=20workflows=20to=20current=20direct?= =?UTF-8?q?ory=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 2 +- .github/workflows/Build-Module.yml | 2 +- .github/workflows/Get-CodeCoverage.yml | 2 +- .github/workflows/Get-TestResults.yml | 2 +- .github/workflows/Get-TestSuites.yml | 2 +- .github/workflows/Test-Module.yml | 2 +- .github/workflows/Test-ModuleLocal.yml | 2 +- .github/workflows/Test-SourceCode.yml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index d214ae03..0489748c 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -31,7 +31,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' permissions: contents: read # to checkout the repo diff --git a/.github/workflows/Build-Module.yml b/.github/workflows/Build-Module.yml index 7e5ae5a8..b61fd893 100644 --- a/.github/workflows/Build-Module.yml +++ b/.github/workflows/Build-Module.yml @@ -31,7 +31,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' permissions: contents: read # to checkout the repository diff --git a/.github/workflows/Get-CodeCoverage.yml b/.github/workflows/Get-CodeCoverage.yml index 7220865d..4f83f2fe 100644 --- a/.github/workflows/Get-CodeCoverage.yml +++ b/.github/workflows/Get-CodeCoverage.yml @@ -27,7 +27,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' permissions: contents: read # to checkout the repo diff --git a/.github/workflows/Get-TestResults.yml b/.github/workflows/Get-TestResults.yml index 1bc1a701..709b63b4 100644 --- a/.github/workflows/Get-TestResults.yml +++ b/.github/workflows/Get-TestResults.yml @@ -27,7 +27,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' permissions: contents: read # to checkout the repo diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 3ba50a3d..11030314 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -27,7 +27,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' outputs: TestSuites: diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 326239af..2a37c8d7 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -66,7 +66,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' env: TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index a1800d6b..957914ce 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -76,7 +76,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' env: TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 4946f8e3..45139d60 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -44,7 +44,7 @@ on: type: string description: The working directory where the script will run from. required: false - default: ${{ github.workspace }} + default: '.' permissions: contents: read # to checkout the repo and create releases on the repo From a8563e12dfac9d082877ee4471e39ffe1e2bc15c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 18:36:23 +0100 Subject: [PATCH 203/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20warning=20?= =?UTF-8?q?output=20for=20module=20installation=20path=20in=20Test-ModuleL?= =?UTF-8?q?ocal=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 957914ce..71d7ad59 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -115,6 +115,7 @@ jobs: run: | $name = Get-ChildItem "outputs/module" | Select-Object -ExpandProperty Name $path = Install-PSModule -Path "outputs/module/$name" -PassThru + Write-Warning $path "path=$path" >> $GITHUB_OUTPUT - name: Test-ModuleLocal From a58d4ad087bfb585598497f27c04bea3b0c927f2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 18:48:26 +0100 Subject: [PATCH 204/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20output?= =?UTF-8?q?=20path=20variable=20to=20use=20environment=20variable=20for=20?= =?UTF-8?q?GitHub=20Actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 71d7ad59..6eb6d3e9 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -116,7 +116,7 @@ jobs: $name = Get-ChildItem "outputs/module" | Select-Object -ExpandProperty Name $path = Install-PSModule -Path "outputs/module/$name" -PassThru Write-Warning $path - "path=$path" >> $GITHUB_OUTPUT + "path=$path" >> $env:GITHUB_OUTPUT - name: Test-ModuleLocal uses: PSModule/Invoke-Pester@v3 From 75fe36873fc575b1886d2fcc559cf892acf7a2e8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 19:12:03 +0100 Subject: [PATCH 205/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Fix=20input=20va?= =?UTF-8?q?riable=20references=20for=20Debug=20and=20Verbose=20in=20Test-M?= =?UTF-8?q?oduleLocal=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 6eb6d3e9..ca2e3f2f 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -122,9 +122,9 @@ jobs: uses: PSModule/Invoke-Pester@v3 continue-on-error: true with: - Debug: true #${{ inputs.Debug }} + Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} - Verbose: true #${{ inputs.Verbose }} + Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} TestResult_TestSuiteName: ${{ inputs.TestName }}-${{ inputs.OS }} TestResult_Enabled: true From 19f57e060d55bf5222ddc816409bb033e9db9144 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 19:21:29 +0100 Subject: [PATCH 206/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Move=20environme?= =?UTF-8?q?nt=20variable=20definitions=20to=20the=20job=20level=20in=20Tes?= =?UTF-8?q?t-ModuleLocal=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index ca2e3f2f..d99be938 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -78,15 +78,6 @@ on: required: false default: '.' -env: - TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} - TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} - TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }} - TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }} - TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} - TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} - TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} - permissions: contents: read # to checkout the repo and create releases on the repo @@ -121,6 +112,14 @@ jobs: - name: Test-ModuleLocal uses: PSModule/Invoke-Pester@v3 continue-on-error: true + env: + TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} + TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} + TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }} + TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }} + TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} + TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} + TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From a1722164e91e0908c19a169733c57ce9efeb011d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 19:51:03 +0100 Subject: [PATCH 207/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20environmen?= =?UTF-8?q?t=20variable=20definitions=20for=20module=20import=20in=20Test-?= =?UTF-8?q?ModuleLocal=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index d99be938..850e49c7 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -102,8 +102,18 @@ jobs: - name: Import-Module id: import-module shell: pwsh + env: + TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} + TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} + TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }} + TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }} + TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} + TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} + TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} working-directory: ${{ inputs.WorkingDirectory }} run: | + Write-Output " Getting envvars" + Get-ChildItem env: | Select-Object Name, Value | Format-Table -AutoSize | Out-String $name = Get-ChildItem "outputs/module" | Select-Object -ExpandProperty Name $path = Install-PSModule -Path "outputs/module/$name" -PassThru Write-Warning $path From 26d65adb43bdfdcb74bb138492581f7326d66bb3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 22:15:04 +0100 Subject: [PATCH 208/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20hardcod?= =?UTF-8?q?ed=20environment=20variables=20from=20Import-Module=20step=20in?= =?UTF-8?q?=20Test-ModuleLocal=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 850e49c7..d99be938 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -102,18 +102,8 @@ jobs: - name: Import-Module id: import-module shell: pwsh - env: - TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} - TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} - TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }} - TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }} - TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} - TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} - TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} working-directory: ${{ inputs.WorkingDirectory }} run: | - Write-Output " Getting envvars" - Get-ChildItem env: | Select-Object Name, Value | Format-Table -AutoSize | Out-String $name = Get-ChildItem "outputs/module" | Select-Object -ExpandProperty Name $path = Install-PSModule -Path "outputs/module/$name" -PassThru Write-Warning $path From 7e9df45c1f72b52fb9c008c00a171a518b11e4f9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 23:05:11 +0100 Subject: [PATCH 209/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20redunda?= =?UTF-8?q?nt=20checkout=20steps=20and=20rename=20lint=20job=20for=20clari?= =?UTF-8?q?ty=20in=20Test-Module=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 2a37c8d7..b5da5585 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -86,9 +86,6 @@ jobs: if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - - name: Checkout Code - uses: actions/checkout@v4 - - name: Download module artifact uses: actions/download-artifact@v4 with: @@ -108,20 +105,17 @@ jobs: Settings: Module Lint-Module: - name: Lint-SourceCode (${{ inputs.RunsOn }}) + name: Lint-Module (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - - name: Checkout Code - uses: actions/checkout@v4 - - name: Download module artifact uses: actions/download-artifact@v4 with: name: module path: ${{ inputs.WorkingDirectory }}/outputs/module - - name: Lint-SourceCode + - name: Lint-Module uses: PSModule/Invoke-ScriptAnalyzer@v2 continue-on-error: true with: From 21a4509a32ebaabe302d6446a0443981280e7c10 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 6 Mar 2025 23:30:32 +0100 Subject: [PATCH 210/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20job=20c?= =?UTF-8?q?onditions=20and=20paths=20in=20workflow=20for=20improved=20reli?= =?UTF-8?q?ability=20and=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 645ff734..c65befb8 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -187,6 +187,7 @@ jobs: Get-TestResults: name: Get-TestResults + if: always() && !cancelled() needs: - Test-SourceCode - Test-Module @@ -201,6 +202,7 @@ jobs: Get-CodeCoverage: name: Get-CodeCoverage + if: always() && !cancelled() needs: - Test-SourceCode - Test-Module @@ -241,13 +243,13 @@ jobs: uses: actions/download-artifact@v4 with: name: module - path: ${{ inputs.ModulesOutputPath }} + path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Publish module uses: PSModule/Publish-PSModule@v1 with: Name: ${{ inputs.Name }} - ModulePath: ${{ inputs.ModulesOutputPath }} + ModulePath: ${{ inputs.WorkingDirectory }}/outputs/module APIKey: ${{ secrets.APIKEY }} WhatIf: ${{ inputs.TestProcess }} Debug: ${{ inputs.Debug }} From 187bbc90d7e22d9dac03e24f7029c9f8cd531cd2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 8 Mar 2025 10:40:57 +0100 Subject: [PATCH 211/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20checkout?= =?UTF-8?q?=20step=20to=20Test-Module=20workflow=20for=20repository=20acce?= =?UTF-8?q?ss?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index b5da5585..096b1cff 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -86,6 +86,9 @@ jobs: if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Download module artifact uses: actions/download-artifact@v4 with: From 66973400a2faca3395459aa4331286ebbaf800d8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 8 Mar 2025 11:56:18 +0100 Subject: [PATCH 212/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20GITHUB?= =?UTF-8?q?=5FTOKEN=20environment=20variable=20from=20Auto-Release=20workf?= =?UTF-8?q?low?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Auto-Release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/Auto-Release.yml b/.github/workflows/Auto-Release.yml index ec157c9d..680da5c0 100644 --- a/.github/workflows/Auto-Release.yml +++ b/.github/workflows/Auto-Release.yml @@ -30,7 +30,5 @@ jobs: - name: Auto-Release uses: PSModule/Auto-Release@v1 - env: - GITHUB_TOKEN: ${{ github.token }} # Used for GitHub CLI authentication with: IncrementalPrerelease: false From c106046fd5265251b0f313250ddbd47c7cfa520b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 9 Mar 2025 14:25:31 +0100 Subject: [PATCH 213/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Enhance=20test?= =?UTF-8?q?=20suite=20discovery=20logic=20in=20Get-TestSuites=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 57 ++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 11030314..44a99114 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -73,10 +73,61 @@ jobs: } Write-Host "Tests found at [$testsPath]" - # Get all subdirectories inside the tests folder; if none, use the tests folder itself. - $testsPaths = Get-ChildItem -Path $testsPath -Directory | ForEach-Object { $_.FullName } - if (-not $testsPaths) { + # First, check if the root tests folder contains configuration.ps1, .container.ps1 or .tests.ps1 files + $hasTestFiles = Get-ChildItem -Path $testsPath -File -Recurse:$false | Where-Object { + $_.Name -like '*.Configuration.ps1' -or + $_.Name -like '*.Container.ps1' -or + $_.Name -like '*.Tests.ps1' + } + + # Define the test paths based on our findings + $testsPaths = @() + if ($hasTestFiles) { + # If the tests folder directly contains test files, only use the root folder + Write-Host "Test files found directly in tests folder. Using only the root tests folder." $testsPaths = @($testsPath) + } else { + # Otherwise, recursively search for subdirectories that might contain tests + Write-Host "No test files found in root tests folder. Searching subdirectories..." + + # Helper function to find test directories recursively + function Find-TestDirectories { + param ( + [string]$Path + ) + + $directories = @() + $childDirs = Get-ChildItem -Path $Path -Directory + + foreach ($dir in $childDirs) { + # Check if this directory contains test files + $hasTests = Get-ChildItem -Path $dir.FullName -File -Recurse:$false | Where-Object { + $_.Name -like '*.Configuration.ps1' -or + $_.Name -like '*.Container.ps1' -or + $_.Name -like '*.Tests.ps1' + } + + if ($hasTests) { + $directories += $dir.FullName + } else { + # Recursively check subdirectories + $directories += Find-TestDirectories -Path $dir.FullName + } + } + + return $directories + } + + $testsPaths = Find-TestDirectories -Path $testsPath + + # If no test directories were found, default to the root tests folder + if (-not $testsPaths) { + Write-Host "No specific test directories found. Using the root tests folder." + $testsPaths = @($testsPath) + } else { + Write-Host "Found test directories:" + $testsPaths | ForEach-Object { Write-Host " - $_" } + } } # Build the test suites matrix. From e2195dfb9ba55d1786796c3dea932c0924ae1a91 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 9 Mar 2025 14:46:06 +0100 Subject: [PATCH 214/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Remove=20unnece?= =?UTF-8?q?ssary=20blank=20line=20in=20README.md=20for=20improved=20readab?= =?UTF-8?q?ility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 4bfcaaea1f45672613f5ae95a15179d37eb4a6d4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 9 Mar 2025 15:02:20 +0100 Subject: [PATCH 215/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Add=20a=20blank?= =?UTF-8?q?=20line=20in=20README.md=20for=20improved=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From b65cfe36c58760c7dc13ad4bddebfd5c0c4fa222 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 9 Mar 2025 15:19:46 +0100 Subject: [PATCH 216/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Remove=20unnece?= =?UTF-8?q?ssary=20blank=20line=20in=20README.md=20for=20improved=20readab?= =?UTF-8?q?ility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 604cd8281821c17f2bea6ae78a5472eafe44f24d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 9 Mar 2025 15:26:42 +0100 Subject: [PATCH 217/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Add=20a=20blank?= =?UTF-8?q?=20line=20in=20README.md=20for=20improved=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 8c13913b5e86be44c385b7884b44a0d62a4cf9d8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 9 Mar 2025 16:14:17 +0100 Subject: [PATCH 218/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Improve=20GitHub?= =?UTF-8?q?=20module=20installation=20with=20retry=20logic=20in=20Build-Do?= =?UTF-8?q?cs=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 0489748c..a1927c40 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -126,7 +126,26 @@ jobs: - name: Reinstall GitHub module shell: pwsh run: | - Install-PSResource -Name GitHub -TrustRepository -Reinstall + 'GitHub' | ForEach-Object { + $name = $_ + Write-Output "Installing module: $name" + $retryCount = 5 + $retryDelay = 10 + for ($i = 0; $i -lt $retryCount; $i++) { + try { + Install-PSResource -Name $name -WarningAction SilentlyContinue -TrustRepository -Repository PSGallery -Reinstall + break + } catch { + Write-Warning "Installation of $name failed with error: $_" + if ($i -eq $retryCount - 1) { + throw + } + Write-Warning "Retrying in $retryDelay seconds..." + Start-Sleep -Seconds $retryDelay + } + } + Import-Module -Name $name + } - name: Structure site uses: PSModule/GitHub-Script@v1 From 3caa1f598e174ffd4b97651be8ed9a87bc3c6e63 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 9 Mar 2025 20:50:30 +0100 Subject: [PATCH 219/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Invoke-?= =?UTF-8?q?ScriptAnalyzer=20action=20to=20version=203=20in=20Test-Module?= =?UTF-8?q?=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 096b1cff..d0dd2050 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -119,7 +119,7 @@ jobs: path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Lint-Module - uses: PSModule/Invoke-ScriptAnalyzer@v2 + uses: PSModule/Invoke-ScriptAnalyzer@v3 continue-on-error: true with: Path: outputs/module From 47d300c7d2529678b55acf66e3e08027a4a7cce4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 9 Mar 2025 20:50:36 +0100 Subject: [PATCH 220/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Upgrade=20Invoke?= =?UTF-8?q?-Pester=20to=20version=204=20and=20Invoke-ScriptAnalyzer=20to?= =?UTF-8?q?=20version=203=20in=20workflow=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 +- .github/workflows/Test-SourceCode.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index d99be938..33f53f82 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -110,7 +110,7 @@ jobs: "path=$path" >> $env:GITHUB_OUTPUT - name: Test-ModuleLocal - uses: PSModule/Invoke-Pester@v3 + uses: PSModule/Invoke-Pester@v4 continue-on-error: true env: TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 45139d60..3b140a77 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -77,7 +77,7 @@ jobs: uses: actions/checkout@v4 - name: Lint-SourceCode - uses: PSModule/Invoke-ScriptAnalyzer@v2 + uses: PSModule/Invoke-ScriptAnalyzer@v3 with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From 88c3b681c569062e29724b416b92f2f6af7e0afa Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 10:29:31 +0100 Subject: [PATCH 221/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20unneces?= =?UTF-8?q?sary=20initialization=20and=20GitHub=20module=20reinstallation?= =?UTF-8?q?=20steps=20in=20Build-Docs=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 33 -------------------------------- 1 file changed, 33 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index a1927c40..b6d78b93 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -46,15 +46,6 @@ jobs: with: fetch-depth: 0 - - name: Initialize environment - uses: PSModule/Initialize-PSModule@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - - name: Download module artifact uses: actions/download-artifact@v4 with: @@ -123,30 +114,6 @@ jobs: pip install mkdocs-git-revision-date-localized-plugin pip install mkdocs-git-committers-plugin-2 - - name: Reinstall GitHub module - shell: pwsh - run: | - 'GitHub' | ForEach-Object { - $name = $_ - Write-Output "Installing module: $name" - $retryCount = 5 - $retryDelay = 10 - for ($i = 0; $i -lt $retryCount; $i++) { - try { - Install-PSResource -Name $name -WarningAction SilentlyContinue -TrustRepository -Repository PSGallery -Reinstall - break - } catch { - Write-Warning "Installation of $name failed with error: $_" - if ($i -eq $retryCount - 1) { - throw - } - Write-Warning "Retrying in $retryDelay seconds..." - Start-Sleep -Seconds $retryDelay - } - } - Import-Module -Name $name - } - - name: Structure site uses: PSModule/GitHub-Script@v1 with: From 8fa9be4647f71bbac42bacd8bca31151cb5504c4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 11:02:38 +0100 Subject: [PATCH 222/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Remove=20unnece?= =?UTF-8?q?ssary=20blank=20line=20in=20README.md=20for=20improved=20format?= =?UTF-8?q?ting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 0577490f056b6c56e85a5795b6218c9fc14650ad Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 11:12:18 +0100 Subject: [PATCH 223/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Add=20a=20blank?= =?UTF-8?q?=20line=20for=20improved=20readability=20in=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From db33504c4320aa5de1f4443cd4741f6b791d5e05 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 11:36:11 +0100 Subject: [PATCH 224/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Remove=20unnece?= =?UTF-8?q?ssary=20blank=20line=20in=20README.md=20for=20improved=20format?= =?UTF-8?q?ting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 82a9c97c6a20fb663fbbd2e1081831d6e6d22ea9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 11:57:42 +0100 Subject: [PATCH 225/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Add=20a=20blank?= =?UTF-8?q?=20line=20for=20improved=20readability=20in=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 06e34a7864f38661e2a372ee71da6582c1f7fc6e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 12:25:39 +0100 Subject: [PATCH 226/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Remove=20unnece?= =?UTF-8?q?ssary=20blank=20line=20in=20README.md=20for=20improved=20format?= =?UTF-8?q?ting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 97b66682e03b3ebc0f9bb5b2fa3cab913adffa85 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 12:41:53 +0100 Subject: [PATCH 227/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Add=20a=20blank?= =?UTF-8?q?=20line=20for=20improved=20readability=20in=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 557818b0a9aaa106087f603c93f5d08461c1fb3e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 12:51:00 +0100 Subject: [PATCH 228/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Build-D?= =?UTF-8?q?ocs.yml=20to=20use=20GitHub-Script=20for=20committing=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 34 +++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index b6d78b93..edb5c2b8 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -71,22 +71,28 @@ jobs: retention-days: 1 - name: Commit all changes + uses: PSModule/GitHub-Script@v1 continue-on-error: true - shell: pwsh - run: | - # Rename the gitignore file to .gitignore.bak - 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" - } + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Script: | + # Rename the gitignore file to .gitignore.bak + 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 - Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force + # Restore the gitignore file + Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force - name: Lint documentation uses: super-linter/super-linter/slim@latest From 597f6e9005cd5a3d533d5705171287309f654be0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 16:06:38 +0100 Subject: [PATCH 229/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20GITHUB=5FT?= =?UTF-8?q?OKEN=20to=20Test-ModuleLocal.yml=20for=20improved=20authenticat?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 33f53f82..adbd4c4e 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -120,6 +120,7 @@ jobs: TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} + GITHUB_TOKEN: ${{ github.token }} with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From 0ef0ef292492c951e402faa4ce31f0a7186d39d8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 10 Mar 2025 20:03:12 +0100 Subject: [PATCH 230/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20CI=20wo?= =?UTF-8?q?rkflow=20conditions=20to=20always=20run=20jobs=20and=20remove?= =?UTF-8?q?=20unnecessary=20permissions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 2 ++ .github/workflows/workflow.yml | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4516bb88..08f30b37 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -180,6 +180,7 @@ jobs: Get-TestResults: name: Get-TestResults + if: always() && !cancelled() needs: - Test-SourceCode - Test-Module @@ -194,6 +195,7 @@ jobs: Get-CodeCoverage: name: Get-CodeCoverage + if: always() && !cancelled() needs: - Test-SourceCode - Test-Module diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index c65befb8..74258985 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -72,8 +72,6 @@ permissions: contents: write # to checkout the repo and create releases on the repo pull-requests: write # to write comments to PRs statuses: write # to update the status of the workflow from linter - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source jobs: Test-SourceCode: From d5e8d41c4625a0e24401acdeba0f279bdb0cd37c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 11:58:09 +0100 Subject: [PATCH 231/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Refactor=20test?= =?UTF-8?q?=20suite=20retrieval=20logic=20and=20standardize=20test=20path?= =?UTF-8?q?=20parameter=20naming?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 94 ++++++++++---------------- .github/workflows/Test-ModuleLocal.yml | 4 +- .github/workflows/workflow.yml | 22 +++--- 3 files changed, 50 insertions(+), 70 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 44a99114..53b99176 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -73,71 +73,51 @@ jobs: } Write-Host "Tests found at [$testsPath]" - # First, check if the root tests folder contains configuration.ps1, .container.ps1 or .tests.ps1 files - $hasTestFiles = Get-ChildItem -Path $testsPath -File -Recurse:$false | Where-Object { - $_.Name -like '*.Configuration.ps1' -or - $_.Name -like '*.Container.ps1' -or - $_.Name -like '*.Tests.ps1' - } + function Get-TestItemsFromFolder { + param ([string]$FolderPath) + + $configFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Configuration.ps1' + if ($configFiles.Count -eq 1) { + return @($configFiles) + } elseif ($configFiles.Count -gt 1) { + throw "Multiple configuration files found in [$FolderPath]. Please separate configurations into different folders." + } - # Define the test paths based on our findings - $testsPaths = @() - if ($hasTestFiles) { - # If the tests folder directly contains test files, only use the root folder - Write-Host "Test files found directly in tests folder. Using only the root tests folder." - $testsPaths = @($testsPath) - } else { - # Otherwise, recursively search for subdirectories that might contain tests - Write-Host "No test files found in root tests folder. Searching subdirectories..." - - # Helper function to find test directories recursively - function Find-TestDirectories { - param ( - [string]$Path - ) - - $directories = @() - $childDirs = Get-ChildItem -Path $Path -Directory - - foreach ($dir in $childDirs) { - # Check if this directory contains test files - $hasTests = Get-ChildItem -Path $dir.FullName -File -Recurse:$false | Where-Object { - $_.Name -like '*.Configuration.ps1' -or - $_.Name -like '*.Container.ps1' -or - $_.Name -like '*.Tests.ps1' - } + $containerFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Container.ps1' + if ($containerFiles.Count -ge 1) { + return $containerFiles + } - if ($hasTests) { - $directories += $dir.FullName - } else { - # Recursively check subdirectories - $directories += Find-TestDirectories -Path $dir.FullName - } - } + $testFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Tests.ps1' + return $testFiles + } - return $directories - } + function Find-TestDirectories { + param ([string]$Path) - $testsPaths = Find-TestDirectories -Path $testsPath + $directories = @() + $childDirs = Get-ChildItem -Path $Path -Directory - # If no test directories were found, default to the root tests folder - if (-not $testsPaths) { - Write-Host "No specific test directories found. Using the root tests folder." - $testsPaths = @($testsPath) - } else { - Write-Host "Found test directories:" - $testsPaths | ForEach-Object { Write-Host " - $_" } + foreach ($dir in $childDirs) { + $directories += $dir.FullName + $directories += Find-TestDirectories -Path $dir.FullName } + + return $directories } - # Build the test suites matrix. - $testSuites = foreach ($folder in $testsPaths) { - foreach ($osConfig in $osConfigs) { - [pscustomobject]@{ - RunsOn = $osConfig.runson - OSName = $osConfig.name - TestFolderPath = Resolve-Path -Path $folder -Relative - TestName = Split-Path -Path $folder -Leaf + $allTestFolders = @($testsPath) + (Find-TestDirectories -Path $testsPath) + + $testSuites = foreach ($folder in $allTestFolders) { + $testItems = Get-TestItemsFromFolder -FolderPath $folder + foreach ($item in $testItems) { + foreach ($osConfig in $osConfigs) { + [pscustomobject]@{ + RunsOn = $osConfig.runson + OSName = $osConfig.name + TestPath = Resolve-Path -Path $item.FullName -Relative + TestName = $item.BaseName + } } } } diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index adbd4c4e..15e9626d 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -37,7 +37,7 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - TestFolderPath: + TestPath: type: string description: The path to the tests folder. required: false @@ -132,6 +132,6 @@ jobs: Output_Verbosity: Detailed CodeCoverage_OutputFormat: JaCoCo CodeCoverage_CoveragePercentTarget: 0 - Path: ${{ inputs.TestFolderPath }} + Path: ${{ inputs.TestPath }} Run_Path: ${{ steps.import-module.outputs.path }} WorkingDirectory: ${{ inputs.WorkingDirectory }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 74258985..ddad987b 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -120,6 +120,16 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} + Get-TestSuites: + name: Get-TestSuites + uses: ./.github/workflows/Get-TestSuites.yml + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Test-Module: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} name: Test-Module @@ -148,16 +158,6 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Get-TestSuites: - name: Get-TestSuites - uses: ./.github/workflows/Get-TestSuites.yml - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - Test-ModuleLocal: name: ${{ matrix.TestName }} if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} @@ -175,7 +175,7 @@ jobs: OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} SkipTests: ${{ inputs.SkipTests }} - TestFolderPath: ${{ matrix.TestFolderPath }} + TestPath: ${{ matrix.TestPath }} TestName: ${{ matrix.TestName }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From 38fd0d5bb209a07f79f154848a847034ca7bacda Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 12:01:16 +0100 Subject: [PATCH 232/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Rename=20TestFol?= =?UTF-8?q?derPath=20to=20TestPath=20for=20consistency=20in=20CI=20workflo?= =?UTF-8?q?w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 08f30b37..ac1c3e97 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -170,7 +170,7 @@ jobs: OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} SkipTests: ${{ inputs.SkipTests }} - TestFolderPath: ${{ matrix.TestFolderPath }} + TestPath: ${{ matrix.TestPath }} TestName: ${{ matrix.TestName }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From 29192222b08463de58446b46cf95b209290de796 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 12:17:40 +0100 Subject: [PATCH 233/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Refactor=20Get-T?= =?UTF-8?q?estSuites=20workflow=20to=20include=20SkipTests=20input=20and?= =?UTF-8?q?=20separate=20outputs=20for=20SourceCode=20and=20Module=20test?= =?UTF-8?q?=20suites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 33 ++++++++++----------- .github/workflows/Get-TestSuites.yml | 44 ++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ac1c3e97..70b3fece 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -69,18 +69,25 @@ permissions: statuses: write # to update the status of the workflow from linter jobs: + Get-TestSuites: + name: Get-TestSuites + uses: ./.github/workflows/Get-TestSuites.yml + with: + SkipTests: ${{ inputs.SkipTests }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Test-SourceCode: name: Test-SourceCode + needs: + - Get-TestSuites strategy: fail-fast: false matrix: - include: - - OSName: Linux - RunsOn: ubuntu-latest - - OSName: macOS - RunsOn: macos-latest - - OSName: Windows - RunsOn: windows-latest + include: ${{ fromJson(needs.Get-TestSuites.outputs.SourceCodeTestSuites) }} uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: ${{ matrix.RunsOn }} @@ -143,16 +150,6 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Get-TestSuites: - name: Get-TestSuites - uses: ./.github/workflows/Get-TestSuites.yml - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - Test-ModuleLocal: name: ${{ matrix.TestName }} if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} @@ -162,7 +159,7 @@ jobs: strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} + include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleTestSuites) }} uses: ./.github/workflows/Test-ModuleLocal.yml secrets: inherit with: diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 53b99176..749cf7a6 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -3,6 +3,11 @@ name: Get-TestSuites on: workflow_call: inputs: + SkipTests: + type: string + description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. + required: false + default: None Debug: type: boolean description: Enable debug output. @@ -30,9 +35,12 @@ on: default: '.' outputs: - TestSuites: - description: The test suites to run. - value: ${{ jobs.Get-TestSuites.outputs.TestSuites }} + SourceCodeTestSuites: + description: Source Code test suites to run. + value: ${{ jobs.Get-TestSuites.outputs.SourceCodeTestSuites }} + ModuleTestSuites: + description: Module test suites to run. + value: ${{ jobs.Get-TestSuites.outputs.ModuleTestSuites }} permissions: contents: read # to checkout the repo @@ -42,7 +50,8 @@ jobs: name: Get-TestSuites runs-on: ubuntu-latest outputs: - TestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).TestSuites }} + SourceCodeTestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).SourceCodeTestSuites }} + ModuleTestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).ModuleTestSuites }} steps: - name: Checkout Code uses: actions/checkout@v4 @@ -50,6 +59,8 @@ jobs: - name: Get-TestSuites uses: PSModule/GitHub-Script@v1 id: Get-TestSuites + env: + PSMODULE_GET_TESTSUITES_INPUT_SkipTests: ${{ inputs.SkipTests }} with: ShowOutput: true Debug: ${{ inputs.Debug }} @@ -60,9 +71,9 @@ jobs: Script: | # Define test configurations as an array of hashtables. $osConfigs = @( - @{ runson = 'ubuntu-latest'; name = 'Linux' } - @{ runson = 'macos-latest'; name = 'macOS' } - @{ runson = 'windows-latest'; name = 'Windows' } + @{ RunsOn = 'ubuntu-latest'; OSName = 'Linux' } + @{ RunsOn = 'macos-latest'; OSName = 'macOS' } + @{ RunsOn = 'windows-latest'; OSName = 'Windows' } ) # Locate the tests directory. @@ -113,8 +124,8 @@ jobs: foreach ($item in $testItems) { foreach ($osConfig in $osConfigs) { [pscustomobject]@{ - RunsOn = $osConfig.runson - OSName = $osConfig.name + RunsOn = $osConfig.RunsOn + OSName = $osConfig.OSName TestPath = Resolve-Path -Path $item.FullName -Relative TestName = $item.BaseName } @@ -122,8 +133,15 @@ jobs: } } - # (Optional) Display the generated matrix in a table for verification. - $testSuites | Format-Table -AutoSize + # Create separate outputs for source code tests (OS only) and module tests (existing detailed output) + $sourceCodeTestSuites = $osConfigs | Select-Object -Property RunsOn, OSName -Unique + + # Display the generated matrices for verification. + Write-Host "Source Code Test Suites:" + $sourceCodeTestSuites | Format-Table -AutoSize | Out-String + Write-Host "Module Test Suites:" + $testSuites | Format-Table -AutoSize | Out-String - # Pass the final object to GitHub Actions output. - Set-GitHubOutput -Name TestSuites -Value $testSuites + # Pass the final objects to GitHub Actions output. + Set-GitHubOutput -Name SourceCodeTestSuites -Value $sourceCodeTestSuites + Set-GitHubOutput -Name ModuleTestSuites -Value $testSuites From 137a6229fcd7c33de3ed32171f4b644b8e2edd51 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 12:19:35 +0100 Subject: [PATCH 234/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Integrate=20Get-?= =?UTF-8?q?TestSuites=20job=20into=20Test-SourceCode=20and=20Test-Module?= =?UTF-8?q?=20workflows=20for=20improved=20test=20suite=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 9 ++------ .github/workflows/workflow.yml | 42 ++++++++++++++-------------------- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 70b3fece..2cf1d2f4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -127,16 +127,11 @@ jobs: name: Test-Module needs: - Build-Module + - Get-TestSuites strategy: fail-fast: false matrix: - include: - - OSName: Linux - RunsOn: ubuntu-latest - - OSName: macOS - RunsOn: macos-latest - - OSName: Windows - RunsOn: windows-latest + include: ${{ fromJson(needs.Get-TestSuites.outputs.SourceCodeTestSuites) }} uses: ./.github/workflows/Test-Module.yml secrets: inherit with: diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index ddad987b..fefd2b85 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -74,18 +74,25 @@ permissions: statuses: write # to update the status of the workflow from linter jobs: + Get-TestSuites: + name: Get-TestSuites + uses: ./.github/workflows/Get-TestSuites.yml + with: + SkipTests: ${{ inputs.SkipTests }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Test-SourceCode: name: Test-SourceCode + needs: + - Get-TestSuites strategy: fail-fast: false matrix: - include: - - OSName: Linux - RunsOn: ubuntu-latest - - OSName: macOS - RunsOn: macos-latest - - OSName: Windows - RunsOn: windows-latest + include: ${{ fromJson(needs.Get-TestSuites.outputs.SourceCodeTestSuites) }} uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: ${{ matrix.RunsOn }} @@ -120,31 +127,16 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Get-TestSuites: - name: Get-TestSuites - uses: ./.github/workflows/Get-TestSuites.yml - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - Test-Module: if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} name: Test-Module needs: - Build-Module + - Get-TestSuites strategy: fail-fast: false matrix: - include: - - OSName: Linux - RunsOn: ubuntu-latest - - OSName: macOS - RunsOn: macos-latest - - OSName: Windows - RunsOn: windows-latest + include: ${{ fromJson(needs.Get-TestSuites.outputs.SourceCodeTestSuites) }} uses: ./.github/workflows/Test-Module.yml secrets: inherit with: @@ -167,7 +159,7 @@ jobs: strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.TestSuites) }} + include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleTestSuites) }} uses: ./.github/workflows/Test-ModuleLocal.yml secrets: inherit with: From 7430ebdc21a08c2e68a273d8aeb9e962a33bdbb0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 12:32:21 +0100 Subject: [PATCH 235/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Enhance=20Get-Te?= =?UTF-8?q?stSuites=20workflow=20to=20support=20skipping=20specified=20tes?= =?UTF-8?q?ts=20based=20on=20input=20parameters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 749cf7a6..199649f5 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -119,10 +119,22 @@ jobs: $allTestFolders = @($testsPath) + (Find-TestDirectories -Path $testsPath) + $skipTests = $env:PSMODULE_GET_TESTSUITES_INPUT_SkipTests -Split ",|\s+" | ForEach-Object { $_.Trim() } + + Write-Host "The following tests will be skipped:" + $skipTests | ForEach-Object { " - $_ " } + $testSuites = foreach ($folder in $allTestFolders) { $testItems = Get-TestItemsFromFolder -FolderPath $folder foreach ($item in $testItems) { foreach ($osConfig in $osConfigs) { + if ($skipTests -contains 'All' -or + $skipTests -contains $osConfig.OSName -or + ($skipTests -contains 'Module' -and $item.Name -match '\.Tests\.ps1$') -or + ($skipTests -contains 'SourceCode' -and $item.Name -match '\.(Configuration|Container)\.ps1$')) { + continue + } + [pscustomobject]@{ RunsOn = $osConfig.RunsOn OSName = $osConfig.OSName @@ -133,8 +145,10 @@ jobs: } } - # Create separate outputs for source code tests (OS only) and module tests (existing detailed output) - $sourceCodeTestSuites = $osConfigs | Select-Object -Property RunsOn, OSName -Unique + # Adjust source code test suites based on SkipTests + $sourceCodeTestSuites = $osConfigs | Where-Object { + -not ($skipTests -contains 'All' -or $skipTests -contains $_.OSName -or $skipTests -contains 'SourceCode') + } | Select-Object -Property RunsOn, OSName -Unique # Display the generated matrices for verification. Write-Host "Source Code Test Suites:" From e5919c9a65472e668b37e2505494d3820e3a5f4e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 12:37:02 +0100 Subject: [PATCH 236/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Replace=20Write-?= =?UTF-8?q?Host=20with=20LogGroup=20for=20better=20test=20suite=20visibili?= =?UTF-8?q?ty=20in=20Get-TestSuites=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 199649f5..539d655e 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -121,8 +121,9 @@ jobs: $skipTests = $env:PSMODULE_GET_TESTSUITES_INPUT_SkipTests -Split ",|\s+" | ForEach-Object { $_.Trim() } - Write-Host "The following tests will be skipped:" - $skipTests | ForEach-Object { " - $_ " } + LogGroup 'Tests to be skipped:' { + $skipTests | ForEach-Object { " - $_ " } + } $testSuites = foreach ($folder in $allTestFolders) { $testItems = Get-TestItemsFromFolder -FolderPath $folder @@ -151,10 +152,12 @@ jobs: } | Select-Object -Property RunsOn, OSName -Unique # Display the generated matrices for verification. - Write-Host "Source Code Test Suites:" - $sourceCodeTestSuites | Format-Table -AutoSize | Out-String - Write-Host "Module Test Suites:" - $testSuites | Format-Table -AutoSize | Out-String + LogGroup 'Source Code Test Suites:' { + $sourceCodeTestSuites | Format-Table -AutoSize | Out-String + } + LogGroup 'Module Test Suites:' { + $testSuites | Format-Table -AutoSize | Out-String + } # Pass the final objects to GitHub Actions output. Set-GitHubOutput -Name SourceCodeTestSuites -Value $sourceCodeTestSuites From 80553b50af2f410fb328654a80c2abd3d2ae852a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 12:37:52 +0100 Subject: [PATCH 237/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Replace=20Write-?= =?UTF-8?q?Host=20with=20Write-Warning=20for=20improved=20error=20handling?= =?UTF-8?q?=20in=20Get-TestSuites=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 539d655e..3e91f6fb 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -79,7 +79,7 @@ jobs: # Locate the tests directory. $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path if (-not $testsPath -or -not (Test-Path -Path $testsPath)) { - Write-Host 'No tests found' + Write-Warning 'No tests found' exit 0 } Write-Host "Tests found at [$testsPath]" From 7678ec23ffb0faaed1c49238206bd3b45a796185 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 12:43:42 +0100 Subject: [PATCH 238/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Get-Tes?= =?UTF-8?q?tSuites=20workflow=20to=20output=20SourceCode=20and=20Module=20?= =?UTF-8?q?test=20suites=20as=20JSON,=20ensuring=20compatibility=20with=20?= =?UTF-8?q?empty=20results?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 3e91f6fb..30f6a282 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -159,6 +159,6 @@ jobs: $testSuites | Format-Table -AutoSize | Out-String } - # Pass the final objects to GitHub Actions output. - Set-GitHubOutput -Name SourceCodeTestSuites -Value $sourceCodeTestSuites - Set-GitHubOutput -Name ModuleTestSuites -Value $testSuites + # Pass the final objects to GitHub Actions output as JSON + Set-GitHubOutput -Name SourceCodeTestSuites -Value ($sourceCodeTestSuites ?? '[]') + Set-GitHubOutput -Name ModuleTestSuites -Value ($testSuites ?? '[]') From 07e2afbb2264977a9a37e3a242b7a6782f16717f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 12:58:11 +0100 Subject: [PATCH 239/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Test=20?= =?UTF-8?q?jobs=20to=20conditionally=20run=20based=20on=20non-empty=20test?= =?UTF-8?q?=20suite=20outputs=20from=20Get-TestSuites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 5 +++-- .github/workflows/workflow.yml | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2cf1d2f4..c9588021 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -82,6 +82,7 @@ jobs: Test-SourceCode: name: Test-SourceCode + if: ${{ needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} needs: - Get-TestSuites strategy: @@ -123,8 +124,8 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-Module: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} name: Test-Module + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} needs: - Build-Module - Get-TestSuites @@ -147,7 +148,7 @@ jobs: Test-ModuleLocal: name: ${{ matrix.TestName }} - if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} needs: - Build-Module - Get-TestSuites diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index fefd2b85..0394c9ac 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -87,6 +87,7 @@ jobs: Test-SourceCode: name: Test-SourceCode + if: ${{ needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} needs: - Get-TestSuites strategy: @@ -128,8 +129,8 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-Module: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} name: Test-Module + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} needs: - Build-Module - Get-TestSuites @@ -152,7 +153,7 @@ jobs: Test-ModuleLocal: name: ${{ matrix.TestName }} - if: ${{ needs.Build-Module.result == 'success' && !cancelled() }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} needs: - Build-Module - Get-TestSuites From e388e420de4185bdbac570d8509e40407603eb7f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 16:14:47 +0100 Subject: [PATCH 240/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Enhance=20Get-Te?= =?UTF-8?q?stSuites=20workflow=20to=20include=20ModuleLocalTestSuites=20an?= =?UTF-8?q?d=20improve=20test=20suite=20descriptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 28 ++++++++++++++++++++++++---- .github/workflows/workflow.yml | 9 +++------ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 30f6a282..79bffa03 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -36,11 +36,14 @@ on: outputs: SourceCodeTestSuites: - description: Source Code test suites to run. + description: Source Code PSModule test suites to run. value: ${{ jobs.Get-TestSuites.outputs.SourceCodeTestSuites }} ModuleTestSuites: - description: Module test suites to run. + description: Module PSModule test suites to run. value: ${{ jobs.Get-TestSuites.outputs.ModuleTestSuites }} + ModuleLocalTestSuites: + description: Module local test suites to run. + value: ${{ jobs.Get-TestSuites.outputs.ModuleLocalTestSuites }} permissions: contents: read # to checkout the repo @@ -52,6 +55,7 @@ jobs: outputs: SourceCodeTestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).SourceCodeTestSuites }} ModuleTestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).ModuleTestSuites }} + ModuleLocalTestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).ModuleLocalTestSuites }} steps: - name: Checkout Code uses: actions/checkout@v4 @@ -151,14 +155,30 @@ jobs: -not ($skipTests -contains 'All' -or $skipTests -contains $_.OSName -or $skipTests -contains 'SourceCode') } | Select-Object -Property RunsOn, OSName -Unique + # Generate ModuleTestSuites (static tests) + $moduleTestSuites = $testSuites | Where-Object { + $_.TestName -match '\.(Configuration|Container)\.ps1$' -and + -not ($skipTests -contains 'All' -or $skipTests -contains $_.OSName -or $skipTests -contains 'Module') + } + + # Generate ModuleLocalTestSuites (local tests) + $moduleLocalTestSuites = $testSuites | Where-Object { + $_.TestName -match '\.Tests\.ps1$' -and + -not ($skipTests -contains 'All' -or $skipTests -contains $_.OSName -or $skipTests -contains 'Module') + } + # Display the generated matrices for verification. LogGroup 'Source Code Test Suites:' { $sourceCodeTestSuites | Format-Table -AutoSize | Out-String } LogGroup 'Module Test Suites:' { - $testSuites | Format-Table -AutoSize | Out-String + $moduleTestSuites | Format-Table -AutoSize | Out-String + } + LogGroup 'Module Local Test Suites:' { + $moduleLocalTestSuites | Format-Table -AutoSize | Out-String } # Pass the final objects to GitHub Actions output as JSON Set-GitHubOutput -Name SourceCodeTestSuites -Value ($sourceCodeTestSuites ?? '[]') - Set-GitHubOutput -Name ModuleTestSuites -Value ($testSuites ?? '[]') + Set-GitHubOutput -Name ModuleTestSuites -Value ($moduleTestSuites ?? '[]') + Set-GitHubOutput -Name ModuleLocalTestSuites -Value ($moduleLocalTestSuites ?? '[]') diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 0394c9ac..cb14e695 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -99,7 +99,6 @@ jobs: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -130,7 +129,7 @@ jobs: Test-Module: name: Test-Module - if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} needs: - Build-Module - Get-TestSuites @@ -144,7 +143,6 @@ jobs: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -153,21 +151,20 @@ jobs: Test-ModuleLocal: name: ${{ matrix.TestName }} - if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleLocalTestSuites != '[]' }} needs: - Build-Module - Get-TestSuites strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleTestSuites) }} + include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleLocalTestSuites) }} uses: ./.github/workflows/Test-ModuleLocal.yml secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - SkipTests: ${{ inputs.SkipTests }} TestPath: ${{ matrix.TestPath }} TestName: ${{ matrix.TestName }} Debug: ${{ inputs.Debug }} From e6dc59ba3298bf73ba11ae4e1122569a015b30bc Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 16:31:30 +0100 Subject: [PATCH 241/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20TestNam?= =?UTF-8?q?e=20extraction=20to=20remove=20file=20extension=20for=20improve?= =?UTF-8?q?d=20clarity=20in=20Get-TestSuites=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 79bffa03..259ffb65 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -144,7 +144,7 @@ jobs: RunsOn = $osConfig.RunsOn OSName = $osConfig.OSName TestPath = Resolve-Path -Path $item.FullName -Relative - TestName = $item.BaseName + TestName = ($item.BaseName -Split '.')[0] } } } From 63cbccd6534a42bd442d66b3b4d7eb58514ed42d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 16:51:10 +0100 Subject: [PATCH 242/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20functional?= =?UTF-8?q?ity=20to=20skip=20tests=20based=20on=20input,=20enhancing=20tes?= =?UTF-8?q?t=20suite=20flexibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 259ffb65..1b4a4413 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -80,6 +80,27 @@ jobs: @{ RunsOn = 'windows-latest'; OSName = 'Windows' } ) + $skipTests = $env:PSMODULE_GET_TESTSUITES_INPUT_SkipTests -Split ",|\s+" | ForEach-Object { $_.Trim() } + + if ($skipTests -contains 'All') { + Write-Host "Skipping all tests as requested." + Set-GitHubOutput -Name SourceCodeTestSuites -Value '[]' + Set-GitHubOutput -Name ModuleTestSuites -Value '[]' + Set-GitHubOutput -Name ModuleLocalTestSuites -Value '[]' + exit 0 + } + + # Filter out OS-specific tests early + $osConfigs = $osConfigs | Where-Object { $skipTests -notcontains $_.OSName } + + if (-not $osConfigs) { + Write-Host "No OS configurations left after filtering. Exiting." + Set-GitHubOutput -Name SourceCodeTestSuites -Value '[]' + Set-GitHubOutput -Name ModuleTestSuites -Value '[]' + Set-GitHubOutput -Name ModuleLocalTestSuites -Value '[]' + exit 0 + } + # Locate the tests directory. $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path if (-not $testsPath -or -not (Test-Path -Path $testsPath)) { From a5a1456da28c3c6d42e019aac8c9589fad55a264 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 18:03:37 +0100 Subject: [PATCH 243/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Refactor=20Get-T?= =?UTF-8?q?estSuites=20workflow=20to=20improve=20test=20skipping=20logic?= =?UTF-8?q?=20and=20enhance=20output=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 159 +++++++++++---------------- 1 file changed, 67 insertions(+), 92 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 1b4a4413..28db9d6d 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -73,15 +73,13 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} Script: | - # Define test configurations as an array of hashtables. - $osConfigs = @( - @{ RunsOn = 'ubuntu-latest'; OSName = 'Linux' } - @{ RunsOn = 'macos-latest'; OSName = 'macOS' } - @{ RunsOn = 'windows-latest'; OSName = 'Windows' } - ) - + # Get-TestSuites $skipTests = $env:PSMODULE_GET_TESTSUITES_INPUT_SkipTests -Split ",|\s+" | ForEach-Object { $_.Trim() } + LogGroup 'Tests to be skipped:' { + $skipTests | ForEach-Object { " - $_ " } + } + if ($skipTests -contains 'All') { Write-Host "Skipping all tests as requested." Set-GitHubOutput -Name SourceCodeTestSuites -Value '[]' @@ -90,116 +88,93 @@ jobs: exit 0 } - # Filter out OS-specific tests early - $osConfigs = $osConfigs | Where-Object { $skipTests -notcontains $_.OSName } + # Define test configurations as an array of hashtables. + $osConfigs = @( + @{ RunsOn = 'ubuntu-latest'; OSName = 'Linux' } + @{ RunsOn = 'macos-latest'; OSName = 'macOS' } + @{ RunsOn = 'windows-latest'; OSName = 'Windows' } + ) | Where-Object { $skipTests -notcontains $_.OSName } if (-not $osConfigs) { - Write-Host "No OS configurations left after filtering. Exiting." + Write-Host "Skipping all OS configurations." Set-GitHubOutput -Name SourceCodeTestSuites -Value '[]' Set-GitHubOutput -Name ModuleTestSuites -Value '[]' Set-GitHubOutput -Name ModuleLocalTestSuites -Value '[]' exit 0 } - # Locate the tests directory. - $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path - if (-not $testsPath -or -not (Test-Path -Path $testsPath)) { - Write-Warning 'No tests found' - exit 0 + LogGroup 'Source Code Test Suites:' { + if ($skipTests -notcontain 'SourceCode') { + $osConfigs | Format-Table -AutoSize | Out-String + Set-GitHubOutput -Name SourceCodeTestSuites -Value $osConfigs + } } - Write-Host "Tests found at [$testsPath]" - function Get-TestItemsFromFolder { - param ([string]$FolderPath) - - $configFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Configuration.ps1' - if ($configFiles.Count -eq 1) { - return @($configFiles) - } elseif ($configFiles.Count -gt 1) { - throw "Multiple configuration files found in [$FolderPath]. Please separate configurations into different folders." + LogGroup 'Module Test Suites:' { + if ($skipTests -notcontain 'Module') { + $osConfigs | Format-Table -AutoSize | Out-String + Set-GitHubOutput -Name ModuleTestSuites -Value $osConfigs } + } - $containerFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Container.ps1' - if ($containerFiles.Count -ge 1) { - return $containerFiles + LogGroup 'Module Local Test Suites:' { + # Locate the tests directory. + $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path + if (-not $testsPath -or -not (Test-Path -Path $testsPath)) { + Write-Warning 'No tests found' + exit 0 } + Write-Host "Tests found at [$testsPath]" - $testFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Tests.ps1' - return $testFiles - } + function Get-TestItemsFromFolder { + param ([string]$FolderPath) - function Find-TestDirectories { - param ([string]$Path) + $configFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Configuration.ps1' + if ($configFiles.Count -eq 1) { + return @($configFiles) + } elseif ($configFiles.Count -gt 1) { + throw "Multiple configuration files found in [$FolderPath]. Please separate configurations into different folders." + } - $directories = @() - $childDirs = Get-ChildItem -Path $Path -Directory + $containerFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Container.ps1' + if ($containerFiles.Count -ge 1) { + return $containerFiles + } - foreach ($dir in $childDirs) { - $directories += $dir.FullName - $directories += Find-TestDirectories -Path $dir.FullName + $testFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Tests.ps1' + return $testFiles } - return $directories - } - - $allTestFolders = @($testsPath) + (Find-TestDirectories -Path $testsPath) + function Find-TestDirectories { + param ([string]$Path) - $skipTests = $env:PSMODULE_GET_TESTSUITES_INPUT_SkipTests -Split ",|\s+" | ForEach-Object { $_.Trim() } + $directories = @() + $childDirs = Get-ChildItem -Path $Path -Directory - LogGroup 'Tests to be skipped:' { - $skipTests | ForEach-Object { " - $_ " } - } + foreach ($dir in $childDirs) { + $directories += $dir.FullName + $directories += Find-TestDirectories -Path $dir.FullName + } - $testSuites = foreach ($folder in $allTestFolders) { - $testItems = Get-TestItemsFromFolder -FolderPath $folder - foreach ($item in $testItems) { - foreach ($osConfig in $osConfigs) { - if ($skipTests -contains 'All' -or - $skipTests -contains $osConfig.OSName -or - ($skipTests -contains 'Module' -and $item.Name -match '\.Tests\.ps1$') -or - ($skipTests -contains 'SourceCode' -and $item.Name -match '\.(Configuration|Container)\.ps1$')) { - continue - } + return $directories + } - [pscustomobject]@{ - RunsOn = $osConfig.RunsOn - OSName = $osConfig.OSName - TestPath = Resolve-Path -Path $item.FullName -Relative - TestName = ($item.BaseName -Split '.')[0] + $allTestFolders = @($testsPath) + (Find-TestDirectories -Path $testsPath) + + $moduleLocalTestSuites = foreach ($folder in $allTestFolders) { + $testItems = Get-TestItemsFromFolder -FolderPath $folder + foreach ($item in $testItems) { + foreach ($osConfig in $osConfigs) { + [pscustomobject]@{ + RunsOn = $osConfig.RunsOn + OSName = $osConfig.OSName + TestPath = Resolve-Path -Path $item.FullName -Relative + TestName = ($item.BaseName -Split '.')[0] + } } } } - } - # Adjust source code test suites based on SkipTests - $sourceCodeTestSuites = $osConfigs | Where-Object { - -not ($skipTests -contains 'All' -or $skipTests -contains $_.OSName -or $skipTests -contains 'SourceCode') - } | Select-Object -Property RunsOn, OSName -Unique - - # Generate ModuleTestSuites (static tests) - $moduleTestSuites = $testSuites | Where-Object { - $_.TestName -match '\.(Configuration|Container)\.ps1$' -and - -not ($skipTests -contains 'All' -or $skipTests -contains $_.OSName -or $skipTests -contains 'Module') - } - - # Generate ModuleLocalTestSuites (local tests) - $moduleLocalTestSuites = $testSuites | Where-Object { - $_.TestName -match '\.Tests\.ps1$' -and - -not ($skipTests -contains 'All' -or $skipTests -contains $_.OSName -or $skipTests -contains 'Module') - } - - # Display the generated matrices for verification. - LogGroup 'Source Code Test Suites:' { - $sourceCodeTestSuites | Format-Table -AutoSize | Out-String + $moduleLocalTestSuites | Format-Table -AutoSize | Out-String + Set-GitHubOutput -Name ModuleLocalTestSuites -Value ($moduleLocalTestSuites ?? '[]') } - LogGroup 'Module Test Suites:' { - $moduleTestSuites | Format-Table -AutoSize | Out-String - } - LogGroup 'Module Local Test Suites:' { - $moduleLocalTestSuites | Format-Table -AutoSize | Out-String - } - - # Pass the final objects to GitHub Actions output as JSON - Set-GitHubOutput -Name SourceCodeTestSuites -Value ($sourceCodeTestSuites ?? '[]') - Set-GitHubOutput -Name ModuleTestSuites -Value ($moduleTestSuites ?? '[]') - Set-GitHubOutput -Name ModuleLocalTestSuites -Value ($moduleLocalTestSuites ?? '[]') From 53dab2986ffe20b97f94d6485d81ece599826c00 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 18:07:01 +0100 Subject: [PATCH 244/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Fix=20condition?= =?UTF-8?q?=20checks=20in=20Get-TestSuites=20workflow=20to=20correctly=20s?= =?UTF-8?q?kip=20tests=20for=20SourceCode=20and=20Module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 28db9d6d..584d3815 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -104,14 +104,14 @@ jobs: } LogGroup 'Source Code Test Suites:' { - if ($skipTests -notcontain 'SourceCode') { + if ($skipTests -notcontains 'SourceCode') { $osConfigs | Format-Table -AutoSize | Out-String Set-GitHubOutput -Name SourceCodeTestSuites -Value $osConfigs } } LogGroup 'Module Test Suites:' { - if ($skipTests -notcontain 'Module') { + if ($skipTests -notcontains 'Module') { $osConfigs | Format-Table -AutoSize | Out-String Set-GitHubOutput -Name ModuleTestSuites -Value $osConfigs } From 150cb58503403dfdcbfa578be2e985e7fbf3d747 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 18:15:34 +0100 Subject: [PATCH 245/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Get-Tes?= =?UTF-8?q?tSuites=20workflow=20to=20use=20PSCustomObject=20for=20OS=20con?= =?UTF-8?q?figurations=20and=20upgrade=20checkout=20action=20to=20v4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 6 +++--- .github/workflows/Test-Module.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 584d3815..b30ace47 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -90,9 +90,9 @@ jobs: # Define test configurations as an array of hashtables. $osConfigs = @( - @{ RunsOn = 'ubuntu-latest'; OSName = 'Linux' } - @{ RunsOn = 'macos-latest'; OSName = 'macOS' } - @{ RunsOn = 'windows-latest'; OSName = 'Windows' } + [PSCustomObject]@{ RunsOn = 'ubuntu-latest'; OSName = 'Linux' } + [PSCustomObject]@{ RunsOn = 'macos-latest'; OSName = 'macOS' } + [PSCustomObject]@{ RunsOn = 'windows-latest'; OSName = 'Windows' } ) | Where-Object { $skipTests -notcontains $_.OSName } if (-not $osConfigs) { diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index d0dd2050..6aaa6cfe 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -87,7 +87,7 @@ jobs: runs-on: ${{ inputs.RunsOn }} steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Download module artifact uses: actions/download-artifact@v4 From cc080d5c92b7db64ccc35e1d7c4ad255cdafc9e9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 18:26:50 +0100 Subject: [PATCH 246/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Simplify=20TestN?= =?UTF-8?q?ame=20extraction=20logic=20in=20Get-TestSuites=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index b30ace47..6819907e 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -169,7 +169,7 @@ jobs: RunsOn = $osConfig.RunsOn OSName = $osConfig.OSName TestPath = Resolve-Path -Path $item.FullName -Relative - TestName = ($item.BaseName -Split '.')[0] + TestName = ($item.BaseName).Split('.')[0] } } } From c05d8f24cae8e97860a8c375533caf72bc3ce62b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 18:35:57 +0100 Subject: [PATCH 247/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20test=20?= =?UTF-8?q?suite=20logic=20to=20correctly=20reference=20ModuleTestSuites?= =?UTF-8?q?=20and=20ModuleLocalTestSuites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 11 ++++------- .github/workflows/workflow.yml | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c9588021..9e15529d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -94,7 +94,6 @@ jobs: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -125,21 +124,20 @@ jobs: Test-Module: name: Test-Module - if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} needs: - Build-Module - Get-TestSuites strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.SourceCodeTestSuites) }} + include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleTestSuites) }} uses: ./.github/workflows/Test-Module.yml secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -148,21 +146,20 @@ jobs: Test-ModuleLocal: name: ${{ matrix.TestName }} - if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleLocalTestSuites != '[]' }} needs: - Build-Module - Get-TestSuites strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleTestSuites) }} + include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleLocalTestSuites) }} uses: ./.github/workflows/Test-ModuleLocal.yml secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} Name: ${{ inputs.Name }} - SkipTests: ${{ inputs.SkipTests }} TestPath: ${{ matrix.TestPath }} TestName: ${{ matrix.TestName }} Debug: ${{ inputs.Debug }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index cb14e695..e53683ff 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -136,7 +136,7 @@ jobs: strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.SourceCodeTestSuites) }} + include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleTestSuites) }} uses: ./.github/workflows/Test-Module.yml secrets: inherit with: From eab3ed03e13e59f6482807c6e8d04458bafe308c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 21:53:32 +0100 Subject: [PATCH 248/324] =?UTF-8?q?=F0=9F=A9=B9=20[DOC]:=20Remove=20unnece?= =?UTF-8?q?ssary=20blank=20line=20from=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00390e9b..f700871a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Process-PSModule - A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From c83ee48682e20a776c32e77b6bb17b214f4b9cb3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 22:17:08 +0100 Subject: [PATCH 249/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Refactor=20Get-T?= =?UTF-8?q?estSuites=20workflow=20to=20improve=20test=20suite=20handling?= =?UTF-8?q?=20and=20output=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 97 ++++++++++++++-------------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 6819907e..8106d555 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -105,76 +105,79 @@ jobs: LogGroup 'Source Code Test Suites:' { if ($skipTests -notcontains 'SourceCode') { - $osConfigs | Format-Table -AutoSize | Out-String - Set-GitHubOutput -Name SourceCodeTestSuites -Value $osConfigs + $sourceCodeTestSuites = $osConfigs } + $sourceCodeTestSuites | Format-Table -AutoSize | Out-String + Set-GitHubOutput -Name SourceCodeTestSuites -Value ($sourceCodeTestSuites ?? '[]') } LogGroup 'Module Test Suites:' { if ($skipTests -notcontains 'Module') { - $osConfigs | Format-Table -AutoSize | Out-String - Set-GitHubOutput -Name ModuleTestSuites -Value $osConfigs + $moduleTestSuites = $osConfigs } + $moduleTestSuites | Format-Table -AutoSize | Out-String + Set-GitHubOutput -Name ModuleTestSuites -Value ($moduleTestSuites ?? '[]') } LogGroup 'Module Local Test Suites:' { - # Locate the tests directory. - $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path - if (-not $testsPath -or -not (Test-Path -Path $testsPath)) { - Write-Warning 'No tests found' - exit 0 - } - Write-Host "Tests found at [$testsPath]" + if ($skipTests -notcontains 'Module') { + # Locate the tests directory. + $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path + if (-not $testsPath -or -not (Test-Path -Path $testsPath)) { + Write-Warning 'No tests found' + exit 0 + } + Write-Host "Tests found at [$testsPath]" - function Get-TestItemsFromFolder { - param ([string]$FolderPath) + function Get-TestItemsFromFolder { + param ([string]$FolderPath) - $configFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Configuration.ps1' - if ($configFiles.Count -eq 1) { - return @($configFiles) - } elseif ($configFiles.Count -gt 1) { - throw "Multiple configuration files found in [$FolderPath]. Please separate configurations into different folders." - } + $configFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Configuration.ps1' + if ($configFiles.Count -eq 1) { + return @($configFiles) + } elseif ($configFiles.Count -gt 1) { + throw "Multiple configuration files found in [$FolderPath]. Please separate configurations into different folders." + } + + $containerFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Container.ps1' + if ($containerFiles.Count -ge 1) { + return $containerFiles + } - $containerFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Container.ps1' - if ($containerFiles.Count -ge 1) { - return $containerFiles + $testFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Tests.ps1' + return $testFiles } - $testFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Tests.ps1' - return $testFiles - } + function Find-TestDirectories { + param ([string]$Path) - function Find-TestDirectories { - param ([string]$Path) + $directories = @() + $childDirs = Get-ChildItem -Path $Path -Directory - $directories = @() - $childDirs = Get-ChildItem -Path $Path -Directory + foreach ($dir in $childDirs) { + $directories += $dir.FullName + $directories += Find-TestDirectories -Path $dir.FullName + } - foreach ($dir in $childDirs) { - $directories += $dir.FullName - $directories += Find-TestDirectories -Path $dir.FullName + return $directories } - return $directories - } - - $allTestFolders = @($testsPath) + (Find-TestDirectories -Path $testsPath) - - $moduleLocalTestSuites = foreach ($folder in $allTestFolders) { - $testItems = Get-TestItemsFromFolder -FolderPath $folder - foreach ($item in $testItems) { - foreach ($osConfig in $osConfigs) { - [pscustomobject]@{ - RunsOn = $osConfig.RunsOn - OSName = $osConfig.OSName - TestPath = Resolve-Path -Path $item.FullName -Relative - TestName = ($item.BaseName).Split('.')[0] + $allTestFolders = @($testsPath) + (Find-TestDirectories -Path $testsPath) + + $moduleLocalTestSuites = foreach ($folder in $allTestFolders) { + $testItems = Get-TestItemsFromFolder -FolderPath $folder + foreach ($item in $testItems) { + foreach ($osConfig in $osConfigs) { + [pscustomobject]@{ + RunsOn = $osConfig.RunsOn + OSName = $osConfig.OSName + TestPath = Resolve-Path -Path $item.FullName -Relative + TestName = ($item.BaseName).Split('.')[0] + } } } } } - $moduleLocalTestSuites | Format-Table -AutoSize | Out-String Set-GitHubOutput -Name ModuleLocalTestSuites -Value ($moduleLocalTestSuites ?? '[]') } From 449252d06484ec779da44aaf018c81316bc7482b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 22:29:25 +0100 Subject: [PATCH 250/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20checks=20b?= =?UTF-8?q?efore=20renaming=20.gitignore=20files=20in=20Build-Docs=20workf?= =?UTF-8?q?low?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index edb5c2b8..356e4d19 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -81,7 +81,9 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Script: | # Rename the gitignore file to .gitignore.bak - Rename-Item -Path '.gitignore' -NewName '.gitignore.bak' -Force + if (Test-Path -Path .gitignore) { + Rename-Item -Path '.gitignore' -NewName '.gitignore.bak' -Force + } try { # Add all changes to the repository @@ -92,7 +94,9 @@ jobs: } # Restore the gitignore file - Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force + if (Test-Path -Path .gitignore.bak) { + Rename-Item -Path '.gitignore.bak' -NewName '.gitignore' -Force + } - name: Lint documentation uses: super-linter/super-linter/slim@latest From 79c09ca7a672034231bf6253cda0844b9163b35a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 22:29:52 +0100 Subject: [PATCH 251/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20continu?= =?UTF-8?q?e-on-error=20option=20from=20Build-Docs=20workflow=20commit=20s?= =?UTF-8?q?tep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 356e4d19..109d1801 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -72,7 +72,6 @@ jobs: - name: Commit all changes uses: PSModule/GitHub-Script@v1 - continue-on-error: true with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From ae03f522281c3cd0a5ba50949ef124e05dc23df5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 23:18:08 +0100 Subject: [PATCH 252/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20redunda?= =?UTF-8?q?nt=20job=20names=20from=20CI=20workflows=20for=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 6 ------ .github/workflows/workflow.yml | 12 ++---------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9e15529d..f178c5bb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -70,7 +70,6 @@ permissions: jobs: Get-TestSuites: - name: Get-TestSuites uses: ./.github/workflows/Get-TestSuites.yml with: SkipTests: ${{ inputs.SkipTests }} @@ -81,7 +80,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-SourceCode: - name: Test-SourceCode if: ${{ needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} needs: - Get-TestSuites @@ -123,7 +121,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-Module: - name: Test-Module if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} needs: - Build-Module @@ -145,7 +142,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-ModuleLocal: - name: ${{ matrix.TestName }} if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleLocalTestSuites != '[]' }} needs: - Build-Module @@ -169,7 +165,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - name: Get-TestResults if: always() && !cancelled() needs: - Test-SourceCode @@ -184,7 +179,6 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - name: Get-CodeCoverage if: always() && !cancelled() needs: - Test-SourceCode diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index e53683ff..59fff4df 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -75,7 +75,6 @@ permissions: jobs: Get-TestSuites: - name: Get-TestSuites uses: ./.github/workflows/Get-TestSuites.yml with: SkipTests: ${{ inputs.SkipTests }} @@ -86,7 +85,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-SourceCode: - name: Test-SourceCode if: ${{ needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} needs: - Get-TestSuites @@ -128,7 +126,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-Module: - name: Test-Module if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} needs: - Build-Module @@ -150,7 +147,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-ModuleLocal: - name: ${{ matrix.TestName }} if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleLocalTestSuites != '[]' }} needs: - Build-Module @@ -174,7 +170,6 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - name: Get-TestResults if: always() && !cancelled() needs: - Test-SourceCode @@ -189,7 +184,6 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - name: Get-CodeCoverage if: always() && !cancelled() needs: - Test-SourceCode @@ -203,8 +197,7 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - PublishModule: - name: Publish module + Publish-Module: if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} needs: - Get-TestResults @@ -245,8 +238,7 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - PublishSite: - name: Publish documentation + Publish-Site: if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} needs: - Get-TestResults From 4149d41c81cfae5b8ae7a9211c29c8bb8780ab93 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 23:32:17 +0100 Subject: [PATCH 253/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20job=20n?= =?UTF-8?q?ame=20format=20in=20Test-ModuleLocal=20workflow=20for=20better?= =?UTF-8?q?=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 15e9626d..dc42d0d4 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -83,7 +83,7 @@ permissions: jobs: Test-ModuleLocal: - name: ${{ inputs.TestName }}-${{ inputs.OS }} + name: Test-${{ inputs.TestName }} (${{ inputs.RunsOn }}) if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: From 99b12ee470c2755ea8f428e59fa14763b6795521 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 23:34:46 +0100 Subject: [PATCH 254/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20SkipTes?= =?UTF-8?q?ts=20input=20from=20Test=20workflows=20for=20simplification?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-Module.yml | 2 -- .github/workflows/Test-ModuleLocal.yml | 6 ------ .github/workflows/Test-SourceCode.yml | 7 ------- 3 files changed, 15 deletions(-) diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 6aaa6cfe..2134e668 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -83,7 +83,6 @@ permissions: jobs: Test-Module: name: Test-Module (${{ inputs.RunsOn }}) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - name: Checkout repository @@ -109,7 +108,6 @@ jobs: Lint-Module: name: Lint-Module (${{ inputs.RunsOn }}) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - name: Download module artifact diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index dc42d0d4..0572f8e6 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -47,11 +47,6 @@ on: description: The path to the tests folder. required: false default: tests - SkipTests: - type: string - description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. - required: false - default: None Debug: type: boolean description: Enable debug output. @@ -84,7 +79,6 @@ permissions: jobs: Test-ModuleLocal: name: Test-${{ inputs.TestName }} (${{ inputs.RunsOn }}) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'Module') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - name: Checkout Code diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 3b140a77..781b9f4c 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -15,11 +15,6 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - SkipTests: - type: string - description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. - required: false - default: None Debug: type: boolean description: Enable debug output. @@ -52,7 +47,6 @@ permissions: jobs: Test-SourceCode: name: Test-SourceCode (${{ inputs.RunsOn }}) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - name: Checkout Code @@ -70,7 +64,6 @@ jobs: Lint-SourceCode: name: Lint-SourceCode (${{ inputs.RunsOn }}) - if: ${{ !(contains(inputs.SkipTests, 'All') || contains(inputs.SkipTests, 'SourceCode') || contains(inputs.SkipTests, inputs.OS)) }} runs-on: ${{ inputs.RunsOn }} steps: - name: Checkout Code From 8a0e128db2deb4e663a0924d1720e9da1baba710 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 11 Mar 2025 23:38:53 +0100 Subject: [PATCH 255/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20SkipTes?= =?UTF-8?q?ts=20input=20from=20Get-TestSuites=20jobs=20for=20simplificatio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 1 - .github/workflows/Test-Module.yml | 5 ----- .github/workflows/workflow.yml | 1 - 3 files changed, 7 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f178c5bb..3d31561a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -72,7 +72,6 @@ jobs: Get-TestSuites: uses: ./.github/workflows/Get-TestSuites.yml with: - SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 2134e668..5bb02695 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -37,11 +37,6 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - SkipTests: - type: string - description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. - required: false - default: None Debug: type: boolean description: Enable debug output. diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 59fff4df..7a3600d4 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -77,7 +77,6 @@ jobs: Get-TestSuites: uses: ./.github/workflows/Get-TestSuites.yml with: - SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} From 77340c793f4a579ee3722f2a0918d00d14289f41 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 12 Mar 2025 13:12:59 +0100 Subject: [PATCH 256/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Test-Mo?= =?UTF-8?q?duleLocal=20workflow=20to=20use=20Invoke-Pester@prescript=20for?= =?UTF-8?q?=20improved=20testing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 0572f8e6..b703bd0c 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -104,7 +104,8 @@ jobs: "path=$path" >> $env:GITHUB_OUTPUT - name: Test-ModuleLocal - uses: PSModule/Invoke-Pester@v4 + # uses: PSModule/Invoke-Pester@v4 + uses: PSModule/Invoke-Pester@prescript continue-on-error: true env: TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} @@ -129,3 +130,5 @@ jobs: Path: ${{ inputs.TestPath }} Run_Path: ${{ steps.import-module.outputs.path }} WorkingDirectory: ${{ inputs.WorkingDirectory }} + Prescript: | + Import-Module -Name '${{ steps.import-module.outputs.path }}' From 61184bdfb2539525538ad09d4959c8e6d8b9ce21 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 12 Mar 2025 13:18:31 +0100 Subject: [PATCH 257/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Test-Mo?= =?UTF-8?q?duleLocal=20workflow=20to=20output=20module=20name=20and=20enfo?= =?UTF-8?q?rce=20specific=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index b703bd0c..50f5bb16 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -101,6 +101,7 @@ jobs: $name = Get-ChildItem "outputs/module" | Select-Object -ExpandProperty Name $path = Install-PSModule -Path "outputs/module/$name" -PassThru Write-Warning $path + "name=$name" >> $env:GITHUB_OUTPUT "path=$path" >> $env:GITHUB_OUTPUT - name: Test-ModuleLocal @@ -131,4 +132,5 @@ jobs: Run_Path: ${{ steps.import-module.outputs.path }} WorkingDirectory: ${{ inputs.WorkingDirectory }} Prescript: | - Import-Module -Name '${{ steps.import-module.outputs.path }}' + Import-Module -Name '${{ steps.import-module.outputs.name }}' -RequiredVersion 999.0.0 +q From 825f96369d954dac91818ed8fbf016c969687362 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 12 Mar 2025 13:18:56 +0100 Subject: [PATCH 258/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20unneces?= =?UTF-8?q?sary=20'q'=20from=20Prescript=20in=20Test-ModuleLocal=20workflo?= =?UTF-8?q?w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 50f5bb16..16036bac 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -133,4 +133,3 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Prescript: | Import-Module -Name '${{ steps.import-module.outputs.name }}' -RequiredVersion 999.0.0 -q From 07d3d44fd29f84d8e1bd2e85624c9333e5b3fb8e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 12 Mar 2025 14:33:48 +0100 Subject: [PATCH 259/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20'Needs'=20?= =?UTF-8?q?input=20to=20Get-TestResults=20workflow=20for=20job=20dependenc?= =?UTF-8?q?y=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 1 + .github/workflows/Get-TestResults.yml | 13 +++++++++++++ .github/workflows/Test-ModuleLocal.yml | 2 +- .github/workflows/workflow.yml | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3d31561a..d7f5b027 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -172,6 +172,7 @@ jobs: uses: ./.github/workflows/Get-TestResults.yml secrets: inherit with: + Needs: ${{ toJson(needs) }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/Get-TestResults.yml b/.github/workflows/Get-TestResults.yml index 709b63b4..00836e47 100644 --- a/.github/workflows/Get-TestResults.yml +++ b/.github/workflows/Get-TestResults.yml @@ -3,6 +3,11 @@ name: Get-TestResults on: workflow_call: inputs: + Needs: + type: string + description: The json objects representing the jobs that this job depends on. + required: false + default: '' Debug: type: boolean description: Enable debug output. @@ -37,6 +42,14 @@ jobs: name: Get-TestResults runs-on: ubuntu-latest steps: + - name: Needs + shell: pwsh + env: + Needs: ${{ inputs.Needs }} + run: | + $env:Needs + $env:Needs | ConvertFrom-Json + - name: Get-TestResults uses: PSModule/Get-PesterTestResults@v1 id: Get-TestResults diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 16036bac..94bed380 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -106,7 +106,7 @@ jobs: - name: Test-ModuleLocal # uses: PSModule/Invoke-Pester@v4 - uses: PSModule/Invoke-Pester@prescript + uses: PSModule/Invoke-Pester@v4 continue-on-error: true env: TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 7a3600d4..f466d094 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -177,6 +177,7 @@ jobs: uses: ./.github/workflows/Get-TestResults.yml secrets: inherit with: + Needs: ${{ toJson(needs) }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} From 429627bcf441be5d281e9d50def93ac84c550eaa Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 12 Mar 2025 14:56:29 +0100 Subject: [PATCH 260/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Remove=20'Needs'?= =?UTF-8?q?=20input=20from=20Get-TestResults=20workflow=20for=20simplifica?= =?UTF-8?q?tion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 1 - .github/workflows/Get-TestResults.yml | 13 ------------- .github/workflows/workflow.yml | 1 - 3 files changed, 15 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d7f5b027..3d31561a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -172,7 +172,6 @@ jobs: uses: ./.github/workflows/Get-TestResults.yml secrets: inherit with: - Needs: ${{ toJson(needs) }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/Get-TestResults.yml b/.github/workflows/Get-TestResults.yml index 00836e47..709b63b4 100644 --- a/.github/workflows/Get-TestResults.yml +++ b/.github/workflows/Get-TestResults.yml @@ -3,11 +3,6 @@ name: Get-TestResults on: workflow_call: inputs: - Needs: - type: string - description: The json objects representing the jobs that this job depends on. - required: false - default: '' Debug: type: boolean description: Enable debug output. @@ -42,14 +37,6 @@ jobs: name: Get-TestResults runs-on: ubuntu-latest steps: - - name: Needs - shell: pwsh - env: - Needs: ${{ inputs.Needs }} - run: | - $env:Needs - $env:Needs | ConvertFrom-Json - - name: Get-TestResults uses: PSModule/Get-PesterTestResults@v1 id: Get-TestResults diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index f466d094..7a3600d4 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -177,7 +177,6 @@ jobs: uses: ./.github/workflows/Get-TestResults.yml secrets: inherit with: - Needs: ${{ toJson(needs) }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} From 2a7a856d7e16e0a411fd7ea452f7561d86ae1f2d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 12 Mar 2025 16:40:40 +0100 Subject: [PATCH 261/324] =?UTF-8?q?=F0=9F=93=9D=20[Docs]:=20Add=20blank=20?= =?UTF-8?q?line=20for=20improved=20readability=20in=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f700871a..00390e9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Process-PSModule + A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. From 09ff31f063f8bc7176e7d5c16296de529331d757 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 12 Mar 2025 22:47:24 +0100 Subject: [PATCH 262/324] =?UTF-8?q?=F0=9F=A9=B9=20[Docs]:=20Enhance=20Buil?= =?UTF-8?q?d-Docs=20workflow=20to=20dynamically=20locate=20mkdocs.yml=20fi?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 109d1801..cceba361 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -189,8 +189,25 @@ jobs: LogGroup 'Build docs - Create mkdocs.yml' { $rootPath = Split-Path -Path $ModuleSourcePath -Parent - # This should be moved to an action so that we can use a default one, and not have to copy it from the repo. - $mkdocsSourcePath = Join-Path -Path $rootPath -ChildPath 'mkdocs.yml' + $possiblePaths = @( + '.github/mkdocs.yml', + 'docs/mkdocs.yml', + 'mkdocs.yml' + ) + + $mkdocsSourcePath = $null + foreach ($path in $possiblePaths) { + $candidatePath = Join-Path -Path $rootPath -ChildPath $path + if (Test-Path -Path $candidatePath) { + $mkdocsSourcePath = $candidatePath + break + } + } + + if (-not $mkdocsSourcePath) { + throw "Mkdocs source file not found in any of the expected locations: $($possiblePaths -join ', ')" + } + $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' Write-Host "Mkdocs Source Path: $mkdocsSourcePath" From f5aa725bf29f59a0481168cfb78ce05412292528 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 13 Mar 2025 21:40:37 +0100 Subject: [PATCH 263/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Add=20'SkipTests?= =?UTF-8?q?'=20input=20to=20Get-TestSuites=20workflow=20for=20enhanced=20t?= =?UTF-8?q?est=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 1 + .github/workflows/workflow.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3d31561a..f178c5bb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -72,6 +72,7 @@ jobs: Get-TestSuites: uses: ./.github/workflows/Get-TestSuites.yml with: + SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 7a3600d4..59fff4df 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -77,6 +77,7 @@ jobs: Get-TestSuites: uses: ./.github/workflows/Get-TestSuites.yml with: + SkipTests: ${{ inputs.SkipTests }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} From af27e3d8528a50bbe7988656fab51a21d5369488 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 13 Mar 2025 22:00:04 +0100 Subject: [PATCH 264/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Upgrade=20PSModu?= =?UTF-8?q?le/Publish-PSModule=20action=20to=20v2=20for=20improved=20funct?= =?UTF-8?q?ionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 59fff4df..f9525b43 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -227,7 +227,7 @@ jobs: path: ${{ inputs.WorkingDirectory }}/outputs/module - name: Publish module - uses: PSModule/Publish-PSModule@v1 + uses: PSModule/Publish-PSModule@v2 with: Name: ${{ inputs.Name }} ModulePath: ${{ inputs.WorkingDirectory }}/outputs/module From 04c5556cf8691816c2297b9eaea0554f15936170 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 14 Mar 2025 14:49:12 +0100 Subject: [PATCH 265/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Refactor=20Get-T?= =?UTF-8?q?estSuites=20workflow=20to=20improve=20output=20formatting=20and?= =?UTF-8?q?=20ensure=20JSON=20array=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 8106d555..20273c58 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -74,10 +74,12 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Script: | # Get-TestSuites - $skipTests = $env:PSMODULE_GET_TESTSUITES_INPUT_SkipTests -Split ",|\s+" | ForEach-Object { $_.Trim() } + $skipTests = $env:PSMODULE_GET_TESTSUITES_INPUT_SkipTests -split '[,\s]+' | ForEach-Object { + $_.Trim() + } LogGroup 'Tests to be skipped:' { - $skipTests | ForEach-Object { " - $_ " } + $skipTests | ForEach-Object { " - $_" } } if ($skipTests -contains 'All') { @@ -108,7 +110,8 @@ jobs: $sourceCodeTestSuites = $osConfigs } $sourceCodeTestSuites | Format-Table -AutoSize | Out-String - Set-GitHubOutput -Name SourceCodeTestSuites -Value ($sourceCodeTestSuites ?? '[]') + $sourceCodeTestSuites = $sourceCodeTestSuites | ConvertTo-Json -AsArray + Set-GitHubOutput -Name SourceCodeTestSuites -Value $sourceCodeTestSuites } LogGroup 'Module Test Suites:' { @@ -116,7 +119,8 @@ jobs: $moduleTestSuites = $osConfigs } $moduleTestSuites | Format-Table -AutoSize | Out-String - Set-GitHubOutput -Name ModuleTestSuites -Value ($moduleTestSuites ?? '[]') + $moduleTestSuites = $moduleTestSuites | ConvertTo-Json -AsArray + Set-GitHubOutput -Name ModuleTestSuites -Value $moduleTestSuites } LogGroup 'Module Local Test Suites:' { @@ -179,5 +183,6 @@ jobs: } } $moduleLocalTestSuites | Format-Table -AutoSize | Out-String - Set-GitHubOutput -Name ModuleLocalTestSuites -Value ($moduleLocalTestSuites ?? '[]') + $moduleLocalTestSuites = $moduleLocalTestSuites | ConvertTo-Json -AsArray + Set-GitHubOutput -Name ModuleLocalTestSuites -Value $moduleLocalTestSuites } From 2cb42547ee1bad5083db24471ef2a7ff27c8e502 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Mar 2025 22:06:42 +0100 Subject: [PATCH 266/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20Get-Tes?= =?UTF-8?q?tSuites=20workflow=20to=20handle=20null=20values=20and=20ensure?= =?UTF-8?q?=20JSON=20array=20output?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-TestSuites.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml index 20273c58..1dda763d 100644 --- a/.github/workflows/Get-TestSuites.yml +++ b/.github/workflows/Get-TestSuites.yml @@ -110,7 +110,7 @@ jobs: $sourceCodeTestSuites = $osConfigs } $sourceCodeTestSuites | Format-Table -AutoSize | Out-String - $sourceCodeTestSuites = $sourceCodeTestSuites | ConvertTo-Json -AsArray + $sourceCodeTestSuites = ($null -ne $sourceCodeTestSuites) ? ($sourceCodeTestSuites | ConvertTo-Json -AsArray) : '[]' Set-GitHubOutput -Name SourceCodeTestSuites -Value $sourceCodeTestSuites } @@ -119,7 +119,7 @@ jobs: $moduleTestSuites = $osConfigs } $moduleTestSuites | Format-Table -AutoSize | Out-String - $moduleTestSuites = $moduleTestSuites | ConvertTo-Json -AsArray + $moduleTestSuites = ($null -ne $moduleTestSuites) ? ($moduleTestSuites | ConvertTo-Json -AsArray) : '[]' Set-GitHubOutput -Name ModuleTestSuites -Value $moduleTestSuites } @@ -183,6 +183,6 @@ jobs: } } $moduleLocalTestSuites | Format-Table -AutoSize | Out-String - $moduleLocalTestSuites = $moduleLocalTestSuites | ConvertTo-Json -AsArray + $moduleLocalTestSuites = ($null -ne $moduleLocalTestSuites) ? ($moduleLocalTestSuites | ConvertTo-Json -AsArray) : '[]' Set-GitHubOutput -Name ModuleLocalTestSuites -Value $moduleLocalTestSuites } From 59fe203854f0e1ac58b8593b7835cd821722377d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 16 Mar 2025 20:19:59 +0100 Subject: [PATCH 267/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Update=20Test-Mo?= =?UTF-8?q?duleLocal=20workflow=20to=20ensure=20consistent=20usage=20of=20?= =?UTF-8?q?Invoke-Pester=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 94bed380..3547c79e 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -105,7 +105,6 @@ jobs: "path=$path" >> $env:GITHUB_OUTPUT - name: Test-ModuleLocal - # uses: PSModule/Invoke-Pester@v4 uses: PSModule/Invoke-Pester@v4 continue-on-error: true env: From 451c7879dc69280b88777d4ee7bc5615f5e2efde Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 24 Mar 2025 19:59:10 +0100 Subject: [PATCH 268/324] =?UTF-8?q?=F0=9F=9A=80=20[Feature]:=20Add=20funct?= =?UTF-8?q?ionality=20to=20configure=20the=20process=20with=20a=20settings?= =?UTF-8?q?=20file=20(#158)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description This pull request includes significant changes to the CI workflow configuration, primarily focusing on the introduction of a new `Get-Settings` workflow and the modification of multiple job dependencies to utilize this new workflow. The changes aim to streamline the settings management and test suite configurations. Key changes include: ### Workflow and Job Modifications: * [`.github/workflows/CI.yml`](diffhunk://#diff-3ab46ee209a127470fce3c2cf106b1a1dbadbb929a4b5b13656a4bc4ce19c0b8L35-R39): Replaced the `Get-TestSuites` job with a new `Get-Settings` job, and updated all subsequent job dependencies and inputs to use the outputs from `Get-Settings`. This includes changes to job conditions, matrix configurations, and input parameters. [[1]](diffhunk://#diff-3ab46ee209a127470fce3c2cf106b1a1dbadbb929a4b5b13656a4bc4ce19c0b8L35-R39) [[2]](diffhunk://#diff-3ab46ee209a127470fce3c2cf106b1a1dbadbb929a4b5b13656a4bc4ce19c0b8L62-R62) [[3]](diffhunk://#diff-3ab46ee209a127470fce3c2cf106b1a1dbadbb929a4b5b13656a4bc4ce19c0b8L72-R95) [[4]](diffhunk://#diff-3ab46ee209a127470fce3c2cf106b1a1dbadbb929a4b5b13656a4bc4ce19c0b8R104-R107) [[5]](diffhunk://#diff-3ab46ee209a127470fce3c2cf106b1a1dbadbb929a4b5b13656a4bc4ce19c0b8R116-R199) ### New Workflow: * [`.github/workflows/Get-Settings.yml`](diffhunk://#diff-68f351d419a9b4db4797434891d5dfad44d83de65bfee7ba1c60badae369dbefR1-R338): Added a new workflow, `Get-Settings`, which processes the settings file and outputs necessary configurations for subsequent jobs. This includes reading settings from various file formats (JSON, YAML, PSD1) and determining test suites to run based on the settings. ### Additional Inputs: * [`.github/workflows/Get-CodeCoverage.yml`](diffhunk://#diff-261187083ecd8c20f585c08962cc876f48b4da8453718d673165a1a9cec9eecaR6-R15): Added new inputs `StepSummary_Mode` and `CodeCoveragePercentTarget` to control the GitHub step summary sections and set a target for code coverage. These inputs are used in the `Get-CodeCoverage` job. [[1]](diffhunk://#diff-261187083ecd8c20f585c08962cc876f48b4da8453718d673165a1a9cec9eecaR6-R15) [[2]](diffhunk://#diff-261187083ecd8c20f585c08962cc876f48b4da8453718d673165a1a9cec9eecaR54-R55) ## Type of change - [ ] 📖 [Docs] - [ ] 🪲 [Fix] - [ ] 🩹 [Patch] - [ ] ⚠️ [Security fix] - [x] 🚀 [Feature] - [ ] 🌟 [Breaking change] ## Checklist - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas --- .github/workflows/CI.yml | 58 +-- .github/workflows/Get-CodeCoverage.yml | 12 + .github/workflows/Get-Settings.yml | 338 ++++++++++++++++++ .github/workflows/Get-TestResults.yml | 15 + .github/workflows/Get-TestSuites.yml | 188 ---------- .github/workflows/Test-Module.yml | 4 +- .github/workflows/Test-ModuleLocal.yml | 1 - .github/workflows/Test-SourceCode.yml | 2 + .../workflows/Workflow-Test-Default-CI.yml | 3 +- .github/workflows/Workflow-Test-Default.yml | 4 +- .../Workflow-Test-WithManifest-CI.yml | 4 +- .../workflows/Workflow-Test-WithManifest.yml | 5 +- .github/workflows/workflow.yml | 96 ++--- README.md | 3 +- tests/srcTestRepo/.github/PSModule.yml | 0 .../.github/PSModule.json | 22 ++ .../.github/PSModule.psd1 | 22 ++ .../.github/PSModule.yml | 13 + 18 files changed, 519 insertions(+), 271 deletions(-) create mode 100644 .github/workflows/Get-Settings.yml delete mode 100644 .github/workflows/Get-TestSuites.yml delete mode 100644 tests/srcTestRepo/.github/PSModule.yml create mode 100644 tests/srcWithManifestTestRepo/.github/PSModule.json create mode 100644 tests/srcWithManifestTestRepo/.github/PSModule.psd1 diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f178c5bb..882ee035 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -32,11 +32,11 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - SkipTests: + SettingsPath: type: string - description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. + description: The path to the settings file. Settings in the settings file take precedence over the action inputs. required: false - default: None + default: .github/PSModule.psd1 Debug: type: boolean description: Enable debug output. @@ -59,7 +59,7 @@ on: default: false WorkingDirectory: type: string - description: The working directory where the script will run from. + description: The path to the root of the repo. required: false default: '.' @@ -69,10 +69,11 @@ permissions: statuses: write # to update the status of the workflow from linter jobs: - Get-TestSuites: - uses: ./.github/workflows/Get-TestSuites.yml + Get-Settings: + uses: ./.github/workflows/Get-Settings.yml with: - SkipTests: ${{ inputs.SkipTests }} + Name: ${{ inputs.Name }} + SettingsPath: ${{ inputs.SettingsPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -80,18 +81,18 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-SourceCode: - if: ${{ needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} + if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} needs: - - Get-TestSuites + - Get-Settings strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.SourceCodeTestSuites) }} + include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -100,8 +101,10 @@ jobs: Build-Module: uses: ./.github/workflows/Build-Module.yml + needs: + - Get-Settings with: - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -110,10 +113,11 @@ jobs: Build-Docs: needs: + - Get-Settings - Build-Module uses: ./.github/workflows/Build-Docs.yml with: - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -121,20 +125,20 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-Module: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' }} needs: - Build-Module - - Get-TestSuites + - Get-Settings strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleTestSuites) }} + include: ${{ fromJson(needs.Get-Settings.outputs.PSModuleTestSuites) }} uses: ./.github/workflows/Test-Module.yml secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -142,22 +146,22 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-ModuleLocal: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleLocalTestSuites != '[]' }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-Settings.outputs.ModuleTestSuites != '[]' }} needs: - Build-Module - - Get-TestSuites + - Get-Settings strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleLocalTestSuites) }} + include: ${{ fromJson(needs.Get-Settings.outputs.ModuleTestSuites) }} uses: ./.github/workflows/Test-ModuleLocal.yml secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} - Name: ${{ inputs.Name }} TestPath: ${{ matrix.TestPath }} TestName: ${{ matrix.TestName }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -165,28 +169,34 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: always() && !cancelled() + if: needs.Get-Settings.result == 'success' && (always() && !cancelled()) needs: + - Get-Settings - Test-SourceCode - Test-Module - Test-ModuleLocal uses: ./.github/workflows/Get-TestResults.yml secrets: inherit with: + ModuleTestSuites: ${{ needs.Get-Settings.outputs.ModuleTestSuites }} + SourceCodeTestSuites: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites }} + PSModuleTestSuites: ${{ needs.Get-Settings.outputs.PSModuleTestSuites }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Get-CodeCoverage: - if: always() && !cancelled() + if: needs.Get-Settings.result == 'success' && (always() && !cancelled()) needs: - - Test-SourceCode + - Get-Settings - Test-Module - Test-ModuleLocal uses: ./.github/workflows/Get-CodeCoverage.yml secrets: inherit with: + CodeCoveragePercentTarget: ${{ fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.PercentTarget }} + StepSummary_Mode: ${{ fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.StepSummaryMode }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/Get-CodeCoverage.yml b/.github/workflows/Get-CodeCoverage.yml index 4f83f2fe..e82496c6 100644 --- a/.github/workflows/Get-CodeCoverage.yml +++ b/.github/workflows/Get-CodeCoverage.yml @@ -3,6 +3,16 @@ name: Get-CodeCoverage on: workflow_call: inputs: + StepSummary_Mode: + type: string + description: | + Controls which sections to show in the GitHub step summary. + Use 'Full' for all sections, 'None' to disable, or a comma-separated list of 'Missed, Executed, Files'. + required: false + default: Missed, Files + CodeCoveragePercentTarget: + type: number + description: The target for code coverage. Debug: type: boolean description: Enable debug output. @@ -41,6 +51,8 @@ jobs: uses: PSModule/Get-PesterCodeCoverage@v1 id: Get-CodeCoverage with: + CodeCoveragePercentTarget: ${{ inputs.CodeCoveragePercentTarget }} + StepSummary_Mode: ${{ inputs.StepSummary_Mode }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml new file mode 100644 index 00000000..7ae1990c --- /dev/null +++ b/.github/workflows/Get-Settings.yml @@ -0,0 +1,338 @@ +name: Get-Settings + +on: + workflow_call: + inputs: + Name: + type: string + description: The name of the module to process. Scripts default to the repository name if nothing is specified. + required: false + SettingsPath: + type: string + description: The path to the settings file. + required: false + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + WorkingDirectory: + type: string + description: The path to the root of the repo. + required: false + default: '.' + + outputs: + Settings: + description: The path to the settings file. + value: ${{ jobs.Get-Settings.outputs.Settings }} + SourceCodeTestSuites: + description: Source Code PSModule test suites to run. + value: ${{ jobs.Get-Settings.outputs.SourceCodeTestSuites }} + PSModuleTestSuites: + description: Module PSModule test suites to run. + value: ${{ jobs.Get-Settings.outputs.PSModuleTestSuites }} + ModuleTestSuites: + description: Module local test suites to run. + value: ${{ jobs.Get-Settings.outputs.ModuleTestSuites }} + +permissions: + contents: read # to checkout the repo + +jobs: + Get-Settings: + name: Get-Settings + runs-on: ubuntu-latest + outputs: + Settings: ${{ fromJson(steps.Get-Settings.outputs.result).Settings }} + SourceCodeTestSuites: ${{ fromJson(steps.Get-Settings.outputs.result).SourceCodeTestSuites }} + PSModuleTestSuites: ${{ fromJson(steps.Get-Settings.outputs.result).PSModuleTestSuites }} + ModuleTestSuites: ${{ fromJson(steps.Get-Settings.outputs.result).ModuleTestSuites }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Get-Settings + uses: PSModule/GitHub-Script@v1 + id: Get-Settings + env: + PSMODULE_GET_SETTINGS_INPUT_Name: ${{ inputs.Name }} + PSMODULE_GET_SETTINGS_INPUT_SettingsPath: ${{ inputs.SettingsPath }} + with: + Name: Get-Settings + ShowInfo: false + ShowOutput: true + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Script: | + 'powershell-yaml' | Install-PSResource -Repository PSGallery -TrustRepository -Reinstall + + $name = $env:PSMODULE_GET_SETTINGS_INPUT_Name + $settingsPath = $env:PSMODULE_GET_SETTINGS_INPUT_SettingsPath + LogGroup "Inputs" { + [pscustomobject]@{ + PWD = (Get-Location).Path + Name = $name + SettingsPath = $settingsPath + } | Format-List | Out-String + } + + if (![string]::IsNullOrEmpty($settingsPath) -and (Test-Path -Path $settingsPath)) { + LogGroup "Import settings" { + $settingsFile = Get-Item -Path $settingsPath + $relativeSettingsPath = $settingsFile | Resolve-Path -Relative + Write-Host "Importing settings from [$relativeSettingsPath]" + $content = $settingsFile | Get-Content -Raw + switch -Regex ($settingsFile.Extension) { + '.json' { + $settings = $content | ConvertFrom-Json + Write-Host ($settings | ConvertTo-Json -Depth 5 | Out-String) + } + '.yaml|.yml' { + $settings = $content | ConvertFrom-Yaml + Write-Host ($settings | ConvertTo-Yaml | Out-String) + } + '.psd1' { + $settings = $content | ConvertFrom-Hashtable + Write-Host ($settings | ConvertTo-Hashtable | Format-Hashtable | Out-String) + } + default { + throw "Unsupported settings file format: [$settingsPath]. Supported formats are json, yaml/yml and psd1." + } + } + } + } else { + Write-Host 'No settings file present.' + $settings = @{} + } + + $settings = [pscustomobject]@{ + Name = ($name ?? $settings.Name) ?? $env:GITHUB_REPOSITORY_NAME + Test = [pscustomobject]@{ + Skip = $settings.Test.Skip ?? $false + Linux = [pscustomobject]@{ + Skip = $settings.Test.Linux.Skip ?? $false + } + MacOS = [pscustomobject]@{ + Skip = $settings.Test.MacOS.Skip ?? $false + } + Windows = [pscustomobject]@{ + Skip = $settings.Test.Windows.Skip ?? $false + } + SourceCode = [pscustomobject]@{ + Skip = $settings.Test.SourceCode.Skip ?? $false + Linux = [pscustomobject]@{ + Skip = $settings.Test.SourceCode.Linux.Skip ?? $false + } + MacOS = [pscustomobject]@{ + Skip = $settings.Test.SourceCode.MacOS.Skip ?? $false + } + Windows = [pscustomobject]@{ + Skip = $settings.Test.SourceCode.Windows.Skip ?? $false + } + } + PSModule = [pscustomobject]@{ + Skip = $settings.Test.PSModule.Skip ?? $false + Linux = [pscustomobject]@{ + Skip = $settings.Test.PSModule.Linux.Skip ?? $false + } + MacOS = [pscustomobject]@{ + Skip = $settings.Test.PSModule.MacOS.Skip ?? $false + } + Windows = [pscustomobject]@{ + Skip = $settings.Test.PSModule.Windows.Skip ?? $false + } + } + Module = [pscustomobject]@{ + Skip = $settings.Test.Module.Skip ?? $false + Linux = [pscustomobject]@{ + Skip = $settings.Test.Module.Linux.Skip ?? $false + } + MacOS = [pscustomobject]@{ + Skip = $settings.Test.Module.MacOS.Skip ?? $false + } + Windows = [pscustomobject]@{ + Skip = $settings.Test.Module.Windows.Skip ?? $false + } + } + CodeCoverage = [pscustomobject]@{ + Skip = $settings.Test.CodeCoverage.Skip ?? $false + PercentTarget = $settings.Test.CodeCoverage.PercentTarget ?? 0 + } + } + Build = [pscustomobject]@{ + Skip = $settings.Build.Skip ?? $false + Module = [pscustomobject]@{ + Skip = $settings.Build.Module.Skip ?? $false + } + Docs = [pscustomobject]@{ + Skip = $settings.Build.Docs.Skip ?? $false + } + } + Publish = [pscustomobject]@{ + AutoCleanup = $settings.Publish.AutoCleanup ?? $true + AutoPatching = $settings.Publish.AutoPatching ?? $true + IncrementalPrerelease = $settings.Publish.IncrementalPrerelease ?? $true + DatePrereleaseFormat = $settings.Publish.DatePrereleaseFormat ?? '' + VersionPrefix = $settings.Publish.VersionPrefix ?? 'v' + MajorLabels = $settings.Publish.MajorLabels ?? 'major, breaking' + MinorLabels = $settings.Publish.MinorLabels ?? 'minor, feature' + PatchLabels = $settings.Publish.PatchLabels ?? 'patch, fix' + IgnoreLabels = $settings.Publish.IgnoreLabels ?? 'NoRelease' + } + } + LogGroup "Final settings" { + switch -Regex ($settingsFile.Extension) { + '.yaml|.yml' { + Write-Host ($settings | ConvertTo-Yaml | Out-String) + } + '.psd1' { + Write-Host ($settings | ConvertTo-Hashtable | Format-Hashtable | Out-String) + } + default { + Write-Host ($settings | ConvertTo-Json -Depth 5 | Out-String) + } + } + } + + Set-GitHubOutput -Name Settings -Value ($settings | ConvertTo-Json -Depth 10) + + # Get-TestSuites + if ($settings.Test.Skip) { + Write-Host 'Skipping all tests.' + Set-GitHubOutput -Name SourceCodeTestSuites -Value '[]' + Set-GitHubOutput -Name PSModuleTestSuites -Value '[]' + Set-GitHubOutput -Name ModuleTestSuites -Value '[]' + exit 0 + } + + # Define test configurations as an array of hashtables. + $linux = [PSCustomObject]@{ RunsOn = 'ubuntu-latest'; OSName = 'Linux' } + $macOS = [PSCustomObject]@{ RunsOn = 'macos-latest'; OSName = 'macOS' } + $windows = [PSCustomObject]@{ RunsOn = 'windows-latest'; OSName = 'Windows' } + + LogGroup 'Source Code Test Suites:' { + $sourceCodeTestSuites = if ($settings.Test.SourceCode.Skip) { + Write-Host 'Skipping all source code tests.' + } else { + if (-not $settings.Test.Linux.Skip -and -not $settings.Test.SourceCode.Linux.Skip) { $linux } + if (-not $settings.Test.MacOS.Skip -and -not $settings.Test.SourceCode.MacOS.Skip) { $macOS } + if (-not $settings.Test.Windows.Skip -and -not $settings.Test.SourceCode.Windows.Skip) { $windows } + } + $sourceCodeTestSuites | Format-Table -AutoSize | Out-String + $sourceCodeTestSuites = ($null -ne $sourceCodeTestSuites) ? ($sourceCodeTestSuites | ConvertTo-Json -AsArray) : '[]' + Set-GitHubOutput -Name SourceCodeTestSuites -Value $sourceCodeTestSuites + } + + LogGroup 'PSModule Test Suites:' { + $psModuleTestSuites = if ($settings.Test.PSModule.Skip) { + Write-Host 'Skipping all PSModule tests.' + } else { + if (-not $settings.Test.Linux.Skip -and -not $settings.Test.PSModule.Linux.Skip) { $linux } + if (-not $settings.Test.MacOS.Skip -and -not $settings.Test.PSModule.MacOS.Skip) { $macOS } + if (-not $settings.Test.Windows.Skip -and -not $settings.Test.PSModule.Windows.Skip) { $windows } + } + $psModuleTestSuites | Format-Table -AutoSize | Out-String + $psModuleTestSuites = ($null -ne $psModuleTestSuites) ? ($psModuleTestSuites | ConvertTo-Json -AsArray) : '[]' + Set-GitHubOutput -Name PSModuleTestSuites -Value $psModuleTestSuites + } + + LogGroup 'Module Local Test Suites:' { + $moduleTestSuites = if ($settings.Test.Module.Skip) { + Write-Host 'Skipping all module tests.' + Set-GitHubOutput -Name ModuleTestSuites -Value $moduleTestSuites + } else { + # Locate the tests directory. + $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path + if (-not $testsPath) { + Write-Warning 'No tests found' + } + Write-Host "Tests found at [$testsPath]" + + function Get-TestItemsFromFolder { + param ([string]$FolderPath) + + $configFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Configuration.ps1' + if ($configFiles.Count -eq 1) { + return @($configFiles) + } elseif ($configFiles.Count -gt 1) { + throw "Multiple configuration files found in [$FolderPath]. Please separate configurations into different folders." + } + + $containerFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Container.ps1' + if ($containerFiles.Count -ge 1) { + return $containerFiles + } + + $testFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Tests.ps1' + return $testFiles + } + + function Find-TestDirectories { + param ([string]$Path) + + $directories = @() + $childDirs = Get-ChildItem -Path $Path -Directory + + foreach ($dir in $childDirs) { + $directories += $dir.FullName + $directories += Find-TestDirectories -Path $dir.FullName + } + + return $directories + } + + $allTestFolders = @($testsPath) + (Find-TestDirectories -Path $testsPath) + + foreach ($folder in $allTestFolders) { + $testItems = Get-TestItemsFromFolder -FolderPath $folder + foreach ($item in $testItems) { + if (-not $settings.Test.Linux.Skip -and -not $settings.Test.Module.Linux.Skip) { + [pscustomobject]@{ + RunsOn = $linux.RunsOn + OSName = $linux.OSName + TestPath = Resolve-Path -Path $item.FullName -Relative + TestName = ($item.BaseName).Split('.')[0] + } + } + if (-not $settings.Test.MacOS.Skip -and -not $settings.Test.Module.MacOS.Skip) { + [pscustomobject]@{ + RunsOn = $macOS.RunsOn + OSName = $macOS.OSName + TestPath = Resolve-Path -Path $item.FullName -Relative + TestName = ($item.BaseName).Split('.')[0] + } + } + if (-not $settings.Test.Windows.Skip -and -not $settings.Test.Module.Windows.Skip) { + [pscustomobject]@{ + RunsOn = $windows.RunsOn + OSName = $windows.OSName + TestPath = Resolve-Path -Path $item.FullName -Relative + TestName = ($item.BaseName).Split('.')[0] + } + } + } + } + } + $moduleTestSuites | Format-Table -AutoSize | Out-String + $moduleTestSuites = ($null -ne $moduleTestSuites) ? ($moduleTestSuites | ConvertTo-Json -AsArray) : '[]' + Set-GitHubOutput -Name ModuleTestSuites -Value $moduleTestSuites + } diff --git a/.github/workflows/Get-TestResults.yml b/.github/workflows/Get-TestResults.yml index 709b63b4..aa6148ad 100644 --- a/.github/workflows/Get-TestResults.yml +++ b/.github/workflows/Get-TestResults.yml @@ -3,6 +3,18 @@ name: Get-TestResults on: workflow_call: inputs: + SourceCodeTestSuites: + type: string + description: The test suites to run for the source code. + required: true + PSModuleTestSuites: + type: string + description: The test suites to run for the PSModule. + required: true + ModuleTestSuites: + type: string + description: The test suites to run for the module. + required: true Debug: type: boolean description: Enable debug output. @@ -41,6 +53,9 @@ jobs: uses: PSModule/Get-PesterTestResults@v1 id: Get-TestResults with: + SourceCodeTestSuites: ${{ inputs.SourceCodeTestSuites }} + PSModuleTestSuites: ${{ inputs.PSModuleTestSuites }} + ModuleTestSuites: ${{ inputs.ModuleTestSuites }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} diff --git a/.github/workflows/Get-TestSuites.yml b/.github/workflows/Get-TestSuites.yml deleted file mode 100644 index 1dda763d..00000000 --- a/.github/workflows/Get-TestSuites.yml +++ /dev/null @@ -1,188 +0,0 @@ -name: Get-TestSuites - -on: - workflow_call: - inputs: - SkipTests: - type: string - description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. - required: false - default: None - Debug: - type: boolean - description: Enable debug output. - required: false - default: false - Verbose: - type: boolean - description: Enable verbose output. - required: false - default: false - Version: - type: string - description: Specifies the version of the GitHub module to be installed. The value must be an exact version. - required: false - default: '' - Prerelease: - type: boolean - description: Whether to use a prerelease version of the 'GitHub' module. - required: false - default: false - WorkingDirectory: - type: string - description: The working directory where the script will run from. - required: false - default: '.' - - outputs: - SourceCodeTestSuites: - description: Source Code PSModule test suites to run. - value: ${{ jobs.Get-TestSuites.outputs.SourceCodeTestSuites }} - ModuleTestSuites: - description: Module PSModule test suites to run. - value: ${{ jobs.Get-TestSuites.outputs.ModuleTestSuites }} - ModuleLocalTestSuites: - description: Module local test suites to run. - value: ${{ jobs.Get-TestSuites.outputs.ModuleLocalTestSuites }} - -permissions: - contents: read # to checkout the repo - -jobs: - Get-TestSuites: - name: Get-TestSuites - runs-on: ubuntu-latest - outputs: - SourceCodeTestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).SourceCodeTestSuites }} - ModuleTestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).ModuleTestSuites }} - ModuleLocalTestSuites: ${{ fromJson(steps.Get-TestSuites.outputs.result).ModuleLocalTestSuites }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Get-TestSuites - uses: PSModule/GitHub-Script@v1 - id: Get-TestSuites - env: - PSMODULE_GET_TESTSUITES_INPUT_SkipTests: ${{ inputs.SkipTests }} - with: - ShowOutput: true - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - Script: | - # Get-TestSuites - $skipTests = $env:PSMODULE_GET_TESTSUITES_INPUT_SkipTests -split '[,\s]+' | ForEach-Object { - $_.Trim() - } - - LogGroup 'Tests to be skipped:' { - $skipTests | ForEach-Object { " - $_" } - } - - if ($skipTests -contains 'All') { - Write-Host "Skipping all tests as requested." - Set-GitHubOutput -Name SourceCodeTestSuites -Value '[]' - Set-GitHubOutput -Name ModuleTestSuites -Value '[]' - Set-GitHubOutput -Name ModuleLocalTestSuites -Value '[]' - exit 0 - } - - # Define test configurations as an array of hashtables. - $osConfigs = @( - [PSCustomObject]@{ RunsOn = 'ubuntu-latest'; OSName = 'Linux' } - [PSCustomObject]@{ RunsOn = 'macos-latest'; OSName = 'macOS' } - [PSCustomObject]@{ RunsOn = 'windows-latest'; OSName = 'Windows' } - ) | Where-Object { $skipTests -notcontains $_.OSName } - - if (-not $osConfigs) { - Write-Host "Skipping all OS configurations." - Set-GitHubOutput -Name SourceCodeTestSuites -Value '[]' - Set-GitHubOutput -Name ModuleTestSuites -Value '[]' - Set-GitHubOutput -Name ModuleLocalTestSuites -Value '[]' - exit 0 - } - - LogGroup 'Source Code Test Suites:' { - if ($skipTests -notcontains 'SourceCode') { - $sourceCodeTestSuites = $osConfigs - } - $sourceCodeTestSuites | Format-Table -AutoSize | Out-String - $sourceCodeTestSuites = ($null -ne $sourceCodeTestSuites) ? ($sourceCodeTestSuites | ConvertTo-Json -AsArray) : '[]' - Set-GitHubOutput -Name SourceCodeTestSuites -Value $sourceCodeTestSuites - } - - LogGroup 'Module Test Suites:' { - if ($skipTests -notcontains 'Module') { - $moduleTestSuites = $osConfigs - } - $moduleTestSuites | Format-Table -AutoSize | Out-String - $moduleTestSuites = ($null -ne $moduleTestSuites) ? ($moduleTestSuites | ConvertTo-Json -AsArray) : '[]' - Set-GitHubOutput -Name ModuleTestSuites -Value $moduleTestSuites - } - - LogGroup 'Module Local Test Suites:' { - if ($skipTests -notcontains 'Module') { - # Locate the tests directory. - $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path - if (-not $testsPath -or -not (Test-Path -Path $testsPath)) { - Write-Warning 'No tests found' - exit 0 - } - Write-Host "Tests found at [$testsPath]" - - function Get-TestItemsFromFolder { - param ([string]$FolderPath) - - $configFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Configuration.ps1' - if ($configFiles.Count -eq 1) { - return @($configFiles) - } elseif ($configFiles.Count -gt 1) { - throw "Multiple configuration files found in [$FolderPath]. Please separate configurations into different folders." - } - - $containerFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Container.ps1' - if ($containerFiles.Count -ge 1) { - return $containerFiles - } - - $testFiles = Get-ChildItem -Path $FolderPath -File -Filter '*.Tests.ps1' - return $testFiles - } - - function Find-TestDirectories { - param ([string]$Path) - - $directories = @() - $childDirs = Get-ChildItem -Path $Path -Directory - - foreach ($dir in $childDirs) { - $directories += $dir.FullName - $directories += Find-TestDirectories -Path $dir.FullName - } - - return $directories - } - - $allTestFolders = @($testsPath) + (Find-TestDirectories -Path $testsPath) - - $moduleLocalTestSuites = foreach ($folder in $allTestFolders) { - $testItems = Get-TestItemsFromFolder -FolderPath $folder - foreach ($item in $testItems) { - foreach ($osConfig in $osConfigs) { - [pscustomobject]@{ - RunsOn = $osConfig.RunsOn - OSName = $osConfig.OSName - TestPath = Resolve-Path -Path $item.FullName -Relative - TestName = ($item.BaseName).Split('.')[0] - } - } - } - } - } - $moduleLocalTestSuites | Format-Table -AutoSize | Out-String - $moduleLocalTestSuites = ($null -ne $moduleLocalTestSuites) ? ($moduleLocalTestSuites | ConvertTo-Json -AsArray) : '[]' - Set-GitHubOutput -Name ModuleLocalTestSuites -Value $moduleLocalTestSuites - } diff --git a/.github/workflows/Test-Module.yml b/.github/workflows/Test-Module.yml index 5bb02695..e97ecfa7 100644 --- a/.github/workflows/Test-Module.yml +++ b/.github/workflows/Test-Module.yml @@ -91,7 +91,6 @@ jobs: - name: Test-Module uses: PSModule/Test-PSModule@v3 - continue-on-error: true with: Name: ${{ inputs.Name }} Debug: ${{ inputs.Debug }} @@ -113,7 +112,6 @@ jobs: - name: Lint-Module uses: PSModule/Invoke-ScriptAnalyzer@v3 - continue-on-error: true with: Path: outputs/module Debug: ${{ inputs.Debug }} @@ -122,3 +120,5 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} Settings: Module + TestResult_Enabled: true + TestResult_TestSuiteName: PSModuleLint-Module-${{ runner.os }} diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 3547c79e..b61912eb 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -106,7 +106,6 @@ jobs: - name: Test-ModuleLocal uses: PSModule/Invoke-Pester@v4 - continue-on-error: true env: TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }} TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }} diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 781b9f4c..23e2e5bd 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -79,3 +79,5 @@ jobs: Path: src Settings: SourceCode WorkingDirectory: ${{ inputs.WorkingDirectory }} + TestResult_Enabled: true + TestResult_TestSuiteName: PSModuleLint-SourceCode-${{ runner.os }} diff --git a/.github/workflows/Workflow-Test-Default-CI.yml b/.github/workflows/Workflow-Test-Default-CI.yml index 3ef99f04..10ba430a 100644 --- a/.github/workflows/Workflow-Test-Default-CI.yml +++ b/.github/workflows/Workflow-Test-Default-CI.yml @@ -22,6 +22,5 @@ jobs: uses: ./.github/workflows/CI.yml secrets: inherit with: - Name: PSModuleTest WorkingDirectory: tests/srcTestRepo - SkipTests: Module + Name: PSModuleTest2 diff --git a/.github/workflows/Workflow-Test-Default.yml b/.github/workflows/Workflow-Test-Default.yml index 2fcf36a6..bd82710f 100644 --- a/.github/workflows/Workflow-Test-Default.yml +++ b/.github/workflows/Workflow-Test-Default.yml @@ -24,7 +24,5 @@ jobs: uses: ./.github/workflows/workflow.yml secrets: inherit with: - Name: PSModuleTest WorkingDirectory: tests/srcTestRepo - TestProcess: true - SkipTests: Module + Name: PSModuleTest2 diff --git a/.github/workflows/Workflow-Test-WithManifest-CI.yml b/.github/workflows/Workflow-Test-WithManifest-CI.yml index 3c9194b8..8c9de2e1 100644 --- a/.github/workflows/Workflow-Test-WithManifest-CI.yml +++ b/.github/workflows/Workflow-Test-WithManifest-CI.yml @@ -22,6 +22,6 @@ jobs: uses: ./.github/workflows/CI.yml secrets: inherit with: - Name: PSModuleTest WorkingDirectory: tests/srcWithManifestTestRepo - SkipTests: Linux + Name: PSModuleTest2 + SettingsPath: .github/PSModule.json diff --git a/.github/workflows/Workflow-Test-WithManifest.yml b/.github/workflows/Workflow-Test-WithManifest.yml index bf8ed601..8caaabc1 100644 --- a/.github/workflows/Workflow-Test-WithManifest.yml +++ b/.github/workflows/Workflow-Test-WithManifest.yml @@ -24,7 +24,6 @@ jobs: uses: ./.github/workflows/workflow.yml secrets: inherit with: - Name: PSModuleTest WorkingDirectory: tests/srcWithManifestTestRepo - TestProcess: true - SkipTests: Linux + Name: PSModuleTest2 + SettingsPath: .github/PSModule.yml diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index f9525b43..bb651635 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -32,21 +32,11 @@ on: type: string description: The name of the module to process. Scripts default to the repository name if nothing is specified. required: false - WorkingDirectory: - type: string - description: The path to the root of the repo. - required: false - default: '.' - SkipTests: + SettingsPath: type: string - description: Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. - required: false - default: None - TestProcess: - type: boolean - description: Whether to test the process. + description: The path to the settings file. Settings in the settings file take precedence over the action inputs. required: false - default: false + default: .github/PSModule.psd1 Debug: type: boolean description: Enable debug output. @@ -67,6 +57,11 @@ on: description: Whether to use a prerelease version of the 'GitHub' module. required: false default: false + WorkingDirectory: + type: string + description: The path to the root of the repo. + required: false + default: '.' permissions: contents: write # to checkout the repo and create releases on the repo @@ -74,10 +69,11 @@ permissions: statuses: write # to update the status of the workflow from linter jobs: - Get-TestSuites: - uses: ./.github/workflows/Get-TestSuites.yml + Get-Settings: + uses: ./.github/workflows/Get-Settings.yml with: - SkipTests: ${{ inputs.SkipTests }} + Name: ${{ inputs.Name }} + SettingsPath: ${{ inputs.SettingsPath }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -85,18 +81,18 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-SourceCode: - if: ${{ needs.Get-TestSuites.outputs.SourceCodeTestSuites != '[]' }} + if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} needs: - - Get-TestSuites + - Get-Settings strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.SourceCodeTestSuites) }} + include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} uses: ./.github/workflows/Test-SourceCode.yml with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -105,8 +101,10 @@ jobs: Build-Module: uses: ./.github/workflows/Build-Module.yml + needs: + - Get-Settings with: - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -115,10 +113,11 @@ jobs: Build-Docs: needs: + - Get-Settings - Build-Module uses: ./.github/workflows/Build-Docs.yml with: - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -126,20 +125,20 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-Module: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleTestSuites != '[]' }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' }} needs: - Build-Module - - Get-TestSuites + - Get-Settings strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleTestSuites) }} + include: ${{ fromJson(needs.Get-Settings.outputs.PSModuleTestSuites) }} uses: ./.github/workflows/Test-Module.yml secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -147,22 +146,22 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Test-ModuleLocal: - if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-TestSuites.outputs.ModuleLocalTestSuites != '[]' }} + if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-Settings.outputs.ModuleTestSuites != '[]' }} needs: - Build-Module - - Get-TestSuites + - Get-Settings strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.Get-TestSuites.outputs.ModuleLocalTestSuites) }} + include: ${{ fromJson(needs.Get-Settings.outputs.ModuleTestSuites) }} uses: ./.github/workflows/Test-ModuleLocal.yml secrets: inherit with: RunsOn: ${{ matrix.RunsOn }} OS: ${{ matrix.OSName }} - Name: ${{ inputs.Name }} TestPath: ${{ matrix.TestPath }} TestName: ${{ matrix.TestName }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} @@ -170,36 +169,43 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: always() && !cancelled() + if: needs.Get-Settings.result == 'success' && (always() && !cancelled()) needs: + - Get-Settings - Test-SourceCode - Test-Module - Test-ModuleLocal uses: ./.github/workflows/Get-TestResults.yml secrets: inherit with: + ModuleTestSuites: ${{ needs.Get-Settings.outputs.ModuleTestSuites }} + SourceCodeTestSuites: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites }} + PSModuleTestSuites: ${{ needs.Get-Settings.outputs.PSModuleTestSuites }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Get-CodeCoverage: - if: always() && !cancelled() + if: needs.Get-Settings.result == 'success' && (always() && !cancelled()) needs: - - Test-SourceCode + - Get-Settings - Test-Module - Test-ModuleLocal uses: ./.github/workflows/Get-CodeCoverage.yml secrets: inherit with: + CodeCoveragePercentTarget: ${{ fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.PercentTarget }} + StepSummary_Mode: ${{ fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.StepSummaryMode }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} Publish-Module: - if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} + if: ${{ needs.Get-Settings.result == 'success' && needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} needs: + - Get-Settings - Get-TestResults - Get-CodeCoverage - Build-Docs @@ -208,10 +214,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - name: Initialize environment uses: PSModule/Initialize-PSModule@v1 with: @@ -229,18 +231,28 @@ jobs: - name: Publish module uses: PSModule/Publish-PSModule@v2 with: - Name: ${{ inputs.Name }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} ModulePath: ${{ inputs.WorkingDirectory }}/outputs/module APIKey: ${{ secrets.APIKEY }} - WhatIf: ${{ inputs.TestProcess }} + WhatIf: ${{ github.repository == 'PSModule/Process-PSModule' }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + AutoCleanup: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.AutoCleanup }} + AutoPatching: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.AutoPatching }} + DatePrereleaseFormat: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.DatePrereleaseFormat }} + IgnoreLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.IgnoreLabels }} + IncrementalPrerelease: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.IncrementalPrerelease }} + MajorLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.MajorLabels }} + MinorLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.MinorLabels }} + PatchLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.PatchLabels }} + VersionPrefix: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.VersionPrefix }} Publish-Site: if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} needs: + - Get-Settings - Get-TestResults - Get-CodeCoverage - Build-Docs @@ -252,10 +264,6 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - name: Debug - if: ${{ inputs.Debug }} - uses: PSModule/Debug@v0 - - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index 00390e9b..135c19ee 100644 --- a/README.md +++ b/README.md @@ -75,8 +75,7 @@ jobs: | `DocsOutputPath` | `string` | The path to the output directory for the documentation. | `false` | `outputs/docs` | | `PublishDocs` | `boolean` | Whether to publish the documentation using MkDocs and GitHub Pages. | `false` | `true` | | `SiteOutputPath` | `string` | The path to the output directory for the site. | `false` | `outputs/site` | -| `SkipTests` | `string` | Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. | `false` | `None` | -| `TestProcess` | `boolean` | Whether to test the process. | `false` | `false` | +| `Skip` | `string` | Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. | `false` | `None` | | `Version` | `string` | Specifies the version of the GitHub module to be installed. The value must be an exact version. | `false` | N/A | | `Prerelease` | `boolean` | Whether to use a prerelease version of the 'GitHub' module. | `false` | `false` | | `Debug` | `boolean` | Whether to enable debug output. Adds a `debug` step to every job. | `false` | `false` | diff --git a/tests/srcTestRepo/.github/PSModule.yml b/tests/srcTestRepo/.github/PSModule.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/srcWithManifestTestRepo/.github/PSModule.json b/tests/srcWithManifestTestRepo/.github/PSModule.json new file mode 100644 index 00000000..b175eeb5 --- /dev/null +++ b/tests/srcWithManifestTestRepo/.github/PSModule.json @@ -0,0 +1,22 @@ +{ + "Name": "PSModuleTest", + "Test": { + "SourceCode": { + "Skip": true + }, + "PSModule": { + "Linux": { + "Skip": true + } + }, + "Module": { + "Skip": false + }, + "CodeCoverage": { + "PercentTarget": 1 + } + }, + "Publish": { + "AutoCleanup": false + } +} diff --git a/tests/srcWithManifestTestRepo/.github/PSModule.psd1 b/tests/srcWithManifestTestRepo/.github/PSModule.psd1 new file mode 100644 index 00000000..e680e8fd --- /dev/null +++ b/tests/srcWithManifestTestRepo/.github/PSModule.psd1 @@ -0,0 +1,22 @@ +@{ + Name = 'PSModuleTest' + Test = @{ + SourceCode = @{ + Skip = $true + } + PSModule = @{ + Linux = @{ + Skip = $true + } + } + Module = @{ + Skip = $false + } + CodeCoverage = @{ + PercentTarget = 1 + } + } + Publish = @{ + AutoCleanup = $false + } +} diff --git a/tests/srcWithManifestTestRepo/.github/PSModule.yml b/tests/srcWithManifestTestRepo/.github/PSModule.yml index e69de29b..d285c1ed 100644 --- a/tests/srcWithManifestTestRepo/.github/PSModule.yml +++ b/tests/srcWithManifestTestRepo/.github/PSModule.yml @@ -0,0 +1,13 @@ +Name: PSModuleTest +Test: + SourceCode: + Skip: true + PSModule: + Linux: + Skip: true + Module: + Skip: false + CodeCoverage: + PercentTarget: 1 +Publish: + AutoCleanup: false From 37916e7185cc02269329c8cce1eafb22c260a59d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Mar 2025 11:36:18 +0100 Subject: [PATCH 269/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20workflo?= =?UTF-8?q?w=20conditions=20to=20ensure=20non-empty=20test=20suite=20outpu?= =?UTF-8?q?ts=20before=20proceeding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 4 ++-- .github/workflows/workflow.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 882ee035..fef4c5a3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -169,7 +169,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' && needs.Get-Settings.outputs.ModuleTestSuites != '[]' && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -187,7 +187,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' && needs.Get-Settings.outputs.ModuleTestSuites != '[]' && (always() && !cancelled()) needs: - Get-Settings - Test-Module diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index bb651635..1ddd60ad 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -169,7 +169,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' && needs.Get-Settings.outputs.ModuleTestSuites != '[]' && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -187,7 +187,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' && needs.Get-Settings.outputs.ModuleTestSuites != '[]' && (always() && !cancelled()) needs: - Get-Settings - Test-Module From 807b085c97440257593ec4ff51ed86a7b5085091 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Mar 2025 11:43:29 +0100 Subject: [PATCH 270/324] =?UTF-8?q?=F0=9F=A9=B9=20[CI]:=20Update=20conditi?= =?UTF-8?q?onal=20checks=20in=20workflows=20to=20allow=20for=20partial=20t?= =?UTF-8?q?est=20suite=20outputs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 4 ++-- .github/workflows/workflow.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index fef4c5a3..eb2bc142 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -169,7 +169,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' && needs.Get-Settings.outputs.ModuleTestSuites != '[]' && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -187,7 +187,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' && needs.Get-Settings.outputs.ModuleTestSuites != '[]' && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-Module diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 1ddd60ad..85f83be9 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -169,7 +169,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' && needs.Get-Settings.outputs.ModuleTestSuites != '[]' && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -187,7 +187,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' && needs.Get-Settings.outputs.ModuleTestSuites != '[]' && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-Module From 5dd81354dec4b440bcb48299d072f86ac435ef9a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Mar 2025 11:47:22 +0100 Subject: [PATCH 271/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Simplify=20PSMod?= =?UTF-8?q?ule.yml=20by=20removing=20unnecessary=20SourceCode=20section?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/srcWithManifestTestRepo/.github/PSModule.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/srcWithManifestTestRepo/.github/PSModule.yml b/tests/srcWithManifestTestRepo/.github/PSModule.yml index d285c1ed..85e659c4 100644 --- a/tests/srcWithManifestTestRepo/.github/PSModule.yml +++ b/tests/srcWithManifestTestRepo/.github/PSModule.yml @@ -1,7 +1,7 @@ Name: PSModuleTest Test: - SourceCode: - Skip: true + Skip: true + # SourceCode: PSModule: Linux: Skip: true From 9ace7804886bbecf2afdb446b15895cea7072d49 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Mar 2025 11:54:08 +0100 Subject: [PATCH 272/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Adjust=20PSModul?= =?UTF-8?q?e.yml=20to=20move=20Skip=20property=20under=20SourceCode=20sect?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/srcWithManifestTestRepo/.github/PSModule.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/srcWithManifestTestRepo/.github/PSModule.yml b/tests/srcWithManifestTestRepo/.github/PSModule.yml index 85e659c4..d285c1ed 100644 --- a/tests/srcWithManifestTestRepo/.github/PSModule.yml +++ b/tests/srcWithManifestTestRepo/.github/PSModule.yml @@ -1,7 +1,7 @@ Name: PSModuleTest Test: - Skip: true - # SourceCode: + SourceCode: + Skip: true PSModule: Linux: Skip: true From 7cdbdd9d9c60219f0bfb1ec136a76c2ee9b85817 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Mar 2025 12:07:24 +0100 Subject: [PATCH 273/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Update=20default?= =?UTF-8?q?=20settings=20file=20path=20in=20CI=20workflows=20to=20use=20PS?= =?UTF-8?q?Module.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 2 +- .github/workflows/workflow.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index eb2bc142..98468a00 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -36,7 +36,7 @@ on: type: string description: The path to the settings file. Settings in the settings file take precedence over the action inputs. required: false - default: .github/PSModule.psd1 + default: .github/PSModule.yml Debug: type: boolean description: Enable debug output. diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 85f83be9..fd9ee2a3 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -36,7 +36,7 @@ on: type: string description: The path to the settings file. Settings in the settings file take precedence over the action inputs. required: false - default: .github/PSModule.psd1 + default: .github/PSModule.yml Debug: type: boolean description: Enable debug output. From f9545f294c9acd9a7cb5e2fd87f2eacf0d7b8dc3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 25 Mar 2025 16:06:06 +0100 Subject: [PATCH 274/324] fix --- .github/workflows/CI.yml | 2 ++ .github/workflows/workflow.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 98468a00..62a4fe77 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -100,6 +100,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Build-Module: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Module.Skip != true }} uses: ./.github/workflows/Build-Module.yml needs: - Get-Settings @@ -112,6 +113,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Build-Docs: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Docs.Skip != true }} needs: - Get-Settings - Build-Module diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index fd9ee2a3..d004e945 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -100,6 +100,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Build-Module: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Module.Skip != true }} uses: ./.github/workflows/Build-Module.yml needs: - Get-Settings @@ -112,6 +113,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Build-Docs: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Docs.Skip != true }} needs: - Get-Settings - Build-Module From 8a4953c7e12da63d4e7fc4e09b7390af17eebc38 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 26 Mar 2025 08:22:24 +0100 Subject: [PATCH 275/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Update=20conditi?= =?UTF-8?q?onal=20checks=20to=20incorporate=20Skip=20settings=20for=20Test?= =?UTF-8?q?Results=20and=20CodeCoverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 4 ++-- .github/workflows/Get-Settings.yml | 3 +++ .github/workflows/workflow.yml | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 62a4fe77..7f51a9ea 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -171,7 +171,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip != 'true' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -189,7 +189,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip != 'true' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-Module diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml index 7ae1990c..d0ca4ebe 100644 --- a/.github/workflows/Get-Settings.yml +++ b/.github/workflows/Get-Settings.yml @@ -173,6 +173,9 @@ jobs: Skip = $settings.Test.Module.Windows.Skip ?? $false } } + TestResults = [pscustomobject]@{ + Skip = $settings.Test.TestResults.Skip ?? $false + } CodeCoverage = [pscustomobject]@{ Skip = $settings.Test.CodeCoverage.Skip ?? $false PercentTarget = $settings.Test.CodeCoverage.PercentTarget ?? 0 diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index d004e945..380f9813 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -171,7 +171,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip != 'true' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -189,7 +189,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip != 'true' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-Module From 8b02c68495c0fc1fa8d5c41e65ebea1ce819d335 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 27 Mar 2025 15:32:08 +0100 Subject: [PATCH 276/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Update=20conditi?= =?UTF-8?q?onal=20checks=20to=20use=20'false'=20for=20Skip=20settings=20in?= =?UTF-8?q?=20TestResults=20and=20CodeCoverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 4 ++-- .github/workflows/workflow.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7f51a9ea..3f862eea 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -171,7 +171,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip != 'true' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip == 'false' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -189,7 +189,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip != 'true' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip == 'false' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-Module diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 380f9813..d3956dee 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -171,7 +171,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip != 'true' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip == 'false' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -189,7 +189,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip != 'true' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip == 'false' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-Module From e10bb3c45c1be7814181c7468eb2d611b22990ff Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 27 Mar 2025 15:58:37 +0100 Subject: [PATCH 277/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Simplify=20condi?= =?UTF-8?q?tional=20checks=20for=20Skip=20settings=20in=20TestResults=20an?= =?UTF-8?q?d=20CodeCoverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 4 ++-- .github/workflows/workflow.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3f862eea..8429370f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -171,7 +171,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip == 'false' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && !fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -189,7 +189,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip == 'false' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && !fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-Module diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index d3956dee..a7dcc9c9 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -171,7 +171,7 @@ jobs: WorkingDirectory: ${{ inputs.WorkingDirectory }} Get-TestResults: - if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip == 'false' && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && !fromJson(needs.Get-Settings.outputs.Settings).Test.TestResults.Skip && (needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' || needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-SourceCode @@ -189,7 +189,7 @@ jobs: Version: ${{ inputs.Version }} Get-CodeCoverage: - if: needs.Get-Settings.result == 'success' && fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip == 'false' && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) + if: needs.Get-Settings.result == 'success' && !fromJson(needs.Get-Settings.outputs.Settings).Test.CodeCoverage.Skip && (needs.Get-Settings.outputs.PSModuleTestSuites != '[]' || needs.Get-Settings.outputs.ModuleTestSuites != '[]') && (always() && !cancelled()) needs: - Get-Settings - Test-Module From d09da5783e241cacb2f5100697e32d86b5722aa6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 30 Mar 2025 12:19:06 +0200 Subject: [PATCH 278/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Add=20Filter=5FE?= =?UTF-8?q?xcludeTag=20for=20Flaky=20tests=20in=20Test-ModuleLocal.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index b61912eb..77db15b9 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -126,6 +126,7 @@ jobs: Output_Verbosity: Detailed CodeCoverage_OutputFormat: JaCoCo CodeCoverage_CoveragePercentTarget: 0 + Filter_ExcludeTag: Flaky Path: ${{ inputs.TestPath }} Run_Path: ${{ steps.import-module.outputs.path }} WorkingDirectory: ${{ inputs.WorkingDirectory }} From 496a8b00ffb6578d3e2ab6aa9c6ca2b02f977681 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 31 Mar 2025 16:10:20 +0200 Subject: [PATCH 279/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Update=20output?= =?UTF-8?q?=20for=20skipped=20module=20tests=20to=20return=20an=20empty=20?= =?UTF-8?q?array?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-Settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml index d0ca4ebe..000d0958 100644 --- a/.github/workflows/Get-Settings.yml +++ b/.github/workflows/Get-Settings.yml @@ -261,7 +261,7 @@ jobs: LogGroup 'Module Local Test Suites:' { $moduleTestSuites = if ($settings.Test.Module.Skip) { Write-Host 'Skipping all module tests.' - Set-GitHubOutput -Name ModuleTestSuites -Value $moduleTestSuites + Set-GitHubOutput -Name ModuleTestSuites -Value '[]' } else { # Locate the tests directory. $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path From 746943801fadae0cae2c1cda586b5d403da24466 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 31 Mar 2025 16:16:01 +0200 Subject: [PATCH 280/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Refactor=20Name?= =?UTF-8?q?=20assignment=20logic=20in=20Get-Settings.yml=20for=20improved?= =?UTF-8?q?=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-Settings.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml index 000d0958..5328ace4 100644 --- a/.github/workflows/Get-Settings.yml +++ b/.github/workflows/Get-Settings.yml @@ -125,7 +125,7 @@ jobs: } $settings = [pscustomobject]@{ - Name = ($name ?? $settings.Name) ?? $env:GITHUB_REPOSITORY_NAME + Name = [string]::IsNullOrEmpty($name) ? $name : [string]::IsNullOrEmpty($settings.Name) ? $settings.Name : $env:GITHUB_REPOSITORY_NAME Test = [pscustomobject]@{ Skip = $settings.Test.Skip ?? $false Linux = [pscustomobject]@{ @@ -261,7 +261,6 @@ jobs: LogGroup 'Module Local Test Suites:' { $moduleTestSuites = if ($settings.Test.Module.Skip) { Write-Host 'Skipping all module tests.' - Set-GitHubOutput -Name ModuleTestSuites -Value '[]' } else { # Locate the tests directory. $testsPath = Resolve-Path 'tests' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path From ebf43666de064851008760f91688e1bfc3d661e6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 31 Mar 2025 16:23:01 +0200 Subject: [PATCH 281/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Rename=20variabl?= =?UTF-8?q?e=20for=20input=20name=20in=20Get-Settings.yml=20for=20better?= =?UTF-8?q?=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-Settings.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml index 5328ace4..e0f024f8 100644 --- a/.github/workflows/Get-Settings.yml +++ b/.github/workflows/Get-Settings.yml @@ -85,12 +85,12 @@ jobs: Script: | 'powershell-yaml' | Install-PSResource -Repository PSGallery -TrustRepository -Reinstall - $name = $env:PSMODULE_GET_SETTINGS_INPUT_Name + $inputName = $env:PSMODULE_GET_SETTINGS_INPUT_Name $settingsPath = $env:PSMODULE_GET_SETTINGS_INPUT_SettingsPath LogGroup "Inputs" { [pscustomobject]@{ PWD = (Get-Location).Path - Name = $name + Name = $inputName SettingsPath = $settingsPath } | Format-List | Out-String } @@ -124,8 +124,18 @@ jobs: $settings = @{} } + LogGroup "Name" { + [pscustomobject]@{ + InputName = $inputName + SettingsName = $settings.Name + RepositoryName = $env:GITHUB_REPOSITORY_NAME + } | Format-List | Out-String + + $name = ![string]::IsNullOrEmpty($inputName) ? $name : [string]::IsNullOrEmpty($settings.Name) ? $settings.Name : $env:GITHUB_REPOSITORY_NAME + } + $settings = [pscustomobject]@{ - Name = [string]::IsNullOrEmpty($name) ? $name : [string]::IsNullOrEmpty($settings.Name) ? $settings.Name : $env:GITHUB_REPOSITORY_NAME + Name = $name Test = [pscustomobject]@{ Skip = $settings.Test.Skip ?? $false Linux = [pscustomobject]@{ From 17b3d0777f291a753f804630bb69cc9b4ada090e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 31 Mar 2025 16:25:25 +0200 Subject: [PATCH 282/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Refactor=20condi?= =?UTF-8?q?tional=20logic=20for=20name=20assignment=20in=20Get-Settings.ym?= =?UTF-8?q?l=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-Settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml index e0f024f8..ba4e6bff 100644 --- a/.github/workflows/Get-Settings.yml +++ b/.github/workflows/Get-Settings.yml @@ -131,7 +131,7 @@ jobs: RepositoryName = $env:GITHUB_REPOSITORY_NAME } | Format-List | Out-String - $name = ![string]::IsNullOrEmpty($inputName) ? $name : [string]::IsNullOrEmpty($settings.Name) ? $settings.Name : $env:GITHUB_REPOSITORY_NAME + $name = ![string]::IsNullOrEmpty($inputName) ? $name : ![string]::IsNullOrEmpty($settings.Name) ? $settings.Name : $env:GITHUB_REPOSITORY_NAME } $settings = [pscustomobject]@{ From c27c7235b1e5d9203d883f0a3e6d77ca6ef65664 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 31 Mar 2025 16:28:39 +0200 Subject: [PATCH 283/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Add=20logging=20?= =?UTF-8?q?for=20module=20name=20selection=20in=20Get-Settings.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-Settings.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml index ba4e6bff..72e99323 100644 --- a/.github/workflows/Get-Settings.yml +++ b/.github/workflows/Get-Settings.yml @@ -132,6 +132,8 @@ jobs: } | Format-List | Out-String $name = ![string]::IsNullOrEmpty($inputName) ? $name : ![string]::IsNullOrEmpty($settings.Name) ? $settings.Name : $env:GITHUB_REPOSITORY_NAME + + Write-Host "Using [$name] as the module name." } $settings = [pscustomobject]@{ From b1fbc71fc1b17e606017997c41091da2f9f0beb2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 12:33:24 +0200 Subject: [PATCH 284/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Remove=20unused?= =?UTF-8?q?=20Prescript=20from=20Test-ModuleLocal=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 2 -- README.md | 23 ++++++++++---- media/Flow.drawio | 42 ++++++++++++++++++------- media/Process-PSModule.png | Bin 73852 -> 108347 bytes 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 77db15b9..0fd223f7 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -130,5 +130,3 @@ jobs: Path: ${{ inputs.TestPath }} Run_Path: ${{ steps.import-module.outputs.path }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Prescript: | - Import-Module -Name '${{ steps.import-module.outputs.name }}' -RequiredVersion 999.0.0 diff --git a/README.md b/README.md index 135c19ee..1a7daeb1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ # Process-PSModule - -A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Document`, `Test`, and `Publish` actions to create a complete -CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization. +A workflow for crafting PowerShell modules using the PSModule framework, which builds, tests and publishes PowerShell modules to the PowerShell +Gallery and produces documentation that is published to GitHub Pages. The workflow is used by all PowerShell modules in the PSModule organization. ## Specifications and practices @@ -21,9 +20,21 @@ Depending on the labels in the pull requests, the workflow will result in differ ![Process diagram](./media/Process-PSModule.png) -- [Test-PSModule](https://github.com/PSModule/Test-PSModule/) - Tests and lints the source code. This runs on 3 different environments to check compatibility. - - PowerShell LTS on Windows, Ubuntu and macOS. -- [Build-PSModule](https://github.com/PSModule/Build-PSModule/) - Compiles the repository into an efficient PowerShell module. +- [Get-Settings](./.github/workflows/Get-Settings.yml) + - Reads the settings file from a file in the module repository to configure the workflow. + - Gathers tests and creates test configuration based on the settings and the tests available in the module repository. + - This includes the selection of what OSes to run the tests on. +- [Build-Module](./.github/workflows/Build-Module.yml) + - Compiles the module source code into a PowerShell module using a temporary version `999.0.0`. +- [Test-SourceCode](./.github/workflows/Test-SourceCode.yml) + - Tests and lints the source code using [PSModule framework settings for style and standards for source code](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#sourcecode-tests) + [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). + - This produces a json based report that is used to later evaluate the results of the tests. +- [Test-Module](./.github/workflows/Test-Module.yml) + - Tests and lints the module using [PSModule framework settings for style and standards foor modules](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#module-tests) + [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). + - This produces a json based report that is used to later evaluate the results of the tests. +- [Test-ModuleLocal](./.github/workflows/Test-ModuleLocal.yml) + - Import and tests the module using Pester test from the module repository. + - This produces a json based report that is used to later evaluate the results of the tests. - [Document-PSModule](https://github.com/PSModule/Document-PSModule/) - Generates documentation and deploys it to GitHub Pages. - [Test-PSModule](https://github.com/PSModule/Test-PSModule/) - Tests the compiled module. This runs on 4 different environments to check compatibility. - PowerShell LTS on Windows, Ubuntu and macOS. diff --git a/media/Flow.drawio b/media/Flow.drawio index 29afd76c..b9fc274b 100644 --- a/media/Flow.drawio +++ b/media/Flow.drawio @@ -1,6 +1,6 @@ - + @@ -13,27 +13,30 @@ - - + + + + + + + + - + - + - + - + - - - @@ -67,10 +70,10 @@ - + - + @@ -122,6 +125,21 @@ + + + + + + + + + + + + + + + diff --git a/media/Process-PSModule.png b/media/Process-PSModule.png index 9c15217e1a7d7cc516a6522e510e5b3135ceeb80..d65889d4898bc584fec6b38220fb4529fdbc4cb7 100644 GIT binary patch literal 108347 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

KZY`HdEdfqBh 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 IU;N|00Lx}vZvX%Q literal 73852 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 From 7517091fd445eaadaf0f4ec29b2480d1510b3040 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 13:03:09 +0200 Subject: [PATCH 285/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Remove=20GITHUB?= =?UTF-8?q?=5FTOKEN=20from=20Test-ModuleLocal=20workflow=20for=20security?= =?UTF-8?q?=20compliance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Test-ModuleLocal.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/Test-ModuleLocal.yml b/.github/workflows/Test-ModuleLocal.yml index 0fd223f7..82037bf0 100644 --- a/.github/workflows/Test-ModuleLocal.yml +++ b/.github/workflows/Test-ModuleLocal.yml @@ -114,7 +114,6 @@ jobs: TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }} TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }} TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }} - GITHUB_TOKEN: ${{ github.token }} with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} From 7f1086acef25205dfd5f1e65cefd1141db839e8e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 13:07:31 +0200 Subject: [PATCH 286/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Remove=20unneces?= =?UTF-8?q?sary=20parameters=20from=20Document-PSModule=20step=20in=20Buil?= =?UTF-8?q?d-Docs=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index cceba361..604b65bf 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -56,10 +56,6 @@ jobs: uses: PSModule/Document-PSModule@v1 with: Name: ${{ inputs.Name }} - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - name: Upload docs artifact From da0af7f42c026a1e520c1e37427a776bf0cd9de7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 13:10:58 +0200 Subject: [PATCH 287/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Add=20default=20?= =?UTF-8?q?value=20for=20StepSummaryMode=20in=20CodeCoverage=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Get-Settings.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml index 72e99323..0d80ec51 100644 --- a/.github/workflows/Get-Settings.yml +++ b/.github/workflows/Get-Settings.yml @@ -191,6 +191,7 @@ jobs: CodeCoverage = [pscustomobject]@{ Skip = $settings.Test.CodeCoverage.Skip ?? $false PercentTarget = $settings.Test.CodeCoverage.PercentTarget ?? 0 + StepSummaryMode = $settings.Test.CodeCoverage.StepSummary_Mode ?? 'Missed, Files' } } Build = [pscustomobject]@{ From 7682ff22757bba7ad8d70951a73d526621cdcf16 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 16:48:14 +0200 Subject: [PATCH 288/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Refactor=20workf?= =?UTF-8?q?low=20to=20include=20Lint-SourceCode=20job=20and=20update=20dep?= =?UTF-8?q?endencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Lint-SourceCode.yml | 66 +++++++++++++++++++++++++++ .github/workflows/Test-SourceCode.yml | 20 -------- .github/workflows/workflow.yml | 20 ++++++++ 3 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/Lint-SourceCode.yml diff --git a/.github/workflows/Lint-SourceCode.yml b/.github/workflows/Lint-SourceCode.yml new file mode 100644 index 00000000..d4df42a2 --- /dev/null +++ b/.github/workflows/Lint-SourceCode.yml @@ -0,0 +1,66 @@ +name: Lint-SourceCode + +on: + workflow_call: + inputs: + RunsOn: + type: string + description: The type of runner to use for the job. + required: true + OS: + type: string + description: The operating system name. + required: true + Name: + type: string + description: The name of the module to process. Scripts default to the repository name if nothing is specified. + required: false + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: '.' + +permissions: + contents: read # to checkout the repo and create releases on the repo + +jobs: + Lint-SourceCode: + name: Lint-SourceCode (${{ inputs.RunsOn }}) + runs-on: ${{ inputs.RunsOn }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Lint-SourceCode + uses: PSModule/Invoke-ScriptAnalyzer@v3 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + Path: src + Settings: SourceCode + WorkingDirectory: ${{ inputs.WorkingDirectory }} + TestResult_Enabled: true + TestResult_TestSuiteName: PSModuleLint-SourceCode-${{ runner.os }} diff --git a/.github/workflows/Test-SourceCode.yml b/.github/workflows/Test-SourceCode.yml index 23e2e5bd..d14fd5e6 100644 --- a/.github/workflows/Test-SourceCode.yml +++ b/.github/workflows/Test-SourceCode.yml @@ -61,23 +61,3 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} Settings: SourceCode - - Lint-SourceCode: - name: Lint-SourceCode (${{ inputs.RunsOn }}) - runs-on: ${{ inputs.RunsOn }} - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Lint-SourceCode - uses: PSModule/Invoke-ScriptAnalyzer@v3 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - Path: src - Settings: SourceCode - WorkingDirectory: ${{ inputs.WorkingDirectory }} - TestResult_Enabled: true - TestResult_TestSuiteName: PSModuleLint-SourceCode-${{ runner.os }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index a7dcc9c9..d9ab9dcf 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -99,6 +99,25 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} + Lint-SourceCode: + if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} + needs: + - Get-Settings + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} + uses: ./.github/workflows/Lint-SourceCode.yml + with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Build-Module: if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Module.Skip != true }} uses: ./.github/workflows/Build-Module.yml @@ -175,6 +194,7 @@ jobs: needs: - Get-Settings - Test-SourceCode + - Lint-SourceCode - Test-Module - Test-ModuleLocal uses: ./.github/workflows/Get-TestResults.yml From ab5fa6b511a4d86c4dc64ad48922bf83f9d17f62 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 16:49:05 +0200 Subject: [PATCH 289/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Add=20Lint-Sourc?= =?UTF-8?q?eCode=20job=20with=20matrix=20strategy=20for=20improved=20code?= =?UTF-8?q?=20quality=20checks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8429370f..c824840a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -99,6 +99,25 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} + Lint-SourceCode: + if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} + needs: + - Get-Settings + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} + uses: ./.github/workflows/Lint-SourceCode.yml + with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Build-Module: if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Module.Skip != true }} uses: ./.github/workflows/Build-Module.yml @@ -175,6 +194,7 @@ jobs: needs: - Get-Settings - Test-SourceCode + - Lint-SourceCode - Test-Module - Test-ModuleLocal uses: ./.github/workflows/Get-TestResults.yml From 2431ed27d78e4443095dc72a38c14106566ec3ab Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 17:09:35 +0200 Subject: [PATCH 290/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Add=20Build-Site?= =?UTF-8?q?=20workflow=20and=20integrate=20it=20into=20the=20main=20workfl?= =?UTF-8?q?ow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Docs.yml | 133 ---------------------- .github/workflows/Build-Site.yml | 176 +++++++++++++++++++++++++++++ .github/workflows/Get-Settings.yml | 31 +++-- .github/workflows/workflow.yml | 16 +++ README.md | 3 +- 5 files changed, 213 insertions(+), 146 deletions(-) create mode 100644 .github/workflows/Build-Site.yml diff --git a/.github/workflows/Build-Docs.yml b/.github/workflows/Build-Docs.yml index 604b65bf..1e21ffdc 100644 --- a/.github/workflows/Build-Docs.yml +++ b/.github/workflows/Build-Docs.yml @@ -108,136 +108,3 @@ jobs: VALIDATE_YAML_PRETTIER: false VALIDATE_JSCPD: false VALIDATE_GITLEAKS: false - - - uses: actions/configure-pages@v5 - - - name: Install mkdoks-material - shell: pwsh - run: | - pip install mkdocs-material - pip install mkdocs-git-authors-plugin - pip install mkdocs-git-revision-date-localized-plugin - pip install mkdocs-git-committers-plugin-2 - - - name: Structure site - uses: PSModule/GitHub-Script@v1 - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - Script: | - LogGroup "Get folder structure" { - $functionDocsFolder = New-Item -Path "outputs/site/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "outputs/docs/*" -Destination "outputs/site/docs/Functions" -Recurse -Force - $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' - $ModuleSourcePath = Resolve-Path 'src' | Select-Object -ExpandProperty Path - $SiteOutputPath = Resolve-Path 'outputs/site' | Select-Object -ExpandProperty Path - - Write-Host "Function Docs Folder: $functionDocsFolder" - Write-Host "Module Name: $moduleName" - Write-Host "Module Source Path: $ModuleSourcePath" - Write-Host "Site Output Path: $SiteOutputPath" - } - - LogGroup "Get folder structure" { - Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List - } - - Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { - $fileName = $_.Name - LogGroup " - $fileName" { - Show-FileContent -Path $_ - } - } - - LogGroup 'Build docs - Process about topics' { - $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' - $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force - $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } - Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | - Rename-Item -NewName { $_.Name -replace '.txt', '.md' } - - Write-Host "About Docs Folder: $aboutDocsFolder" - Write-Host "About Source Folder: $aboutSourceFolder" - } - - LogGroup 'Build docs - Copy icon to assets' { - $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' - $assetsFolder = New-Item -Path $assetsFolderPath -ItemType Directory -Force - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $iconPath = Resolve-Path 'icon\icon.png' | Select-Object -ExpandProperty Path - Copy-Item -Path $iconPath -Destination $assetsFolder -Force -Verbose - - Write-Host "Assets Folder: $assetsFolder" - Write-Host "Icon Path: $iconPath" - } - - LogGroup 'Build docs - Copy readme.md' { - $readmePath = Resolve-Path 'README.md' | Select-Object -ExpandProperty Path - $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' - Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose - - Write-Host "Readme Path: $readmePath" - Write-Host "Readme Target Path: $readmeTargetPath" - } - - LogGroup 'Build docs - Create mkdocs.yml' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $possiblePaths = @( - '.github/mkdocs.yml', - 'docs/mkdocs.yml', - 'mkdocs.yml' - ) - - $mkdocsSourcePath = $null - foreach ($path in $possiblePaths) { - $candidatePath = Join-Path -Path $rootPath -ChildPath $path - if (Test-Path -Path $candidatePath) { - $mkdocsSourcePath = $candidatePath - break - } - } - - if (-not $mkdocsSourcePath) { - throw "Mkdocs source file not found in any of the expected locations: $($possiblePaths -join ', ')" - } - - $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' - - Write-Host "Mkdocs Source Path: $mkdocsSourcePath" - Write-Host "Mkdocs Target Path: $mkdocsTargetPath" - - $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) - $mkdocsContent | Set-Content -Path $mkdocsTargetPath -Force - Show-FileContent -Path $mkdocsTargetPath - } - - - name: Debug File system - shell: pwsh - working-directory: ${{ inputs.WorkingDirectory }} - run: | - Get-ChildItem -Path . -Recurse | ForEach-Object { - [System.IO.Path]::GetRelativePath($PSScriptRoot, $_.FullName) - } | Sort-Object - - - name: Build mkdocs-material project - working-directory: ${{ inputs.WorkingDirectory }}/outputs/site - shell: pwsh - run: | - LogGroup 'Build docs - mkdocs build - content' { - Show-FileContent -Path mkdocs.yml - } - - LogGroup 'Build docs - mkdocs build' { - mkdocs build --config-file mkdocs.yml --site-dir ../../_site - } - - - uses: actions/upload-pages-artifact@v3 - with: - name: github-pages - path: ${{ inputs.WorkingDirectory }}/_site - retention-days: 1 diff --git a/.github/workflows/Build-Site.yml b/.github/workflows/Build-Site.yml new file mode 100644 index 00000000..f9d89a1d --- /dev/null +++ b/.github/workflows/Build-Site.yml @@ -0,0 +1,176 @@ +name: Build-Site + +on: + workflow_call: + inputs: + Name: + type: string + description: The name of the module to process. Scripts default to the repository name if nothing is specified. + required: false + Debug: + type: boolean + description: Enable debug output. + required: false + default: false + Verbose: + type: boolean + description: Enable verbose output. + required: false + default: false + Version: + type: string + description: Specifies the version of the GitHub module to be installed. The value must be an exact version. + required: false + default: '' + Prerelease: + type: boolean + description: Whether to use a prerelease version of the 'GitHub' module. + required: false + default: false + WorkingDirectory: + type: string + description: The working directory where the script will run from. + required: false + default: '.' + +permissions: + contents: read # to checkout the repo + +jobs: + Build-Site: + name: Build-Site + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download docs artifact + uses: actions/download-artifact@v4 + with: + name: docs + path: ${{ inputs.WorkingDirectory }}/outputs/docs + + - name: Install mkdocs-material + shell: pwsh + run: | + pip install mkdocs-material + pip install mkdocs-git-authors-plugin + pip install mkdocs-git-revision-date-localized-plugin + pip install mkdocs-git-committers-plugin-2 + + - name: Structure site + uses: PSModule/GitHub-Script@v1 + with: + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Script: | + LogGroup "Get folder structure" { + $functionDocsFolder = New-Item -Path "outputs/site/docs/Functions" -ItemType Directory -Force + Copy-Item -Path "outputs/docs/*" -Destination "outputs/site/docs/Functions" -Recurse -Force + $moduleName = [string]::IsNullOrEmpty('${{ inputs.Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ inputs.Name }}' + $ModuleSourcePath = Resolve-Path 'src' | Select-Object -ExpandProperty Path + $SiteOutputPath = Resolve-Path 'outputs/site' | Select-Object -ExpandProperty Path + + Write-Host "Function Docs Folder: $functionDocsFolder" + Write-Host "Module Name: $moduleName" + Write-Host "Module Source Path: $ModuleSourcePath" + Write-Host "Site Output Path: $SiteOutputPath" + } + + LogGroup "Get folder structure" { + Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List + } + + Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { + $fileName = $_.Name + LogGroup " - $fileName" { + Show-FileContent -Path $_ + } + } + + LogGroup 'Build docs - Process about topics' { + $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' + $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force + $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } + Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | + Rename-Item -NewName { $_.Name -replace '.txt', '.md' } + + Write-Host "About Docs Folder: $aboutDocsFolder" + Write-Host "About Source Folder: $aboutSourceFolder" + } + + LogGroup 'Build docs - Copy icon to assets' { + $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' + $assetsFolder = New-Item -Path $assetsFolderPath -ItemType Directory -Force + $rootPath = Split-Path -Path $ModuleSourcePath -Parent + $iconPath = Resolve-Path 'icon\icon.png' | Select-Object -ExpandProperty Path + Copy-Item -Path $iconPath -Destination $assetsFolder -Force -Verbose + + Write-Host "Assets Folder: $assetsFolder" + Write-Host "Icon Path: $iconPath" + } + + LogGroup 'Build docs - Copy readme.md' { + $readmePath = Resolve-Path 'README.md' | Select-Object -ExpandProperty Path + $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' + Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose + + Write-Host "Readme Path: $readmePath" + Write-Host "Readme Target Path: $readmeTargetPath" + } + + LogGroup 'Build docs - Create mkdocs.yml' { + $rootPath = Split-Path -Path $ModuleSourcePath -Parent + $possiblePaths = @( + '.github/mkdocs.yml', + 'docs/mkdocs.yml', + 'mkdocs.yml' + ) + + $mkdocsSourcePath = $null + foreach ($path in $possiblePaths) { + $candidatePath = Join-Path -Path $rootPath -ChildPath $path + if (Test-Path -Path $candidatePath) { + $mkdocsSourcePath = $candidatePath + break + } + } + + if (-not $mkdocsSourcePath) { + throw "Mkdocs source file not found in any of the expected locations: $($possiblePaths -join ', ')" + } + + $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' + + Write-Host "Mkdocs Source Path: $mkdocsSourcePath" + Write-Host "Mkdocs Target Path: $mkdocsTargetPath" + + $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw + $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) + $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) + $mkdocsContent | Set-Content -Path $mkdocsTargetPath -Force + Show-FileContent -Path $mkdocsTargetPath + } + + - name: Build mkdocs-material project + working-directory: ${{ inputs.WorkingDirectory }}/outputs/site + shell: pwsh + run: | + LogGroup 'Build docs - mkdocs build - content' { + Show-FileContent -Path mkdocs.yml + } + + LogGroup 'Build docs - mkdocs build' { + mkdocs build --config-file mkdocs.yml --site-dir ../../_site + } + + - uses: actions/upload-pages-artifact@v3 + with: + name: github-pages + path: ${{ inputs.WorkingDirectory }}/_site + retention-days: 1 diff --git a/.github/workflows/Get-Settings.yml b/.github/workflows/Get-Settings.yml index 0d80ec51..a954ace8 100644 --- a/.github/workflows/Get-Settings.yml +++ b/.github/workflows/Get-Settings.yml @@ -137,8 +137,8 @@ jobs: } $settings = [pscustomobject]@{ - Name = $name - Test = [pscustomobject]@{ + Name = $name + Test = [pscustomobject]@{ Skip = $settings.Test.Skip ?? $false Linux = [pscustomobject]@{ Skip = $settings.Test.Linux.Skip ?? $false @@ -194,7 +194,7 @@ jobs: StepSummaryMode = $settings.Test.CodeCoverage.StepSummary_Mode ?? 'Missed, Files' } } - Build = [pscustomobject]@{ + Build = [pscustomobject]@{ Skip = $settings.Build.Skip ?? $false Module = [pscustomobject]@{ Skip = $settings.Build.Module.Skip ?? $false @@ -202,17 +202,24 @@ jobs: Docs = [pscustomobject]@{ Skip = $settings.Build.Docs.Skip ?? $false } + Site = [pscustomobject]@{ + Skip = $settings.Build.Site.Skip ?? $false + } } Publish = [pscustomobject]@{ - AutoCleanup = $settings.Publish.AutoCleanup ?? $true - AutoPatching = $settings.Publish.AutoPatching ?? $true - IncrementalPrerelease = $settings.Publish.IncrementalPrerelease ?? $true - DatePrereleaseFormat = $settings.Publish.DatePrereleaseFormat ?? '' - VersionPrefix = $settings.Publish.VersionPrefix ?? 'v' - MajorLabels = $settings.Publish.MajorLabels ?? 'major, breaking' - MinorLabels = $settings.Publish.MinorLabels ?? 'minor, feature' - PatchLabels = $settings.Publish.PatchLabels ?? 'patch, fix' - IgnoreLabels = $settings.Publish.IgnoreLabels ?? 'NoRelease' + Module = [pscustomobject]@{ + Skip = $settings.Publish.Module.Skip ?? $false + AutoCleanup = $settings.Publish.Module.AutoCleanup ?? $true + AutoPatching = $settings.Publish.Module.AutoPatching ?? $true + IncrementalPrerelease = $settings.Publish.Module.IncrementalPrerelease ?? $true + DatePrereleaseFormat = $settings.Publish.Module.DatePrereleaseFormat ?? '' + VersionPrefix = $settings.Publish.Module.VersionPrefix ?? 'v' + MajorLabels = $settings.Publish.Module.MajorLabels ?? 'major, breaking' + MinorLabels = $settings.Publish.Module.MinorLabels ?? 'minor, feature' + PatchLabels = $settings.Publish.Module.PatchLabels ?? 'patch, fix' + IgnoreLabels = $settings.Publish.Module.IgnoreLabels ?? 'NoRelease' + } + } } LogGroup "Final settings" { diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index d9ab9dcf..04a82f6e 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -145,6 +145,20 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} + Build-Site: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Site.Skip != true }} + needs: + - Get-Settings + - Build-Docs + uses: ./.github/workflows/Build-Site.yml + with: + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Test-Module: if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' }} needs: @@ -286,6 +300,8 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: + - uses: actions/configure-pages@v5 + - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index 1a7daeb1..98728afa 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ Depending on the labels in the pull requests, the workflow will result in differ - [Test-ModuleLocal](./.github/workflows/Test-ModuleLocal.yml) - Import and tests the module using Pester test from the module repository. - This produces a json based report that is used to later evaluate the results of the tests. -- [Document-PSModule](https://github.com/PSModule/Document-PSModule/) - Generates documentation and deploys it to GitHub Pages. +- [Build-Docs](./.github/workflows/Build-Docs.yml) + - Generates documentation - [Test-PSModule](https://github.com/PSModule/Test-PSModule/) - Tests the compiled module. This runs on 4 different environments to check compatibility. - PowerShell LTS on Windows, Ubuntu and macOS. - [Publish-PSModule](https://github.com/PSModule/Publish-PSModule/) - Publishes the module to the PowerShell Gallery, docs to GitHub Pages, and creates a release on the GitHub repository. From 81e80638f54ee463d499db61216901b29a16a3cb Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 17:11:21 +0200 Subject: [PATCH 291/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Update=20Publish?= =?UTF-8?q?=20settings=20to=20reference=20Module-specific=20parameters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 04a82f6e..ffe170ee 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -275,15 +275,15 @@ jobs: Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - AutoCleanup: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.AutoCleanup }} - AutoPatching: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.AutoPatching }} - DatePrereleaseFormat: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.DatePrereleaseFormat }} - IgnoreLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.IgnoreLabels }} - IncrementalPrerelease: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.IncrementalPrerelease }} - MajorLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.MajorLabels }} - MinorLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.MinorLabels }} - PatchLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.PatchLabels }} - VersionPrefix: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.VersionPrefix }} + AutoCleanup: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.AutoCleanup }} + AutoPatching: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.AutoPatching }} + DatePrereleaseFormat: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.DatePrereleaseFormat }} + IgnoreLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.IgnoreLabels }} + IncrementalPrerelease: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.IncrementalPrerelease }} + MajorLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.MajorLabels }} + MinorLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.MinorLabels }} + PatchLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.PatchLabels }} + VersionPrefix: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.VersionPrefix }} Publish-Site: if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} From 41c9634a3c56106c744f17b9dda747a590f7f62e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 17:24:48 +0200 Subject: [PATCH 292/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Update=20Build-S?= =?UTF-8?q?ite=20job=20dependencies=20and=20conditions=20in=20CI=20workflo?= =?UTF-8?q?ws?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 15 +++++++++++++++ .github/workflows/workflow.yml | 8 ++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c824840a..cc2834c0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -68,6 +68,7 @@ permissions: pull-requests: write # to write comments to PRs statuses: write # to update the status of the workflow from linter +jobs: jobs: Get-Settings: uses: ./.github/workflows/Get-Settings.yml @@ -145,6 +146,20 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} + Build-Site: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Site.Skip != true }} + needs: + - Get-Settings + - Build-Docs + uses: ./.github/workflows/Build-Site.yml + with: + Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} + Debug: ${{ inputs.Debug }} + Prerelease: ${{ inputs.Prerelease }} + Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.Version }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Test-Module: if: ${{ needs.Build-Module.result == 'success' && !cancelled() && needs.Get-Settings.outputs.PSModuleTestSuites != '[]' }} needs: diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index ffe170ee..236ba4c3 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -239,12 +239,12 @@ jobs: Version: ${{ inputs.Version }} Publish-Module: - if: ${{ needs.Get-Settings.result == 'success' && needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} + if: ${{ needs.Get-Settings.result == 'success' && needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} needs: - Get-Settings - Get-TestResults - Get-CodeCoverage - - Build-Docs + - Build-Site runs-on: ubuntu-latest steps: - name: Checkout Code @@ -286,12 +286,12 @@ jobs: VersionPrefix: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.VersionPrefix }} Publish-Site: - if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Docs.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} + if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} needs: - Get-Settings - Get-TestResults - Get-CodeCoverage - - Build-Docs + - Build-Site permissions: pages: write # to deploy to Pages id-token: write # to verify the deployment originates from an appropriate source From 13edb78696de300fb5ae03910a7d4470b38ee0e4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 17:27:14 +0200 Subject: [PATCH 293/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Remove=20redunda?= =?UTF-8?q?nt=20line=20before=20jobs=20section=20in=20CI=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index cc2834c0..2eeb7538 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -68,7 +68,6 @@ permissions: pull-requests: write # to write comments to PRs statuses: write # to update the status of the workflow from linter -jobs: jobs: Get-Settings: uses: ./.github/workflows/Get-Settings.yml From 39a8c65448ff912bfbe21cc4dd4817a9b04b077c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 17:33:05 +0200 Subject: [PATCH 294/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Remove=20redun?= =?UTF-8?q?dant=20file=20listing=20in=20Build-Site=20workflow=20and=20upda?= =?UTF-8?q?te=20documentation=20generation=20description?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Site.yml | 7 ------- README.md | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/Build-Site.yml b/.github/workflows/Build-Site.yml index f9d89a1d..e1b88265 100644 --- a/.github/workflows/Build-Site.yml +++ b/.github/workflows/Build-Site.yml @@ -86,13 +86,6 @@ jobs: Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List } - Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { - $fileName = $_.Name - LogGroup " - $fileName" { - Show-FileContent -Path $_ - } - } - LogGroup 'Build docs - Process about topics' { $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force diff --git a/README.md b/README.md index 98728afa..fd6a1445 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Depending on the labels in the pull requests, the workflow will result in differ - Import and tests the module using Pester test from the module repository. - This produces a json based report that is used to later evaluate the results of the tests. - [Build-Docs](./.github/workflows/Build-Docs.yml) - - Generates documentation + - Generates documentation - [Test-PSModule](https://github.com/PSModule/Test-PSModule/) - Tests the compiled module. This runs on 4 different environments to check compatibility. - PowerShell LTS on Windows, Ubuntu and macOS. - [Publish-PSModule](https://github.com/PSModule/Publish-PSModule/) - Publishes the module to the PowerShell Gallery, docs to GitHub Pages, and creates a release on the GitHub repository. From 90e030486e63c7170694967cf997276266ab8674 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 17:41:44 +0200 Subject: [PATCH 295/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Add=20installati?= =?UTF-8?q?on=20step=20for=20PSModuleHelpers=20and=20enhance=20documentati?= =?UTF-8?q?on=20file=20logging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build-Site.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/Build-Site.yml b/.github/workflows/Build-Site.yml index e1b88265..dc98a559 100644 --- a/.github/workflows/Build-Site.yml +++ b/.github/workflows/Build-Site.yml @@ -46,6 +46,9 @@ jobs: with: fetch-depth: 0 + - name: Install-PSModuleHelpers + uses: PSModule/Install-PSModuleHelpers@v1 + - name: Download docs artifact uses: actions/download-artifact@v4 with: @@ -86,6 +89,13 @@ jobs: Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List } + Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { + $fileName = $_.Name + LogGroup " - $fileName" { + Show-FileContent -Path $_ + } + } + LogGroup 'Build docs - Process about topics' { $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force From 54b3ebb40f73a734651934cb99dbdd4ba0371182 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 17:55:33 +0200 Subject: [PATCH 296/324] =?UTF-8?q?=F0=9F=94=A7=20[CI]:=20Refactor=20job?= =?UTF-8?q?=20dependencies=20and=20conditions=20in=20CI=20workflows=20for?= =?UTF-8?q?=20improved=20clarity=20and=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 58 +++++++++---------- .github/workflows/workflow.yml | 100 ++++++++++++++++----------------- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2eeb7538..1227576c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -80,18 +80,12 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Test-SourceCode: - if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} + Build-Module: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Module.Skip != true }} + uses: ./.github/workflows/Build-Module.yml needs: - Get-Settings - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} - uses: ./.github/workflows/Test-SourceCode.yml with: - RunsOn: ${{ matrix.RunsOn }} - OS: ${{ matrix.OSName }} Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -99,18 +93,13 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Lint-SourceCode: - if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} + Build-Docs: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Docs.Skip != true }} needs: - Get-Settings - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} - uses: ./.github/workflows/Lint-SourceCode.yml + - Build-Module + uses: ./.github/workflows/Build-Docs.yml with: - RunsOn: ${{ matrix.RunsOn }} - OS: ${{ matrix.OSName }} Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -118,11 +107,12 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Build-Module: - if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Module.Skip != true }} - uses: ./.github/workflows/Build-Module.yml + Build-Site: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Site.Skip != true }} needs: - Get-Settings + - Build-Docs + uses: ./.github/workflows/Build-Site.yml with: Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} @@ -131,13 +121,18 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Build-Docs: - if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Docs.Skip != true }} + Test-SourceCode: + if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} needs: - Get-Settings - - Build-Module - uses: ./.github/workflows/Build-Docs.yml + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} + uses: ./.github/workflows/Test-SourceCode.yml with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -145,13 +140,18 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Build-Site: - if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Site.Skip != true }} + Lint-SourceCode: + if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} needs: - Get-Settings - - Build-Docs - uses: ./.github/workflows/Build-Site.yml + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} + uses: ./.github/workflows/Lint-SourceCode.yml with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 236ba4c3..aabfe28e 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -80,18 +80,12 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Test-SourceCode: - if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} + Build-Module: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Module.Skip != true }} + uses: ./.github/workflows/Build-Module.yml needs: - Get-Settings - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} - uses: ./.github/workflows/Test-SourceCode.yml with: - RunsOn: ${{ matrix.RunsOn }} - OS: ${{ matrix.OSName }} Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -99,18 +93,13 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Lint-SourceCode: - if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} + Build-Docs: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Docs.Skip != true }} needs: - Get-Settings - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} - uses: ./.github/workflows/Lint-SourceCode.yml + - Build-Module + uses: ./.github/workflows/Build-Docs.yml with: - RunsOn: ${{ matrix.RunsOn }} - OS: ${{ matrix.OSName }} Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -118,11 +107,12 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Build-Module: - if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Module.Skip != true }} - uses: ./.github/workflows/Build-Module.yml + Build-Site: + if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Site.Skip != true }} needs: - Get-Settings + - Build-Docs + uses: ./.github/workflows/Build-Site.yml with: Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} @@ -131,13 +121,18 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Build-Docs: - if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Docs.Skip != true }} + Test-SourceCode: + if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} needs: - Get-Settings - - Build-Module - uses: ./.github/workflows/Build-Docs.yml + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} + uses: ./.github/workflows/Test-SourceCode.yml with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -145,13 +140,18 @@ jobs: Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} - Build-Site: - if: ${{ fromJson(needs.Get-Settings.outputs.Settings).Build.Site.Skip != true }} + Lint-SourceCode: + if: ${{ needs.Get-Settings.outputs.SourceCodeTestSuites != '[]' }} needs: - Get-Settings - - Build-Docs - uses: ./.github/workflows/Build-Site.yml + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.Get-Settings.outputs.SourceCodeTestSuites) }} + uses: ./.github/workflows/Lint-SourceCode.yml with: + RunsOn: ${{ matrix.RunsOn }} + OS: ${{ matrix.OSName }} Name: ${{ fromJson(needs.Get-Settings.outputs.Settings).Name }} Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} @@ -238,6 +238,27 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + Publish-Site: + if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} + needs: + - Get-Settings + - Get-TestResults + - Get-CodeCoverage + - Build-Site + permissions: + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - uses: actions/configure-pages@v5 + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + Publish-Module: if: ${{ needs.Get-Settings.result == 'success' && needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} needs: @@ -284,24 +305,3 @@ jobs: MinorLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.MinorLabels }} PatchLabels: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.PatchLabels }} VersionPrefix: ${{ fromJson(needs.Get-Settings.outputs.Settings).Publish.Module.VersionPrefix }} - - Publish-Site: - if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} - needs: - - Get-Settings - - Get-TestResults - - Get-CodeCoverage - - Build-Site - permissions: - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - uses: actions/configure-pages@v5 - - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 From 9810ff99229ea10e93af61433108a495c2eb9c2a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 18:37:40 +0200 Subject: [PATCH 297/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20READM?= =?UTF-8?q?E=20to=20clarify=20module=20compilation=20and=20testing=20proce?= =?UTF-8?q?sses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fd6a1445..68087ad1 100644 --- a/README.md +++ b/README.md @@ -25,18 +25,20 @@ Depending on the labels in the pull requests, the workflow will result in differ - Gathers tests and creates test configuration based on the settings and the tests available in the module repository. - This includes the selection of what OSes to run the tests on. - [Build-Module](./.github/workflows/Build-Module.yml) - - Compiles the module source code into a PowerShell module using a temporary version `999.0.0`. + - Compiles the module source code into a PowerShell module. - [Test-SourceCode](./.github/workflows/Test-SourceCode.yml) - - Tests and lints the source code using [PSModule framework settings for style and standards for source code](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#sourcecode-tests) + [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). + - Tests and lints the source code in parallel (matrix) using [PSModule framework settings for style and standards for source code](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#sourcecode-tests) + [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). - This produces a json based report that is used to later evaluate the results of the tests. - [Test-Module](./.github/workflows/Test-Module.yml) - - Tests and lints the module using [PSModule framework settings for style and standards foor modules](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#module-tests) + [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). + - Tests and lints the module in parallel (matrix) using [PSModule framework settings for style and standards foor modules](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#module-tests) + [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). - This produces a json based report that is used to later evaluate the results of the tests. - [Test-ModuleLocal](./.github/workflows/Test-ModuleLocal.yml) - - Import and tests the module using Pester test from the module repository. + - Import and tests the module in parallel (matrix) using Pester tests from the module repository. - This produces a json based report that is used to later evaluate the results of the tests. - [Build-Docs](./.github/workflows/Build-Docs.yml) - - Generates documentation + - Generates documentation and lints the documentation using [SuperLinter](https://github.com/super-linter/super-linter). +- [Build-Site](./.github/workflows/Build-Site.yml) + - Generates a static site using [MkDocs](https://www.mkdocs.org/). - [Test-PSModule](https://github.com/PSModule/Test-PSModule/) - Tests the compiled module. This runs on 4 different environments to check compatibility. - PowerShell LTS on Windows, Ubuntu and macOS. - [Publish-PSModule](https://github.com/PSModule/Publish-PSModule/) - Publishes the module to the PowerShell Gallery, docs to GitHub Pages, and creates a release on the GitHub repository. From aef415218aa6ea7f7675f74d73c163800af56564 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 19:58:19 +0200 Subject: [PATCH 298/324] diag --- media/Process-PSModule.png | Bin 73852 -> 105581 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/media/Process-PSModule.png b/media/Process-PSModule.png index 9c15217e1a7d7cc516a6522e510e5b3135ceeb80..08305e8611ad093189e17595739f0710eb0049c4 100644 GIT binary patch literal 105581 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 $vAK5@93WBo8c8;gajYiUDWIMTVGQO!dO0R-I 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%0A2o+tCzHuGIW7-%qI6< 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 R)X9GV-J^T;{{dR5c3}Vj literal 73852 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 From b72045f093dbe4c8fd333160933c954271d7ba3a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 20:06:16 +0200 Subject: [PATCH 299/324] fix diag --- media/Process-PSModule.png | Bin 105581 -> 107036 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/media/Process-PSModule.png b/media/Process-PSModule.png index 08305e8611ad093189e17595739f0710eb0049c4..26131f1d218f15ffdeeb518484bf09bb2c8f1846 100644 GIT binary patch literal 107036 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
      ^lbs&V^Ui*)U?$~Jy_k`M`%ExfTvk-==(U;i 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 From 414774cfd0ac23295f5e3a1533a1bfbf8d4c8f3d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 21:32:30 +0200 Subject: [PATCH 301/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Enhance=20READ?= =?UTF-8?q?ME=20with=20detailed=20settings=20table=20and=20examples=20for?= =?UTF-8?q?=20testing=20and=20build=20configurations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 140 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 78 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 179e2be7..6811bd99 100644 --- a/README.md +++ b/README.md @@ -96,54 +96,85 @@ The file can be a JSON, YML or PSD1 file. By default it will look for `.github/P The following settings are available in the settings file: Here's a Markdown-formatted table describing your PowerShell object structure clearly and concisely: -| Name | Type | Description | Default | -| ----------------------------------------- | --------------- | -------------------------------------------------------------- | ------------------------------ | -| `Name` | `String` | Name identifier for the settings | `null` | -| **Test** | `Object` | Settings related to testing | | -| `Test.Skip` | `Boolean` | Skip all tests | `false` | -| `Test.Linux.Skip` | `Boolean` | Skip tests on Linux | `false` | -| `Test.MacOS.Skip` | `Boolean` | Skip tests on macOS | `false` | -| `Test.Windows.Skip` | `Boolean` | Skip tests on Windows | `false` | -| **Test.SourceCode** | `Object` | Settings for source code tests | | -| `Test.SourceCode.Skip` | `Boolean` | Skip source code tests | `false` | -| `Test.SourceCode.Linux.Skip` | `Boolean` | Skip source code tests on Linux | `false` | -| `Test.SourceCode.MacOS.Skip` | `Boolean` | Skip source code tests on macOS | `false` | -| `Test.SourceCode.Windows.Skip` | `Boolean` | Skip source code tests on Windows | `false` | -| **Test.PSModule** | `Object` | Settings for PowerShell module tests | | -| `Test.PSModule.Skip` | `Boolean` | Skip PowerShell module tests | `false` | -| `Test.PSModule.Linux.Skip` | `Boolean` | Skip PS module tests on Linux | `false` | -| `Test.PSModule.MacOS.Skip` | `Boolean` | Skip PS module tests on macOS | `false` | -| `Test.PSModule.Windows.Skip` | `Boolean` | Skip PS module tests on Windows | `false` | -| **Test.Module** | `Object` | Settings for generic module tests | | -| `Test.Module.Skip` | `Boolean` | Skip generic module tests | `false` | -| `Test.Module.Linux.Skip` | `Boolean` | Skip generic module tests on Linux | `false` | -| `Test.Module.MacOS.Skip` | `Boolean` | Skip generic module tests on macOS | `false` | -| `Test.Module.Windows.Skip` | `Boolean` | Skip generic module tests on Windows | `false` | -| **Test.TestResults** | `Object` | Settings for test result publishing | | -| `Test.TestResults.Skip` | `Boolean` | Skip test result processing | `false` | -| **Test.CodeCoverage** | `Object` | Settings for code coverage | | -| `Test.CodeCoverage.Skip` | `Boolean` | Skip code coverage tests | `false` | -| `Test.CodeCoverage.PercentTarget` | `Integer` | Target code coverage percentage | `0` | -| `Test.CodeCoverage.StepSummaryMode` | `String` | Step summary mode for code coverage reports | `'Missed, Files'` | -| **Build** | `Object` | Settings for build processes | | -| `Build.Skip` | `Boolean` | Skip all build tasks | `false` | -| `Build.Module.Skip` | `Boolean` | Skip module build | `false` | -| `Build.Docs.Skip` | `Boolean` | Skip documentation build | `false` | -| `Build.Site.Skip` | `Boolean` | Skip website build | `false` | -| **Publish.Module** | `Object` | Settings for module publishing | | -| `Publish.Module.Skip` | `Boolean` | Skip module publishing | `false` | -| `Publish.Module.AutoCleanup` | `Boolean` | Automatically cleanup old module versions | `true` | -| `Publish.Module.AutoPatching` | `Boolean` | Automatically patch module version | `true` | -| `Publish.Module.IncrementalPrerelease` | `Boolean` | Use incremental prerelease versioning | `true` | -| `Publish.Module.DatePrereleaseFormat` | `String` | Format for date-based prerelease | `''` (empty string) | -| `Publish.Module.VersionPrefix` | `String` | Prefix for version tags | `'v'` | -| `Publish.Module.MajorLabels` | `String` | Labels indicating a major version bump | `'major, breaking'` | -| `Publish.Module.MinorLabels` | `String` | Labels indicating a minor version bump | `'minor, feature'` | -| `Publish.Module.PatchLabels` | `String` | Labels indicating a patch version bump | `'patch, fix'` | -| `Publish.Module.IgnoreLabels` | `String` | Labels indicating no release | `'NoRelease'` | - -This table clearly represents each nested property, type, brief description, and the default values you've specified in your provided PowerShell structure. +| Name | Type | Description | Default | +|----------------------------------------|-----------|---------------------------------------------|---------------------| +| `Name` | `String` | Name identifier for the settings | `null` | +| **Test** | `Object` | Settings related to testing | | +| `Test.Skip` | `Boolean` | Skip all tests | `false` | +| `Test.Linux.Skip` | `Boolean` | Skip tests on Linux | `false` | +| `Test.MacOS.Skip` | `Boolean` | Skip tests on macOS | `false` | +| `Test.Windows.Skip` | `Boolean` | Skip tests on Windows | `false` | +| **Test.SourceCode** | `Object` | Settings for source code tests | | +| `Test.SourceCode.Skip` | `Boolean` | Skip source code tests | `false` | +| `Test.SourceCode.Linux.Skip` | `Boolean` | Skip source code tests on Linux | `false` | +| `Test.SourceCode.MacOS.Skip` | `Boolean` | Skip source code tests on macOS | `false` | +| `Test.SourceCode.Windows.Skip` | `Boolean` | Skip source code tests on Windows | `false` | +| **Test.PSModule** | `Object` | Settings for PSModule framework tests | | +| `Test.PSModule.Skip` | `Boolean` | Skip PSModule framework tests | `false` | +| `Test.PSModule.Linux.Skip` | `Boolean` | Skip PSModule framework tests on Linux | `false` | +| `Test.PSModule.MacOS.Skip` | `Boolean` | Skip PSModule framework tests on macOS | `false` | +| `Test.PSModule.Windows.Skip` | `Boolean` | Skip PSModule framework tests on Windows | `false` | +| **Test.Module** | `Object` | Settings for module tests | | +| `Test.Module.Skip` | `Boolean` | Skip module tests | `false` | +| `Test.Module.Linux.Skip` | `Boolean` | Skip module tests on Linux | `false` | +| `Test.Module.MacOS.Skip` | `Boolean` | Skip module tests on macOS | `false` | +| `Test.Module.Windows.Skip` | `Boolean` | Skip module tests on Windows | `false` | +| **Test.TestResults** | `Object` | Settings for test result publishing | | +| `Test.TestResults.Skip` | `Boolean` | Skip test result processing | `false` | +| **Test.CodeCoverage** | `Object` | Settings for code coverage | | +| `Test.CodeCoverage.Skip` | `Boolean` | Skip code coverage tests | `false` | +| `Test.CodeCoverage.PercentTarget` | `Integer` | Target code coverage percentage | `0` | +| `Test.CodeCoverage.StepSummaryMode` | `String` | Step summary mode for code coverage reports | `'Missed, Files'` | +| **Build** | `Object` | Settings for build processes | | +| `Build.Skip` | `Boolean` | Skip all build tasks | `false` | +| `Build.Module.Skip` | `Boolean` | Skip module build | `false` | +| `Build.Docs.Skip` | `Boolean` | Skip documentation build | `false` | +| `Build.Site.Skip` | `Boolean` | Skip website build | `false` | +| **Publish.Module** | `Object` | Settings for module publishing | | +| `Publish.Module.Skip` | `Boolean` | Skip module publishing | `false` | +| `Publish.Module.AutoCleanup` | `Boolean` | Automatically cleanup old module versions | `true` | +| `Publish.Module.AutoPatching` | `Boolean` | Automatically patch module version | `true` | +| `Publish.Module.IncrementalPrerelease` | `Boolean` | Use incremental prerelease versioning | `true` | +| `Publish.Module.DatePrereleaseFormat` | `String` | Format for date-based prerelease | `''` | +| `Publish.Module.VersionPrefix` | `String` | Prefix for version tags | `'v'` | +| `Publish.Module.MajorLabels` | `String` | Labels indicating a major version bump | `'major, breaking'` | +| `Publish.Module.MinorLabels` | `String` | Labels indicating a minor version bump | `'minor, feature'` | +| `Publish.Module.PatchLabels` | `String` | Labels indicating a patch version bump | `'patch, fix'` | +| `Publish.Module.IgnoreLabels` | `String` | Labels indicating no release | `'NoRelease'` | + +### Example 1 - Rapid testing + +This example runs all steps and will require that code coverage is 80% before passing. +```yaml +Test: + CodeCoverage: + PercentTarget: 80 +``` + +### Example 2 - Rapid testing + +This example ends up running Get-Settings, Build-Module and Test-Module (tests from the module repo) on ubuntu-latest. + +```yaml +Test: + SourceCode: + Skip: true + PSModule: + Skip: true + Module: + MacOS: + Skip: true + Windows: + Skip: true + TestResults: + Skip: true + CodeCoverage: + Skip: true +Build: + Docs: + Skip: true +``` ## Usage @@ -153,11 +184,6 @@ This table clearly represents each nested property, type, brief description, and | ---- | ---- | ----------- | -------- | ------- | | `Name` | `string` | The name of the module to process. This defaults to the repository name if nothing is specified. | `false` | N/A | | `Path` | `string` | The path to the source code of the module. | `false` | `src` | -| `ModulesOutputPath` | `string` | The path to the output directory for the modules. | `false` | `outputs/modules` | -| `DocsOutputPath` | `string` | The path to the output directory for the documentation. | `false` | `outputs/docs` | -| `PublishDocs` | `boolean` | Whether to publish the documentation using MkDocs and GitHub Pages. | `false` | `true` | -| `SiteOutputPath` | `string` | The path to the output directory for the site. | `false` | `outputs/site` | -| `Skip` | `string` | Defines what types of tests to skip. Allowed values are 'All', 'SourceCode', 'Module', 'None', 'macOS', 'Windows', 'Linux'. | `false` | `None` | | `Version` | `string` | Specifies the version of the GitHub module to be installed. The value must be an exact version. | `false` | N/A | | `Prerelease` | `boolean` | Whether to use a prerelease version of the 'GitHub' module. | `false` | `false` | | `Debug` | `boolean` | Whether to enable debug output. Adds a `debug` step to every job. | `false` | `false` | @@ -204,13 +230,3 @@ permissions: ``` For more info see [Deploy GitHub Pages site](https://github.com/marketplace/actions/deploy-github-pages-site). - -## Compatibility - -The action is compatible with the following configurations: - -| OS | Shell | -| --- | --- | -| windows-latest | pwsh | -| macos-latest | pwsh | -| ubuntu-latest | pwsh | From 2c436592d056954bc5d52687b5cbdbe71e2cea55 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 21:43:39 +0200 Subject: [PATCH 302/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20READM?= =?UTF-8?q?E=20to=20clarify=20module=20name=20description=20and=20improve?= =?UTF-8?q?=20test=20settings=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6811bd99..1f240d3c 100644 --- a/README.md +++ b/README.md @@ -98,39 +98,31 @@ Here's a Markdown-formatted table describing your PowerShell object structure cl | Name | Type | Description | Default | |----------------------------------------|-----------|---------------------------------------------|---------------------| -| `Name` | `String` | Name identifier for the settings | `null` | -| **Test** | `Object` | Settings related to testing | | +| `Name` | `String` | Name of the module. Defaults to repo name. | `null` | | `Test.Skip` | `Boolean` | Skip all tests | `false` | | `Test.Linux.Skip` | `Boolean` | Skip tests on Linux | `false` | | `Test.MacOS.Skip` | `Boolean` | Skip tests on macOS | `false` | | `Test.Windows.Skip` | `Boolean` | Skip tests on Windows | `false` | -| **Test.SourceCode** | `Object` | Settings for source code tests | | | `Test.SourceCode.Skip` | `Boolean` | Skip source code tests | `false` | | `Test.SourceCode.Linux.Skip` | `Boolean` | Skip source code tests on Linux | `false` | | `Test.SourceCode.MacOS.Skip` | `Boolean` | Skip source code tests on macOS | `false` | | `Test.SourceCode.Windows.Skip` | `Boolean` | Skip source code tests on Windows | `false` | -| **Test.PSModule** | `Object` | Settings for PSModule framework tests | | | `Test.PSModule.Skip` | `Boolean` | Skip PSModule framework tests | `false` | | `Test.PSModule.Linux.Skip` | `Boolean` | Skip PSModule framework tests on Linux | `false` | | `Test.PSModule.MacOS.Skip` | `Boolean` | Skip PSModule framework tests on macOS | `false` | | `Test.PSModule.Windows.Skip` | `Boolean` | Skip PSModule framework tests on Windows | `false` | -| **Test.Module** | `Object` | Settings for module tests | | -| `Test.Module.Skip` | `Boolean` | Skip module tests | `false` | -| `Test.Module.Linux.Skip` | `Boolean` | Skip module tests on Linux | `false` | -| `Test.Module.MacOS.Skip` | `Boolean` | Skip module tests on macOS | `false` | -| `Test.Module.Windows.Skip` | `Boolean` | Skip module tests on Windows | `false` | -| **Test.TestResults** | `Object` | Settings for test result publishing | | +| `Test.Module.Skip` | `Boolean` | Skip module tests | `false` | +| `Test.Module.Linux.Skip` | `Boolean` | Skip module tests on Linux | `false` | +| `Test.Module.MacOS.Skip` | `Boolean` | Skip module tests on macOS | `false` | +| `Test.Module.Windows.Skip` | `Boolean` | Skip module tests on Windows | `false` | | `Test.TestResults.Skip` | `Boolean` | Skip test result processing | `false` | -| **Test.CodeCoverage** | `Object` | Settings for code coverage | | | `Test.CodeCoverage.Skip` | `Boolean` | Skip code coverage tests | `false` | | `Test.CodeCoverage.PercentTarget` | `Integer` | Target code coverage percentage | `0` | | `Test.CodeCoverage.StepSummaryMode` | `String` | Step summary mode for code coverage reports | `'Missed, Files'` | -| **Build** | `Object` | Settings for build processes | | | `Build.Skip` | `Boolean` | Skip all build tasks | `false` | | `Build.Module.Skip` | `Boolean` | Skip module build | `false` | | `Build.Docs.Skip` | `Boolean` | Skip documentation build | `false` | | `Build.Site.Skip` | `Boolean` | Skip website build | `false` | -| **Publish.Module** | `Object` | Settings for module publishing | | | `Publish.Module.Skip` | `Boolean` | Skip module publishing | `false` | | `Publish.Module.AutoCleanup` | `Boolean` | Automatically cleanup old module versions | `true` | | `Publish.Module.AutoPatching` | `Boolean` | Automatically patch module version | `true` | From 45698da8d1d68a60b7ba3ca34dfcd410e10f4830 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 21:45:38 +0200 Subject: [PATCH 303/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20setti?= =?UTF-8?q?ngs=20table=20in=20README=20for=20clarity=20and=20improved=20de?= =?UTF-8?q?scriptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 74 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 1f240d3c..7330b80c 100644 --- a/README.md +++ b/README.md @@ -96,43 +96,43 @@ The file can be a JSON, YML or PSD1 file. By default it will look for `.github/P The following settings are available in the settings file: Here's a Markdown-formatted table describing your PowerShell object structure clearly and concisely: -| Name | Type | Description | Default | -|----------------------------------------|-----------|---------------------------------------------|---------------------| -| `Name` | `String` | Name of the module. Defaults to repo name. | `null` | -| `Test.Skip` | `Boolean` | Skip all tests | `false` | -| `Test.Linux.Skip` | `Boolean` | Skip tests on Linux | `false` | -| `Test.MacOS.Skip` | `Boolean` | Skip tests on macOS | `false` | -| `Test.Windows.Skip` | `Boolean` | Skip tests on Windows | `false` | -| `Test.SourceCode.Skip` | `Boolean` | Skip source code tests | `false` | -| `Test.SourceCode.Linux.Skip` | `Boolean` | Skip source code tests on Linux | `false` | -| `Test.SourceCode.MacOS.Skip` | `Boolean` | Skip source code tests on macOS | `false` | -| `Test.SourceCode.Windows.Skip` | `Boolean` | Skip source code tests on Windows | `false` | -| `Test.PSModule.Skip` | `Boolean` | Skip PSModule framework tests | `false` | -| `Test.PSModule.Linux.Skip` | `Boolean` | Skip PSModule framework tests on Linux | `false` | -| `Test.PSModule.MacOS.Skip` | `Boolean` | Skip PSModule framework tests on macOS | `false` | -| `Test.PSModule.Windows.Skip` | `Boolean` | Skip PSModule framework tests on Windows | `false` | -| `Test.Module.Skip` | `Boolean` | Skip module tests | `false` | -| `Test.Module.Linux.Skip` | `Boolean` | Skip module tests on Linux | `false` | -| `Test.Module.MacOS.Skip` | `Boolean` | Skip module tests on macOS | `false` | -| `Test.Module.Windows.Skip` | `Boolean` | Skip module tests on Windows | `false` | -| `Test.TestResults.Skip` | `Boolean` | Skip test result processing | `false` | -| `Test.CodeCoverage.Skip` | `Boolean` | Skip code coverage tests | `false` | -| `Test.CodeCoverage.PercentTarget` | `Integer` | Target code coverage percentage | `0` | -| `Test.CodeCoverage.StepSummaryMode` | `String` | Step summary mode for code coverage reports | `'Missed, Files'` | -| `Build.Skip` | `Boolean` | Skip all build tasks | `false` | -| `Build.Module.Skip` | `Boolean` | Skip module build | `false` | -| `Build.Docs.Skip` | `Boolean` | Skip documentation build | `false` | -| `Build.Site.Skip` | `Boolean` | Skip website build | `false` | -| `Publish.Module.Skip` | `Boolean` | Skip module publishing | `false` | -| `Publish.Module.AutoCleanup` | `Boolean` | Automatically cleanup old module versions | `true` | -| `Publish.Module.AutoPatching` | `Boolean` | Automatically patch module version | `true` | -| `Publish.Module.IncrementalPrerelease` | `Boolean` | Use incremental prerelease versioning | `true` | -| `Publish.Module.DatePrereleaseFormat` | `String` | Format for date-based prerelease | `''` | -| `Publish.Module.VersionPrefix` | `String` | Prefix for version tags | `'v'` | -| `Publish.Module.MajorLabels` | `String` | Labels indicating a major version bump | `'major, breaking'` | -| `Publish.Module.MinorLabels` | `String` | Labels indicating a minor version bump | `'minor, feature'` | -| `Publish.Module.PatchLabels` | `String` | Labels indicating a patch version bump | `'patch, fix'` | -| `Publish.Module.IgnoreLabels` | `String` | Labels indicating no release | `'NoRelease'` | +| Name | Type | Description | Default | +|----------------------------------------|-----------|----------------------------------------------------------------------------------------------------------|---------------------| +| `Name` | `String` | Name of the module to publish. Defaults to repository name. | `null` | +| `Test.Skip` | `Boolean` | Skip all tests | `false` | +| `Test.Linux.Skip` | `Boolean` | Skip tests on Linux | `false` | +| `Test.MacOS.Skip` | `Boolean` | Skip tests on macOS | `false` | +| `Test.Windows.Skip` | `Boolean` | Skip tests on Windows | `false` | +| `Test.SourceCode.Skip` | `Boolean` | Skip source code tests | `false` | +| `Test.SourceCode.Linux.Skip` | `Boolean` | Skip source code tests on Linux | `false` | +| `Test.SourceCode.MacOS.Skip` | `Boolean` | Skip source code tests on macOS | `false` | +| `Test.SourceCode.Windows.Skip` | `Boolean` | Skip source code tests on Windows | `false` | +| `Test.PSModule.Skip` | `Boolean` | Skip PSModule framework tests | `false` | +| `Test.PSModule.Linux.Skip` | `Boolean` | Skip PSModule framework tests on Linux | `false` | +| `Test.PSModule.MacOS.Skip` | `Boolean` | Skip PSModule framework tests on macOS | `false` | +| `Test.PSModule.Windows.Skip` | `Boolean` | Skip PSModule framework tests on Windows | `false` | +| `Test.Module.Skip` | `Boolean` | Skip module tests | `false` | +| `Test.Module.Linux.Skip` | `Boolean` | Skip module tests on Linux | `false` | +| `Test.Module.MacOS.Skip` | `Boolean` | Skip module tests on macOS | `false` | +| `Test.Module.Windows.Skip` | `Boolean` | Skip module tests on Windows | `false` | +| `Test.TestResults.Skip` | `Boolean` | Skip test result processing | `false` | +| `Test.CodeCoverage.Skip` | `Boolean` | Skip code coverage tests | `false` | +| `Test.CodeCoverage.PercentTarget` | `Integer` | Target code coverage percentage | `0` | +| `Test.CodeCoverage.StepSummaryMode` | `String` | Step summary mode for code coverage reports | `'Missed, Files'` | +| `Build.Skip` | `Boolean` | Skip all build tasks | `false` | +| `Build.Module.Skip` | `Boolean` | Skip module build | `false` | +| `Build.Docs.Skip` | `Boolean` | Skip documentation build | `false` | +| `Build.Site.Skip` | `Boolean` | Skip website build | `false` | +| `Publish.Module.Skip` | `Boolean` | Skip module publishing | `false` | +| `Publish.Module.AutoCleanup` | `Boolean` | Automatically cleanup old prerelease module versions | `true` | +| `Publish.Module.AutoPatching` | `Boolean` | Automatically patch module version | `true` | +| `Publish.Module.IncrementalPrerelease` | `Boolean` | Use incremental prerelease versioning | `true` | +| `Publish.Module.DatePrereleaseFormat` | `String` | Format for date-based prerelease ([.NET DateTime](https://learn.microsoft.com/dotnet/standard/base-types/standard-date-and-time-format-strings)) | `''` | +| `Publish.Module.VersionPrefix` | `String` | Prefix for version tags | `'v'` | +| `Publish.Module.MajorLabels` | `String` | Labels indicating a major version bump | `'major, breaking'` | +| `Publish.Module.MinorLabels` | `String` | Labels indicating a minor version bump | `'minor, feature'` | +| `Publish.Module.PatchLabels` | `String` | Labels indicating a patch version bump | `'patch, fix'` | +| `Publish.Module.IgnoreLabels` | `String` | Labels indicating no release | `'NoRelease'` | ### Example 1 - Rapid testing From 39da908cec3f58d791297aa175cfd7b609432123 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 21:56:37 +0200 Subject: [PATCH 304/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Add=20default?= =?UTF-8?q?=20`PSModule.yml`=20configuration=20example=20to=20README=20for?= =?UTF-8?q?=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/README.md b/README.md index 7330b80c..934f6f60 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,76 @@ Here's a Markdown-formatted table describing your PowerShell object structure cl | `Publish.Module.PatchLabels` | `String` | Labels indicating a patch version bump | `'patch, fix'` | | `Publish.Module.IgnoreLabels` | `String` | Labels indicating no release | `'NoRelease'` | +
      +`PSModule.yml` with all defaults + +```yml +Name: null + +Build: + Skip: false + Module: + Skip: false + Docs: + Skip: false + Site: + Skip: false + +Test: + Skip: false + Linux: + Skip: false + MacOS: + Skip: false + Windows: + Skip: false + SourceCode: + Skip: false + Linux: + Skip: false + MacOS: + Skip: false + Windows: + Skip: false + PSModule: + Skip: false + Linux: + Skip: false + MacOS: + Skip: false + Windows: + Skip: false + Module: + Skip: false + Linux: + Skip: false + MacOS: + Skip: false + Windows: + Skip: false + TestResults: + Skip: false + CodeCoverage: + Skip: false + PercentTarget: 0 + StepSummaryMode: 'Missed, Files' + +Publish: + Module: + Skip: false + AutoCleanup: true + AutoPatching: true + IncrementalPrerelease: true + DatePrereleaseFormat: '' + VersionPrefix: 'v' + MajorLabels: 'major, breaking' + MinorLabels: 'minor, feature' + PatchLabels: 'patch, fix' + IgnoreLabels: 'NoRelease' + +``` +
      + ### Example 1 - Rapid testing This example runs all steps and will require that code coverage is 80% before passing. From a1ea96281f5d38fe2473d75f24930241acb96852 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 21:58:39 +0200 Subject: [PATCH 305/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20examp?= =?UTF-8?q?le=20section=20in=20README=20to=20reflect=20defaults=20with=20c?= =?UTF-8?q?ode=20coverage=20target?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 934f6f60..ef9de267 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,7 @@ Publish: ``` -### Example 1 - Rapid testing +### Example 1 - Defaults with Code Coverage target This example runs all steps and will require that code coverage is 80% before passing. From a83a826f335afe2077f25a50e882cb6455f52a0d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 22:10:13 +0200 Subject: [PATCH 306/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Fix=20formatti?= =?UTF-8?q?ng=20in=20README=20for=20clarity=20on=20publishing=20steps=20an?= =?UTF-8?q?d=20site=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ef9de267..16c16e09 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ Depending on the labels in the pull requests, the workflow will result in differ - [Publish site](./.github/workflows/Publish-Site.yml) - Publishes the static site with the module documentationto GitHub Pages. - [Publish module](./.github/workflows/Publish-Module.yml) - - Publishes the module to the PowerShell Gallery. - - Creates a release on the GitHub repository. + - Publishes the module to the PowerShell Gallery. + - Creates a release on the GitHub repository. To use the workflow, create a new file in the `.github/workflows` directory of the module repository and add the following content.
      @@ -122,7 +122,7 @@ Here's a Markdown-formatted table describing your PowerShell object structure cl | `Build.Skip` | `Boolean` | Skip all build tasks | `false` | | `Build.Module.Skip` | `Boolean` | Skip module build | `false` | | `Build.Docs.Skip` | `Boolean` | Skip documentation build | `false` | -| `Build.Site.Skip` | `Boolean` | Skip website build | `false` | +| `Build.Site.Skip` | `Boolean` | Skip site build | `false` | | `Publish.Module.Skip` | `Boolean` | Skip module publishing | `false` | | `Publish.Module.AutoCleanup` | `Boolean` | Automatically cleanup old prerelease module versions | `true` | | `Publish.Module.AutoPatching` | `Boolean` | Automatically patch module version | `true` | From 31e7ce083dd7eef4132a133cb582b5b36e8a15a0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 10:37:17 +0200 Subject: [PATCH 307/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Enhance=20"How?= =?UTF-8?q?=20to=20get=20started"=20section=20with=20detailed=20repository?= =?UTF-8?q?=20configuration=20steps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 16c16e09..be1d8229 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,16 @@ Process-PSModule follows: - [SemVer 2.0.0 specifications](https://semver.org) - [Continiuous Delivery practices](https://en.wikipedia.org/wiki/Continuous_delivery) +## How to get started + +1. [Create a repository from the Template-Module](https://github.com/PSModule/Template-PSModule). +This will create a new repository with the same structure as the PSModule organization. +2. Configure the repository: + 1. Enable GitHub Pages in the repository settings. Set it to deploy from `GitHub Actions`. + This will create an environment called `github-pages` that is used to deploy the documentation to GitHub Pages. Remove the branch protection on it. + 2. Create a new secret in the repository called `APIKey` and set it to the API key for the PowerShell Gallery. +3. Create a branch, make your changes, create a PR and let the workflow run. + ## How it works The workflow is designed to be trigger on pull requests to the repository's default branch. From 3cbad1ced633efdaa587270c59731f12a636cfbf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 10:37:39 +0200 Subject: [PATCH 308/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20API?= =?UTF-8?q?=20key=20secret=20name=20for=20consistency=20in=20repository=20?= =?UTF-8?q?configuration=20instructions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index be1d8229..9c5807b1 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This will create a new repository with the same structure as the PSModule organi 2. Configure the repository: 1. Enable GitHub Pages in the repository settings. Set it to deploy from `GitHub Actions`. This will create an environment called `github-pages` that is used to deploy the documentation to GitHub Pages. Remove the branch protection on it. - 2. Create a new secret in the repository called `APIKey` and set it to the API key for the PowerShell Gallery. + 2. Create a new secret in the repository called `APIKEY` and set it to the API key for the PowerShell Gallery. 3. Create a branch, make your changes, create a PR and let the workflow run. ## How it works From ddf490b9a9e376d099d4e2728a30dd72493f4ff2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 10:52:49 +0200 Subject: [PATCH 309/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20READM?= =?UTF-8?q?E=20for=20consistency=20in=20configuration=20file=20format=20an?= =?UTF-8?q?d=20add=20new=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9c5807b1..bba59523 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ jobs: ## Configuration The workflow is configured using a settings file in the module repository. -The file can be a JSON, YML or PSD1 file. By default it will look for `.github/PSModule.yml`. +The file can be a `JSON`, `YAML` or `PSD1` file. By default it will look for `.github/PSModule.yml`. The following settings are available in the settings file: Here's a Markdown-formatted table describing your PowerShell object structure clearly and concisely: @@ -255,11 +255,12 @@ Build: | Name | Type | Description | Required | Default | | ---- | ---- | ----------- | -------- | ------- | | `Name` | `string` | The name of the module to process. This defaults to the repository name if nothing is specified. | `false` | N/A | -| `Path` | `string` | The path to the source code of the module. | `false` | `src` | -| `Version` | `string` | Specifies the version of the GitHub module to be installed. The value must be an exact version. | `false` | N/A | +| `SettingsPath` | `string` | The path to the settings file. Settings in the settings file take precedence over the action inputs. | `false` | `.github/PSModule.yml` | +| `Version` | `string` | Specifies the version of the GitHub module to be installed. The value must be an exact version. | `false` | `''` | | `Prerelease` | `boolean` | Whether to use a prerelease version of the 'GitHub' module. | `false` | `false` | | `Debug` | `boolean` | Whether to enable debug output. Adds a `debug` step to every job. | `false` | `false` | | `Verbose` | `boolean` | Whether to enable verbose output. | `false` | `false` | +| `WorkingDirectory` | `string` | The path to the root of the repo. | `false` | `.` | ### Secrets From 51459f099106cebbefef0f84f863ce590e088090 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 10:57:02 +0200 Subject: [PATCH 310/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20permi?= =?UTF-8?q?ssions=20in=20workflow=20for=20Pages=20deployment=20and=20add?= =?UTF-8?q?=20id-token=20for=20source=20verification?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/workflow.yml | 2 ++ README.md | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index aabfe28e..bc750250 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -67,6 +67,8 @@ permissions: contents: write # to checkout the repo and create releases on the repo pull-requests: write # to write comments to PRs statuses: write # to update the status of the workflow from linter + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source jobs: Get-Settings: diff --git a/README.md b/README.md index bba59523..a5576ca6 100644 --- a/README.md +++ b/README.md @@ -269,8 +269,7 @@ in the workflow file. | Name | Location | Description | Default | | ---- | -------- | ----------- | ------- | -| `GITHUB_TOKEN` | `github` context | The token used to authenticate with GitHub. | `${{ secrets.GITHUB_TOKEN }}` | -| `APIKey` | GitHub secrets | The API key for the PowerShell Gallery. | N/A | +| `APIKEY` | GitHub secrets | The API key for the PowerShell Gallery. | N/A | | `TEST_APP_ENT_CLIENT_ID` | GitHub secrets | The client ID of an Enterprise GitHub App for running tests. | N/A | | `TEST_APP_ENT_PRIVATE_KEY` | GitHub secrets | The private key of an Enterprise GitHub App for running tests. | N/A | | `TEST_APP_ORG_CLIENT_ID` | GitHub secrets | The client ID of an Organization GitHub App for running tests. | N/A | From ac851175b71a16e156551b32e8a0aca34bd5ea79 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 12:17:34 +0200 Subject: [PATCH 311/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Specify=20APIK?= =?UTF-8?q?EY=20secret=20in=20workflow=20for=20enhanced=20security=20and?= =?UTF-8?q?=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a5576ca6..55e69d43 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,8 @@ permissions: jobs: Process-PSModule: uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v2 - secrets: inherit + secrets: + APIKEY: ${{ secrets.APIKEY }} ```
      From 220404e4e5019f0d98813c516cd7e778b8a00dfd Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 12:40:08 +0200 Subject: [PATCH 312/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20instr?= =?UTF-8?q?uctions=20for=20creating=20API=20key=20on=20PowerShell=20Galler?= =?UTF-8?q?y=20and=20clarify=20permissions=20required?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 55e69d43..1350d474 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ This will create a new repository with the same structure as the PSModule organi 2. Configure the repository: 1. Enable GitHub Pages in the repository settings. Set it to deploy from `GitHub Actions`. This will create an environment called `github-pages` that is used to deploy the documentation to GitHub Pages. Remove the branch protection on it. - 2. Create a new secret in the repository called `APIKEY` and set it to the API key for the PowerShell Gallery. + 2. [Create an API key on the PowerShell Gallery](https://www.powershellgallery.com/account/apikeys). Give it enough permission to manage the module you are working on. + 3. Create a new secret in the repository called `APIKEY` and set it to the API key for the PowerShell Gallery. 3. Create a branch, make your changes, create a PR and let the workflow run. ## How it works From a5e468a30ad3895dfd79865a4c4fd1e220dd46ec Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 13:00:29 +0200 Subject: [PATCH 313/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Clarify=20inst?= =?UTF-8?q?ructions=20for=20GitHub=20Pages=20environment=20setup=20and=20b?= =?UTF-8?q?ranch=20protection=20removal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1350d474..884bc895 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ Process-PSModule follows: This will create a new repository with the same structure as the PSModule organization. 2. Configure the repository: 1. Enable GitHub Pages in the repository settings. Set it to deploy from `GitHub Actions`. - This will create an environment called `github-pages` that is used to deploy the documentation to GitHub Pages. Remove the branch protection on it. + This will create an environment called `github-pages` that is used to deploy the documentation to GitHub Pages. + Within the environment, remove the branch protection for `main`. 2. [Create an API key on the PowerShell Gallery](https://www.powershellgallery.com/account/apikeys). Give it enough permission to manage the module you are working on. 3. Create a new secret in the repository called `APIKEY` and set it to the API key for the PowerShell Gallery. 3. Create a branch, make your changes, create a PR and let the workflow run. From 9df179396ec3991b435640135bdf6e3c67c5b54d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 13:11:54 +0200 Subject: [PATCH 314/324] Refactor code structure for improved readability and maintainability --- README.md | 15 +++++++++------ media/pagesEnvironment.png | Bin 0 -> 27320 bytes 2 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 media/pagesEnvironment.png diff --git a/README.md b/README.md index 884bc895..edd152b7 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,17 @@ Process-PSModule follows: ## How to get started 1. [Create a repository from the Template-Module](https://github.com/PSModule/Template-PSModule). -This will create a new repository with the same structure as the PSModule organization. -2. Configure the repository: +1. Configure the repository: 1. Enable GitHub Pages in the repository settings. Set it to deploy from `GitHub Actions`. - This will create an environment called `github-pages` that is used to deploy the documentation to GitHub Pages. + 1. This will create an environment called `github-pages` that GitHub deploys your site to. Within the environment, remove the branch protection for `main`. - 2. [Create an API key on the PowerShell Gallery](https://www.powershellgallery.com/account/apikeys). Give it enough permission to manage the module you are working on. - 3. Create a new secret in the repository called `APIKEY` and set it to the API key for the PowerShell Gallery. -3. Create a branch, make your changes, create a PR and let the workflow run. +
      + Remove the branch protection for `main` + ![Remove the branch protection on main](./media/pagesEnvironment.png) +
      + 1. [Create an API key on the PowerShell Gallery](https://www.powershellgallery.com/account/apikeys). Give it enough permission to manage the module you are working on. + 1. Create a new secret in the repository called `APIKEY` and set it to the API key for the PowerShell Gallery. +1. Create a branch, make your changes, create a PR and let the workflow run. ## How it works diff --git a/media/pagesEnvironment.png b/media/pagesEnvironment.png new file mode 100644 index 0000000000000000000000000000000000000000..fd3bccc13f46cf0e8a4209bd085ddfeb24711910 GIT binary patch literal 27320 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
      |VP79`Odr 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 literal 0 HcmV?d00001 From 41b1681976c40489d8e3c630ab10a1255afc11a6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 13:13:14 +0200 Subject: [PATCH 315/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Add=20details?= =?UTF-8?q?=20for=20removing=20branch=20protection=20in=20GitHub=20Pages?= =?UTF-8?q?=20setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index edd152b7..ef7ed9b4 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,9 @@ Process-PSModule follows: Within the environment, remove the branch protection for `main`.
      Remove the branch protection for `main` + ![Remove the branch protection on main](./media/pagesEnvironment.png) +
      1. [Create an API key on the PowerShell Gallery](https://www.powershellgallery.com/account/apikeys). Give it enough permission to manage the module you are working on. 1. Create a new secret in the repository called `APIKEY` and set it to the API key for the PowerShell Gallery. From af6024cba79e9a8604598b52c3bf297b521efc31 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 19 Apr 2025 13:15:46 +0200 Subject: [PATCH 316/324] =?UTF-8?q?=F0=9F=94=A7=20[Media]:=20Update=20page?= =?UTF-8?q?sEnvironment.png=20for=20improved=20visual=20representation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- media/pagesEnvironment.png | Bin 27320 -> 26530 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/media/pagesEnvironment.png b/media/pagesEnvironment.png index fd3bccc13f46cf0e8a4209bd085ddfeb24711910..59f411d052b340fe39143871c6214ffd7878e021 100644 GIT binary patch literal 26530 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
      ^lbs&V^Ui*)U?$~Jy_k`M`%ExfTvk-==(U;i z8dg!`8vEoFdcDzV*w$#&K671`fmJaN#1r-|u#YgBJL9LyRJreH97)$RJ&#Dpkz*^*{w>m4UvU1(0gj? z)^Tw;Na!cvtiL_p3wPwh%F4k4wn4f(&IUqxf8Thi6lwYYxr zbqdA)5J-9FZxt6$bBCZtsmx4=q^YCIl>P}OZr>jbheJ>DTa}*3E9Nhk|F$zMzWVX$fL!d?1gB#?it?m>D`xv# zzlyzkwr+hvsTE(_H%VrL=AC-aIY6A8N|~goPnJorMN>tq#gEgNMhb@nJ}TODz?K5L zge7v#JB&lTUwist%kFiVFe|1(MQy6B`R4CEr*fNoSp4t#mH+q3$hlFRPM+TmB3=iJ zpm(gFmH$dkmon6@HcdKutUov$?bAG)dEXU?-TRPyWb1g#wwMn|3}^Fr z*)I9?7~7QIjTAflB;P@x$|S6X_t#Lk=A0t=prw@7%jz3B8BRs1?S_g+RGvQD!xfyf zal@{D)7xhZ3^pY@ZKw?}k>pug*RbQLD}`yv4Y)2&Qp_$kTo!)qv^)`3%pQ4)(8rYQon9RgA19)vqQN~k$YQtU+Mjyw(F%0o}-e)QrOkaS-4QAI!8J}2sM zm*v!Gf&1LMM*3$h**4{vQI6H=YF)tcVXf{Rprdg1P`E|w^iisN0YjRO@wcvIOZUO^ z?H@rsw(a@CF`ne{5LU+7fxRZ~ZfHCT1GL{uBch@rDRcDU`?J@8a>Cf?!JXcfI!^FP zVf2ifaA@n+liZB!VlF7*>g(W`MKe0xW%6>cfQHTc(ya3Ga-cgN#hP1NixKQSp!K?p zmwSxY?QTlKM)O>gv3$Rh;v6eC_uRBCP<-xPOh;L3-|FtTy}$7}^^QUxQK=s;^y-$% zPgpMsnlz4Xo?VI|Sw#1qHPF}|ZFrEWGW4gR0I4KwaObZi1|Q4b=hs4Is!Fo-_HkXf zyXnVNvbpJ!jfVI3qZ45L2L`T&i8}#)DTiKfIHIar&9)|5q3VTyoNF&g2;28lQWPx> z+x&KGUx-c}PD+TL(65}trO%gqbsgIXV;#2HThvw|K63Zewh_#u{exVLem&5dHtWM` zt&7NJcyakH#wlu#UE&J^gP~ON1G!~T#@3UV0+KVk`X?EQ1r*pfKw7yiV6?{BjnQ$e zw$s+fey*s-5G_rp)z|ws@zWPQ(emK@(ikA_m~WUZ%2SBXFZ*f2L`Ufh4GDddsWGw+5V&u$OVAnMr(ASg`E&5`EyS=Yqq3`B0?-y_A zP7nO4WqVg3cu)BXc}Ky@49QSy%=&xI-r3F>o3b!d@uW#Qvs`(r55BT)KdIV{lvO0R zD|hG1-+L}l^^SBy*DLMD*0@e#?_JSOuPI3op)#8n2_3Ns7++S`&|r_G;2(}AoW)*r zYL@x)dj_D3ai`j2pJxHdkdfjyw$BJVFQT_nrG=y`gR|$>{VX_wTaSLPsWs@&#r>eg z+?KP|82MU#<1s_Ss3!EtR3y#R7UsP6zy!=Dn6Mgv>Q%3W{d2R7X8Wp98)q~=z7OVJ z#ZS-o?1!FF13$f-(|Y;*)>OB9jApi3AQc*FLIAqyM0^lwp_P)FTPYQ#4jM;?F_$=W zSnE>LH15uIlGhfrCpq0iFE#h><=(E#xUTf3Enimam4K>Q_WjOtRDO7Z_v*s2-*& z7%NBemTQzWye5q$ykf8{mX# zH+enW?s4MUkBJ!>oZS0Vi5kCTRr0qVRVd!c%EopZ+1J~H7SKN8h@{X9_#SE^<{jfY zuoKoEcd7-(F=6$85!efblfscT{|`^^0Z(=R{*Q|yWu<{+ri5fv=s#NRzq#t#UZKLgFeK z_Eodj{Ys)?#U*oTXlPu?du{tZFE3A%rG?AWq0GIhR>fY^Se`f5|xX<78<0=p4 zbHAPuLIpxI>(0M;(T53cuy{!}05+P4VRcaq+*dR3PD~H{fII+qB;yL)a%q8WgoFme zEPHP(0p=eI^$==6S3_nDQqZMgdl-f0`EjbH3~rvv2QwG2k{BSQLIylJ0_Cm{ext%X zr9!=rsXa~{P#!0WOwPM_ZZV>3H5?Ysqc4g>iuel9P5xm`J*Q5^Ot44A#B58X!g4)9 z?&ZyRsh*EGXL?@16{r9gxW_}M;aFP^cZ7wz2X}*giN4a|BLE;F@$OF`^W$#@z7oG; z;eAzy&*&jwD*yKxh0Pr|t-BYnn$q2PcYfbU=e99`yjEbhj5v)WZWjRHJ)>o3zaRJK zwxX@z2e=>G{`za=Io5;C;E51^q_Tr~12kuxlNLh&ML*Nl)n%8FFbG) z)yD1~^7fbQ1|v-bSc8Ufr*JFBl`ASKF~dG3oGC%yIKVg5KNV6^nz*JMIu0MQ5Vw(tj!mT#-M)$bwyC#Y`EP5m&T)=cGISl7)a@N_XkbX(~`uV@< z-2=kOxUHx0j0_jIJ@!Ms6)beix6JL|6FVgZA?i7#i&E0%C`j{tPK+3&Kv`q+uLt=w zfiH%*Z73QTFu<@Ojg%A+_xz;?0#dm-g@wA?e(+%qOHaPt?-L7 zMW0Nc8SS{)P={Pwd;3*kVI2ojBB|qp^&j2cNPmXrQpePw?c+d)^>0@2aWnKT~@pkx;jB&zGse2#7_OA3u z8O!o8sZ5?kFIjCj%W}$^zwiQaDTB;E$**?9Kv}<5C)r!CX73~O8^sGNt@N#s}$;W=o z=h-hCKuE5G2rhj0x@d@~a-2VFdDS4);lfeTuxq`c)cFkl+4m|b-~F#*Ob62BPq^P+ zv|0WNaiC(7_>>eHZp#5z#gqGeW~T)%Fnj$uCnO|<`1G9!;eq53WbO);PW35iYDjyA ziu*K3RD@&>H?&MrIXy<7k(v4sgcm0oSOB`P+zwo;KwnedOB}wWlm)vnrL(VZLR|Zf zTGiQ!m*KAlLfC!cUMD(b8f`vcW6c#h?N`WYn>BBjV8al{kzQs+TwZ@5YK&U$-|*R* z{p6`%?{PJQlBtOoqg6R@ad?r^!~4uPZrQC~NkNHAq#Zk`@n?lvO}P zCuM{T;6z|i3I^N6@CGuQ*~4_tza>qmmj1*f?BvnKeC_HHhwnhPZ~ZF+iNLK$RRCVu z5hnh;u=OEXg*HigZ>yq#GN~sN^hNgl+IqO+x<~@Y~4Z=10at{=62Qa5*WDi+y@+Zog;~ioPi5 z=_RzgNQP9nJjr*eb6)#{V0k;z9^0ScWCXL_V#9*KzY=Nihi*7NTz1=kB*mxK>qiY6 zSCaZ-_Ievm+|%0HT7CO;Z9$Z?>Y|gFE87gjaL4F8emAp#ukN0}Ylv5b@z}a?u`s)0Cnwmxn^Hg!x(ZVXTvKss1COhE**r4|xusX#b} zXW#~+sTo6HhMkc<|E!~LwssUhQCaVxzz@j7U$l0=8rVr~ zn^{`j*qHj*k|Y_eG!qF%yaKR*f(?m%o?>V0t-en%pV&m*E}9D;2WUlZnsnBZ(k$_1vkVTZPwxxy@I3H4GPgsc^?0Jbx3$fmq4fukz6E=8cucS}$imJ6 z)ac`uc>*z^_gu)$j{W$N;@b%P{iXgl7&JscPwwjGmJX#I923=kgJxL5{r`BhiP-G1 zt}s^r-x20NA&itDgZ!RZ)rb^^a4aQsGmn!(HSo|y9=#IyT3 zkVN-t>9f=Iw6rqo?}=ZbGOqV!FgxDEv~}3NSlza0l=E$TlawSW!_Gb(m_0?wq5Sj~ z7ncE7IpA48W(Y01%5jO(htW<9e9HaXfZhE?uJVLE?@SM|kH=HY3%VUz~AJiME& zu=`**5sDl$P~WHeu93rlh74FBVEFnEl?RO{_yv-I{RZMm2GKHu?eG&rE(h@2p0&S* zK>CRYJ*B*8;rxR0BPTCU9omL{906b=ox8uVg+p(92J2QGX=Fib{BendqX6En%`UW)UwqmuoDkm` z(eUc~=lmgPccbza(F%~*kw+Dqug?7l-r(RyNCjt22n3bGu>i&XP|~k)l%_o#eK51h z!FZVYt|DBA(X9`h*v(%O@FdlJswq+tP$Qej8h7cuYN(Wbi)lpUpa6@f;+_BfWP@^e z8U)wXm|w`a1dd)GKVBVpw07+WHRI4uq4pmdn1Trt%1Z=eKZ;um?Nmod80UiKj@d3Q zmOZDf)&eR>j;KVNJ?Sb|u4|$caJtT_&(8jN(tMKM8#loI3d5RF6bNzh1IY2{I zKjbjXF+06hPBmTS0+XquiR1kM6ov=+n2?nM8C%3$TwH$DWSS->1*VcWM1O$uK8#tH z%O@a6^c67F*aQV>0ce5S6_!^x&g&m?Oxp9J50Zm17|aZmew8rafh(%zqSD2fvah!~ z-OQ}5KlKG>KN2g10lR4eetDDLws8O_^V3uoQH&$}_S9DdbwdqQ`3XN{~b9UF{FqAvw@-Ik{3L~A0X8UDXL9n^VK)p7@tq^ z1hXpl52b?CgfD`SK1ukP8T0*qoX|2bAWc`*AW19%E<35oHs!ws{*t}?*B>9g-$_Dg zx4gWS(vn=4e!pl+^--)Qg~wK}X~UN;OvcLVq0oT6JceHyN@ZhjjL?xS3D=1N4pwNb ztDay30qLpDb+wyICnWfIvnkV`4|pT(tTMWHzF`pnY6PR7}(-e5;kdBxYIsv5c zT2^cAzA>NdK!A^z(&R>7bgH^ED&;0!PuBaM83LctBZ_UXv^wMpQH7BO|#< zzqJ~*Mp6-gwS%bM_R|nNGKd5EcECCJ!cP%u#l~+??;;s5h7m4c7Ke;7+B&oW=?;JO z>N{YMoJ5TPN4)?m#i9V0U@y?ap6Cnm=H)u>^{sn#uGQYZc=xR5Wq`Q7vSXq=8-*2p za-esy0+`P~OhfO#mTGJ9ToMWG4<|w}Z=j!qKNx13HjF4{8o}0vT#7;TJ8vr(=Yx4G z1nF#&ylzt0(fKTMP%z^(4VNMAFFF;{kn#q&1G=Tp$r7z^HIZus05RBcYqenHoSAT9 zc)0IvdW!8z)SCA-<$kH)CMWQgKGue~_FnL8=mykSQv5|G8Ytut5Muf5m9tjw#O}8- z)IG=(awt@JQxA4e-Un;!LKgC2EmIy<@LjeJ4i}P6V8or_TOcZDFsU)+2A;Q<^KOnM z_ZCkpp=`v#G$A`#m*NyRuHf+ZH_lGi@vYPxhBC0sFQ6zJ46U>EDZA9=)dhcJgC|izpnM z0H4HuOz_gw&^Y&V^A0cr6s1K6_rVmZ(K31 zQralLQrQ~?Oya{^T^Om*=RJ=V!1aE@PhC%M&c#eq-$jka&hu;{MJbFWkfIuC;0!df z5t;(zsX%M7%CN|MQz>&(Xhi9X`;HXC~|L;;o#mzI0_} zt8?L4F79PG|0}zlwie9_d-=5)7=ma9=*l}8g2oBvXDvv-3?KqxcQ;()!H4wd$gB_Q z6@phmp+zMqo&aUZ!fU~maxXb6ElqBbl;~iyC_ral+V7S7Wa9~`oylM@VRterg66(r zQ`2FrS|=F|c9nbI1gU4eR6NfWPL241xyE()jFCJ9IHNTde~Wvrurm8?XaE3U0US*v zwOAeEr{T%>na2H)ufX+M;)d6)aNKgeNg7E{VG3c>Vi8H*-4Dl{wp3VkA9xWwed?sa zk(}gfG|8c1ziKv9zp1vFS&?c5=&VX49T)(5^*v&H84*GLM=?!pdS(W3@dYKrNI^y@ zB(`5f3}hgJiPinowNZH(!Tdu1xGf>Er&OqY zXhee)?&Lnl!FbJ`<;n)E=F?Ackene=P{BCl2jT|HH|;JC`SxPy5Pco+9P7mI{RNkL#JietHOSYFP-#zp7mPxI zkjH-e_IY5qp{6v^tx1J`i^6Njv~E%^OBf@SK~4i7TGgxBO20JOXw;GXZ0KN{HPL!};0-^sVoVB^{9`Y3he^PZ^DFJz$&P;aCYeQ%`0Y7 z6~STaU)2GZ``P0Hkq$pPI+~EsdngD0oSv(~;#t*@`xyGO&FaT6RE0RAcerwWla`R} zFimmoDkb=VJC7e{8M$@Bi3;6X>HySz75icE89o1st!Ld=Pcey`~Oe| zXw&_uyvGrEhfszo2CZRn-hBdkqVwyb@Z`t@CRMCKJ&wc9)Y|$_E;7F(xws*usQCG= zV*3`AJ>K5d<XxW6zrVOSd5yh0x><`CWbjgRG?9uZsLy?Q^!ELDfF zMb}wg62rm-r|eGYZtfZ^dxmAuj~ox7^IEcSH6l-7?MA?0l0oC~j1WeYR1H<8_PxSYS4}aLWWwx$}V=<uC;JxDwzBb>uGBbj*g6opKWxpGz;G`|MNR5eMbWJqjL+JbhgneXh zpmwodH}KaSL~0yd=SO z+C8G3rCD6e_+tDeKGQEX*Uwe-EV2C{*NfHTK~6PjUhfC zN$>3SD@%*Xss@Ek^by-?_h!(krb~qFW>)3*UO0VMle#aY0zvh>7|a%TUv&5@7kQ;+ z7QeLzjE3jKGJc1iI!{ZhZfyJ#p4tjDOT(phZzOzO?d|gmHJ`w=9r&gv^gOi=rfak1 zvUh5RvzR0fkgnXVWq4Tsrb+b$;21&}QS>db;oraiic;tUEfSh}gk1&Km(sImCDkV2 zgP|Ru`}cD}=P(^a1Ooij2!wZJze2x;ge+_C78f>k;-9o^loNmPXkF@~0nT0ZOUFuO6W z_~jsiN2x=so1#ashEEF}Giv224{9%e%L}4!HlNIrsD`-v^*sL8w>gBW$yU$2&uB@h zboXuuYTuXXSbboe$PA*qF|$DITrjWQ*0qgv0BVdw^hvou`{(Px2chdtUJ@RuZ?0T(mT*WF%ic2J9QebnP&6oV)#xfrTXoQl-HIwrS3_Wr*MB@R7jfXy$ug@YGQH z4$+_cOm4f-@~RGKN#^}pn-5HG^lx72IcS~g9a8^nFX8yZ*|PQ=z9HcD(tBF{zq)aO zOH286_@C{wq+jd4=Tt_;mEh5ZA7WXcy{o4AEaqEIzXY7->y}nl=NK8I0LZ#PN0-l5 zhk#eGjw`uzZ*I{2eZk|Ick{R$htdjmb_!v-2tc?#)ScDL(5pcxwAQ_3I1pN(y%?Oo z3t#et2m+Ybgn-@Af_ySa-B5RaBLk1!wOOQ|c)(Zpr`++VwXF@YD1_D=_K6%6l;Gj- z#-{cx1uK{7d2>=CbpldmE}y;-(1N#P@{FPVD*ZzPmfK6on$5*L44w=6m)JDXA_%OdoLd*Ni zHWq-Q-NW)MO`Yt#JQY9a7uued<#qTM03wo4ur%YpQaJSslH!Nl@(K%;SQS3odtu9= zcTQc022Byp0V6SFq&{}*bKjIxjw6=(Z7Bh|w`%I1R+(oerTe=3Q(;3--Eb`RuU>Ob zOSSrGK>zbB`EI&|%moS1h9Xso2D;^Ii?EOnptwaVFdvJygrQbVWK>kPN?d7Kk*IfW zSOue_A=I;6g$p0j*~edKhhxr7FP}k+VlQAB9gcoW3J7S_ap9p?or~`*=V@J6eJ0*n z>aKT6CqyA*4TPLc@w;q@r zE&1%+2G&-Ivap5xGC{&@?md=3hiQLWwt#&uPUazYrP`i$^?gLU_Mc^80sT@u#C07m zkvRSs(z>gip|1Hn1;$2U!>5QmA@C0>L>d+rKKEaz`8^yJ;sl(#g_IX^1F?+V7g}CP z5BN}foaxiZ9-wGh+AF$gpOPs}_QvL5UC(MIAmx6mNd=x~*=vCCc6E;0$bw&S)4r&w>rQ02UdH^e2h56xv{6{QXdYKMs!Yz{p0f+e5*fhz6 z!O+>#i)R7WY{-*UIByNc66!53$Y?!;w9G5C$gec*KmTo8g`^Wx>W;!8Hcz!xhMELfkQ!LE*Q;@S}b!o3H4aTGPXj229-6 z#Ea}*TapxP;D(d=if*XURME?AC&2$+Ec-3{Sgxn7xu3|1<(St+E)PNo8j?pR&YFdE zSofRMMu}>b!N3rjEHJ<&75>x;+jbZ78feoM;)u%LIISjd%@TmjV3O9!~ zNqDCO*PR~trizu%KQQGwdU~0V1MO(581j`8>Z$%R7C4Fj|BYmo3*x* z&n2VTzcw%qtscW3PT}e8pd19>oa!Eh5xUMJDc66o?QXv%;6HscTKf9oSQ%!YGbwGB zAD)!xkH>S&JL=tKi2+nu1TdPn2?=Hw_JJc<3LC5fPC2zx#k7ITZwgIo+Cry(SPNP- zzaaN#IVvRhj>T@YE#-A)e9VRfmB=@qLl_%Ul`ASHa%naY@da>?=boClgOs}TdhQ) zP1-f#mTcMmUcgdIt`&a~ZT16!Z!7&ibPn`Qmql?N#S81VZeA*qY;6aFuA%w;wLJ!u zwSm8?10$)@=spt9*qRl)x1iS$3Fx0W^jw}uH3y02qu`)1Z5@nyUw3p%Nl7U_D*Djk zWW7T;fAl@IlbUqCgJDc%P_@aw-gC+p%;l$kCs&B@U3o|?>Pc;irP-I7w$n03^jzU$Ze~0t3Q>+4eG|e zh?)9z7dx5hUb%e|!#}E0BT}2&Eh#Q;K<7PB7*kQ4RKcB|QCTTAwpO=#DSl9sTO6t< zMi}S5z#So|CQu+=zj-qwsz0BPwER06>q{`(z_4kA8NEdue zJOF)z=DFxF^85Gifz7WK3d+lW&y~aeN)Nfd}01S;zVHS z)DF$^#D~<>286dO1uN&QavbaeyA-j4c-p0#+}xJJBGC8igK(e_sy;8J%x8H6^W6}{ z+gC-LnreH!=7w^=E`}ziWgLK&61#!x4b%cozx8zW+&1C$NF8nrEYLZ>a~W7aTa5PKQXFByou|d{DO&YupFvrZ`l^E1Gq04w2t_QnG&X%= zKfk2p7a{A|e8OpH2{gJ(?q6E(0V{237i+~uwN8!^(bdsGf-@OK9OUlaJ#|@Ldu+l% zq=r{*AI&+~#b~Lvo%ww2Enq@gU;e_hvmV$5sxa^H#bHkK`@hUtKUN33qaVG!TVjjb za%VU$HARI_5A4(xk#zI@qWc+NywI+qo6R>6MRHClAK6`}_NOiBd@TuS5#&_#AInQI3s`Sq|hNoO?t!_TO#*Kn{H1 z&%?tbNJOjhe(Oa2JDZW25(cHBhPmqM>a5VcqxhTRPZ%>F#>u?TeZlz7H=>RuPBd3#P(PW#2DtzGsm!SUU$?BTuC0L9k#5&ZO5-=zd5Fgm;+ zqQ6MS`7vODz-k+6fsrX4qPDWKdYzDveYVnWzidiG4SEOHcbsK+R0&e=Rt%xTkvK-+ z)rv9qq&;89SdH902Egmj-b#`5P(9p*i08XXN}-rAcS(7TRgGMI!~biNz(lc{)fB9R zVJrBC679>^EWt$29j8iANSCHczfP*5P<8X#O(Wo&0XBsoo}Mt@ErB!wSjJIrw!6$5 z;!BHcW+y(g|CDp96a>oFy8Vr#&~w@KXU!+PDLnz!?STjoGe8=;ERJ?yi<^g49$mPy zs)RB_v4S{#b86nQzPj45;v)c!2wVn&E`)qSxw+&d1{ieiJ`EcHmH>W1U8#YatmY~# zjq*FXp~HF++9ssdgzEi2>vENfw zr2^8>=klg^M|$NC=3yB*C%ar9ADRZV@xW-JcT)h$nYXi>Q5Bh4SxSe%DA4fm1*ifg2|rAHCOQs{-9APTO`p|(wE+ZR*aVAA!oBMI4A&6hjnj*Oeai!Mc`eX+FtSQfl?uCVgM1E}F@gvi` zLrzXkgslfV5OGF5Oi2hOSsg8G02`;e6h^FY%P{0ede?5Hn+6$IoMhKtpD$8x_^p%y z=g}xoQD&t@KC%FCz!yPjcqAX5sR8y%!-JehTLm1-rX(K^{SG76&z49S#4p3Nu!AZ5 z^*lxB51*H>t!hu+_K}aVtQ-*j@b?KDO>S}+j~G|Jqe|@8Y(kLu>W%%1j-Ae)AiW5b zhw;5%DY6!aQ2|65*DW3{a_GgR&UPj`<+cAe{x4ed8GQc?Q%$K6;3WOp82X~2r-_|2 z(EGF?vVJ5)2k`N)eNThxLqF=;k_2FsoK!LfXt4rbP zxe|2ge{EIS*K8;nz}We<3gh0UF0T-HA%Wl7Z)qf?<(c3Rpnt0{n9duLR!fn}JsT4$ zu_Jb&=o)&+wruLL*)em=yCySwjzI1=gZEA>8pX7K7dGy^gg&%*Tzj*t>QYo2Mp3qCebMgedJVARte8V2QKC`f(>>`txQ3vxy%uJm;m@Xc;)Bg;=x7Cu7gO;OQ8>B~=);0Gii z7QlQ<0G`3O^eSxbP_TFTmm>PMHK`0BxN1J3T_4ZtUj)u4r_j79h4sb#kM&>LTNeJ%FRvT07Z zxw}U`%COiJHIDoAID6oO4xAlDrKKB8C9)TeHqFe0FSE02U86VVU7AwWb3x1XUkq9# z47`vWVzucj!p`NaJ8i~93A6IyNxvkbm0YbS8Ahm+2tT;I&K4b~pR)S?sOddD-<0aJ zDy-W!{nDa=sKDsR10`!$*gDL8hoOm;s?&5e2hy!`3iP>hyMY?y-rQ!rnzjMuh6UApwAZd* zukJCU;2?EAZ{U-u?Q`{O!&^BUUETPl%dJn#s0_=L2}eMeL$$Y0wBV{_jrS#_rI{eR z;r->t3t`&Svt^$~9Fzb@2efz5%`3Rfj7$rhTkh)pc%1Uf_Txg{;{3(`R&Wr;Df{oY zPbbc5sZTzqoIAC4&4=)$9cUak;A+a53++q@D$Udozw*lB(B`AL?e@2Z=`&~0?OelN zr<@PZ=NxrE@L^(8j>EZyHjq)We7zaKUT(MR)1x_YiY8^#z(n|^@mmf%dq_I`0>glx zujp=y`E>CPy!`%eHI_rzlYAqT$;V$?{(~uTT<061DOF*jJfO+T{%F)gMSOqN&N+iK zi#qFh-#uIFJ3dU+(rwjf2loVXPSk>%J>%_U+MIeWs;aZvKHz+Fa^d4cAm%c%XPAcz z`jv7XX9Xz_MGKNQ7vt+gKk0J2$a|*9=T7HR^b~5(A7C-{e?=&b?}$2@t5ek2&G9MI z0>O&mXC@z1LxW)rjgO&iK#j>8Fli>;(;yB!VjdT~nVwM~=mqTj)S`2|jyW3pANCPU zEEUu#G2mf@fXE2irK;-gV-oV*J*9JHK1ga$!KkDhco0Yg5QJwAVG_0`nw=mYv0iyUwQgDc@5>JRnzwNlJ& zs<0OP=AZlOFe@@PG^{3WR8fwr)x{@p*gXKrPS!AJH8?yAzkPGL6r3E~g{e|0#+*2c zq=Wuv>`8mN6lRkXswyUn2UBRjduLW3JUJ>KB z-NRpn9+l(4=|5M5Da453oMhSE_qf)zwr^=fkF^oH`~*By(F`v$uANhDk+RZ$dD(rj zpnLu*YcAzoZWHE~WEH(-sf?G6U(wO+Tldh-k7lkKt8Fbu@#tx+G#{JemSme4+|Eyb zpE%P&Gi6i7{M$tGW=;MW5RNfhN^K8`I9iT#k_XY)K7q1ysbA=TeWT4MYEz<)IE1tx zqfo>%#583XFX*}nC)iltwMYwfvppl_bzpjld9I{M7+3NkFs)4levAd%msHl`9R;1} zeqB#cKXVc!RRBvM;!Pzu^#oo%`RM-rpG*%N)rWC3vq7QvNj{s@7h%NYR}A|N|AU+8 zZF{?~q_D&YPKr}NS@&^Rgkt9l$DMjRh2*19oI1*Q*V|TYN!lcb=c1F8Gz^`MiqUDd zB;hc51Fa0O;hY)W#~2A@lmKwlDdP!j{`_o5%v7z^hKlujZGPAN(>T^JMbaH70-;p| zjv1-1?+wpG&*M~tzi|oFls|fU2>6vHSYtw`eUtk_aM5ax=F7l#lR>jX=LZ`rJ`(YjPK!jq|JcrQr(#5nQ{iRfu(*3RmAkVui2NKe|9P9P>IJv)gZY9oIDu} zFMZ0^ZR33{#+#dZ8td?=3#$XV`p#lkKro>M2n%FQxwYT8Mio@Xav_ErI^ugi>#ekp3u zqR#toZ;Lynfp;eGWYi4}BZ0!|DV-Wzd^lZCpZi>z48!d4jXxtuUp>7V>+?(!I^FeJ z2Ik(Ox&k9J(-=dpW?Q18zdF$S11<(Q(Jp1H=I|;2*PBOjhco}pus6L0CB!yV7IwPeqGnuyj z9%0YzN~ULjaWsyJX$BxkS@cS2che(RsH)kMlDYTo=-jVWqUv!S#+->#wo>p-h?%Me z9+(M#uNJ==;~(wk4k~4eyfzY!fxonb6&#Dz$<4i;0igtGEJA5l1ck{k6AfVtR-xA@ znG=DGAlT}N=OYx415K!!|I=>(S%w_PVbV3s13w>~dDuByOyC1mdze0p6pA$?q zajlq05gL5Ko?T9b9lzNFLu7~+Gl%eO)4pcQtvgu|O|Hu)Poy!3{a5&Am6p1m4V;7jrgYktQ(LNH(-*5zoi3g&N#g(rN!7hn9>(@Ld`bI z4KTT?!j5}wK8|+-%h;eVTd z^MD}_g9h(|()KoMK@hv#p*)8GM5EcDhTO((Y1`=hA!L31%G}vwgYFuTF+1=OiGz1Q zc%R(sRm{tmqiiBz=Kv~>vdT)&s9{wS1u1lyVFAi)qr|Ylw9nvhbwg^lOB}nUo`Q#2 z*Jjso=T|9>-nk2qvh;g1#u~fse~pGGrHBVZf}P>;r$P&UaGhHp|NGfEYIkOS^G3by z-nzGTINk&%8=Defyn8h#KR9`r9?7hVzoJ%>GzAPIX!pJ)>Yp)9qt>E8WHE^F#_zFtIlrH`|^ zP;xc3LFU!-NRMZ^w=X?A|Hk4af7L0zG5ODlZi69`kWz8m5uK2)wtuC^fkRo|TH7IM zD(n98XG(>ZIcfEPqSYxS$t!MvX26Vka3K-aVheDo5#dc)-V`A7(xi;iA>wTlQ&+p^ zBSiFbDAN6bq*3<#a|6Fc8jPlf8cpo&dE)uZUOh?myM*`^!1_iIdxWb6{Euq$O!q^1 zwp+KTz|)z;xE(#Hm0s22T9FJ9kc)de2`&;_84| zfiSz=@YiLii4gwC<{YBR145i4z>kpX`wU*o<|f_K;7vnXu61#*wNFbE>SAl#qya9V; z$x&vk*NX*`q$aQfjz&NMJO}^=q13Rj_`$bwZ|&6M925#J?j0!^;4cEM0c-rH&R%-` zK>e`?bU8%)UH?G@wYc_2#syq39YWtm1PJU$j`R`(*=l+Lh57kfeaQfB4^C_oaC564 z?QcXhDT2VIxmmtUefKF=nd+xD6PBo;QnnR? z;D<1*KvI2xuLL`%rjAsKX%69o7iuB2J2=ySIU0F;<0w`NSSW_10~ydMZA0 zst%qEz9|FnpStqgFJBaa{ks*>&;u zu3nN*{*d6@%>%sDbxXptRV7Jz5@SqOx~Fs`GHb@%>~y;iPqkF-Fj4QfAe8Q3(BJrm zqXT`akLV1WMl9H50FQ~{+nE%)Ysy&c(2#H$a#bk%Kf+T!-a4odT^t_B zqV{--dwcSed!-9zxo}SL9`W%J)9s^~*No<`&idYmG#TU8^LNqdYYj;>k`~;S(+wxd zH5!T7u~x33bMR%n`+=T zfz6Q)G3lU&0wQJ6<%dZyYfkZ9Q=S^BYfZ~4&&!@hrpo!3n{|F^FzyY|k~~+LRk>!I zLwOzys7m{qssO}?zD`+Brv$`9|EF+uy`xAJ9vyub(x?KpExNnA2mSoNjQuSzs#s`_ zQ3J|;;Fn-d@C0!?YtIafWn`}+vWb1NLYf(fJ#iZ#k%K-7XHS4@OgsNE@;$(5Vw)&z z^5%_rPA)_(9B@Jnv7`r@QAdD4+B z`&^FoJBDVTC0;gz3n?dOI{|BzhE(S9Fq6Y%uRmEmtB>50^gf7-zAHxB9kUYMxq7~+ zNQyu$@DUu(VTc_DfFcwu>4k;2(lCJ?*3Ob5;3Mid_N4oLdXlQaoOyz1KXM64CilLx ztdWo7*jDob#}@54j@+vJ{HUp3wn@7e9F@K3x9cBTTU*nD9pSxS@OoxtmAN-7KoF1X zux^HDAMGXV@j!AX-T1efyh0v~2zK4*O~)ViC5g+x*z}PmqwBMI^XAPefLyr^_FfXQ zup<`)Dhvz2$PEJQ0DtJ0#=HU8KW456iStd6wsOp!q8IyQbS|*i3$&6ftvx3CSZL+P7T?NAY9y~sJ}!`t-6kl@h}MD=DE{l}pGLQe z{%|@6X^V3e=WRC-d}ORr3aot9k44(#a<-Zc_HP^0bpddDLbjDLkAw@bNnjEox%b7e zbsR=3e-Vs6W2dBAlM(^2MB$h50`GAm^sUr#Qe%@tYZyM2hYz)5)cpNrAUf&a)``y* z7MHkO;dae~i|(&@a_>!+i$0TQyqKZYVB&K}EEWE^N-(TkVegCDafJpe+f- zD~SR$os{aUo1acfm%UBO2fz_!*01^A_}zOz_;H(=>;QqyNzqK&vr0>k%{=mdR`>4p z$yz3bla;lvdxcBKTr6w4q;ywdA8(9idwSmpzL=R@aW1ZO?vo$F#H(1p(+2C*F9o+5 z22MV}gs*&bhOqm&$mQ_0iVxM2Bg>-{DF$E>BPJ$&`xnN04==(=L%ksU_J1Vk%7TP7 zZ)2c771kAXKX#ETdXrvxD>HVDp&thI=acpp!NUXIn>HZ)xMn(2&>`y_p}GU#fC!A_ zo5@&wSygFcA0+tRJIkTGmp?3Way-FiHw76Mg6g4u$%68Xvf#lRHg*+Cp{-EHcj}+y z$>q3Dbd0+TSm!>hSYff!sQjb!uueebb{*QxxIU7F;7e_@|0-iZjJ#w99nv)X%|GZ? z#gplj2_KU5#EBut!ES}*n7ydKbIh-;zDv{;GCVJmzbKVj6lE?*OTx>?r^a-O^Fq4N zwMISQ832X?8^H>w4S?|l$gQV>B(7QpSU0A@4hUo@6hz_T4*(-VD+0Ej9_E2T1^i4= zP~BLK$G!<&0r2%;t?*o&5^Rl|iQw>O>brW^jS0kq6gH0^vx9LQVL2*0)!*gA-t?m40+{ zDF#^gJGCRZ6fQac@Fk-aXcp*vGL8yOvVVO6QldluNWGtrx!LSG8zigxLL+sFNS0>* zLLA3CIy$=Tqs(jU8Rz(9WhZdrJCXp4Z-+;xx2^{qzokiWK1zB2UW`@Llq@oPQ#7eZ z2CYJMO${&kajQbMbL+#ytiV^Ghtp&EH?w-SO=|Ltn}qSjFyFDCo30f5Uu%Oz=;w}8 zDhtU~PdM#cCJfB`7Jm8SpcsH44>EnnC(;U`DrzJ?2EPH-v^m+PpD9TnjEC09)}@q3 zvYce~7*(bPG`BR0OXu3s#eS2ldT%K0OK23DgzmeIs3#wXy%8Pvw2CTvO#&Bz@3__a zAJ{=F`fd+5R$8d9^6^n4O7;XZu&0S_pV0%RE6B(69hO8L!PN|?eLy~)ft>rFkML?* zT5tMRl3=_B*Nc$3PR-#*7vr}!UiJVHRt*chUE&opWVy{Ye@j`gQl~+iMf!UWHHGZ@cD4ZwOn%H6RKUh0gYU<4Heo(-#RQWvp#4U`=HPuz|M5pWq!o}7A zyS-~~Ec(06zPwS5@=M~B51cQ0&Mk!>11v6ow`l=%>;RoM+03Y%F_e1wvaWp(B_Gwr=T)$Op?VON?h^8 zvW(}sVjV;(I*SYebAp-%CiRMddt!DQ6=u~hOBJ$>xprK-Y(`nMq?;fqqKCv{_V@x>Jp}2qgdop9uV=Yb115-6miBLa- z@%uWE9HkL&6Qd(VNg9md^98}_KUQT;{g9hVHFA9c&(ozvlLV~3r=@ao;aXjUms_m{ zF*8Ndd{k{E%;A_!Q7oq8CBto{QMVCWh_RnIhbslgXJQ6|<{W&ujUcMMDN^GFrh5Ya z^FPP{rQ9MFV@h+f%0ARK&keVGdsQ2@t>MZ0tONs7@GwBVjGF4*Jr(f5;U)bWcID6% z(nrG@*C4!6QfP?Jq)C~4XV3B1&gvRt@EH$@LN_Z6BWLkZo42pOFsT*i_+Q{id+DS4 z>SQ*bEKl{0J6>o>=7w=i2Tf3T&U>v&%5n5?*sDH_9fUzos6Zwz2%UC1)ciA!mI@?n z#h_+7YEF)|sTyI0l7l9_;rxjONvL?u`FEs5gsMSMhNxt)$T2g-a}hosU>M!tmW1Jk|> zc%R9R)|Cvk8pr>&mdtZjAl?UL1ch6jX>U^=E!Q!6*MFX{;a)RF5TiWx?8gRzlj-T@ zPb`)J+EP#e_fZH~t9*EP9UvP}xc^$VSE@wi;b86qdMEvk zXz(zo@;|JuNV1*Twc%sW`1K&}(_h%bPfL=);OoLt!|{;^k?{pwnberxS~jS^(qcJ{ z@AM&_6^OBFTOr#V?`W>AogH}&eRQ+gmH7*gf&-eMfjiDuuG(mMdxTXv!_U)SW9BS4-AGtx7GH({4{*3N_IPWF65_KWO^= zb>AE*V2NbT;mQ!ZUJ-CuA%b$K7#J8xUbq-w50iQ0xfHT2uXFcJhs(}QcqalrVeo3q0TSU_K!G7gWq8uLeet84d7TzC^su>e@?0g zAzhcK=`fL86dMqd;Eh^43QUJI>DO&;S9@^LwUTX+19_PVIKx{N;8%7-+mw#6bdR<_ zQN~Y#idiZgnAnjf%w?se<}lNIfBOlQso$nfiO>C=vmV5aU<0)ZLC;Y=rl)AA7*_b) z0BiX}tPg4!)c*(yA3zRsq27xuS5hZ3Jl;1{@|_&V28b2QQ|9BYGiZE0P_pi0BFnt9 zkletsKT&Sk_N}39Rjtr+k@7e&M_}f;;jO`y$IGtMF0Kky`Tsd7Zh2o4xK8!;CMJqN zayQ;4wMegKte4{aIWI&|1oO}gQ2rCq0OJ5k5^y94e-j!44sSe|rBKMBejG57vP!48 zSOnG346w&6Zxc<1(3!4a>7F8iDNuw2!tX?x5Csx&6=4o0#KU0gdDCF}HY^S;$ZP_3 z%*io)7eE~*n;Kdmw@nz2*-5lp(TfypuD{rT_6^r4B)_k zwV<0nWVQJa4SIFgF3=%7E!Kj8=DHU5M{n$RAQqSutB;B}4)80 z(A1tXCCCr`YKjNy3aA{5aHsV=2XL!8Faz`P?Lj(GXn|qsUOmI~L(0w^{?G9>N5@Q? z5Q#L*-vwoWQ}b;YCao=S)iR^M{7)DGMqy;iaZ*Q)kjZ!E-O|#MiDi;5xGGJk2Xlhv zDHwc}fsP-B+}(>?IiEkD0`Eu9f9YY*FYigw16b#;@F^%%63EcQi|<;dR(y`#ijS5O z-o9Pr=H)ff0C$KZGmh8nM*1A<7vvh1&wM#( zuPd@y$P3Yazc=-rT$-Q~&=-&?U}wB6vOt`U!r@K+yx*}O`}JKmfF(h{ zM*H-7hDKIF0VR|dU?p*VsTzL^8At+|#aW-a4^@F9VL0>=C8GbiPB!)=cBS(jkEPcA zVFwX}Z-Fa!G;L9Z&k)A#Enw4Ht9t$n{EAv?g$Qw(EW!cVoyBsj+D*R#m5i|?c3aKp zd&o<4pyR-*3Di>(SStu22&`z@P&&|zBIZm$+}NR5=Yr(`W1Jb0?y7j&OTd$)tI<{| z`w1o$cr5s~w-e>@L7OE*k^m%l=yk#nc`$Q#XQw=PVPhQ6y2?POh;(b~tK|repbsh$ z+#a>gDYd&$r0iWr_Az244>%o?k^rv*^-jI6-irR*jVR8-B2nYHy{#)49d8c1Z#WSRCwy8rndI9<>4 z-x1b6Tv63NY){VFi!sQ-?zkObz86_xZhu>8`E2(6{rz0g(Ogu~u@k2^aZ2jT|3}z& zfaUo9?LUdEiWVuA2B9IeXljZyL_>?xK&iAfjTRCiDV2tXQYzYe2uVdL4NdKx_WGZ9 zzUzID_c;Fd@qN9HetDkzzV7S#%=2@eS1RI+7NoORmKWN_$B$67UvFL5ERP_G7C8@r zfkL{~nCE;rh+qE>#-nV~-qb>ce#T1Fv&U=m_5yMeEeV;d+1=vvW9MF)3^k^LKs}_f z<$!P~Utf)>kr9W1$C5p0Z8Zr*ZBiw{OoiW%s~)`8S++6atazA8?{_3RmNdp*%?x+`(%Se!~196sJ@t&-54{dN%*tmG7m@rTFjr&P;B! zYkq7TvooTjy+1BO(*sJC(>vU$>c@BR4Gg*kTzrFZg`x_Z4W}`z-%RT98z%jPBg$5^ z021#ZaMx|UN3tr*larHmQ0-yQ@2>l=yUkgUiOp;(3ApI?-Eo;UuU`BxytFc?>IzPe$|?mY;GO8HYw0?b*~U1N)to6gfMQj1%wrB?D9cRs+QM0BWZkEpnPyz=59 z0<4DF#3Dr24}yamN7cd(Ril81Db8u<@K3Ju^R9dlSovzdsor&sn>#iUntUZ3EjvC~ zQ+2Y@c{DS=>XIc_4f^%kD6~?X`Ws*b{9VvmYWq@E6~;l7gT^$@oayF!Q$6F%5v6|l z#VWFlu{$z|?JwFg^n|jY`&fQeYdta9b?4O8 z$C3I8Pw8*uQqf41M&)|3+V*l=s@$)F?g)@GAtPao>KZ&;Zd+{4%vxb-l9t!!3$ zuT;hIb<1{_3+e25Y<=8<&AcI5zxh|n8f)|jKm3#elj=7d zqSgsfRzaQ)mAz!uI1>3?qgCT2UYm_HB3M8>*(d!Hqhe%09-~k&Wu_0dver2Jjpv6gB^kn%K@Gl+U{~o zyYiGtz&;)EF(l0?baa05h|j#c7K{8z2pXgI`Xl)>2C2GJxot}-788l@-kr6eom<>P z2mLl7Vd1FcWNJh*2rvjVMD8pI1qg5fx>!xZZu7t2#EYL`|257W8pw693>28>G)Oz& zY4eV}-0+8&8hf=89f7IL;?gCWP!b72 zNa>Z7{2rn1Y;XvtOv*`>gl%|p-E0?GcCG2ppiEA#Xu;C+_iD5T>b%ADOH&h%9M3k( z2|h^6!CB`UtHq*~(xoWI{9vUdH*3!+xx6DgPL!+tE>md5^0jC6lrdD;4=2gIcmF}A zXy&Nap(1_r;Qr}X7p`@yrDUM1}4FURf^98uQLL;#6exv8pMy%_si z@%%V`{j=QU@#6gr;HDS{8)23V-%Bt0TBXBszxT3{Xoa=PvSv_1Y)2XOFke7S_8Ab zaPQYMs%8X=>W8yu7+Srb-M?IDoJ$b^SMDt^+4s);x%skI3lq%61aWp z#pSh4$*;y=crxCj5l{%Zzu0*pL1T!S7qbIA<-+QYjv`2H0I#F}j=BLBmi*N@eqiKW zBIc>xm*%Ht@~IkLZIEYBwd(i`)KK&6C#{00E9eTzAgWHLN`4TZdEQhYuZj}|XUn~v zapBiLy{1ZbUQ6dH0S>4}uAD4D2{p&KqR7A@hw$pwU-8s>;BA}B&m#guDyN-qyB5gp ziEU$xA&m-P)&yNZP6w-aFoD>Cv|dD-HgERM9Aw9Tt~Kn`hX<5)G3;B|54BI!S79#2 zZc-bqk#@@;rFr#aZvD~G<=bLpYtJn4JaCg_`uN57S>VC_2Fz(g!@swVoZ)_C^D>&b zP_*0mt!5mZ)34WsU2Tqa9YeqNmZ|2j(5Txy5L_o!4q*Ys(X{FO);q0*68@Ez4c8YI zI<7SfEt*Y5jD0ioxc#BeDYco~_zWc_jqy*K=Jnr}X4+O%c0DoA&CRW?s}p=N%889+ z4};}d8kWXurJrRT+3b?SG^Pg$IeDwncl-JEvbNTg%$I05(I!WJUH=I?xO`7hMUK;z z8DTbcXd~knb_w5Qgn%EJ3Gn_{OEf2FYH}xMi^xd!z87XtZEaJQe!*V7>@5aXqq`^?tz*#1|F-#7ZLq1J z!tce-S1*1r=l!N1dCZC&Z(Y@^6V)=XxHm{jo+U9q*>8$XdUKtjOk(}OtTFd!*-q!`~xlO0FmbaUxEFSo5 zp#IXubuhuOQ|gMOtX)!X(%l0OjXN(`cfM(qY~03o?(v}IMVVUcFB|0i(#!r^X{fT` z)&bT_S+`fh+~BQw?Y2~!CQojXXc(M*31Wh`8P}H;WM1U06P8*WlTF@PUAxN!dn*Fc!qc zl)q-j=|OWr3KoUO!FlQvPl_)*{e!s7oiZM!;M5BvJG=Mdl*%aA$1zm_ zx!@LnYR8}6d)T0IXIS=FU<|JZyA6tLT8Ylo z?-w@GJdDrHWj3o0m)FpsgPke6Y88?KhU0+7_?mU%Px*AG?{g_#HIaNrfC|r+A3k`n z*7!p@qKN}}V>jm)AfQSN)(1qMu$tTu6xY#4)1Bj6`pJdv{M45j{OcZDf))-JRSde( zmqFGOz+0Je*X_n3M#|7~Oq%_k#8QU7W^yKm5wb0E)&a?%d;Z5Uk z&say%rX72B@9uclU|_r1c^bLMP$;P`^?IDy4ALCRxzQ>$Kb7NHV?S?|)0t=#M!o3a70MEZ+R zdkvP5s>ijb6V;%Rj{vqaU2Iq?wR3F;$s{SSkG zAu1&9dzcaV>hj_b|EoYEyzWFM+@Cu3RT_$t|HGq+;L}qbhR-3Hy{m6qk7Rbu%7>Y2?btEC$IZG>gW3*6y^X#K=_eR-6hCs!!n=08Ah^3{T;zS z=|LF4ZJ$n1obT{C44ngO2Y(d>P>anum=_5ZACpCBoL0aDO{GfZo zOGt3T{m_NlW4hNM&uRQjs#}b1p?iLHI!HnVQvo=Ti%&_};P2*7B1MsuO37(hSVTfTsfRC<{L^h0XRiA0Wr zX}|2;a`kFTSJHu$E*~kKE}=#+UwKNT^>*mh93=}@Yl3*1s1Smulqk*4W_m1$Ajj%$%xk0gjKrp9pPDg6917`N31H{=gakoEu3xMr!A)hg=2w{8 z!!jiPSTmx!_P4X%RW|vGw%b|ER)+TN>%Xd`TE*uhRnfqtF0*H~GM+-9W+>%aT*>R3 z+%=Ovh8A?|v>$$rM*2ilf{kpYzbEN*iKy+khtU&6$vR4SMw6Z{e`N#&>+>of z6GSyq2yYc3#io`;Cw;gytl%TfY{*4{>l>7(7n8g>ygXwFA<{DmET{FuA|PY-*R zOJhD#a+;dfGmEf5gv5tm)siM=*`ZvnZ!vv|7_cdD&2Ah5{n6nphvAUMBu=H%lYzTW zI`|F$d7utdv%8mw0UkX1q#lEZX|{K{PJ%cwv$>6dVJG z@dZP2>v2?o(YK7@Cinh%?5c!T;SkG+o-U0BrOveX!E)=krnu!KDubMG&f6#KE1xW6 z=uJ6J9dR=gP%!@7cw5TVoyLQ1p`;wiTrDS+54+Xi&0O@_I>|QFH-5Yn|5RDIAF^91 z$E-F=KHJDg%78o^CeuYRFvhXW;Wc6eK_Q{Y++5wEO^q6=5?*a9%QHaqTuY3C?wv0x zhwac#rj9>n>H!MqE+47I$Q=I8nn6NSRc$cpkLUQKDEzktrSad^HuuHxlL;}|KGTgS z6!lonYZNzHM>q1=WG;KuwO8zyky!R&1xAmNp^?Q~>AC45z6rPYd)34;eIBy3UTPEz zOCE@gJ0E*g%H*g?fk9B>XW50&ts{0q3))xNlqlpXPRT5G@95=-syb=7aO`5fs8UuA zQ9rXeJE`~a1viaX!d--;`A}4hMSxjjw(T49%jLHiem<-5T%~tks=gq&N0px)lD8O1 z2TM9V^c&L~#rqHo-6UW?m-HbhvxceU=Xn9;sxMzy-+5g8o?pLG$?Bs zZntbJXzgw5Q~OX|Ju}NX#B}W`YTfaXt}DGzOZV4YRWyq{^mr8gZ|PNHSXCyB*8=FjZbyIGMPJYE zS9kU(h0NZI?B%{Sk=s4*p|vEa^euVERBMgcVXe$7k^`>0j|X01&FR;hRA15h%3JCg z9%mjmmB#NK-oGFd7(@NBe^K`K_(1Z?_5I&h1m0a3g1C=1JD9LYk(&=f61r-Ei4A(HBa@Pg{IUxhICuD}Z24rbD_vjB zCkzZJB4#@(CWdcMgs(ew>J+6Ttyc|>YFjpTkYq>dp*aEBFsNM-nS~* zAiiHO%bKjJiY!c4UyzY9U173jXp{S`r>hG{F{-9%jnwA z^#xmjC*owpXr8D|XW5&i9%M=s&{__ydJkD~X>fIokkI@pas3W17BJIp{SN8gXuR%Uj6dE7?lf&ex+bas`>hrR#|EMLNqp86<&mo z_U={U5}dmKegXbIMXbss@lH{6^;BT2|4Jc&UP+@wA5lz5|6z?9`f~{v;l82Ua3-zT zDU)!I{CC`7?*)&pW%-i{D+P{h6zu*1Eefo}?O&M}=TGdLbnhrxms*L@7s5Dmi;0Q7 za6@I_zn5SLywl!>emhC3U47Qk=;&jkLQ511F6)I-YFb7l`*df?n!U(Va8EBaqMwqBfU7w|_%f*qGem@isRuHRWuQ&Y z11(?~glk1?M+Jx%hKoK+I^`YOL3BUc0bNobqDwtCSeKwdw*A{K4kl{c<9$e@rs|X} zymxD7N^^S!U{86$c?7=i(o8WHf+eyZsN0A4vJFU68O$NzbW3+<*aNl4RXzo>ulR;4%#q|(`_2mtlum#9ST&e8ZgzG>6s2lWapHaktM|)0{ zpuOHg7#o7{WpNd+33+1Q0y-(i8Mt( z-#1{i7$FdO0pUuHBG^TfYu=QUd1v?zM44RYDh<7B&FOQo057p^J0O0cK%jzNPA%gz z%>4W#g<)K=zwBUCJ({vDqDLZ zGbuh#9AZD2Yh;FJ&kCVm$x5=0YwT6cqL3h#2HO*Lm#LR`l=aQb%zE%<4%}ghsqo~6 zFC%jOTD2XYW>)M6zYl}yGaI9Wf+2v{T|vW=r+iwC`O^#$yZ`+-dL*$j2UKX3(W?M{ zB)80A(@&@yrNRwWk#6pnWAMhdKbLLYQQ}xeO$2?v&3qkRqjTP~`()7PHDk{kd#jP~ zV8b316cJfSG!@uOcxSwKL1AG+4;H+xl9@0W&M?-ihc>%|3QA|iXki&{Zzi_e&Az@q z{Xnj9gN-!mDW=|HvP1-wt5=$lvQ}Vcq5*QLyorK^knt0EfEqvq6{WpwwNO|yacgz;AISNhHXcvbA8oBtzW$r8ZtccDCM^; zEq=ZfCu}iq{f=l`3DQEz?N<~Jq1q%-FP3@7vd*LFMI3LX2g5?CS{Ut+-dl4T@)ZQGUYvmXi=pIJ4eUp=xA~v3e?$_euGKk z!>2D_di+1_nq!WVz&Jf_#^^9j?HdOWBrQTufF{&lR1PMN>T#s|iecu}R&lV_Y-{%O zRp11Q!p5s@eT!P*%6bl<2p2(Pd5A3LWT0IfmlAe9>j4!-IeHb8E%#PlOUL0RkI%(C zk3ELXYUBkdPKf5MST(+h)C>B>=8Jeg+K)>~H`B5?L*62;#$~cfr1xW5-kKtEQpvCD zol(4%xl|OgLW%ZxbLwwo&J}BbTDTRdWoH6ueu^&!LQw?30+X$T{0H0z%Cb3RWUzjGk_@QvBG+I#di3ZRu$^6?(h;>EphwT{Mzmr8@$cbAHp*w&4k8bMI{^KP zFV(p?m9P?gLYXN?)P+GnJApHz36)sF+%@K(495a}S}mg9_H*c`vb2oUy@J z@yXAJf1&@0^=Ja%X%oru5X@ESjlui@gc+J(?D%%^kX!22)|@b8XM?*SnPbS~BFpyUqJ}v59h*7K->x8&SHO3-DO%iYuQkrdJtV z!L94AMue1ww6*bINiD~yQwlFXfAY2k^D!b1oD|znTxq}oj za+?a<7*gx@jd80s=9CRp14f?d{Csb!A@mE1jBnY2+iPzlaWLtJnCKM5#mAc;zaxLU zc|l6=nCh+K2mLvQ;Ngt$H4k2p3yhh;k*w&j9@>B40Nb5U59vMImZviv4GP`eHhID< zsy^iESJ4TofNNtd65T>pbC<;bG0nC1yntY3nk!Aw0tx2nx(5mivJ;u%gf%HRR_Mu= ze2kb?0Y^&?EDzb1mV0}2@lb6)emLKey-Guq5Q5^0*-s6G43%>PRP^d}J7pusN<`aji z12?*bvc^S{MqTuBf&0>RO|VKW7*$Abjw4L&>b2?T1N|bXAxIgrS6)lzQtDV9{(O{_ z%Q&=C6z{Kkt@Y|g@ux_<&Q07|ZM+au+e!m+8k@WZ|2DOwhqgcu{ZfF zFSQ8?F6={WJUi>8{9Kd>fTrwNyOJD zQg4z2ts;mGr6{wm8bVtg(E*YrXg%J*+!7R+;5C^{=HLXgP=yBbDUS;6X%-e1nB8KG zcY4FvLr2H&5hdvF-d||RvH|aQNsQ8?vJtY{`g$)29624&6gzb2bY?58ZzoqN1&^?5ir)_|(A!m}_AJ(0Ii^&`}evH(GCd}$A@Q)Nsy%$&*Nh#|62 zJPL8mAF$v-Q1j=qhFHr^NmoWg*V;$^Ob7@BE3H6)I+#+ps-n@!#cm5hEJFB^Q2PY{ zRFI2Zk(6cEPpc9k>5r&?I~MOq#!iQ`?NYnA`&;D?0YUL4OaWj5o7bBmMJ<*^Tt_tO$X zFhqeJ@GPc1D$jk15#mSdexc03{=<=E-T!rW>b|5f2^URd1^--8TaEvIIp%AxSXlgq z+U48KOdnU#*<~2Bt)Vhda6I2x=9iO!(71KfjpmhS?`o5^zByBOtnKjKo9=tR_%EgD z8tw{+Rto6*E?e1f<<6fYu==OWEj-`q6-C4QVAoFwB$UOn)4eK+(L8r9L^mrvI+`;^ zHfiQ*%J9{@A-AXd{EkVzEh~^_)u-9hD*kp}cj@teK5g+ow>vmARECV$AL1kLhCP;2 zRseu?A_Lk&BW}mXk-SNj)Qu3Y`|e4#{%_wxyhZv=|LlDK^CB(Q74f&`tc#LrZnDYGge;#e`&_AzS@FslIMpbvI9n~q4 zUTu$6i##MP%Xy><7;FoODJR3{u5#CZJ<%FNPxA$4X|bW;0sg(zwf{MC=4(Sk7`>t@ z4j3t1Tl+phXji|&#w~4E$_kYiSSEs=k&!Sx(D}{VpV+S+D@%XvSAyvrmZZhGH>@+p z*U#@5V6d7=+Bc%2IPB*YS%FT#IpqG+Y521sOsD^|8f=S89Mp9IrEQWzo$1w7P;yp) zx-RE=-_mA9PBN{cbZF+eUTzE(y0Q&@ocp8hGr527TD;89Awrvh?rbb@6C*%8LUq}0 z3l2$o*|e~OBG}pSDl5ZQ9?Zm)8}K$f{5Suzh~^*uT|^l|bQ5emvCZGvK}1Cw+nr7q zcCbI|an=^cSpL&-mX|Mo6+gV#ipSQ@zb<5CWK_mq563XJH0ohUWj`Mx3_(t!Ty3+m zG;6O=7a>m&}nG1Qm+p7 zOF540L?g4XFLt9yx@lDjGE&^$ECg`)U~&JwsCNAONx^>^zASua{ig7rMCy{$7K*Y6 zp_!;FnmzeN3|0vVY{{zH-2b?v|9s8^7*nL%Ydot5!tPkPPlm!Ze|@*FdW&Lbj`s-+ zRW<&*IOX4rIn6z_|( z{+6}rdQzA@wQl0L#JiK3tpE8y!7MI9*xXma2PG373vy4)MzSA~A|_5jkD-aM&<=$) z)Lid~QlTd|Lj=x?FEK#?4L4;-`5@yagiG6KzCES+=(FEOcS+ZRS{Dd>GjkmjKV;{AiZc?0nyi8?bTm^>3vKTL z^1o%)WlXK$uckhY`U(MhhX2gIdGqGy;NV~lk^}hkl~J5Czn$}KiZ#;~QD+=dvrL)i zp7Dh!u@NxqmbiH&BIX$VIl>*|`9jI!FP z85dE!pSO+lwCGuvzPNV2NyF@0?gcWSTdMc-e#UJ>dlCyC- z-T#=@SRR5lNRU$<54??dGhrB0{yF_6#nNX{Bxc~z+_h(qg2kSHKl|^4Uki)iS4vAq zlg;S=J`5uYUF8l@=K;FQczwS((Musu%R_Bwx_|beVf)j<#oY)IZ=;h$M*4oyW8=z% z|5#%C-15Tc-Bav`(Rm^uPK1R=j-8-qgceY`Y(P~r517Mmq zqcl?1^WYic58iE?dBAS{&sF>2kFU1F!%}cMeT?+=^Ic1E>q2;=LU(mzU!}Ia6`gy? zBsXtFn}#zTiFLl0XSTXGTpCf@)$3L&;cqz{$DLevA7Nd`bG7K?po`C?h#)6*kzuvL zzCP)bCsl*(Ux@C!Pe%3dKi^5SPKK5lk8Ey-p4roKVbTMWxqftnucb;n{%$#cA-(Qb z-dPK+7PN$dkJ|6Yot5#UO4C13pGc$&bCbR0{I7d(epDHlWviMOJdg?d=1U@r{@=$O z6B8^Izjd3-O-V&hs5gFNyGSaz1-=f(36;Gb9 zaigay78bm$PVHo=N6b?Smvb7sO`G0cg4;E+{qWDRSH!X3qV!JHuz6|lnS7rwwR__% zj2SgaRAjo+X<^zmwK*kW`%n3S1bw5!?XT>vV-DeN)rCsb=~1FGNk!}aGMb& z)sA^dWw|=Tdq2=_e194i1qGDE83>j z5d<4U2dEx$3Y=HWzb+-)zmzSpP2ujG6B#M0Pu`pA@&QuYn~6})HX?t1Adx+c?Vl$= z8Pj8}y9lv_3XjHJ8JM4u4B?VZM?fxf;Xc$T{eu^O!2RU1M9 z0a;!=AlUz2f)`6Bsi|;JR7X&-(B%zsUTtT21sF$gz38mk;gr|Oti9whS~RU?RjfN2 z@NJ!Bwd>WQ$k>anOM`|LmYJ>I7~01uTRYTLD-gQfwbggbStmDBVDdhrA+{@!Q>B4l ziIz+0X7PDz7u24+Caa}pW(l8D#r+t3iiB!ICw`{Yj9~hWZLi8=`+BJ&;Dz5@Y2e4e zq7j@}W40|f+-%(?v7<*`>3x>!TpAOdUdh6K&Pta;br&l zyuelqJX3xUQ;>gV8^4|}QNa6AReWpxg1GWL0y5}7t-0=wvOL&J`56cNco$sfoa%ux z-KP=T9@@4T+xY8Y%CO}1O3psP5a>7eJa1Y@G7kv3-R0Ltle?5t3b9Fp$$XEzjlZ3? zY(sMteHg#0{W?Kfz{N}ry`j0hw{68|a6tguY<%&b3dUWA)jj-ll@F>H;y-t`?BLMrr>0?qAWKbZmSsz-pM}^4&QepE1hUwoNXycy~@4-kg?J%tYp_S3M zH_>ZZZjHY@;HG4;iKi`Rra4&DCJI}>QrMW$!g1Gp&afPPFk)ngIK6oL_6(IhDCgoY zRAXY5pnw8p8&Vd`$*QqwCY~Mo*M*ab7L)m0)e1zwFPdC8F*14L`2p*{CyX(l>8 zegj&1w7DcA-E!NsfYdU<@T~ay(@^;+SXokpFl4(;?gE{4-mf6tlB0EEYS@vB#8d(X z=S@srwyDLSJB!B#plkhW8Bp^w8}~Z= z9d+04`s0Y#2$h=)j(o1JZu@wdu=(T%_U$85_m%9Gnn(<7szjMQYpQ33`i7=xu_%+f4;V5ZDbEi>LeLbP=4L2~-<3#2-< z8qFOCiU=b>=jDO(-FLTqVj3tdEdZ|XZ|6ps8MPcLaA6H{Rc{mmQ+asvJboXT{o%39 zO_V>N)hRU8*!F@`??MGE8(Ob@vcHz1J&MEgr7Ccy#y=mfZinRghL6IfLdpw7%-8cq z-~rY>FEKg!yVua4A!!0OOGvW)t)xeUR!F#VUc{ZQ`WN=$ec;dS#{GpChg5Ji*81MP zdyA-_1qn zJrTH4ps2vUd7-?lj5y`xWJK{(YQ8q0>?*0qv2a0Ozc2m(5jw__HGqn( zT5>_z0^;f8RFGhMWNs;O_omtRj>*lvuYv67fFN$eKsIM};JV6Ej2KfuDZ%Di z3I;!}D>KmTQ69^&7#=5tb4K1hdj32~hMu(9KKZuA3_>#;|-`zXt zP5XUQW|83wqE0{nZE}Qnw>VD^nGt0ZWFp-M$G*0C_Np;mst6^kj&xh;U9cV-au6d1 z`r81wCP?Q8W5<7CPF)mtJHLSbiFko392n-XRH%MC2Zo2=$2_>cuB@!AbZOyT2E}qu zGsqeevd*6IdpSAD!8N}%)E+1bn7zC&5Z}St*AKb^ui(R}cpp4i&!LN#p>kuyV|dy* z9jXqXLi4S{w`~QbK_2Vo^dI-YakC3AZ0Ph4XtRLz^=2{0OWGu1apt~pO2LcD`A+}F z#O3TwMDUh~OrM~YNJwUHK5%D=ESOsu!~?Y-B5yA}SK(e>N{A!i11ZIiA9gag%~FKB zriru=vmbx;8HiKO&8Du0konAy#Xw`$?1dVf*mkwq1KNaM ziSC2bXTZJyWwKNqdkps#PQt0hqs#2XyjW$m3yMsCgkrpCe?kJ9A(y08s6ACr_p)U0 zywyM0r75aaf7HE7mk?bm3S3bu8l-oZB(tchF-IxKd5d;>aAf5D$_$R$l`CLzrPfT= z^Mg7!y=~8DnutR~gvEitVVPOPl(!g0mfDD~1+JUT!1))$J!TOV*Ct;9rT~#zwXf7# zSA|1wC5Mbhx^+GMGm3MM}BpqIg@-t4b_JY|L>o3<2a~js~em6O>ZCm|>P>PzytKgD%QUK%Sc^hd# zYi1f|MgO?g&a17uj2avBuOd!B-& zYl%mShI|u()OlAYrmxTuq`~O**p3MRXkInaAL>*ag6^P_NM7#jaLoVSSPT@+`_ z-^2$MI(s!eqD8Mdjv-GZB4&c8HiS+}MkyNk3#hp(tImcfrjlE&v6O^U; zwnG)E3qeT^q7bkIS)Tj*XfjFuk4mnrs{9u+DXG=stO*awKV^GBP)5kBt}>Y|coweT zg784Cqb;l^+i9EwE{scf;mLysp75}~RrEayU&kTLAX)kzqR9O4D+|+8= z;G)az790y zoM(0`MsGGr${Hgzr)fqXxXJ)oMbL?F*Vw67S-Qk{_ zobAvvcfD$XTa2aSVeeh3F_i$w`3+_A4pvtkB~j*rGAX~2H#P(_Xp@24p4k_yaK|0z zibCuCXiCMo*j9`U#h{tnI|XRU^Ie86F1g6R!crmG#ISAK(G+8U?s!oavTE~Qb${as z<7Zzy%`Acs)w%^!7N1uGRaEkMt2`I!BHL@HW@c7U6_H0s(_58udT~LDL|h5CcQ=ud zJWnbpyg!sqK`NrmY~v+KKQ_@Ryz(fx#G-lR@RiO5kFOI>;>q{J@R7)flaE9LHLEhK zUK&~6$nRfUbJ31hJ$`I)E-U-ZrR}-5-5eb=uUPECsj&%HopPRam7H60*W#n!lx@Jd z+kbk8M+xuhS9^BLp=?OXBDNAw6%&bc_{UgUvu8R2S&&%XodE()&6lrfe!F zA>kuK%RO#dKXVjtlKK5jeco$>M^pIZeQVL7O}F+uY8<=5MQdZv<8Ovv0K*+)gV1w} z)R_``7ptg~ueeWxEd9Bng(%U^#KNE?@vXpZL2uOW*SM1c@5gZ8>?ASMa8Nnct_f!g zS+{zN51wyuT0q@2Mek}VTn zI|jgUm+!9gT(s)8w&{p|^@;&oO4ai?x7t}e|TIDx4+3t zCORAdqFkBC2l(~pzdB9ee&cbG5YffG**`b?J8It`!HD)#D)LyEUKyl z!^3CsGBa4H=&*AAXl8x29y{>!+DL@!gx`HuiTzYoDPV~JI7JKVH8DA&S*d7Me3tbFKp;Bbr>awS>SX1_A(=6$?`Yx_Rnb#PS*7q`tW18KeM;(cPp1 zDPW*?hVO+gWV2$)v)?mO7l6Jg5&b6A_Zz^k(Q$9iRT64X0|*xH$Z>p`x+@WYWYKN5 zW0Z+MSvOM!+zK`ZZ8jAwsLxuLgyOUi_lMVQWtDQX_yrLzX5Wl8NYV0`kMkJFyFcIk zNcDL{W?yv$AUyR=O|MV|u|4`;pcP;|w9>S`a-@Uoce(_~6vyEe8#3YrN}rCt#Z4j! z@J%c%-8LkV_Q7~c9zc^6ZmG_y2r{_VQ^oi%<*JTkto?bwawS-|Q#Hu?gSdC1W@F`~tj~Cda-J z+F{gd?Z(y;PkY{bSNld1N#PCe;E{9+u3P3>?4&FM7gVb(o2RcS**x7(@t}#fGG|wR z0tgk*gq_;{dHjs9Yr$xU{rHlH0vHJihKje>rv_*$JrteASwS3*DxEUm2zQuA?(K(4 z?xjop@y+J|?29LpepJx~;_zphDFzZo5gIHT?olu_fO2RcTdp+7z0jlXhz2+YL`Q_~ zJDzftY>RIY*w4+ai0tBeryqCc7e9l$a?Om@?|kzk_AK)Wr)vjIHJDmzpWL;zJy(Eu z9Ma+2Cfi7)q9HYP^$Vfzv@VDs0-fpMdAZ!;=TaU9IOePYipT>H zZwI+bMjUZ_-{03)!;_N7QEu0^V|dF`#;_fMr@SKkpT)d>UB#OXjz-nF!diueMX30O zO}KG~!p|fO?n z3a_}Rcel|)?A}achp>Lz3UJ<RUZE_XySQO?!fZg1+=kKI5hg0P2r`EmjMfoG))RDD`5JKha1_TGN9x87dBUoq{BX!;Czb+#|H9csW&R44 zo+ArG0|SSASWLIG=TzWxl$G7wmew_A7#XGmS21y=H! zeJ)6E)J1nX7*x~4Ea_%mtxvC(OaudrEh9d!3k?&G3#k95>jZQnUihr+Ubu3kGEITX zx+!BRPltT+GePa7B%n1g`Xh0aTCcm5e&-P|_b)n)YTetLEFu)IMnRjzP0 zpmz(z7}yq|_PyKz(%btXx9AA04|fa5jxuy^b`aV_!^2Ow;EOMTQMreHdq73B+TNJr z;$t}YeA;iM4d=f;jp=yP2XkwWFq`INj0bqX2n*y>3c|Q+{_^r1G_dfmqN8Qu9pF5^ zqc}K)>dJ?%ar_r-rM{Q`G{}x%&EedVQ4l!MP_h>Pn)nQgTlfrcoO^TaW2AhQpRW%G zfUN}R?%|AqZSd#y^)HdEC15HKlM47p&|y5*Vw_{}=v~Blfp{nj+ZdMC%5l)3CUc~M zu2tptvX>0Iy`!VpB>1q6e@X;q=L00(+k5e?+Cc?J%rvEUUmI&L-Z%Q{a8s{`u5R<= zQD)Kuad^WmadC0mPv(5v$xIxHtYaEWOKqbwDX1Q-Y*&h2F8zXibnDiwm*~D0SlnNA zES}wF&k*zoh@qjBs9BNGxX$vHN} zn{zkxEk{j{v<`-BPt49f(y`=!^>FQ6F~0Qwu!Q8Kz)IAOf>4giFC|O_lg8BQdOZF8 z+(c)vDpfnkBn&inF1xmFcrHL3aoFh3MYO~Cf4lkkhRG_^XqP+N(vqg&nNlFx{u^tQ zmk0DfAfomsyd6%HNE#cRS*d;MfBqa{iXfgJUv|{Gy(qq;Fdj!RKA}G+jYPK%zfn{3 zK)^1c!}Ah?+!8et4r~#e2$8&qo}QlDUFsk}Luh)^={3aM6{#FA&o-f~R?Qo5S$sxh zCpEf7pEfd+lRTg8#=W-VP;zAwQ9V*l9?Yk+wq;oAy2;CzJ6ERtWN(4%B)pBa{)+ux z5-E6&*4~=giaTO0zjn~O!r0iJeYVneW6$WZPjR=&=isUd&)0GFPVEDuz4X`C9mF7B zm?aKR1MRSB+y^LRGHl;2HW}T@XMF1}j@iVV>lY_GUWcEEh@M15jOKA4HSFqZ-$CX0 ze#90kJgAF3Y8XTyr;b1sQQ&i%h-!l1w|B}(`MdjPm%ec)BHjRRpHk@zDkh~29AJO^ zh6>#C26cq9SU}IoqdBh|2U}ZOlB`8}QyK=3PCK!PceS>`NZ}6l(faMB-*lw;+t~7= z`^s&PY18Pz;r6bXg@|Uv5R(M9oE{C5msddvPz+MZ#6aT&ol9Q zz~6%{^cH1!!bT!~`&3=+Xc?E82}Xbt1+y=WmhvgacDlf{pG6>hSgW+ST{}|k!@Juq zIMWE8W5hR z+kaww{0Ckv!Yfc{;NT$1LR{Gue9}+#c12e$vgGcWg)nPlajYlePiq4o8TN+RiwM}0 zO-k@KBsfS+XZ7@W11h@m!aq!OVv&&3ez}s~WzK6WmDh&*r|rXy1&kshd7S`IH0p-GU5gh&1{Rpl_~B>+-#68plzixeGo zqYRBFnAL00g!jB;G){j5+P*iR<~vCZk<`RC)L9S==NeCT+Lt=d6ZB)*AYV zujf$JPJ-oOu9e@hdZV8$R->3K6d;C@6B2azFQvz9vvsAHIq+O z)t{U@awu-!9}87~^*fXlL}=NntUPeUY3(GtglS8u4Qb!~DGH9zdddYC+SX108z8#?bXvePiqm3C$frvPEDUC0& zk*?OPEm+CKkLs{}Ca{dHcEhVt<}RVt0EiAwI=2wPr`z@G^AiwoQ}p)sHejN5b!R+0 zeA7gyddq?F`=K9tC;L(5S4Vw{h>lQtq+u@u_E%|RC*lC^52!<_47X%!V3!g8Nkik? zsm+d`Hf#&&6?;bHisFT+)9D-29jxsV>Mf%(@|z%I?A50420&iX&!JgT#xc{6p=faNBBZ~65DGJ19Kba~uRi~liCfN|37XqvlY#(L5SSu-twqH-TF?NF#zrGzWA{Qs#MgyA|+w#IoC(odU zaS5#$rb7;Z`gaUaUJgm(e`@SUrTqU|dlPUf*Y!Xe2UZ z9(J{p6gw&{nM!2Hka;LHN{NzIhESPOB4i#*QLTl{G9-zWIkAi_zVlvazrXMQe#7zq zzUO$~z1w^9tY_WNeP6?Qp4WAmJID6z#o#&zYz{OkHEgKS@P~bWz__#j^zJe5P`4UA zCz;Yck3I%otR%J}qp0OvsP$PJC;9pV_H=?aCGWgrf!N-JiUXi{e@nyG_9$W;Hq^4? z2`o;9*W?2kUHcIn5>m8~`FEE4zC+dJ?cSFjH`_SBp7AQN#7F|5mV*#7tO%>^SU^~7 zcyx1MTxDy;mn6#(oXbM~m^AM(BO{{*)|+dmHr{y`Snr+VM6C9$kVh4J>&-1K*Y=;s z=I)la#vhro=EJqf^RcBBNek9yT^LgNF!#~+BFp+6Ql02)rCJ5tKu<<*( zD4YS_l%2lH9>+de@qLJ~Q&XSD$Cn)SggRJWsph1S4`gX*I%zpXh|!An7@Ag z;$N$H-uZwWljzsyPZ&N34Yj1A2K<92^jh3P$TI;;{e!Bs%&e@cva(0`$|NmCtVv>& z&shk>Nb}>JC$dalUHSt{@6hIs?5Jed+_`g8&VEW+E|1CDm1Sk?RWrd<;U+{(3Oh+2 z+TLEe`2d15-U!4K?(Xh%zJw8gTlR>L%$(hT=gC5z2;X@W$|?GSIhRZ1;eP+zaG)HO zo8*T!`_$IgKf`WZtK_bWdCZ9j76PNjc@1H-&#t6Aqp$**OB1%`o-AHJCYa8Je)+yJP_D zjN)K{V!-@Sls!NDoaMJ|-)`q%RcWLB7P%n)_s6cx$-lz#`i@@aYaCrt2AKNH!VChZ9%Pe%nXAy z*G#pXcpax&{_*4D8Kpe0JDKKaKmlu9rRUUW%#{Tm3vNy5WV%+3Y`X6}5p!vwRnOAX zj{{iS*k&euUgyY>NTij)d(Qn`@U-vsLj<2fg3B7KO^Y_EIyE}nhs-X;tYVX$X~U@m zmgyLXhccuP`#6oaZTd#47OvE9-M(EdeJ!V#82n-sT!!6#7zC)LjI1^u!=Q>M^*2}d zCV~d}_5-w^(vEhW6OIL7`Uj5y=?QTBIT^VD`SF>A@4gI;(S&Jr7S)0|FgIhKlm`dV zAS9J?b9t7KRG~=bUe~j$#PN~rz`jV*N&aztzq9=Ov?UAYEcf2K%zN**KId=!Bl|+- zsNWSOdEI%12c-4Oc0?lMcURc8F{0*+>yS95MvRwB&Tq{K&vh}6)J;Yq$wvV{ zP;6u4L?9P^!&(Tx3%svL3qAxOg}kDK#1T_U^#NMa*ExP1hS5ouV^=KeRfK4+ z3XA7;NflXd%4?eNC5dllBo)5TnW_3}$Rje?)ayK_hg6%}&V6?mB0eYEHJ@H60>>N} zg-lKx6G`oZ9aLBI^6JXpYjgu6;`wPC&v<^w!5O6x;opannPFU?x-!U!TWala!=xx5hGwr20xzWr_~!>)M7WB=wUQY!G% z@yBa9JSk6+1YD0yUtc0)*A@^W$-%Kn%hc}_C}jj0qW^CvRtaxG+G`%bL3ErU?Q+7-yO zaz}llQBe!kxEpYsXg%tT?jiWfc@w9xygqf}CPKIu?VU&xCa>GP#5alF1e3(=|JAW8 z(K72iGze1Ni%P)Hyh;)ppEZ+X6*Vku{O6&r2YC%b-|L3Px&KeU?ioYheMCp6j)okX zh8q8M%m$y*F#x~vJIp>HvJijwm^g8(6)}i<4J0i5C8VYI=X1BL`12|W9^plmVK~$k z*htG^pa6AXwmTIP0dV0}kvx@<1Co-lfU}xyY9Gix1vd#>aAr+eH|n&5wDb^Zgc^m@ zGZLZWCbvWanAK5cc`HSse-x^Lr%_SHyKANnQ0!F_Hze!AG%isU31XhSi6Io9Gk6~H zbL0;Mqq|e_a9oVI1jj0b;?*H3A+dP>mngILasPQ01X3K(BDn1X{@h(>5r2xV@>yfJ z@ak>=xc}_gbD7A%=}}t=GqR&eji-Y=UWW zL9E+(aKi5OYTg_5f2sQ`4rP>@jr?rI8u-f0<`6GO4C?@Zk2RQ;cUvs0vq54PCBoOXAXEPOk!dWm|p3w(lAJs{Z(g!md;^s|28I zJ(50~m6Qx%mQ8q6g?Iqpl11?hy2S+}uT037v-R$8;);%Mimf2%G#3Yl=4E3_lbFR_ z;lt@#{yn*4R%nB+`Qdrm=clc-BD$6DAU|b>sxU$zd=>uyMEKyfiD&~keh@d87qiYH zK_&rNBXBmP^(0Gyp)~`vRN}0yt=*u0kMPkpj2p|hlROmP-5hinTq$5Dhe9A|Ft-nC zq|`9=7uc+BjdH>IkKZEzfya6koYYRQV6$2WNiKo$fUQGgdNrHts@V7tw&`3F{jcK` zsj|XbGf|)d;0DCz%8oaScXH(Wq~#KrzmVA(bshFt=B3R^J#9HPOf6Gmg!5Nr{EepiRMTI|Pd8@aB7m>c-L#F z>X?9IQVm5C%V4=r$ic+9x!^A%W32H;SS=yR`5fXt#uN{QMm@rs(C=*7ONbEp()aIq zB(qm7&ssJD5MIwHv9}v>&mS9&g4T-N)jL~MMzX@%)vZidY>C!jxG7wopDwc5h)2=U zCPN=Te%uITSF~tf;=4)k)-NV1N&%dg9aInsc!=#gH_znouiKCbOYGT)#THZZCE;MH zxVZT8g>$$ScNpY$(WPcR02>pZh(TK<*n+;~O+%0X29+$YI}28G()b*|G08D;EG1uG zG#DK(61NiY7(|g&QQ>y{5fmo4AtWh`p|P3}2RyC!b@0gj(8D8X7dZdMF+pNa2sX&Z z*OA!Q#1!NB!C*yUVhSv9qvYmKzy-0A8RoAHKhAemL^@8)pPSp*b&JWEYkC2Wu3Ib( z3Qc>1S^w-zmqHygP$}_iR$Wz9{N#2Fjsr?s*+-m8 zH77INJL9wHW&{I%R)Kt-T$=2RT+|8-$ry6vV+VAM>j(S&m$Ho8cf=J6WhnGq{QrVywu7R^ic-og|O8Fp2d9I&R$K$tmgSgndc5ET!?__i~ zhH{ce1leH0MYbckOjeT6!SFS3S-(o)I0(1&kY-wN&Q;{U{ZeLh6#^o@d9&lsP@FiF ze;&uUtiBRNk*stX{POMnpl|!L!TEq)l~fD@{DtC$O*M*p9^JN3k0ZE+pbC;;kRP-P zM8;1sS{;HZb=XAulb%TS18}78WJ7VBYq-wmBH+wY8byocJj0S%9Q6G(VATfkPo6jj zS&^sA2Ky6=RG-Wlj6VmR$z3u99vUKSvKT)2QM_SDmH}&tpZup%H(ue`Srzm-k~ZI; zl#)^<)cB%o5R$e?vf;4ZPZpKcw)RXegJ{;`Nm3qX3AsyiA7C9mM3U_9>I{Fl!46wc zIRJ2iaL8xO12Dgyn2|w&5dkv>9Pr##Y0!`e7XV5j1m36jSbo*QOj+wf$9|uoOyEtD zN=v;3hbmvc&&;obSM@tzBs<;bj{CB+$o#Sw%}l!KqHMm>jtK^_>! zqnMPwJ#U-SKbkMMTseeAM>ZYV+zmBLC&~dpJQ8&c z{yT(Z4t-z$K2whkr<3Xv-68(B7``xB;wh(&KdEZsi1(bc|7j1>ND)@-9K1@hkcBm( zP79dPUT|S?5)9bSPem<#$m8hCJr{z|!wYxl_5tcl5?g&0IQ2|fn`;Fp3Fd%w6`@tU z<(v95FLRA)E3^+4y!v3upnrF>#`Yl$`7*UY`F3X?P*v+JR=}lnfe?XnN3tZb!JcP1=iX7) zc)A@3f?w`=2=rTgEu2e`Xd}Q-5h~(q?H?h24nmQ@JxHf{942ZY{ub@&+b4H*7N_T7*O}b3As~EsK;r7hQ&Zl=d|xF!Ow%k zzvhabD1KQw@xG9ubPAZt)q;}%S77eJ8{L}sm#-l7bF$X^(w1Zij2*}OMkpuGS9+yM z?r>SlS_^|RqZ?uO0lpkNR{f;^&M*Jwet!02(a%mvY2HXS6x-ditXB#)R4Ls^fMw-^ zlXNgPaQ)jwM66#ot8-cxF#5M5!UG9av;5M4vpfjC8s=y38+^UTv8S{Kvd=3TydGiS zm}CD1Vw7-2{5gB(X25cMz^EulJ_p`8zYb$7_>i$pU)+0$&%lx0L6BB0iLR|?RW@Jx zx7MeI^RHg*YG!Ks9f7F+`M$TC`g5j#2?^gd;?Ae7@4~r?oiO{3dBb0Cwvzj}ptO#b z%-*r=-?{5K`Q!iIK-qsi*&O~Qkbo60<)AyWC4>L|chPNZ<1TyNbj2y=z`%DHZb=%P z2+^UTHJ}(RnwzZE)Ro_5Oh|Ii*i>|3+C)prHLjjvxGULmjH$ftpHtPFPk>6WtQH`i z@x#OgXrXwVnhwLTn9S$UMCZ}z#J$u|abm`oHnnS|9_$;7CYQa!>NMC>jdLujIXKM4 z7D#Cki%R0Nsml;Ed*Iik8d2|^1a4^oG%Y5H+!vJ%^ALd|kD>-iawwZa?p$U!0YHmUvB*Zj&+S?vEkCRW?tDLdtYT>7wFk*Wvp^H*uqntyxG*VaP4jt7g;6>_h119ehIwV|n+r&}B-cT&-}$0oUIdP$0f{7h zBaPbvBU!NjA;n*heCg-UKP#yhJ_#nSbNEQM4T5d(cdbMQV6s-rXj1%Y!-veUE#TbE zMs>ue`flBlb{}5eP)MzP!8mPUZ5O9qM6z`OP)1Q;dg?{WSCs29ammw z^LkRngF8*%(etKdeXDz3_-%#+Jn&96BREV^wf!?EgOw7aO@GM4>Dx8v>FKqJ`s?By zCjsfnF;TeD6H1;4m#Fwu4B}%*skYi3R)LN|4!iZ_5xv4e6pH~eLP|z~m{|^5YNG=E z$8K!%fnTLBoHAGEAdYe)f+Ix2DhuYH{1aaYs?=opr{45GZr4G5a*WGM?tYL_=3s{V zDH|J`G|F7|hjVZUY^D+Ea^zDe?Cay+Zrid&R81998x?TlRdD^1($Y_Sd=}b$IK~Og*?|dXC^+noxC-cv%lS*}LcE!L}T} zZ(NfS_36Hb%8)vYDgBsK%aq59+{Km|n%oK+_iDuhu-c^ZcG6TgN=a#xu5ZOZBfn4T zx{80k%tTA1d+4wdb+QQhjZPTPilrUAhfGYOZSCwFP@)^MM||dt(z01$$Rl4^%2^eq zZK+RfO0gV^>g04S87OUzUA(4b0Mcx$2a|f3oyjV&J>>wJ9@HRdEMXWw_B=C5a=q>e zN4N;|#OT^j;A@D!TCN>LbcSRI^JDIdegR>`Mnu)^dyLT4DBn)LW*xjSaO#bhZX3Zx z?oZbfluqsA)dq2d-=Zg}Au9v$_26L?q$TDMWyjx+b+J@2`mDt1p&>)$M`L#*AuK@3 z7}QERxowsrRIDtU7j{vIgj2g?@TeWdqs93QCC^Xh+mxn2-!8WFi9rY~JKAnT7_-8}qkssw=c#)hmhaK-zkGjZYX-pAZP)TNKI@iUQ>Mt<}+I z&z|KKKTGJh%F1sY*IaV|WexyI5^TVXp|rb+O1dX*GyRV<;sg^UkDkn^Hb# zYD!mbgNiBz(J)bgU^9`qo#HEyDAD~8vXcgKx+&jNkxIYB&meo%K|)z&Y@hjeL1>vB zvcrO>o#*MSnV)OE*ve0oBJ%M`!+%Y`VbEtGWDvQES9tD-lGs zW5TEG`QaBRUZii8IxWAJQD|gnXt>YbTOPqcqCcV zc4yL;tSfUMA~f4CSd8VB;%~2wfxmj97F-0P+3{*8_8ZBzVd!M)YmtT_+7Fe1wX?eY zF%DfSrR(v_fIHCch?5s zOPFUOOQ~+0{*T$?aEo6hP`e)xaEOkIVmV-&w7?_!Et)G^R4+Ml$+CXY;vTjHgd}2Y zvO(EDg#N<7!y|9J)nNSZ-n@xiELdelMMQzuqE2*-34B=+ayKP%_{a`gSWr+b{LZ`H zq3w(3eJ>sFDy47b77H3O-B#+BghPAKJbn3ll-Etmt6I9+WIzshSXPTFf_6d%WA2AaHH}*kBY?Q}Juj_EWuD@J1FwA6ojP^-c`+G|Kh#B=kK{ zyin(o3y)ND{D{2=0ThRN)-oAfR#+AA-}6mXk<=a4)*gx{kP7<>lwmXb0vYhP$@Y4q zV`EIxr-svZU(u$G4`e8MbtuX_L*4WiJ$#r5b2}1?__VC7;;BNE$H2RTD>i*YOnTS0 zTOc+ep;SmP#ZPhcozVKf;c9wF9)lFJzh=$A8>Tns0pDtwB%p6qSH&FPca=e6Q*&nE z_#;K}7d&f}K|sVOCZ?tU%}SOKK9vwv)WXxBUbH4P=Wt>XLcb#U_}Wf0KJBwk#Ta&e zc*5yZSGh~hsXd`c-}xLoptg&+X14R`&ie*ZoF4kt1Y6>tH+#5iD)9H@@gbv<}2zyGd=;!ZVRrygc!i~-ld z;U!ga6Jbk?T3qZ+lsaU6k9)gE-(C%wyJJmdrO^GC6wRA5iZ}R!{_rudm+9J)yeC3{ zkol$B(3Jeiyj8f+*thB^VDikFo{6t=ysa$cXH9-m*sn=NAGXE=VZ*Y{EIOXDd5_)fZ9Xe~)th~Ss zoRYi`!%@_`t;gG}2b?^HoOCcgQ+)Hi=ejbsQ59ss(g*70xtfPz2K&C=6xo$Sa^QlC zkByNURR1tK2b9LDUm;LByp%Cp6zUZn9rqgfl#Gl|E>LCL>CyE4HaD0BKegGo$pCB! zfj#C};K#W0<3RUZy_!He5Tp;SOxP&=6=GKfQo)f=0Q3UA0I5ZsoC>hl>Evad19>+J zhuR4D%-udPEeQ(zYwFE~k2Nre&9%g&$kkjP7)JL#NeJjqaD`Sm&SEG7uhErRrOiY` z>GU=Zq>o&covE_`d=iOWg))-bO~8tr++&3RqFbUeBa8i6RJO!F1K{;_KFo-QUT z!Fdv!68ZYRF&G$#p$B|P3wSM5P&>a4BM|`Jxyg7d^E(8=9Ix;$z1|tVbmj%x!LD3rEHOGLe9tc!J) z=hJou-A93#o*g4FMw|ox%1@+z;F@zeUevg2tk}4@zP?^B;Se-6CR-ovZLU}||7IcI zkn^QjDO#~S+~YGMM(kmr^?{zIS7iv(50e zOr_u=h3ZsD-XP+Ch^Xoo&#AS3W$}lRGTG@uUPo_%WhHzN&WG+_jR?I6dyc+T1WLax zHYoc>G5k8xBDB~eT?-NH&+kok@!OfTkdu@3I_|A3W(bq_*^AD0Chy-S#ciCT`}5hA zvWC>*s)_W6HFYaGYVuTTg6zyjnbzgZ&ZbB;v$Xcml7(i{Uu2}EO>-sNpX;O?Krmc~ z<|W8vQck~LYJBF5Mb*=z71g*YCky7- ztwfO_%D=8#1+DJ+?4ocnqc-1EVxg&H$<1qnrwT5%Ev@$_;(f-5X+7dokX23BUF8#- zD~N@>Fj-R2Qg>`aV$DNH04ha|5$1EDv~VY|VT3a>nwgm6q%@Q)lAuy1r9>u%drXo=oG znP_BR{PPM)e1zUIi4H$+yk_F5kB`OrDrYfqaS|Jl_knJGPOmeN*O!PT5u%~E`7l6c zfrcJuLD^n|roP*A7^j046;7N~&bEM<#@sWf*C7BINX-+DEf%~I1+&<`+JPd7e#r>GQ>o}t z0WG23uQE%vPS1V#5k@HySROka-BO>VrPa7t>+65M-ZF%X3mJS=e@g+ktcD#0>j7%46P>>Zd1Pf(jlq)L*_$)z={&W( zC|18_VE}{;7OJDGtFnmSBTfX>5+%C*uE9m5(3dFugoX2Hmja8(U~`}?sr?|_eWcS66=wDzC-bsf2ty0vV&k9_*b!3ji*Z_{Ru=}IH2PtE z+pL7K_A5gz75d(AqloKbzw545&u-Sgx;!^r$|CmLBQHK#g3IWsrUe@vMjy=b$A8}> zjaKaDahL>PlL2l*LL0Pa2f*mh=ZAkZ)20d(*R5DfFm;oQixh{I5e{S~d|4x#^JAhs zXhfvrb&^v6Gi7xn+I+_wJE4ofE~89m6C7*w#x-%#L=h9!GXS`l3sFIJ-812Q{|G|8 z<+(RkHaxga#O;kzFxyoS(jZgTo?AGX{>da5fn)$yl=1o=^k)FyNZA(77dQs)-MlxU zIB=-(!3i(fiKO(9v)QOK22yQA3B-7feFpw_iG>8I6G6uCN)JF)Zihct-``<6FE7X{A$CwIp-e1TY8pd zfmq~vcnr}Qd9;tB{m}uF?b}hG8vwcfsI@TQkzbUe7|46ysY%N-EjzLHrceTYqwtY;-W`K|~} zqQjnxZ=it0vst{kaFa8BA2>ep54uI*ty)UF=loq%SBOju6czWitE8F;V8X3h^|Sd} zEx%mAQsHL&Wrvq1AIPDI66!)hL1DCaf|d6yElnE%SKBg<{jwxl;O^>bZ|4zjh_z_S z(aN+FXD?Bp{7XSZ4$1q_yU?=w6dY(^R3zzE9~d=XW->P)K(r>kzSNn|efT6+#jT_h zb6PI6ZZ|kr%;V?M-`0MjX_QI{dr@QH(I}J=2WzLHI1)(-TZUE_AAz0FZFe^f7fJ;L z$@H~W9P%z1D;Ak6VMAM*EFY~RH@@4yQf`7T$IkjH>|N`bCN1|;_hcbeolN`K>bRic zq}~ca_-(59u1~2sGK=TEQTnv3`G1vQiZkt`t3aDEnxU9!P20S!E=VkMEh4NQ!!z;( z`rvR?C=y?i2o=yH`kMI;zMEWcfdm9#5LmO>mDB25`q$8U=RwQWy{y1ER#fnBIDWgk zN*b_mSBUuP;=rDqsvlIlsQj>D3fg$HXD(t%&t=s}$HT(-;7vC{%IY8H(#BKM35Y{* z;p;(>39@=nZq{4*I`z!{aANembrIBoM2tv1gjUt8ht-$B7PY@=JHZT z-h-zhDH6Zi)Z1i9SQ)+YtFK%cshLHZE|C-*K%2&v6`UiB>^ zA{t-_ZS@V%G8N@J@iMV=ln6&fo?G9)pd-|y^a}ss%k4oM3k&t|00^ua$K9={ zT2cb-UQVuU>kWV&dMT$#6D>di$DZpLQ~e7kO4E+^Hk{bmtWr5b7x7uOrnIHTN&cHG zSESE>NJWK07H|aG;`?q*vvkXdis<;B>t$8*@>O77NeT)FwY!np#n-(5f-#6DW}4{vxlKx{MrhX7nAFt4>yc%d z(ZXo-;f!gI9A8XU^|XyR3oNBT4B6KFf*~SA+pz49b?uxU$5^||{m#~ZmKPO$A-{ND zKt&3h-QqYn=fBV{%_vsdsWzWEG}NgiVp$`nA~x{)Gr!;WcR~9N48k3I8e%=h86J-M zYUNYAZ%uMbh?I3$F7vr{Q0sis!oS#`hS@|`f2Jrk1>h-BA3v9z~54^KkHE^xCvh*ZJ`e7tpChwy%GlQGTrrEcB z4@q|qkh&mV$=<r-DR{rhF_{^@-&ja9^{<-IKy$_a8uefqfz%yrA$Us zdbNv||2Shzq{B;ug=NUp?N_n;<@`@;$clC~nFTLdeWmRaak}4qT21t9ibJj7$7CHk zbOIfo?%i-_E9ae=@6nPh9xV~j&*&rt@-G^kq5|llY_zY9l9^sopl9FM8UF2=;~mX+ zT}@m6C@y_jyq;Cumh9T4F>xF@zl4|W<50!$;ky#7qGxK%*VQBO-3qB-VZz5$>2lFc zA=bHO)J;_w=tE+xqyI0ZjWoK{zl#tkJ-G-Ed&}P$o~itG@We#-RY6&F*p&Gu4N3(a z$V{nvJ;%=;rkH~c`4hT^|o*!;c-J{1%Ym8 zh-Ck`gqAE0Kfk?CU#o1?m~wi*MczOnCG41WcHcEh@G>v1wZTb0w%n!@jYc$x{J9YO zHuA1Xz#kcObZ?rvJiRC3l!E8OUj;9W3~exRxsqgkm03|Zp@%B6O4P817A+9T#v~j? z#8Hj?S4-(>8QDYpL8CPW4aU?M6gbpJI@JOG7osH_9V0dq=-L4R%P?iB(&O8ID-_^z zr#~uGQEEKFUL!!rAKh&RnaqsBYLBWG*R`ErJ)`dHmzFn;cPVv#I1^DCvSVzhw^ zak}HHCkj_|`Lh2;Q~XTKg&z2Fc~J+LjY@PVB)+b*NA7Fh(0v6y%chC&f!xMDLdSk13Sb2$v zB1jt$5`-bY!LFj)>Ly?S0%f%p$ZA4D0a8#cM?3>aGa8XnO?H&p{f;oVp0YiQ6e1B- zm`Tq@Tl@syz%{f~m5C*zm`2Dy)POq;xaAGG1;Y}{EYp76@7_M_>xHG8-MYosJ(5a;vPG#ZlSyW`iTxF^wr{$$0hD~ z#yCc0l1@MEp=}DndP<92nM#U3gE0q%&u_C8#A9UI zPY3mc)lS;RU-fycdIyoaxmc3FH{3awqlEsaAhF5e_0nB>RgOCYJ&+-vj)u4uMNG){ zOS1T@?%Dgnqg*IxrjKW+RfRG)xBUnlxBJdnJSNe{I_bJKkwf?x3H$~P}xN;IOQqlwEwl5HY4O*z+sXx=!eU?ZwD+Al9s6s1+P zxy}qLvnwesuEIZ?auqoMKG<0hEmeQ(!Px)xrxoN>Z^EbgtBYMlov}oh)DnV$6l-d_ z*c9w3(frY;TPkBQ=fRLO`j|~qefW8IHny$oeF9zTB+Kqf}Kl#GCCM{jRl z{EH@dO$SD(Q*djfO}%AWI~bZO)LgcN4c(f}izC$&$;DK!V*M+D;z(yp+xOcdGd9^8 z`>RcAy)Y$-c%r@EdvP<8qwA)44}Z|keGIT9S-u;+A|vxA#wPakw-qD0baMEaea9x| znp|qUPRa+N&9`E+o2JYb{^r><=_bBm##kKE8|v)hu8VC`oDxu?GUSu!d^u`k2r&V z*75o|=2SsdkAcmLIz6_HP%-B(viCx-TiXi(GlcIr>|!)-F;P)NYP2puJfLbuRAx%T zg+m@A_nWE!zC?DHBFRh6lZ@E{kp-ZOhZMdvMC2WaurUZi+$*{PW%^IXawtP?V!%EK zvt#UKSsya%V!nH_@B2I3!V5S=|7$q(`x!EdU}GSe&!E%Ro-;Qk z=kabNb`LfPp8R5+{n=yU0>&+tAH8`^4#2MuL4}b*KwOgEX1a7{SjE<=9;q3n?Qa>P zo}X^~77BiGWp|w5usV*-Eg=y((VZ}UAP)nQQ9D96+uCYjFczFU*4T7aP6WFNvqa3B zUteY0FNG+2;n;LJ7hbT`8n$$*;kIdQFKW{(CPuM7FpH!#r8q>YQ?6;m7tO&#yBOuQTD8-evYxCKmpZ$cqSL|l@hy0kv z@iZZ!292ao=L!q{&o5H(imhdhMN_ih^-Nze&^->l|F)=(VxHSGl*Jw=eennmCPOSj zDC5F~@cl`xea-@^XfcfMOchtu$_AWD1S76)ZdLX57FRY})34CFc^v8JNGl=dHVsp!$;S6^|>lCEB7F@;iVjc75 zJF6491Gj&!X>|k;T8C1Fp)Cpujl96#+o1rhn#+IwAsAM>E!B4rdmKes!PG_G0Jh^7 z85#61V-g6F|NM`OG7`~P2lo4ID-E~i63oFF?m$1POblm`3HV6ros@-mYE6vra!$Fsj{yxE=aOb|NXWgyEU=ZI#M+2Si_-}yW(*jOOr zNM_S)`Is7TQq_>%`I4J}=T>w>f7|Hyzf~8?L>@_BZS;pcs6aX2w%Bu-4OC>I zGIoVRS*Y|>Mi0oEIHR8*-*Ut9Pc%;7Ltyvh#{&hbwWd^uqv&OoBih5dCQ{yfs|PM* z1^qAi@DLEBzYrWblCqe|>v1`W!j%84w_d@q?n9Cg)g(`qts^A?Kh&rzuEY_({mK@xTfrrN_;>w8vp%J=G}kTO zBGs7=D5N$~U(?%|vRx3JD>lDcS-d;$gjL2{p&9#kqA)m!Z8XF@T zcJdNmGNleZ0L}fsVr#=q8zv?A`^{n({{X~D%IF;+4uB8cwsB*@1KWzdLmqJQq%j-Y zb{cC!it-&i7qLu8x>1*EsvcwuHDo1r`@PW6=P;bX1zHeb{(~d->SdS{Q2)+s6lN7~ z6`wQt6nLimg8`&V9IpL>|AW!FN2Gs69>2U$!X>17KqLIK#|M=m4^ZtOY7SzIO&KXZ zR}WbR_1fr2sYg6h_H)hLHhGo%`6^73pCFqwQvW!vFa5s%m=#4aW>v53tM zz2E5whGDp`#l)o!-b)jnJd6!OsFr>D6bsFWS$l2JJESb2S{yLI035>9b#MvWA3&D+ z2mvulPC{BE#lbSb3i?*9J+~WeQlFw(Gy;$%oO0@^r^}w-6rpd*x7zbt1vzVBo2ex~Vn$yc2cvh_nT%xxDYB9OkzlwrvKdH#Q)>zYb>J15t;ZYLacVxBr1yD6vvTC7DhUJeh?@4HpZ4Rh!D-P_QhY5G_J?s z84nZnpxf`WRkU0_-?fAWOtawm^zGLv{{E`}Rqq3>UvasE453ehmtk@jyNzKHpW8uX zXN3PHr&T@VHeRv%hm^aKNIjDSDiue+Z$#DR)U_#y)b``rFZjQvRPi)ts?h|A)!?|2 z<<}#etVqjc3Mb2-ocL8bA#e8R{c&*7ghZ{#=&Al7MI!Q3GCEia!|^@#d&S>{s;Re*3iB%7q$mV@{DpE~okQxEFd zzL((5xHOMvmxM;|eU%ns`SNzltu0%&tXk5;i`P^sSZ#geaeuCaQ|zcUMXXsx$nLDX z-zyounq8+FO^39m?!+OwYid~|Um!I%MF9Dsq{PwOqhHD+B5y1!kHCAOGO=eNyE9R> z&SMP*2+v*g`?b~~)Qv47-6R`oB z{1-_6hN9Men$mNxyNUqme@lHa{W$(yQ#(-eIPkyRvE#nugYWrRcC1sZAF&VhFEroG z>{U`FLwrotHB?Csu781f6ferm&@i9(capLH!1R$g`F|%yuuKq$h3MjZz0aNhEj7Z_ zQyc2A%{HnuuCh8jbU#{HE+BM%Cp|-gH7eCk=>4dd^#kf>u1WCz;N|6&XbK(x&>My6 zQI-wqho^Qo#%83LS8c<#jYa46HM`E*><%U5f3{0YG^h*3W8sdyv-sx1EBXGs^iXJ9L1`q3C@JhH-p9YkHoHig0e;)H8hbn1~8os>dLj{mK6QB3Cw@VjNvZTCBdP<@8b74bzENC#X6<%V{4l z_G3tO<8=mDD7UVDZwvGPufY<1E|koEiOSnz%@_!U;)cW4v{Re1Fb!eX=wOi zxtTW&e!b@P?fmlUGSP!PONF|F$QR;uHvESjW1~B^BjZDWST?<-iR1y;-35Bi`h3e8 z@~UavyQ*C_hrlb7L=z%}KhT>k)Xb6%br1d&7@l*G!v$zu^we-riUa%YoiDqF`|=uK7;TU zEX@4g<;6|;erO_Dx>kczLvI_f6eeT7L>#pRJ0 zVtf?ZRLXBF6u4{p%q+QgqUXqPMErcGV_lt{6-19lp+@00vP^`}nQelX5nBdDsrC=I z_-P!FQlDG^eE55I*uJv)SFaR;f&hRiQ+H-wPKmU}{@b zcn!b1@QAE4pN#Drp+mvsHA7pcl{9;*svnWo-YHvUcnuBZ%P-`49Pkggpb|`N8g08m z6*Cxn>%<&07?4g-%gZ?8kyRYg?J;^n_@{vOyMBauL|sO^YtmjGg~sLfq(Xc0s$lC| z@n`YMUndmHsGLOutfcVH(!6ue`=bR|r9%dliws7Q_&H>>`LzxAJ^UagTz=nnh3QyJ zc*O)|B+IzYE_p|Kn|c~zG00$r>9R-B13lo{{@=&5kX>BH{s;qw^O}pEXFnVXN|lMs z`*i-8AFG|;0zh5cZMByb3~mqq=m}?sSp8brrj(qb>I-orc1qqZMFVdA#Zq`rfY{RL zOQ)WkBmWS)N&rjD^Ys4(@MRu7y!334|%B`w+ zTdvJlSEBm$2|~NVZjRNR@q&AF#-jXC&BC^9<&l`9^)cY8%J1*L>CzO|A^!1(h<^Ef z50O(;l`Uh(jw@OIYD%$fJs@n5+u)M@<26Y#(E+_o!C;tvK7{5raVIt{GYK~aA{{cI z9s-KY*oA$r$RppD`2Dy9fA=U?I-InBbx*@55LByAOdR#=bcnk-i>mLcpyn}_JP}8` zY**ZDmgX_xPAW%QI|mm5fxnxnF#YvC*X$h6o5Ox;&&YFq6<7cKm1gYPt0d-dE?>+` zZ^xp~B=~BCipmugQcU1i<^aVqF-y;3Xl-B97>&;_wRb{ebm+@UOc#BSr$_(`;^ULM zRw4KR&K?8nZ%wxfx6U1jMl}6z9Gw4BRcg{FM*5HS=6R%1ZXyHGRr6E9z6*+4qS%vl zXzeSxfqi2P<^-$t6f3DHV*BNC#tPjsVV;_{2LRS5fDqOA*WWio+kwpP)Ovf8>|nQ# z<}{5dF!jO`lyn*y^!t(gdEHfu&)Uk+@WJ--JAX^N&RPB~wD9_b~SYl}6*H|HyKNH%~_s`4Zku(QI(W za~Znm%ecyFX#VxrMaqFc$<$iP>NGT--)>FG8{P3KQzCu;tniYZG3j)gbb^w8 zbtbQ`Q|0fxBu(|?f8gKO*{$iZN~#^t3|LQdf8I-Amt+2;IXqP0HNfKUsla<<;x^=8 z-(4|CLj+606j+wX1+L>`&3i_(@+REy{W{uX!mHWPKxQLM36vy%MO$$QGqm@-3Mw_jN2ol6D`{f&I61V@dtZl6j3!Jx ztctJ!2i7czUkZ7YUicu+*itZjD4-i&%3B&(ajr7Al)aL#s|}w z0C+ma9j>;WFv;fLtPVXlTi-?m#sujlFVOwRW&ZDTm4+|Ei83)=HON|ResZ7t?*(uC zZ_)Y{=_yv@fWJGy`wmQGt%lf?-Ib$+p)}#ba4~4w?0*)^tXf`pYYkGoR-e*kr2Y%_ zhq0eO>k}@e;2bt6DypX07a94Dk##Jn_2>77PqQr3)*|2jF;SS{TBW5^mtwGfU~rIp zELA|eR>L1(s6~FxoKaG(jGEwJ@d`RRRPILAXNgN`s9X(i@J^G?-=}z8&{XKoVHB+7 zkqgvn(=z)?o7!`D-)Mp^>Sb~TO0b(csb_<7!KY|^Peev_0efJVl#~&@`uEXM7CSi| zu0sm;-VT#v!P^A2?rg*?olI0&6pQ)mZfmsuH^!##or;gQTE=;v0k#h@ml1VF_^*ZF(c!F2}~v*gyK1;)k@RQemhe0&;G+$59Z)_ceu!;DF1H!g zhG$fDtbJz$rufdDc~OPFVfsPdUm_jZ@TDmy0oP>-(@t$Q;qb3q>b;jw^!L*WaI>jF z1acn;1`Gm%-K3c#auII?2{uiosuXgO}VPTd;cQF^WA1{?Yp-)Z0hnao8XU~`}y0U@ALD?zf%2MeQ*43!%P1MQiXu+ literal 105581 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 $vAK5@93WBo8c8;gajYiUDWIMTVGQO!dO0R-I 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%0A2o+tCzHuGIW7-%qI6< zXa~2KKDE$E^e8*~)Dnm+q0U2KicsxCZIZ^VCBgrU*g|qct!bDm+S20(Ch-1zX?21l z?aZBxw+2{c4z9nS+p;^ozWxkd%<$Z5?|YAfg5)>WO77aVu8hCZqEfNV+2&&Ed~;>L z;SC;=JD=np{q*zAE5B}+JEQ2U`I7|D#N|ctKLLH1zJufEgw4Bztt^w2w&8;Jl|23` zRsUTg2KIvrin#~qWvzDWlc0_ZTeXNwsF8itX^S>*_>Q(y!h0iG7%4oLR&P*@tKqjD zZC4a@85g~m4~@ z`=M})jG@ZtZ3~w3JtxA_A>`1=i)*x}WiUD|Km<#27iA&+a$1h)WI%Eb1A%U0VuQFU z;2E1hLw)@Mqc2?%*QJlpSDPz-hbcr{B6#8DPB0X67?7>1YuG_IbSEr5%ZSVP&pOX- zr-=?pUNFKs;qH%RN})4ivO6V3jm{7adO7BUP;afy;Ou$;yYaoz9^GVUxpVKhdx%kHpc0_K< z*3%2zP-Nkg?W>xOP8zLkfzUAP6&e($$Fg7wti9`Rdr1zddqpGu{O#eMx+t`Z)M4gi z>4ZUQlQA{c1)%Z-%!8!t-`E5lXa-*%6_*)_$|o{#t92FS)?W{m;~){*1a%8!`&5J4 zt|67JjqL1+5Rt^Te9C2GpSbIkm0~@9eomprZ-3-$tf^95pB8W??eY z;bHu?X#cdWU^!TgU1Q_pLjk$;K?zlxuAnn#p7F?W6+iUK3|YVo7+lWmTi!Z&-TGVJ zpX5b=BIMxY6uUWxHx_uFx?S8f(P?!CyG61n{OyvtDv2j91Bbt{c|(K6_Qegb{tjkR zh|H+I#fnX3ehcsJ=N>t6H6rO#j0`BRC_)DH5bLI8b#8Nd7WkxHul-VPdM9oCE+tjM zESi_?B!0uS4Ye!NkG!6cMK3L*3pJvv<Ld){!8Sh$I1d$bq&mR?L%tF&cWYWj;;)_r1;q&j+U)_lTR4%+?RXfaXsy;1 zZ&6ZYF+hTt57-yvTfvm=aR$WfCw%bp=g;jjBMuoPLO3%HIY9hZHnXkkmZ+riC8azb zvAa^ND{QA$$5YT8XnGnXzxG{Kk7rhi%~%Q^xwegVQ^l7$6bADIAfY^cfC!} zne4g!cbP8xmUib4Mm6wteGTQC?3DO8R$<{08X`S7{Bd8YQMQ$lQJ#}YEqJ#8WK0lB zMt}cq3ZQwjsHhsq5|S0-&lAuHSfHG$rWTBt)(A}&iT7xg#|&o&G!=M_zqMLR5f%U< z=xy%9(Oob3C|m2it{CThG3mA&dmSG(DOlY$Q>sqB7(C#VZbtBMDQly{vc7qJ#=I-m z4P>%}>ZzN}Ox8cF!t7ygmk~owd6tV_^9MsaR|ki2-b61*Br(Z3wuH z;GY1=uHhtR5=RNzp45i~3~i%dYB^Mud`~ZEQ%DVrEx-apTFIVhU@SI0CBrwbkGN59 z4T838M_*k7c1kN5tkYGs8)X8(O>gKft#8kBlx@uO|e zq*o)jA8Wj}d{A+8t3zX~j!`>3>QGwQsbYtNRatflSyKi2ljs2Ugb((xt0%2@r-X<; z?ol~!xs0x7I0^;w1@~cR4h2n>(Mq513%YqCSn0@-3J9wc%YZ za~axdWv2z$na$iba-&qQPTjzZe~uq7_z_a6W#q}XwAM3>-qBUiq!hDGChp$W62E*D zYjtLh_lV|SBpb6bVz?bMt%8G0uYLy3w@fL&V2p>^&%WJ;UHL0Rn+ul)tAxI zwt@T9{o28A!ja<^pWM1-%N>phR4`e4)}RCk;l9;<$BZ)oFup9b7#<$(#5+lanhh&% zjjo|cUen$>VSA1ZCuMQHdeTsV9Iu0uW_Oy$<>xapv9b%z)QDVBcwITZXn9RdSGt6N zfFYwFpQ_$g2-i*0CWsx5LePl1meq@HAW3OY9(b=7)ZvChX5*Vn}CBr8N;)qo4#EaYjEt9oy1JIlD@u| z^Z;}$xx`2TG?>VemRb5>4EGT+Up!Zlg`g4-*>M-=}=x;mrQPt%+{;K>- zWKOf5~75Bec%E#!W`B(M;#+8L3B>|*442~=3gTY59KY>f=2%pU(X}yiApojfF8^ZB@TMk z%4G-WsBu-#7F)MON?R15wDufz05@nIUid;Uk`Dky@|l}^{uVg=mvMR*yIibgRiQ9p z$};!U&aA)o_DzX?H(CIK^J>?;P>(wU8DZ>1fysKBiWtYyrO-t5#DZ$ka|tBnv6DXX zYQUcL-ew$hLK>IGl1J0IjRDzb{d_Of{%xV|nKWQ)F8z0PlBf3GF%ry|n)s0~RMbh+ znyyP*Igb^Y{3anR{IsXX-0btq-5%Dx86y{l<~0;!*h&*)G+2IY1HjYVyvNtDYb~7?iu#sbBtI0uw(O2d;(a17dH(#|+n1J5q!OK|slblLh|Ngr^TlhuNRiUNxR{8+)8 z!uMj&KR`0CLpYd7y^AQ@!t?7}l$siNhP9v#vbwEp67oy`2ZmxUSvr8tVh2FipVpb| zRM)l&JNMCpzdF&(j~bYW!W>_IFQiT#81TL$U*r|K{As6Je-u=0$Kb%Q<7(kqPN~Mv z2h67q#mu)*7R`U;@cmtol81v=eOwZc-3QLV^3F`#Csod$1(iL}v;DQpNV(wjPSGIhf=3WP8Dl{xFd!!9PRE{WE-}`BDZbe zh~#JXBcwQaj`hY|QLcwo3c=49ehY2f1f1^UHKw2G4XF}vT58^!{5+uM#ITuf=j5%5 zsg*|@9n+|nkVjKjWChox+4klqnlVGE3tVr!1H%D!)z)w3tQxhG@Z~`^mb{{_E(RSN zRoC@A4ncGI!lBftD3iCmwOR)XS9rQgx}Yz$3M4VE3S!SE}H6w)qW4tFV>Uw7n@Z>P4EOilLE z8U)|JLkum|u_Lmi_6~n_^PkEIMXCqfx$C@uKwPDI5g~=04I;O4N_&BCTu=_hlD=`= z{MAuUqvhmPXx1eD#TT<xKxU30uc29ui?<~rE?nLV zS%l_7qBTc?|4^SwWD}Ay&+vPg9$#SrF)^~I)zs+KPzyk*c5qdqSr#Dq zN^}rhX|#a#5TbiXio!eRhS$@;kELITZmtS_d8+U}qt-0nuAO?`^V~Tk@&=pDCz#G@ zgTwQR4v+tNS#szuN%?s?vXt`h&`<<4R^SU;i<2`)3oN#Xi&qG$)+n~sO+3+DTJLG#DKPZ; zw)`W$q3szB6(v@Yr$#cO(tC0Ys2-041LcBMURm+4_+uBBc`(`-96%I1_~?iN_Qo%r z=5Ce$=rpTgu;#n^Rm{>GKe?dFVqLmRNaZ7i&-PXUTzP?qslb+A+eVK3_oVP3PM@5XcvknPIP~>|^n>RC+8!$lkw7->+;)g83!b zklAeUx|U7n?;^-TRikoRtwY1Zqacvjs4aQLE>S<*a2f{fb2 zwmWA{gpZY3xYXOLc}#^{I7RYg{%9krpaPzvn>_Oq9LFzBx>N=@4Bt*0q@CJs^&ws~ zHo3L%HPC|q^z`wzNxZ)28FlHyx&7ym*$62+ltdqx2HoS_=F8fm^gmj>ZT9A1IJu^8 z-zYTEHrQUhRnzx^-`=q26{!&SE*sHOBi+TO3wzc*3>+;ti=x8K=viS)YdwoBzLr%kQ{!fIcCXyh}f+a z6PIVN!z}ff>u<$08`GDfrpA#m%pb>n>k)-o6ogGRxB7ah-!FZ9)G*4W;GadY)0p6XOlled9cSEs_=G zCs$1=CQ zU}`e6jDd%1LRLIr*AePf-q0X~NO3&NF2~6)KaJ@bNt^m|h%OV3)IhJ^m>w7B-ty(u zQ$nJcV&>9qAd_Jw1)`;z|I@wJZa*@)weAsrekkO{larINuWn|xUd(VC?06cg?q<+# zafUfhJ4<9LJ>?R{y#w|3ZDAiD&ti^yn=ki{`&C=YLO-W`B;~HC{a5=jcvzOCjIPOp z9ftWQ#&u40)X|hH!moKse!pbaz7rX37Y0R_Z*Z4+et_Fv5qq!6kgen3 z_a<66ZK=~SC8hq+p;vf;=y@)Z?}qK0G2WBrfGIEn-NV>8(a2tW^>ue|oi4{r-?@3S zaUF7xyTC<#tk!Em$+BJi?(9P2oeGTU^usEzJo>NlC^Webb%{Qq7w_M@m*<%KbO+`| z*H2D6faf-&%B(frDu-g}Q7v92%BiKu8a z3ks^Smbv`3h)*d)xwoojxs2X2)eANaX`i~}Og%$O9LJu-IlUKDE=zAnI)pqB;Vkts zR4u{KypDZ5cdtr^=G=|dx>S>>e!~Ps4n~5|B7O}VO&J}NTtbmBdEUF$;{^I$4J)sn z-K%e!y>fy0z44BF^St9XnIoXb)e0l$4C%bKu`x=SFRv^To-9bUrk=j!_{9HlbkO|t zv0fhgg3TU$?zwE@IH%|xTWOY5XW*Ip(~CCh#V+(H5R3v4pwJP_Nchy;-;Vidtq<}Q zn+k8EqxDHljwwZdB*wEBNcA6$$cA-&m$|2a%~0n_ zXS9dgvVHq0h>;~__5*Z50;%WO#yC7Tu*nKi^-65lbFAR3UnwUnsk*>_{6z0a%${s3 zb07w1Daq6s9SH6x+H}SQVF%@+K;YW|(bdbwkL0e+?E9U*N}c-)YVTG#iHS-Y7F-($ zyyFunJ+rp>N24vv6ue78y5b$09AD9^j)v0MA_W+$k)54=@2v~mR4TI9f=gQHRxLe< z&c7W1Gw(apOR!m{BeeJ`RW5yc?fw4fV7E$Im`8 z$fr$6Y@p?6J*u_K=EuCr#+&jdG&Ow#orkFc-|gtT58VHU3!#^M)A4qzmhz9w2bmK; znaBZs108!LNd<+7q~ZPTWq|yWk+hQ@XSh#w=RUkL+>}x^lNQ*7m**D>~5G00LVF{P8(9^U}qNz zXM6_w^b{#auKt3uFX;{c-p#d$N~{_0F%&IT1Lq>e(07!xCR&7SS{Xi)UF|;p{?Q=8 z=z>aP!7(nA?))`_a77)MO%N+7s5G;QsDYk@ViM~@-hhGW`{>bew8^fq0ePmI+|S?3KOlmW6snlk@S9BA z8e|e{rXyLhP_90@w=d(LwF#D=EzX};#01NU8!l4=K`7VoDO>reDr?HdxlKB2vF#Zg z;u*mXOVi`9hkEP3`_o*U6!PW{SZs~_m6%>+v8$LB!CD;0R*(#60zX3B=EDQr zA~)M^;GKX)dpmAeGmMV;)j0-SuSCAIS)vYvR3Po3Fo23_mtom-J+%Q^|2IB%u}5!} zHTOPV-S?YJ_{MchI#EDXwn%Er`tR#3u4F|>flR`t3b!fbknM$n34qTVPT#dFyIt7& z{7(bqFywds7=06_q7$kE^-GuH2_jc&7~~v=8O=tPmc^WRtRqn~6@Y@a>C2S_QX0a4 z*nRj=T>QZ0$D^Qjh_zaaL(nwf8P=tStcm2R5wa`@m>g3v8c$N}S&c=OHnT~7VnH1` zo3<9GKQJ2cb8V}wMsKdO`SDZbM4O4=yoqFD!m~O=3d>F`o&bQ36Hk(T6%bG$y7Ej$0FpSS zj`w)Vd*8cy#M>iZ5+|?X4{yASk6sHEC={c!8*zo_c@{|j`7FY|v!42|#KyP9)0k7v zkfs_DX(|dZXCBpi(e$@mr#tz3(}_wzF(r?QH?_0+16OBMQG(9 zN!&}`*{{qGQ9OlDEe9+5IHUGo!!f6T_O%=rQqWtsBTIfH}SH`Ny0h;HxZo z6u@$zTOnv3?W1Py(>H~|6wA!26O@!a1x3Q&l{Yp%g<2sFaMcA%%cI2MKBhw5y@Oz| z0Fe%1u&2=2V# zxR&JQ@7`104O1kxdj!I!s9U}zXB@NL0dl1hh!-{YrT%N!Fbb$rl{ThEoEEsEvb?-o zP;mbIPA@{H5{EPwuE6+9ygr>HeiEv|3V`SJ_4Sgny=Z_;WSzn8a-|1&oWK1h*A@(c z)|D%B=$svdnNjuGN7jT~t;an`3j$pIO>Oeb6qfSQV?NVbL}t_&l#m<2KLCm zY*h%hO5oaO-k8rGf?`%#0WN8Q9lLhDK$Za7F`sjGgHh<$iAlnB@kLUSI=;xx{ELPd zSxWjqoUi*cyu~YPA`~BL=-Iq~*Y|ZM{Vw$!vL8Td(_uTOFM~N`=ivHUjDcK?(j)8~ z9LJG#)?>bF26Jk>v!`cgcz(oe0E1%cV(K&q0ZJ;Gxyjp+N^v6IjCpYs> z-aXU!XA*?;AbOg#!v!1#a!jCTBJPTa*lZ9Wq4zrEr|I_mK)AspemhAQCIkaxkK{+$ ztUe{Y`@vn%YM)!(*rKN1MKq{i6u=poQxP6_Qy}tG7or^rwzK;MAsWHQ{B@1Ln%g@_6}%wPsYd@*`JNq z3?$7-OU&V6U;UfNO!3jnXMkorU+YRzIe_b+Zi$qw@5V)$br+g%a9Uva!IZaU8(B6l zjVvl#z(~dW4vyq)X4UQoTR)%R-n*H*YUlbo(-AfD%j6Q4oLN)8mng|L0SEkv!LYtS zo2;V6WKGs&RY05UFL~P($-9BltmtI=S1FVgi)XTggSr^UL>d>zg7R1PKraNSb^ojO z$U0r`g!7Hm7lQ{Lnf$Ur3h6WAaD}<2|9|Q(W*){hnWf)=G5D<#N48fcFf_|P@-%bs z$D+x;4p+DIL4Mhvy&<%pH)+D*0wEg?xDkpJZ>b6<2pQtcwZd!0pgqVwWhi*6J4pMO z%Bee^LPw6b)_G3Zsl`tTj~|(Av#{q^A{x+|*87NOMkiTav=S3fkrq3F4xO80w9_j6 zNvMPJ>#o}ZfhdZK5oNy0*pYab zA;0sRJC=w1bIL><|qIp+KLnf;5c4bd8$np3TI>S=di6G7ur;o zmm4AABqAb+fc;0^<;GqF(x&Xm-_}l(Vfez?{izMh>q;gUtZAIYxvx{)(B^|M*!h1K&EWGN0fYaqT68q8d- zlDi3DP2LHT4R&O0oo^;AI^V`KmDhSr^`^#mn&~@DI+7gl$)iWjjPA}(UkPm)aG0p- zH1*Vb8!reQ#LOiuF#Bd)VOYw+uwW|vLDqSRacTT36&a+zByI2jEd&50unnE8SSY_G z_4=bhXo6|@Md1ApABe0*9GoC3)vWSf!TVs|@CW-kgsjWuerAgc)JLCAQo%}tRfSf# z;FrDl&-$SR;1p~e=6dy7_i+}Xg+rS|T}4GG9J>0pz-Vj-fZ?+^9_#3m$7o$LV|Z8Q z&2TctZ+imH{*R2z>|%Xs*CVeo+(G+-3|5S|Aldx{ThP5&DxF?C?nBCJ0`(= zq82M?T1YzEpiZK&3oTR7@GnnX;2|;w`YMUo5SL>>hk}MTm~N7^VZflNAJ1x+`ejWl zOP&2*V6+76NO+SqF7hhIC5q6eu=(uLc@5D-Bd zJo0>3Mp?knjQKjR(rQ<_jRJ?N@Y1WOz{zwgu(=0?_ zG;=ZJSYSPT2L;Uos&t^F)J!z>QPY8Lz~qcfGRw>PK;pE1W8JP_8|oaZ zp9dakA@2t5YUYW^sZ1#VtuKubw1JE%T zY&HNm0}5Jvt8(_QM>@=62JnHcDF}6Be>%4DEBTD@84q2?0toW8xr zKQ?Q$h+B4?hZfZm_;ZncAf`wnRxprceeAJgy9K6W41AVw+ssiGR^67-&DLF89@^{0 zJV6^PD3Z1~RLUH@uR4^YKBa|?5j)yE+Lz;c*+M6_p(s_YNbaK7RMDq~Z9rBoz8ANR zovx`V%891)qc8M@TfagP-7UZFF?oaO&#mpaPg%{(>L4v6Sk;}GyRACSHcs-}%AUc| zZ`neJtC%}^sWV* z#fMIMd6g2(#AmOYRa;?1a`I=vv|9Q(4I$IsJ5iz4u$(MK7bhDEJ^+{Q$p0TcjTG>0 z8@k8S_c&z2|NJDie?2re(g9NZ1iui<81#TN#=56ADmHgAd{47`$K@*DeTSRq^321I4~V+7;@VoICRM9$PH#%&KHsXd;JZ|D{m- zbC9kdIVlu1NS>i=cRuIkl%3Xopbm$i#Oef6P(lE9q9}mks?vExk=9$3ChIWVmsOTE zKl4RM$j^zP-8wo!m=Jc(lMDNf0P92eS(WN;I_AMbwjni&sR#03qZj~yB#wcwzb&2f*l54l~cQ9SrMjl@t*%G7iYL9L0#hYZ{ zDQK{+e4VNIvAAs&JT1f01N|L1db2vM;4~702!t=R#0;ZAx`=tkeB)5e0*lDV(8l`?Bv}*uFUgZQ zmR_0qnJXV?X?(dRvA{zQfmTLF2Fc93N~)^DF|v5?-LtNqYrl!^|Pz+cD^9U=sSNBxwSCwwy(jRng|*7U>QM=4v>sc;qnZF+&3UUJ5t z2T!H>SOrZ(`Ljt|YcL-W4RW=fk+~slxP^1r&yDaS2AgAL;yaEJZ=|1lxR5%~m>zyE ztnHVFd(LWlfsXi`WP?!eY&|{c0)fC5S=l;H4?bue7@NL(p~%6pH={~0_Xc_OsCDoL zZ2jd$o3rSgTsS46*u5Eao2=Pmo&9shP_DQ+oil^+c6jXR84LBd$g?cS)jFYTyI2v{ zOrUD)NtDc`ISfTk_4H0H-$spB1pFSW5-7pegOIZlC)B4US;X&OR8(=MkAUkgf@=f! zGl5Izyt6o5g@BNKH=#K#L(1KCoy%fp`-_s7%@Dr}Xf1M%^_LpGG8M$b%pyO5fGRw# zCw1$_w&)W5YC0qZm$bYK#;3)cSjS%r<4+3w!XT`SB9Oo2sAa#AkQX$|qtOqtW+dFWTmkS0;b&}f6$`VmYNh&1rI8K8HPEU^UC?|HnNSE1W zjcZ$Jco0D@8vY@RBp%YZ67_GLM6OEJVUAS|wb7=y0Iwc!7*3H*Egv~;b%)r&ybbQ& zEt{d2D}!XEqM^ZJSwSki#>ElGs2*Fv|68s&9b+o&QGV>&rbRvgxI{rbUiJ_}w5WZo z_(7m^D?1wQc&ml%S~78@0#NHyII@%rO_ps3c(ehc%Z5%(x!{;qalYqml=NZ&sI!4N zLboPd|1lIt)5h?{-nRjSqd`KMKmZL%f?Zcyq7r;L_2`rA#*2yX0Y&8hrTxp3X&L($T!9cZ8L-KuBEN* znZS}60%mH*kgl?a8xD{g445rE`}e=R%QQNMog!?eGwu)@>wH;TRd(ocq0_ozo;7Pa zPB)BsW)8(zbRb77li0b&+rnq0Fi-vM-lOp^58#?&K+4B)t%SnrR}U^lVvCz|-IYCDFo%<+Qw2LXgi)7LR+)V_gmx8; zkIO$i4|jaf1DrHQ2{hd+TFc|qM;Q5VZ9Zb`}r@l{VQ`)w{; zz5K7Tbk@D`e+>SakknO)pWk_E>venxf$crMEgDxU#V!iSZESP}%mgv6mQ|}C{zP?a z?dFe?z4$jj%v{)$@ry`$$2Jq1>K<42+FsGv*qCtDjbo`a3ToO5rF+G0w%!nO?ocKs zIrGPpxWiqqP$}lzvQF7V2z$bg&Z4NU&OXmi)2mL%o_Py0<89@Sdxe65NL>sRLl<0cbmhSngaCxJ!G9; z1>lsYudhp|ZASLhgkR9G=SzVH#jyva&_Y5QXsU@5$fG!KR(el<>DB=zPnvjt^u@=U R)X9GV-J^T;{{dR5c3}Vj From 1dbdc800b2728fba9c9f1951e71e262242486a82 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 18 Apr 2025 21:18:04 +0200 Subject: [PATCH 300/324] =?UTF-8?q?=F0=9F=94=A7=20[Docs]:=20Update=20READM?= =?UTF-8?q?E=20for=20clarity=20and=20enhance=20workflow=20descriptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 94 ++++++++++++++++++++++++++++++++----- media/Process-PSModule.png | Bin 107036 -> 113633 bytes 2 files changed, 81 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 68087ad1..179e2be7 100644 --- a/README.md +++ b/README.md @@ -20,28 +20,39 @@ Depending on the labels in the pull requests, the workflow will result in differ ![Process diagram](./media/Process-PSModule.png) -- [Get-Settings](./.github/workflows/Get-Settings.yml) +- [Get settings](./.github/workflows/Get-Settings.yml) - Reads the settings file from a file in the module repository to configure the workflow. - Gathers tests and creates test configuration based on the settings and the tests available in the module repository. - This includes the selection of what OSes to run the tests on. -- [Build-Module](./.github/workflows/Build-Module.yml) +- [Build module](./.github/workflows/Build-Module.yml) - Compiles the module source code into a PowerShell module. -- [Test-SourceCode](./.github/workflows/Test-SourceCode.yml) - - Tests and lints the source code in parallel (matrix) using [PSModule framework settings for style and standards for source code](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#sourcecode-tests) + [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). +- [Test source code](./.github/workflows/Test-SourceCode.yml) + - Tests the source code in parallel (matrix) using [PSModule framework settings for style and standards for source code](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#sourcecode-tests) - This produces a json based report that is used to later evaluate the results of the tests. -- [Test-Module](./.github/workflows/Test-Module.yml) +- [Lint source code](./.github/workflows/Lint-SourceCode.yml) + - Lints the source code in parallel (matrix) using [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). + - This produces a json based report that is used to later evaluate the results of the linter. +- [Framework test](./.github/workflows/Test-Module.yml) - Tests and lints the module in parallel (matrix) using [PSModule framework settings for style and standards foor modules](https://github.com/PSModule/Test-PSModule?tab=readme-ov-file#module-tests) + [PSScriptAnalyzer rules](https://github.com/PSModule/Invoke-ScriptAnalyzer). - This produces a json based report that is used to later evaluate the results of the tests. -- [Test-ModuleLocal](./.github/workflows/Test-ModuleLocal.yml) +- [Test module](./.github/workflows/Test-ModuleLocal.yml) - Import and tests the module in parallel (matrix) using Pester tests from the module repository. - This produces a json based report that is used to later evaluate the results of the tests. -- [Build-Docs](./.github/workflows/Build-Docs.yml) - - Generates documentation and lints the documentation using [SuperLinter](https://github.com/super-linter/super-linter). -- [Build-Site](./.github/workflows/Build-Site.yml) - - Generates a static site using [MkDocs](https://www.mkdocs.org/). -- [Test-PSModule](https://github.com/PSModule/Test-PSModule/) - Tests the compiled module. This runs on 4 different environments to check compatibility. - - PowerShell LTS on Windows, Ubuntu and macOS. -- [Publish-PSModule](https://github.com/PSModule/Publish-PSModule/) - Publishes the module to the PowerShell Gallery, docs to GitHub Pages, and creates a release on the GitHub repository. +- [Get test results](./.github/workflows/Get-TestResults.yml) + - Gathers the test results from the previous steps and creates a summary of the results. + - If any tests have failed, the workflow will fail here. +- [Get code coverage](./.github/workflows/Get-CodeCoverage.yml) + - Gathers the code coverage from the previous steps and creates a summary of the results. + - If the code coverage is below the target, the workflow will fail here. +- [Build docs](./.github/workflows/Build-Docs.yml) + - Generates documentation and lints the documentation using [super-linter](https://github.com/super-linter/super-linter). +- [Build site](./.github/workflows/Build-Site.yml) + - Generates a static site using [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/). +- [Publish site](./.github/workflows/Publish-Site.yml) + - Publishes the static site with the module documentationto GitHub Pages. +- [Publish module](./.github/workflows/Publish-Module.yml) + - Publishes the module to the PowerShell Gallery. + - Creates a release on the GitHub repository. To use the workflow, create a new file in the `.github/workflows` directory of the module repository and add the following content.
      @@ -77,6 +88,63 @@ jobs: ```
      +## Configuration + +The workflow is configured using a settings file in the module repository. +The file can be a JSON, YML or PSD1 file. By default it will look for `.github/PSModule.yml`. + +The following settings are available in the settings file: +Here's a Markdown-formatted table describing your PowerShell object structure clearly and concisely: + +| Name | Type | Description | Default | +| ----------------------------------------- | --------------- | -------------------------------------------------------------- | ------------------------------ | +| `Name` | `String` | Name identifier for the settings | `null` | +| **Test** | `Object` | Settings related to testing | | +| `Test.Skip` | `Boolean` | Skip all tests | `false` | +| `Test.Linux.Skip` | `Boolean` | Skip tests on Linux | `false` | +| `Test.MacOS.Skip` | `Boolean` | Skip tests on macOS | `false` | +| `Test.Windows.Skip` | `Boolean` | Skip tests on Windows | `false` | +| **Test.SourceCode** | `Object` | Settings for source code tests | | +| `Test.SourceCode.Skip` | `Boolean` | Skip source code tests | `false` | +| `Test.SourceCode.Linux.Skip` | `Boolean` | Skip source code tests on Linux | `false` | +| `Test.SourceCode.MacOS.Skip` | `Boolean` | Skip source code tests on macOS | `false` | +| `Test.SourceCode.Windows.Skip` | `Boolean` | Skip source code tests on Windows | `false` | +| **Test.PSModule** | `Object` | Settings for PowerShell module tests | | +| `Test.PSModule.Skip` | `Boolean` | Skip PowerShell module tests | `false` | +| `Test.PSModule.Linux.Skip` | `Boolean` | Skip PS module tests on Linux | `false` | +| `Test.PSModule.MacOS.Skip` | `Boolean` | Skip PS module tests on macOS | `false` | +| `Test.PSModule.Windows.Skip` | `Boolean` | Skip PS module tests on Windows | `false` | +| **Test.Module** | `Object` | Settings for generic module tests | | +| `Test.Module.Skip` | `Boolean` | Skip generic module tests | `false` | +| `Test.Module.Linux.Skip` | `Boolean` | Skip generic module tests on Linux | `false` | +| `Test.Module.MacOS.Skip` | `Boolean` | Skip generic module tests on macOS | `false` | +| `Test.Module.Windows.Skip` | `Boolean` | Skip generic module tests on Windows | `false` | +| **Test.TestResults** | `Object` | Settings for test result publishing | | +| `Test.TestResults.Skip` | `Boolean` | Skip test result processing | `false` | +| **Test.CodeCoverage** | `Object` | Settings for code coverage | | +| `Test.CodeCoverage.Skip` | `Boolean` | Skip code coverage tests | `false` | +| `Test.CodeCoverage.PercentTarget` | `Integer` | Target code coverage percentage | `0` | +| `Test.CodeCoverage.StepSummaryMode` | `String` | Step summary mode for code coverage reports | `'Missed, Files'` | +| **Build** | `Object` | Settings for build processes | | +| `Build.Skip` | `Boolean` | Skip all build tasks | `false` | +| `Build.Module.Skip` | `Boolean` | Skip module build | `false` | +| `Build.Docs.Skip` | `Boolean` | Skip documentation build | `false` | +| `Build.Site.Skip` | `Boolean` | Skip website build | `false` | +| **Publish.Module** | `Object` | Settings for module publishing | | +| `Publish.Module.Skip` | `Boolean` | Skip module publishing | `false` | +| `Publish.Module.AutoCleanup` | `Boolean` | Automatically cleanup old module versions | `true` | +| `Publish.Module.AutoPatching` | `Boolean` | Automatically patch module version | `true` | +| `Publish.Module.IncrementalPrerelease` | `Boolean` | Use incremental prerelease versioning | `true` | +| `Publish.Module.DatePrereleaseFormat` | `String` | Format for date-based prerelease | `''` (empty string) | +| `Publish.Module.VersionPrefix` | `String` | Prefix for version tags | `'v'` | +| `Publish.Module.MajorLabels` | `String` | Labels indicating a major version bump | `'major, breaking'` | +| `Publish.Module.MinorLabels` | `String` | Labels indicating a minor version bump | `'minor, feature'` | +| `Publish.Module.PatchLabels` | `String` | Labels indicating a patch version bump | `'patch, fix'` | +| `Publish.Module.IgnoreLabels` | `String` | Labels indicating no release | `'NoRelease'` | + +This table clearly represents each nested property, type, brief description, and the default values you've specified in your provided PowerShell structure. + + ## Usage ### Inputs diff --git a/media/Process-PSModule.png b/media/Process-PSModule.png index 26131f1d218f15ffdeeb518484bf09bb2c8f1846..42d9cac2979b1050bf2a96ffda12e8aa4ad2c026 100644 GIT binary patch literal 113633 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
      ^JUi7OQ5L1nwR9A_tG}=|5yN4B95SFN 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

      e`7v^br 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 M-b&5b^xNtG0cbo@rvLx| literal 107036 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