Skip to content

Commit 42c8d42

Browse files
author
James Brundage
committed
feat: PSJekyll Action Improvements ( Fixes #102, Fixes #104, Fixes #105, Fixes #106, Fixes #129 ) [skip ci]
Refactoring based off of recent ugit release's example
1 parent 71e8016 commit 42c8d42

File tree

2 files changed

+277
-145
lines changed

2 files changed

+277
-145
lines changed

Build/GitHub/Actions/PSJekyllAction.ps1

+114-58
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,72 @@
11
<#
22
.Synopsis
3-
GitHub Action for PSJekyll
3+
GitHub Action for ugit
44
.Description
5-
GitHub Action for PSJekyll. This will:
5+
GitHub Action for ugit. This will:
66
7-
* Import PSJekyll
8-
* Run all *.PSJekyll.ps1 files beneath the workflow directory
9-
* Run a .PSJekyllScript parameter.
7+
* Import ugit
8+
* If `-Run` is provided, run that script
9+
* Otherwise, unless `-SkipScriptFile` is passed, run all *.ugit.ps1 files beneath the workflow directory
10+
* If any `-ActionScript` was provided, run scripts from the action path that match a wildcard pattern.
1011
1112
If you will be making changes using the GitHubAPI, you should provide a -GitHubToken
1213
If none is provided, and ENV:GITHUB_TOKEN is set, this will be used instead.
1314
Any files changed can be outputted by the script, and those changes can be checked back into the repo.
1415
Make sure to use the "persistCredentials" option with checkout.
15-
1616
#>
1717

1818
param(
19-
# A PowerShell Script that uses PSJekyll.
19+
# A PowerShell Script that uses ugit.
2020
# Any files outputted from the script will be added to the repository.
2121
# If those files have a .Message attached to them, they will be committed with that message.
2222
[string]
23-
$PSJekyllScript,
23+
$Run,
2424

25-
# If set, will not process any files named *.PSJekyll.ps1
25+
# If set, will not process any files named *.ugit.ps1
2626
[switch]
27-
$SkipPSJekyllPS1,
27+
$SkipScriptFile,
2828

2929
# A list of modules to be installed from the PowerShell gallery before scripts run.
3030
[string[]]
3131
$InstallModule,
3232

33+
# If provided, will commit any remaining changes made to the workspace with this commit message.
34+
[string]
35+
$CommitMessage,
36+
3337
# If provided, will checkout a new branch before making the changes.
38+
# If not provided, will use the current branch.
3439
[string]
3540
$TargetBranch,
3641

37-
# If provided, will commit any remaining changes made to the workspace with this commit message.
42+
# The name of one or more scripts to run, from this action's path.
43+
[string[]]
44+
$ActionScript = '[\/]Examples[\/]*',
45+
46+
# The github token to use for requests.
3847
[string]
39-
$CommitMessage,
48+
$GitHubToken = '{{ secrets.GITHUB_TOKEN }}',
4049

4150
# The user email associated with a git commit. If this is not provided, it will be set to the [email protected].
4251
[string]
4352
$UserEmail,
4453

4554
# The user name associated with a git commit.
4655
[string]
47-
$UserName
56+
$UserName,
57+
58+
# If set, will not push any changes made to the repository.
59+
# (they will still be committed unless `-NoCommit` is passed)
60+
[switch]
61+
$NoPush,
62+
63+
# If set, will not commit any changes made to the repository.
64+
# (this also implies `-NoPush`)
65+
[switch]
66+
$NoCommit
4867
)
4968

5069
$ErrorActionPreference = 'continue'
51-
$error.Clear()
5270
"::group::Parameters" | Out-Host
5371
[PSCustomObject]$PSBoundParameters | Format-List | Out-Host
5472
"::endgroup::" | Out-Host
@@ -59,13 +77,19 @@ $gitHubEvent =
5977
} else { $null }
6078

6179
$anyFilesChanged = $false
62-
$moduleName = 'PSJekyll'
80+
$ActionModuleName = 'PSJekyll'
6381
$actorInfo = $null
6482

6583
"::group::Parameters" | Out-Host
6684
[PSCustomObject]$PSBoundParameters | Format-List | Out-Host
6785
"::endgroup::" | Out-Host
6886

