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
1818param (
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+
6993function 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}
81110function 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
132168function 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