Skip to content

Commit a762e44

Browse files
Copy CI and release workflows from HeyItsGilbert/.github (#6)
* 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 * Fix Publish to only be workflow and bootstrap * Clean up --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent a98535d commit a762e44

2 files changed

Lines changed: 162 additions & 81 deletions

File tree

.github/workflows/ModuleCI.yml

Lines changed: 24 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,68 +11,44 @@ jobs:
1111
name: Run Linters
1212
runs-on: [ubuntu-latest]
1313
steps:
14-
- uses: actions/checkout@v4
15-
- uses: streetsidesoftware/cspell-action@v6
16-
with:
17-
strict: false
18-
suggestions: true
19-
incremental_files_only: true
20-
- uses: reviewdog/action-alex@v1.16.0
21-
with:
22-
github_token: ${{ secrets.github_token }}
23-
# Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review].
24-
reporter: github-pr-review
25-
level: warning
26-
- shell: pwsh
27-
name: Apply PSScriptAnalyzer Fixes
28-
run: Invoke-ScriptAnalyzer . -Fix
29-
- name: PSScriptAnalyzer Fixes
30-
uses: reviewdog/action-suggester@v1.21.0
31-
with:
32-
tool_name: 'PSScriptAnalyzer'
14+
- uses: actions/checkout@v4
15+
- uses: streetsidesoftware/cspell-action@v6
16+
with:
17+
strict: false
18+
suggestions: true
19+
incremental_files_only: true
20+
- shell: pwsh
21+
name: Apply PSScriptAnalyzer Fixes
22+
run: Invoke-ScriptAnalyzer . -Fix
23+
- name: PSScriptAnalyzer Fixes
24+
uses: reviewdog/action-suggester@v1.21.0
25+
with:
26+
tool_name: "PSScriptAnalyzer"
3327
test:
34-
name: Run Tests
28+
name: Run Pwsh Tests
29+
# We still have the azure pipeline setup that's running windows
3530
runs-on: ${{ matrix.os }}
3631
strategy:
3732
fail-fast: false
3833
matrix:
3934
os: [ubuntu-latest, windows-latest, macOS-latest]
4035
steps:
41-
- uses: actions/checkout@v4
42-
- name: Install and cache PSDepend
43-
id: psdepend
44-
uses: potatoqualitee/psmodulecache@v6.2.1
45-
with:
46-
modules-to-cache: PSDepend:0.3.8
47-
- name: Determine modules to cache
48-
shell: pwsh
49-
id: modules-to-cache
50-
run: |
51-
$dependancies = Get-Dependency
52-
$f = $dependancies | ?{ $_.DependencyType -eq 'PSGalleryModule' } | %{ "{0}:{1}" -F $_.DependencyName, $_.Version}
53-
Write-Output "::set-output name=ModulesToCache::$($f -join ', ')"
54-
- name: Install and cache PowerShell modules
55-
id: psmodulecache
56-
uses: potatoqualitee/psmodulecache@v6.2.1
57-
with:
58-
modules-to-cache: ${{ steps.modules-to-cache.outputs.ModulesToCache }}
36+
- uses: actions/checkout@v4
37+
- name: Test
5938
shell: pwsh
60-
- name: Test
61-
shell: pwsh
62-
run: ./build.ps1 -Task Test
63-
- name: Upload Unit Test Results
64-
if: always()
65-
uses: actions/upload-artifact@v4
66-
with:
67-
name: Unit Test Results (OS ${{ matrix.os }})
68-
path: ./tests/out/testResults.xml
39+
run: ./build.ps1 -Task Test -Bootstrap
40+
- name: Upload Unit Test Results
41+
if: always()
42+
uses: actions/upload-artifact@v4
43+
with:
44+
name: Unit Test Results (OS ${{ matrix.os }})
45+
path: ./tests/out/testResults.xml
6946
publish-test-results:
7047
name: "Publish Unit Tests Results"
7148
needs: test
7249
runs-on: ubuntu-latest
7350
# the test job might be skipped, we don't need to run this job then
7451
if: success() || failure()
75-
7652
steps:
7753
- name: Download Artifacts
7854
uses: actions/download-artifact@v4
Lines changed: 138 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,153 @@
1+
# spell-checker:ignore BHPS PSGALLERY pwsh
12
name: Publish Module
3+
4+
concurrency:
5+
group: publish-${{ github.ref }}
6+
cancel-in-progress: false
7+
8+
permissions:
9+
contents: write
10+
211
on:
312
workflow_call:
13+
inputs:
14+
version:
15+
description: "The version to publish. Leave empty to use the version in the module manifest."
16+
required: false
17+
type: string
18+
isPrerelease:
19+
description: "Is this a prerelease version?"
20+
required: false
21+
default: false
22+
type: boolean
23+
dry_run:
24+
type: boolean
25+
description: "If true, skip actual publishing and just validate the workflow logic."
26+
required: false
27+
default: false
28+
secrets:
29+
PS_GALLERY_KEY:
30+
description: "The API key for publishing to the PowerShell Gallery."
31+
required: true
32+
433
jobs:
5-
publish:
6-
name: Publish Module
34+
check_version:
35+
name: Check Version
36+
timeout-minutes: 15
737
runs-on: windows-latest
38+
outputs:
39+
version_bumped: ${{ steps.check_if_versions_bumped.outputs.BUMPED }}
40+
module_name: ${{ steps.check_if_versions_bumped.outputs.MODULE_NAME }}
41+
new_version: ${{ steps.check_if_versions_bumped.outputs.NEW_VERSION }}
842
steps:
9-
# Get the current version
1043
- uses: actions/checkout@v4
11-
- name: Install and cache PSDepend
12-
id: psdepend
13-
uses: potatoqualitee/psmodulecache@v6.2.1
14-
with:
15-
modules-to-cache: PSDepend:0.3.8, BuildHelpers
16-
- shell: pwsh
17-
name: Check if this version is already published
18-
# Give an id to the step, so we can reference it later
44+
- name: Check if version is already published
1945
id: check_if_versions_bumped
20-
run: |
21-
Set-BuildEnvironment
22-
[version]$GalleryVersion = Get-NextNugetPackageVersion -Name $env:BHProjectName -ErrorAction Stop
23-
[version]$GithubVersion = Get-MetaData -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -ErrorAction Stop
24-
$bumped = $GithubVersion -ge $GalleryVersion
25-
26-
# Set the output named "version_bumped"
27-
Write-Host "::set-output name=version_bumped::$bumped"
28-
- name: Determine modules to cache
2946
shell: pwsh
30-
id: modules-to-cache
31-
if: steps.check_if_versions_bumped.outputs.version_bumped == 'True'
3247
run: |
33-
$dependancies = Get-Dependency
34-
$f = $dependancies | ?{ $_.DependencyType -eq 'PSGalleryModule' } | %{ "{0}:{1}" -F $_.DependencyName, $_.Version}
35-
Write-Output "::set-output name=ModulesToCache::$($f -join ', ')"
36-
- name: Install and cache PowerShell modules
37-
id: psmodulecache
38-
uses: potatoqualitee/psmodulecache@v6.2.1
39-
if: steps.check_if_versions_bumped.outputs.version_bumped == 'True'
48+
Install-Module BuildHelpers
49+
Import-Module BuildHelpers
50+
Set-BuildEnvironment -Force
51+
[version]$githubVersion = Get-MetaData -Path $env:BHPSModuleManifest -PropertyName 'ModuleVersion' -ErrorAction 'Stop'
52+
Write-Host "Current Version: $githubVersion"
53+
54+
# Override version if specified as input
55+
if (-not [String]::IsNullOrEmpty('${{ inputs.version }}')) {
56+
# Split version and prerelease suffix if present
57+
if('${{ inputs.version }}' -match '^(?<version>\d+\.\d+\.\d+)(-(?<prerelease>.+))?$') {
58+
$githubVersion = [version]$matches['version']
59+
if ($matches['prerelease']) {
60+
$prereleaseSuffix = $matches['prerelease']
61+
}
62+
} else {
63+
Write-Warning "Invalid version format: '${{ inputs.version }}'. Expected format: '1.2.3' or '1.2.3-beta'"
64+
}
65+
Write-Host "Module version was specified in workflow: $githubVersion"
66+
Update-MetaData -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -Value $githubVersion -ErrorAction 'Stop'
67+
}
68+
69+
$moduleSplat = @{
70+
Name = $env:BHProjectName
71+
}
72+
73+
# Handle pre-release versions
74+
$isPrerelease = '${{ inputs.isPrerelease }}' -eq 'true'
75+
Write-Host "Prerelease: $isPrerelease"
76+
if ($isPrerelease) {
77+
$PSData = Get-MetaData -Path $env:BHPSModuleManifest -PropertyName PrivateData.PSData -ErrorAction 'Stop'
78+
$moduleSplat['AllowPrerelease'] = $true
79+
$moduleSplat['RequiredVersion'] = "$githubVersion-$($PSData.Prerelease)"
80+
} else {
81+
$moduleSplat['AllowPrerelease'] = $false
82+
$moduleSplat['RequiredVersion'] = $githubVersion
83+
}
84+
Write-Host "Version to Publish: $($moduleSplat.RequiredVersion)"
85+
86+
# Check if exact version exists in PSGallery
87+
try {
88+
$existingModule = Find-Module @moduleSplat -ErrorAction Stop
89+
$bumped = $false
90+
Write-Host "Version $($moduleSplat.RequiredVersion) already exists in PSGallery - skipping publish"
91+
} catch {
92+
if ($_.CategoryInfo.Category -eq 'ObjectNotFound') {
93+
$bumped = $true
94+
Write-Host "Version $($moduleSplat.RequiredVersion) not found in PSGallery - will publish"
95+
} else {
96+
Write-Warning "Failed to check existing version: $($_.Exception.Message)"
97+
$bumped = $false
98+
}
99+
}
100+
101+
# Strip prerelease suffix for changelog lookup
102+
$versionForChangelog = "$($moduleSplat.RequiredVersion)" -replace '-.*$', ''
103+
104+
Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value "BUMPED=$bumped" -Confirm:$false -Encoding UTF8
105+
Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value "MODULE_NAME=$env:BHProjectName" -Confirm:$false -Encoding UTF8
106+
Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value "NEW_VERSION=$($moduleSplat.RequiredVersion)" -Confirm:$false -Encoding UTF8
107+
108+
create_release:
109+
name: Create GitHub Release
110+
runs-on: ubuntu-latest
111+
needs:
112+
- check_version
113+
steps:
114+
- uses: actions/checkout@v4
115+
- name: Read and validate changelog (keepachangelog)
116+
id: changelog
117+
uses: mindsers/changelog-reader-action@v2
118+
with:
119+
validation_level: warn
120+
version: ${{ needs.check_version.outputs.new_version }}
121+
path: ./CHANGELOG.md
122+
- name: Create GitHub Release
123+
uses: softprops/action-gh-release@v2
40124
with:
41-
modules-to-cache: ${{ steps.modules-to-cache.outputs.ModulesToCache }}
42-
shell: pwsh
125+
tag_name: ${{ needs.check_version.outputs.new_version }}
126+
name: Release ${{ steps.changelog.outputs.version }}
127+
body: ${{ steps.changelog.outputs.changes }}
128+
prerelease: ${{ steps.changelog.outputs.status == 'prereleased' }}
129+
draft: ${{ steps.changelog.outputs.status == 'unreleased' }}
130+
131+
publish:
132+
name: Publish Module
133+
runs-on: windows-latest
134+
needs:
135+
- check_version
136+
if: needs.check_version.outputs.version_bumped == 'True'
137+
steps:
138+
- uses: actions/checkout@v4
43139
- name: Publish to PSGallery
44140
shell: pwsh
45-
if: steps.check_if_versions_bumped.outputs.version_bumped == 'True'
46141
env:
47142
PSGALLERY_API_KEY: ${{ secrets.PS_GALLERY_KEY }}
48-
run: ./build.ps1 -Task Publish
143+
PACKAGE: ${{ needs.check_version.outputs.module_name }}
144+
VERSION: ${{ needs.check_version.outputs.new_version }}
145+
DRY_RUN: ${{ inputs.dry_run || false }}
146+
run: |
147+
if ($env:DRY_RUN -eq 'true') {
148+
Write-Host "DRY RUN: Would publish module to PSGallery"
149+
Write-Host "Module: $env:PACKAGE"
150+
Write-Host "Version: $env:VERSION"
151+
exit 0
152+
}
153+
./build.ps1 -Task 'Publish' -Bootstrap

0 commit comments

Comments
 (0)