From 03d935a049b6283ffac6e6d17fd2f164b772b6f6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 21 Mar 2026 20:40:02 +0000 Subject: [PATCH 1/3] Copy CI and release workflows from HeyItsGilbert/.github - ModuleCI.yml: Add push/PR/workflow_dispatch triggers, remove deprecated psmodulecache caching steps, switch test task to use -Bootstrap flag, and drop the alex linter step - PublishModule.yml: Fully revamp release workflow with multi-job pipeline (check_version, git_tag, create_release, publish), workflow_call inputs for version/isPrerelease/dry_run, proper GITHUB_OUTPUT usage, and automated GitHub release creation via changelog reader https://claude.ai/code/session_01BSfUTWxTZcPMLRyLcaEDft --- .github/workflows/ModuleCI.yml | 50 +++---- .github/workflows/PublishModule.yml | 204 +++++++++++++++++++++++----- 2 files changed, 196 insertions(+), 58 deletions(-) diff --git a/.github/workflows/ModuleCI.yml b/.github/workflows/ModuleCI.yml index 700535b..a5234d1 100644 --- a/.github/workflows/ModuleCI.yml +++ b/.github/workflows/ModuleCI.yml @@ -1,5 +1,9 @@ name: CI on: + push: + branches: [ $default-branch ] + pull_request: + workflow_dispatch: workflow_call: permissions: checks: write @@ -17,12 +21,6 @@ jobs: strict: false suggestions: true incremental_files_only: true - - uses: reviewdog/action-alex@v1.16.0 - with: - github_token: ${{ secrets.github_token }} - # Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review]. - reporter: github-pr-review - level: warning - shell: pwsh name: Apply PSScriptAnalyzer Fixes run: Invoke-ScriptAnalyzer . -Fix @@ -39,27 +37,29 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v4 - - name: Install and cache PSDepend - id: psdepend - uses: potatoqualitee/psmodulecache@v6.2.1 - with: - modules-to-cache: PSDepend:0.3.8 - - name: Determine modules to cache - shell: pwsh - id: modules-to-cache - run: | - $dependancies = Get-Dependency - $f = $dependancies | ?{ $_.DependencyType -eq 'PSGalleryModule' } | %{ "{0}:{1}" -F $_.DependencyName, $_.Version} - Write-Output "::set-output name=ModulesToCache::$($f -join ', ')" - - name: Install and cache PowerShell modules - id: psmodulecache - uses: potatoqualitee/psmodulecache@v6.2.1 - with: - modules-to-cache: ${{ steps.modules-to-cache.outputs.ModulesToCache }} - shell: pwsh + # Caching doesn't seem to be working. Commenting out for now. + # Maybe replace with modulefast. + #- name: Install and cache PSDepend + # id: psdepend + # uses: potatoqualitee/psmodulecache@v6.2.1 + # with: + # modules-to-cache: PSDepend:0.3.8 + #- name: Determine modules to cache + # shell: pwsh + # id: modules-to-cache + # run: | + # $dependancies = Get-Dependency + # $f = $dependancies | ?{ $_.DependencyType -eq 'PSGalleryModule' } | %{ "{0}:{1}" -F $_.DependencyName, $_.Version} + # Write-Output "::set-output name=ModulesToCache::$($f -join ', ')" + #- name: Install and cache PowerShell modules + # id: psmodulecache + # uses: potatoqualitee/psmodulecache@v6.2.1 + # with: + # modules-to-cache: ${{ steps.modules-to-cache.outputs.ModulesToCache }} + # shell: pwsh - name: Test shell: pwsh - run: ./build.ps1 -Task Test + run: ./build.ps1 -Task Test -Bootstrap - name: Upload Unit Test Results if: always() uses: actions/upload-artifact@v4 diff --git a/.github/workflows/PublishModule.yml b/.github/workflows/PublishModule.yml index 0f8f924..a30250d 100644 --- a/.github/workflows/PublishModule.yml +++ b/.github/workflows/PublishModule.yml @@ -1,48 +1,186 @@ +# spell-checker:ignore BHPS PSGALLERY pwsh name: Publish Module + +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: false + +permissions: + contents: write + on: workflow_call: + inputs: + version: + description: "The version to publish. Leave empty to use the version in the module manifest." + required: false + type: string + isPrerelease: + description: "Is this a prerelease version?" + required: false + default: false + type: boolean + dry_run: + type: boolean + description: "If true, skip actual publishing and just validate the workflow logic." + required: false + default: false + secrets: + PS_GALLERY_KEY: + description: "The API key for publishing to the PowerShell Gallery." + required: true + jobs: - publish: - name: Publish Module + check_version: + name: Check Version + timeout-minutes: 15 runs-on: windows-latest + outputs: + version_bumped: ${{ steps.check_if_versions_bumped.outputs.BUMPED }} + module_name: ${{ steps.check_if_versions_bumped.outputs.MODULE_NAME }} + new_version: ${{ steps.check_if_versions_bumped.outputs.NEW_VERSION }} steps: - # Get the current version - uses: actions/checkout@v4 - - name: Install and cache PSDepend - id: psdepend - uses: potatoqualitee/psmodulecache@v6.2.1 - with: - modules-to-cache: PSDepend:0.3.8, BuildHelpers - - shell: pwsh - name: Check if this version is already published - # Give an id to the step, so we can reference it later + + - name: Bootstrap + shell: pwsh + run: ./build.ps1 -Task 'Init' -Bootstrap + + - name: Check if version is already published id: check_if_versions_bumped - run: | - Set-BuildEnvironment - [version]$GalleryVersion = Get-NextNugetPackageVersion -Name $env:BHProjectName -ErrorAction Stop - [version]$GithubVersion = Get-MetaData -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -ErrorAction Stop - $bumped = $GithubVersion -ge $GalleryVersion - - # Set the output named "version_bumped" - Write-Host "::set-output name=version_bumped::$bumped" - - name: Determine modules to cache shell: pwsh - id: modules-to-cache - if: steps.check_if_versions_bumped.outputs.version_bumped == 'True' run: | - $dependancies = Get-Dependency - $f = $dependancies | ?{ $_.DependencyType -eq 'PSGalleryModule' } | %{ "{0}:{1}" -F $_.DependencyName, $_.Version} - Write-Output "::set-output name=ModulesToCache::$($f -join ', ')" - - name: Install and cache PowerShell modules - id: psmodulecache - uses: potatoqualitee/psmodulecache@v6.2.1 - if: steps.check_if_versions_bumped.outputs.version_bumped == 'True' + Import-Module BuildHelpers + Set-BuildEnvironment -Force + [version]$githubVersion = Get-MetaData -Path $env:BHPSModuleManifest -PropertyName 'ModuleVersion' -ErrorAction 'Stop' + Write-Host "Current Version: $githubVersion" + + # Override version if specified as input + if (-not [String]::IsNullOrEmpty('${{ inputs.version }}')) { + # Split version and prerelease suffix if present + if('${{ inputs.version }}' -match '^(?\d+\.\d+\.\d+)(-(?.+))?$') { + $githubVersion = [version]$matches['version'] + if ($matches['prerelease']) { + $prereleaseSuffix = $matches['prerelease'] + } + } else { + Write-Warning "Invalid version format: '${{ inputs.version }}'. Expected format: '1.2.3' or '1.2.3-beta'" + } + Write-Host "Module version was specified in workflow: $githubVersion" + Update-MetaData -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -Value $githubVersion -ErrorAction 'Stop' + } + + $moduleSplat = @{ + Name = $env:BHProjectName + } + + # Handle pre-release versions + $isPrerelease = '${{ inputs.isPrerelease }}' -eq 'true' + Write-Host "Prerelease: $isPrerelease" + if ($isPrerelease) { + $PSData = Get-MetaData -Path $env:BHPSModuleManifest -PropertyName PrivateData.PSData -ErrorAction 'Stop' + $moduleSplat['AllowPrerelease'] = $true + $moduleSplat['RequiredVersion'] = "$githubVersion-$($PSData.Prerelease)" + } else { + $moduleSplat['AllowPrerelease'] = $false + $moduleSplat['RequiredVersion'] = $githubVersion + } + Write-Host "Version to Publish: $($moduleSplat.RequiredVersion)" + + # Check if exact version exists in PSGallery + try { + $existingModule = Find-Module @moduleSplat -ErrorAction Stop + $bumped = $false + Write-Host "Version $($moduleSplat.RequiredVersion) already exists in PSGallery - skipping publish" + } catch { + if ($_.CategoryInfo.Category -eq 'ObjectNotFound') { + $bumped = $true + Write-Host "Version $($moduleSplat.RequiredVersion) not found in PSGallery - will publish" + } else { + Write-Warning "Failed to check existing version: $($_.Exception.Message)" + $bumped = $false + } + } + + # Strip prerelease suffix for changelog lookup + $versionForChangelog = "$($moduleSplat.RequiredVersion)" -replace '-.*$', '' + + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value "BUMPED=$bumped" -Confirm:$false -Encoding UTF8 + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value "MODULE_NAME=$env:BHProjectName" -Confirm:$false -Encoding UTF8 + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value "NEW_VERSION=$($moduleSplat.RequiredVersion)" -Confirm:$false -Encoding UTF8 + + git_tag: + name: Tag Release + runs-on: ubuntu-latest + needs: check_version + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Create Git Tag + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ needs.check_version.outputs.new_version }} + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + + # Remove existing tag if present to maintain consistency + if git rev-parse "$VERSION" >/dev/null 2>&1; then + echo "Tag $VERSION already exists. Deleting and recreating." + git tag -d "$VERSION" + git push origin :refs/tags/"$VERSION" 2>/dev/null || true + fi + + echo "Creating tag $VERSION" + git tag -a "$VERSION" -m "$VERSION" + git push origin "$VERSION" + + create_release: + name: Create GitHub Release + runs-on: ubuntu-latest + needs: + - check_version + - git_tag + steps: + - uses: actions/checkout@v4 + - name: Read and validate changelog (keepachangelog) + id: changelog + uses: mindsers/changelog-reader-action@v2 + with: + validation_level: warn + version: ${{ needs.check_version.outputs.new_version }} + path: ./CHANGELOG.md + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 with: - modules-to-cache: ${{ steps.modules-to-cache.outputs.ModulesToCache }} - shell: pwsh + tag_name: ${{ needs.check_version.outputs.new_version }} + name: Release ${{ steps.changelog.outputs.version }} + body: ${{ steps.changelog.outputs.changes }} + prerelease: ${{ steps.changelog.outputs.status == 'prereleased' }} + draft: ${{ steps.changelog.outputs.status == 'unreleased' }} + + publish: + name: Publish Module + runs-on: windows-latest + needs: + - check_version + - git_tag + if: needs.check_version.outputs.version_bumped == 'True' + steps: + - uses: actions/checkout@v4 - name: Publish to PSGallery shell: pwsh - if: steps.check_if_versions_bumped.outputs.version_bumped == 'True' env: PSGALLERY_API_KEY: ${{ secrets.PS_GALLERY_KEY }} - run: ./build.ps1 -Task Publish + PACKAGE: ${{ needs.check_version.outputs.module_name }} + VERSION: ${{ needs.check_version.outputs.new_version }} + DRY_RUN: ${{ inputs.dry_run || false }} + run: | + if ($env:DRY_RUN -eq 'true') { + Write-Host "DRY RUN: Would publish module to PSGallery" + Write-Host "Module: $env:PACKAGE" + Write-Host "Version: $env:VERSION" + exit 0 + } + ./build.ps1 -Task 'Publish' -Bootstrap From f3f19f90f92155255b3311b37f79a0c6a6b4ea60 Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Sat, 21 Mar 2026 16:03:45 -0700 Subject: [PATCH 2/3] Fix Publish to only be workflow and bootstrap --- .github/workflows/ModuleCI.yml | 24 ------------------------ .github/workflows/PublishModule.yml | 4 +--- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/.github/workflows/ModuleCI.yml b/.github/workflows/ModuleCI.yml index a5234d1..935f33c 100644 --- a/.github/workflows/ModuleCI.yml +++ b/.github/workflows/ModuleCI.yml @@ -1,9 +1,5 @@ name: CI on: - push: - branches: [ $default-branch ] - pull_request: - workflow_dispatch: workflow_call: permissions: checks: write @@ -37,26 +33,6 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v4 - # Caching doesn't seem to be working. Commenting out for now. - # Maybe replace with modulefast. - #- name: Install and cache PSDepend - # id: psdepend - # uses: potatoqualitee/psmodulecache@v6.2.1 - # with: - # modules-to-cache: PSDepend:0.3.8 - #- name: Determine modules to cache - # shell: pwsh - # id: modules-to-cache - # run: | - # $dependancies = Get-Dependency - # $f = $dependancies | ?{ $_.DependencyType -eq 'PSGalleryModule' } | %{ "{0}:{1}" -F $_.DependencyName, $_.Version} - # Write-Output "::set-output name=ModulesToCache::$($f -join ', ')" - #- name: Install and cache PowerShell modules - # id: psmodulecache - # uses: potatoqualitee/psmodulecache@v6.2.1 - # with: - # modules-to-cache: ${{ steps.modules-to-cache.outputs.ModulesToCache }} - # shell: pwsh - name: Test shell: pwsh run: ./build.ps1 -Task Test -Bootstrap diff --git a/.github/workflows/PublishModule.yml b/.github/workflows/PublishModule.yml index a30250d..420c8c3 100644 --- a/.github/workflows/PublishModule.yml +++ b/.github/workflows/PublishModule.yml @@ -42,14 +42,12 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Bootstrap - shell: pwsh - run: ./build.ps1 -Task 'Init' -Bootstrap - name: Check if version is already published id: check_if_versions_bumped shell: pwsh run: | + Install-Module BuildHelpers Import-Module BuildHelpers Set-BuildEnvironment -Force [version]$githubVersion = Get-MetaData -Path $env:BHPSModuleManifest -PropertyName 'ModuleVersion' -ErrorAction 'Stop' From 58a788e06b7914e8151adb732dd330b1045b6e3a Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Sat, 21 Mar 2026 16:11:41 -0700 Subject: [PATCH 3/3] Clean up --- .github/workflows/ModuleCI.yml | 50 ++++++++++++++--------------- .github/workflows/PublishModule.yml | 31 ------------------ 2 files changed, 25 insertions(+), 56 deletions(-) diff --git a/.github/workflows/ModuleCI.yml b/.github/workflows/ModuleCI.yml index 935f33c..5b10ae1 100644 --- a/.github/workflows/ModuleCI.yml +++ b/.github/workflows/ModuleCI.yml @@ -11,44 +11,44 @@ jobs: name: Run Linters runs-on: [ubuntu-latest] steps: - - uses: actions/checkout@v4 - - uses: streetsidesoftware/cspell-action@v6 - with: - strict: false - suggestions: true - incremental_files_only: true - - shell: pwsh - name: Apply PSScriptAnalyzer Fixes - run: Invoke-ScriptAnalyzer . -Fix - - name: PSScriptAnalyzer Fixes - uses: reviewdog/action-suggester@v1.21.0 - with: - tool_name: 'PSScriptAnalyzer' + - uses: actions/checkout@v4 + - uses: streetsidesoftware/cspell-action@v6 + with: + strict: false + suggestions: true + incremental_files_only: true + - shell: pwsh + name: Apply PSScriptAnalyzer Fixes + run: Invoke-ScriptAnalyzer . -Fix + - name: PSScriptAnalyzer Fixes + uses: reviewdog/action-suggester@v1.21.0 + with: + tool_name: "PSScriptAnalyzer" test: - name: Run Tests + name: Run Pwsh Tests + # We still have the azure pipeline setup that's running windows runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@v4 - - name: Test - shell: pwsh - run: ./build.ps1 -Task Test -Bootstrap - - name: Upload Unit Test Results - if: always() - uses: actions/upload-artifact@v4 - with: - name: Unit Test Results (OS ${{ matrix.os }}) - path: ./tests/out/testResults.xml + - uses: actions/checkout@v4 + - name: Test + shell: pwsh + run: ./build.ps1 -Task Test -Bootstrap + - name: Upload Unit Test Results + if: always() + uses: actions/upload-artifact@v4 + with: + name: Unit Test Results (OS ${{ matrix.os }}) + path: ./tests/out/testResults.xml publish-test-results: name: "Publish Unit Tests Results" needs: test runs-on: ubuntu-latest # the test job might be skipped, we don't need to run this job then if: success() || failure() - steps: - name: Download Artifacts uses: actions/download-artifact@v4 diff --git a/.github/workflows/PublishModule.yml b/.github/workflows/PublishModule.yml index 420c8c3..54dab87 100644 --- a/.github/workflows/PublishModule.yml +++ b/.github/workflows/PublishModule.yml @@ -41,8 +41,6 @@ jobs: new_version: ${{ steps.check_if_versions_bumped.outputs.NEW_VERSION }} steps: - uses: actions/checkout@v4 - - - name: Check if version is already published id: check_if_versions_bumped shell: pwsh @@ -107,39 +105,11 @@ jobs: Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value "MODULE_NAME=$env:BHProjectName" -Confirm:$false -Encoding UTF8 Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value "NEW_VERSION=$($moduleSplat.RequiredVersion)" -Confirm:$false -Encoding UTF8 - git_tag: - name: Tag Release - runs-on: ubuntu-latest - needs: check_version - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Create Git Tag - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - VERSION: ${{ needs.check_version.outputs.new_version }} - run: | - git config --global user.name 'github-actions[bot]' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - - # Remove existing tag if present to maintain consistency - if git rev-parse "$VERSION" >/dev/null 2>&1; then - echo "Tag $VERSION already exists. Deleting and recreating." - git tag -d "$VERSION" - git push origin :refs/tags/"$VERSION" 2>/dev/null || true - fi - - echo "Creating tag $VERSION" - git tag -a "$VERSION" -m "$VERSION" - git push origin "$VERSION" - create_release: name: Create GitHub Release runs-on: ubuntu-latest needs: - check_version - - git_tag steps: - uses: actions/checkout@v4 - name: Read and validate changelog (keepachangelog) @@ -163,7 +133,6 @@ jobs: runs-on: windows-latest needs: - check_version - - git_tag if: needs.check_version.outputs.version_bumped == 'True' steps: - uses: actions/checkout@v4