Skip to content

Commit 03bb3b2

Browse files
Merge pull request #64 from StartAutomating/IrregularWorkflow
Irregular workflow
2 parents bd9f453 + 5030e0b commit 03bb3b2

File tree

2 files changed

+371
-2
lines changed

2 files changed

+371
-2
lines changed

.github/workflows/IrregularTests.yml

+370-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,88 @@
11

2-
name: IrregularTests
2+
name: Test, Tag, Release, and Publish
33
jobs:
4+
PowerShellStaticAnalysis:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- name: InstallScriptCop
8+
id: InstallScriptCop
9+
shell: pwsh
10+
run: |
11+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
12+
Install-Module -Name ScriptCop -Repository PSGallery -Force -Scope CurrentUser
13+
Import-Module ScriptCop -Force -PassThru
14+
- name: InstallPSScriptAnalyzer
15+
id: InstallPSScriptAnalyzer
16+
shell: pwsh
17+
run: |
18+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
19+
Install-Module -Name PSScriptAnalyzer -Repository PSGallery -Force -Scope CurrentUser
20+
Import-Module PSScriptAnalyzer -Force -PassThru
21+
- name: InstallPSDevOps
22+
id: InstallPSDevOps
23+
shell: pwsh
24+
run: |
25+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
26+
Install-Module -Name PSDevOps -Repository PSGallery -Force -Scope CurrentUser
27+
Import-Module PSDevOps -Force -PassThru
28+
- name: Check out repository
29+
uses: actions/checkout@v2
30+
- name: RunScriptCop
31+
id: RunScriptCop
32+
shell: pwsh
33+
run: |
34+
$Parameters = @{}
35+
$Parameters.ModulePath = ${env:ModulePath}
36+
foreach ($k in @($parameters.Keys)) {
37+
if ([String]::IsNullOrEmpty($parameters[$k])) {
38+
$parameters.Remove($k)
39+
}
40+
}
41+
Write-Host "::debug:: RunScriptCop $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
42+
& {param([string]$ModulePath)
43+
Import-Module ScriptCop, PSDevOps -PassThru | Out-Host
44+
45+
if (-not $ModulePath) {
46+
$orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/"
47+
$ModulePath = ".\$moduleName.psd1"
48+
}
49+
if ($ModulePath -like '*PSDevOps*') {
50+
Remove-Module PSDeVOps # If running ScriptCop on PSDeVOps, we need to remove the global module first.
51+
}
52+
53+
54+
$importedModule =Import-Module $ModulePath -Force -PassThru
55+
56+
$importedModule | Out-Host
57+
58+
$importedModule |
59+
Test-Command |
60+
Tee-Object -Variable scriptCopIssues |
61+
Out-Host
62+
63+
foreach ($issue in $scriptCopIssues) {
64+
Write-GitHubWarning -Message "$($issue.ItemWithProblem): $($issue.Problem)"
65+
}
66+
} @Parameters
67+
- name: RunPSScriptAnalyzer
68+
id: RunPSScriptAnalyzer
69+
shell: pwsh
70+
run: |
71+
Import-Module PSScriptAnalyzer, PSDevOps -PassThru | Out-Host
72+
$invokeScriptAnalyzerSplat = @{Path='.\'}
73+
if ($ENV:PSScriptAnalyzer_Recurse) {
74+
$invokeScriptAnalyzerSplat.Recurse = $true
75+
}
76+
$result = Invoke-ScriptAnalyzer @invokeScriptAnalyzerSplat
77+
78+
foreach ($r in $result) {
79+
if ('information', 'warning' -contains $r.Severity) {
80+
Write-GitHubWarning -Message "$($r.RuleName) : $($r.Message)" -SourcePath $r.ScriptPath -LineNumber $r.Line -ColumnNumber $r.Column
81+
}
82+
elseif ($r.Severity -eq 'Error') {
83+
Write-GitHubError -Message "$($r.RuleName) : $($r.Message)" -SourcePath $r.ScriptPath -LineNumber $r.Line -ColumnNumber $r.Column
84+
}
85+
}
486
TestPowerShellOnLinux:
587
runs-on: ubuntu-latest
688
steps:
@@ -107,6 +189,293 @@ jobs:
107189
name: PesterResults
108190
path: '**.TestResults.xml'
109191
if: ${{always()}}
192+
TagReleaseAndPublish:
193+
runs-on: ubuntu-latest
194+
if: ${{ success() }}
195+
steps:
196+
- name: Check out repository
197+
uses: actions/checkout@v2
198+
- name: TagModuleVersion
199+
id: TagModuleVersion
200+
shell: pwsh
201+
run: |
202+
$Parameters = @{}
203+
$Parameters.ModulePath = ${env:ModulePath}
204+
$Parameters.UserEmail = ${env:UserEmail}
205+
$Parameters.UserName = ${env:UserName}
206+
$Parameters.TagVersionFormat = ${env:TagVersionFormat}
207+
$Parameters.TagAnnotationFormat = ${env:TagAnnotationFormat}
208+
foreach ($k in @($parameters.Keys)) {
209+
if ([String]::IsNullOrEmpty($parameters[$k])) {
210+
$parameters.Remove($k)
211+
}
212+
}
213+
Write-Host "::debug:: TagModuleVersion $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
214+
& {param(
215+
[string]
216+
$ModulePath,
217+
218+
# The user email associated with a git commit.
219+
[string]
220+
$UserEmail,
221+
222+
# The user name associated with a git commit.
223+
[string]
224+
$UserName,
225+
226+
# The tag version format (default value: 'v$(imported.Version)')
227+
# This can expand variables. $imported will contain the imported module.
228+
[string]
229+
$TagVersionFormat = 'v$($imported.Version)',
230+
231+
# The tag version format (default value: '$($imported.Name) $(imported.Version)')
232+
# This can expand variables. $imported will contain the imported module.
233+
[string]
234+
$TagAnnotationFormat = '$($imported.Name) $($imported.Version)'
235+
)
236+
237+
238+
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
239+
[IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
240+
} else { $null }
241+
242+
243+
@"
244+
::group::GitHubEvent
245+
$($gitHubEvent | ConvertTo-Json -Depth 100)
246+
::endgroup::
247+
"@ | Out-Host
248+
249+
if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?<PRNumber>\d+)") -and
250+
(-not $gitHubEvent.psobject.properties['inputs'])) {
251+
"::warning::Pull Request has not merged, skipping Tagging" | Out-Host
252+
return
253+
}
254+
255+
256+
257+
$imported =
258+
if (-not $ModulePath) {
259+
$orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/"
260+
Import-Module ".\$moduleName.psd1" -Force -PassThru -Global
261+
} else {
262+
Import-Module $modulePath -Force -PassThru -Global
263+
}
264+
265+
if (-not $imported) { return }
266+
267+
$targetVersion =$ExecutionContext.InvokeCommand.ExpandString($TagVersionFormat)
268+
$existingTags = git tag --list
269+
270+
@"
271+
Target Version: $targetVersion
272+
273+
Existing Tags:
274+
$($existingTags -join [Environment]::NewLine)
275+
"@ | Out-Host
276+
277+
$versionTagExists = $existingTags | Where-Object { $_ -match $targetVersion }
278+
279+
if ($versionTagExists) {
280+
"::warning::Version $($versionTagExists)"
281+
return
282+
}
283+
284+
if (-not $UserName) { $UserName = $env:GITHUB_ACTOR }
285+
if (-not $UserEmail) { $UserEmail = "$UserName@github.com" }
286+
git config --global user.email $UserEmail
287+
git config --global user.name $UserName
288+
289+
git tag -a $targetVersion -m $ExecutionContext.InvokeCommand.ExpandString($TagAnnotationFormat)
290+
git push origin --tags
291+
292+
if ($env:GITHUB_ACTOR) {
293+
exit 0
294+
}} @Parameters
295+
- name: ReleaseModule
296+
id: ReleaseModule
297+
shell: pwsh
298+
run: |
299+
$Parameters = @{}
300+
$Parameters.ModulePath = ${env:ModulePath}
301+
$Parameters.UserEmail = ${env:UserEmail}
302+
$Parameters.UserName = ${env:UserName}
303+
$Parameters.TagVersionFormat = ${env:TagVersionFormat}
304+
foreach ($k in @($parameters.Keys)) {
305+
if ([String]::IsNullOrEmpty($parameters[$k])) {
306+
$parameters.Remove($k)
307+
}
308+
}
309+
Write-Host "::debug:: ReleaseModule $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
310+
& {param(
311+
[string]
312+
$ModulePath,
313+
314+
# The user email associated with a git commit.
315+
[string]
316+
$UserEmail,
317+
318+
# The user name associated with a git commit.
319+
[string]
320+
$UserName,
321+
322+
# The tag version format (default value: 'v$(imported.Version)')
323+
# This can expand variables. $imported will contain the imported module.
324+
[string]
325+
$TagVersionFormat = 'v$($imported.Version)'
326+
)
327+
328+
329+
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
330+
[IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
331+
} else { $null }
332+
333+
334+
@"
335+
::group::GitHubEvent
336+
$($gitHubEvent | ConvertTo-Json -Depth 100)
337+
::endgroup::
338+
"@ | Out-Host
339+
340+
if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?<PRNumber>\d+)") -and
341+
(-not $gitHubEvent.psobject.properties['inputs'])) {
342+
"::warning::Pull Request has not merged, skipping GitHub release" | Out-Host
343+
return
344+
}
345+
346+
347+
348+
$imported =
349+
if (-not $ModulePath) {
350+
$orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/"
351+
Import-Module ".\$moduleName.psd1" -Force -PassThru -Global
352+
} else {
353+
Import-Module $modulePath -Force -PassThru -Global
354+
}
355+
356+
if (-not $imported) { return }
357+
358+
$targetVersion =$ExecutionContext.InvokeCommand.ExpandString($TagVersionFormat)
359+
$targetReleaseName = $targetVersion
360+
$releasesURL = 'https://api.github.com/repos/${{github.repository}}/releases'
361+
"Release URL: $releasesURL" | Out-Host
362+
$listOfReleases = Invoke-RestMethod -Uri $releasesURL -Method Get -Headers @{
363+
"Accept" = "application/vnd.github.v3+json"
364+
"Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}'
365+
}
366+
367+
$releaseExists = $listOfReleases | Where-Object tag_name -eq $targetVersion
368+
369+
if ($releaseExists) {
370+
"::warning::Release '$($releaseExists.Name )' Already Exists" | Out-Host
371+
return
372+
}
373+
374+
375+
Invoke-RestMethod -Uri $releasesURL -Method Post -Body (
376+
[Ordered]@{
377+
owner = '${{github.owner}}'
378+
repo = '${{github.repository}}'
379+
tag_name = $targetVersion
380+
name = "$($imported.Name) $targetVersion"
381+
body =
382+
if ($env:RELEASENOTES) {
383+
$env:RELEASENOTES
384+
} elseif ($imported.PrivateData.PSData.ReleaseNotes) {
385+
$imported.PrivateData.PSData.ReleaseNotes
386+
} else {
387+
"$($imported.Name) $targetVersion"
388+
}
389+
draft = if ($env:RELEASEISDRAFT) { [bool]::Parse($env:RELEASEISDRAFT) } else { $false }
390+
prerelease = if ($env:PRERELEASE) { [bool]::Parse($env:PRERELEASE) } else { $false }
391+
} | ConvertTo-Json
392+
) -Headers @{
393+
"Accept" = "application/vnd.github.v3+json"
394+
"Content-type" = "application/json"
395+
"Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}'
396+
}
397+
} @Parameters
398+
- name: PublishPowerShellGallery
399+
id: PublishPowerShellGallery
400+
shell: pwsh
401+
run: |
402+
$Parameters = @{}
403+
$Parameters.ModulePath = ${env:ModulePath}
404+
foreach ($k in @($parameters.Keys)) {
405+
if ([String]::IsNullOrEmpty($parameters[$k])) {
406+
$parameters.Remove($k)
407+
}
408+
}
409+
Write-Host "::debug:: PublishPowerShellGallery $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
410+
& {param(
411+
[string]
412+
$ModulePath
413+
)
414+
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
415+
[IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
416+
} else { $null }
417+
418+
419+
@"
420+
::group::GitHubEvent
421+
$($gitHubEvent | ConvertTo-Json -Depth 100)
422+
::endgroup::
423+
"@ | Out-Host
424+
425+
if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?<PRNumber>\d+)") -and
426+
(-not $gitHubEvent.psobject.properties['inputs'])) {
427+
"::warning::Pull Request has not merged, skipping Gallery Publish" | Out-Host
428+
return
429+
}
430+
431+
432+
$imported =
433+
if (-not $ModulePath) {
434+
$orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/"
435+
Import-Module ".\$moduleName.psd1" -Force -PassThru -Global
436+
} else {
437+
Import-Module $modulePath -Force -PassThru -Global
438+
}
439+
440+
if (-not $imported) { return }
441+
442+
$foundModule = try { Find-Module -Name $imported.Name -ErrorAction SilentlyContinue } catch {}
443+
444+
if ($foundModule -and $foundModule.Version -ge $imported.Version) {
445+
"::warning::Gallery Version of $moduleName is more recent ($($foundModule.Version) >= $($imported.Version))" | Out-Host
446+
} else {
447+
448+
$gk = '${{secrets.GALLERYKEY}}'
449+
450+
$rn = Get-Random
451+
$moduleTempFolder = Join-Path $pwd "$rn"
452+
$moduleTempPath = Join-Path $moduleTempFolder $moduleName
453+
New-Item -ItemType Directory -Path $moduleTempPath -Force | Out-Host
454+
455+
Write-Host "Staging Directory: $ModuleTempPath"
456+
457+
$imported | Split-Path |
458+
Get-ChildItem -Force |
459+
Where-Object Name -NE $rn |
460+
Copy-Item -Destination $moduleTempPath -Recurse
461+
462+
$moduleGitPath = Join-Path $moduleTempPath '.git'
463+
Write-Host "Removing .git directory"
464+
if (Test-Path $moduleGitPath) {
465+
Remove-Item -Recurse -Force $moduleGitPath
466+
}
467+
Write-Host "Module Files:"
468+
Get-ChildItem $moduleTempPath -Recurse
469+
Write-Host "Publishing $moduleName [$($imported.Version)] to Gallery"
470+
Publish-Module -Path $moduleTempPath -NuGetApiKey $gk
471+
if ($?) {
472+
Write-Host "Published to Gallery"
473+
} else {
474+
Write-Host "Gallery Publish Failed"
475+
exit 1
476+
}
477+
}
478+
} @Parameters
110479
on:
111480
push:
112481
workflow_dispatch:

Irregular.GitHubWorkflow.PSDevops.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#requires -Module PSDevOps
2-
New-GitHubWorkflow -Name IrregularTests -Job TestPowerShellOnLinux -On Push, Demand |
2+
New-GitHubWorkflow -Name "Test, Tag, Release, and Publish" -Job PowerShellStaticAnalysis, TestPowerShellOnLinux, TagReleaseAndPublish -On Push, Demand |
33
Set-Content .\.github\workflows\IrregularTests.yml -Encoding UTF8

0 commit comments

Comments
 (0)