87+
$checkDetached = git symbolic-ref -q HEAD
88+
if ($LASTEXITCODE) {
89+
"::warning::On detached head, skipping action" | Out-Host
90+
exit 0
91+
}
92+
6993
function InstallActionModule {
7094
param([string]$ModuleToInstall)
7195
$moduleInWorkspace = Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse -File |
@@ -74,8 +98,13 @@ function InstallActionModule {
7498
$(Get-Content $_.FullName -Raw) -match 'ModuleVersion'
7599
}
76100
if (-not $moduleInWorkspace) {
77-
Install-Module $moduleToInstall -Scope CurrentUser -Force
101+
$availableModules = Get-Module -ListAvailable
102+
if ($availableModules.Name -notcontains $moduleToInstall) {
103+
Install-Module $moduleToInstall -Scope CurrentUser -Force -AcceptLicense -AllowClobber
104+
}
78105
Import-Module $moduleToInstall -Force -PassThru | Out-Host
106+
} else {
107+
Import-Module $moduleInWorkspace.FullName -Force -PassThru | Out-Host
79108
}
80109
}
81110
function ImportActionModule {
@@ -90,19 +119,19 @@ function ImportActionModule {
90119
#endregion -InstallModule
91120

92121
if ($env:GITHUB_ACTION_PATH) {
93-
$LocalModulePath = Join-Path $env:GITHUB_ACTION_PATH "$moduleName.psd1"
122+
$LocalModulePath = Join-Path $env:GITHUB_ACTION_PATH "$ActionModuleName.psd1"
94123
if (Test-path $LocalModulePath) {
95124
Import-Module $LocalModulePath -Force -PassThru | Out-String
96125
} else {
97-
throw "Module '$moduleName' not found"
126+
throw "Module '$ActionModuleName' not found"
98127
}
99-
} elseif (-not (Get-Module $moduleName)) {
100-
throw "Module '$ModuleName' not found"
128+
} elseif (-not (Get-Module $ActionModuleName)) {
129+
throw "Module '$ActionModuleName' not found"
101130
}
102131

103-
"::notice title=ModuleLoaded::$ModuleName Loaded from Path - $($LocalModulePath)" | Out-Host
132+
"::notice title=ModuleLoaded::$ActionModuleName Loaded from Path - $($LocalModulePath)" | Out-Host
104133
if ($env:GITHUB_STEP_SUMMARY) {
105-
"# $($moduleName)" |
134+
"# $($ActionModuleName)" |
106135
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
107136
}
108137
}
@@ -112,10 +141,17 @@ function InitializeAction {
112141

113142
# Configure git based on the $env:GITHUB_ACTOR
114143
if (-not $UserName) { $UserName = $env:GITHUB_ACTOR }
115-
if (-not $actorID) { $actorID = $env:GITHUB_ACTOR_ID }
144+
if (-not $actorID) { $actorID = $env:GITHUB_ACTOR_ID }
145+
$actorInfo =
146+
if ($GitHubToken -notmatch '^\{{2}' -and $GitHubToken -notmatch '\}{2}$') {
147+
Invoke-RestMethod -Uri "https://api.github.com/user/$actorID" -Headers @{ Authorization = "token $GitHubToken" }
148+
} else {
149+
Invoke-RestMethod -Uri "https://api.github.com/user/$actorID"
150+
}
151+
116152
if (-not $UserEmail) { $UserEmail = "$UserName@noreply.github.com" }
117153
git config --global user.email $UserEmail
118-
git config --global user.name $env:GITHUB_ACTOR
154+
git config --global user.name $actorInfo.name
119155

120156
# Pull down any changes
121157
git pull | Out-Host
@@ -131,58 +167,77 @@ function InitializeAction {
131167

132168
function InvokeActionModule {
133169
$myScriptStart = [DateTime]::Now
134-
$myScript = $ExecutionContext.SessionState.PSVariable.Get("${ModuleName}Script").Value
170+
$myScript = $ExecutionContext.SessionState.PSVariable.Get("Run").Value
135171
if ($myScript) {
136172
Invoke-Expression -Command $myScript |
137173
. ProcessOutput |
138174
Out-Host
175+
return
139176
}
140177
$myScriptTook = [Datetime]::Now - $myScriptStart
141178
$MyScriptFilesStart = [DateTime]::Now
142179

143180
$myScriptList = @()
144-
$shouldSkip = $ExecutionContext.SessionState.PSVariable.Get("Skip${ModuleName}PS1").Value
145-
if (-not $shouldSkip) {
181+
$shouldSkip = $ExecutionContext.SessionState.PSVariable.Get("SkipScriptFile").Value
182+
if ($shouldSkip) {
183+
return
184+
}
185+
$scriptFiles = @(
146186
Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE |
147-
Where-Object Name -Match "\.$($moduleName)\.ps1$" |
148-
ForEach-Object -Begin {
149-
if ($env:GITHUB_STEP_SUMMARY) {
150-
"## $ModuleName Scripts" |
151-
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
152-
}
153-
} -Process {
154-
$myScriptList += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/')
155-
$myScriptCount++
156-
$scriptFile = $_
157-
if ($env:GITHUB_STEP_SUMMARY) {
158-
"### $($scriptFile.Fullname -replace [Regex]::Escape($env:GITHUB_WORKSPACE))" |
159-
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
187+
Where-Object Name -Match "\.$($ActionModuleName)\.ps1$"
188+
if ($ActionScript) {
189+
if ($ActionScript -match '^\s{0,}/' -and $ActionScript -match '/\s{0,}$') {
190+
$ActionScriptPattern = $ActionScript.Trim('/').Trim() -as [regex]
191+
if ($ActionScriptPattern) {
192+
$ActionScriptPattern = [regex]::new($ActionScript.Trim('/').Trim(), 'IgnoreCase,IgnorePatternWhitespace', [timespan]::FromSeconds(0.5))
193+
Get-ChildItem -Recurse -Path $env:GITHUB_ACTION_PATH |
194+
Where-Object { $_.Name -Match "\.$($ActionModuleName)\.ps1$" -and $_.FullName -match $ActionScriptPattern }
160195
}
161-
$scriptCmd = $ExecutionContext.SessionState.InvokeCommand.GetCommand($scriptFile.FullName, 'ExternalScript')
162-
foreach ($requiredModule in $CommandInfo.ScriptBlock.Ast.ScriptRequirements.RequiredModules) {
163-
if ($requiredModule.Name -and
164-
(-not $requiredModule.MaximumVersion) -and
165-
(-not $requiredModule.RequiredVersion)
166-
) {
167-
InstallActionModule $requiredModule.Name
168-
}
196+
} else {
197+
Get-ChildItem -Recurse -Path $env:GITHUB_ACTION_PATH |
198+
Where-Object Name -Match "\.$($ActionModuleName)\.ps1$" |
199+
Where-Object FullName -Like $ActionScript
200+
}
201+
}
202+
) | Select-Object -Unique
203+
$scriptFiles |
204+
ForEach-Object -Begin {
205+
if ($env:GITHUB_STEP_SUMMARY) {
206+
"## $ActionModuleName Scripts" |
207+
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
208+
}
209+
} -Process {
210+
$myScriptList += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/')
211+
$myScriptCount++
212+
$scriptFile = $_
213+
if ($env:GITHUB_STEP_SUMMARY) {
214+
"### $($scriptFile.Fullname -replace [Regex]::Escape($env:GITHUB_WORKSPACE))" |
215+
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
216+
}
217+
$scriptCmd = $ExecutionContext.SessionState.InvokeCommand.GetCommand($scriptFile.FullName, 'ExternalScript')
218+
foreach ($requiredModule in $CommandInfo.ScriptBlock.Ast.ScriptRequirements.RequiredModules) {
219+
if ($requiredModule.Name -and
220+
(-not $requiredModule.MaximumVersion) -and
221+
(-not $requiredModule.RequiredVersion)
222+
) {
223+
InstallActionModule $requiredModule.Name
169224
}
170-
$scriptFileOutputs = . $scriptCmd
171-
$scriptFileOutputs |
172-
. ProcessOutput |
173-
Out-Host
174225
}
175-
}
226+
$scriptFileOutputs = . $scriptCmd
227+
$scriptFileOutputs |
228+
. ProcessOutput |
229+
Out-Host
230+
}
176231

177232
$MyScriptFilesTook = [Datetime]::Now - $MyScriptFilesStart
178-
$SummaryOfMyScripts = "$myScriptCount $moduleName scripts took $($MyScriptFilesTook.TotalSeconds) seconds"
233+
$SummaryOfMyScripts = "$myScriptCount $ActionModuleName scripts took $($MyScriptFilesTook.TotalSeconds) seconds"
179234
$SummaryOfMyScripts |
180235
Out-Host
181236
if ($env:GITHUB_STEP_SUMMARY) {
182237
$SummaryOfMyScripts |
183238
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
184239
}
185-
#region Custom
240+
#region Custom
186241
#endregion Custom
187242
}
188243

@@ -237,11 +292,12 @@ function PushActionOutput {
237292
}
238293

239294
$checkDetached = git symbolic-ref -q HEAD
240-
if (-not $LASTEXITCODE) {
241-
"::notice::Pushing Changes" | Out-Host
295+
if (-not $LASTEXITCODE -and -not $NoPush -and -not $noCommit) {
242296
if ($TargetBranch -and $anyFilesChanged) {
297+
"::notice::Pushing Changes to $targetBranch" | Out-Host
243298
git push --set-upstream origin $TargetBranch
244299
} elseif ($anyFilesChanged) {
300+
"::notice::Pushing Changes" | Out-Host
245301
git push
246302
}
247303
"Git Push Output: $($gitPushed | Out-String)"
@@ -269,7 +325,7 @@ filter ProcessOutput {
269325
} elseif ($outItem) {
270326
$outItem.FullName, (git status $outItem.Fullname -s)
271327
}
272-
if ($shouldCommit) {
328+
if ($shouldCommit -and -not $NoCommit) {
273329
"$fullName has changed, and should be committed" | Out-Host
274330
git add $fullName
275331
if ($out.Message) {

0 commit comments

Comments
 (0)