1
+ <#
2
+ . Synopsis
3
+ GitHub Action for PSJekyll
4
+ . Description
5
+ GitHub Action for PSJekyll. This will:
6
+
7
+ * Import PSJekyll
8
+ * Run all *.PSJekyll.ps1 files beneath the workflow directory
9
+ * Run a .PSJekyllScript parameter.
10
+
11
+ If you will be making changes using the GitHubAPI, you should provide a -GitHubToken
12
+ If none is provided, and ENV:GITHUB_TOKEN is set, this will be used instead.
13
+ Any files changed can be outputted by the script, and those changes can be checked back into the repo.
14
+ Make sure to use the "persistCredentials" option with checkout.
15
+
16
+ #>
17
+
18
+ param (
19
+ # A PowerShell Script that uses PSJekyll.
20
+ # Any files outputted from the script will be added to the repository.
21
+ # If those files have a .Message attached to them, they will be committed with that message.
22
+ [string ]
23
+ $PSJekyllScript ,
24
+
25
+ # If set, will not process any files named *.PSJekyll.ps1
26
+ [switch ]
27
+ $SkipPSJekyllPS1 ,
28
+
29
+ # A list of modules to be installed from the PowerShell gallery before scripts run.
30
+ [string []]
31
+ $InstallModule ,
32
+
33
+ # If provided, will checkout a new branch before making the changes.
34
+ [string ]
35
+ $TargetBranch ,
36
+
37
+ # If provided, will commit any remaining changes made to the workspace with this commit message.
38
+ [string ]
39
+ $CommitMessage ,
40
+
41
+ # The user email associated with a git commit. If this is not provided, it will be set to the [email protected] .
42
+ [string ]
43
+ $UserEmail ,
44
+
45
+ # The user name associated with a git commit.
46
+ [string ]
47
+ $UserName
48
+ )
49
+
50
+ $ErrorActionPreference = ' continue'
51
+ $error.Clear ()
52
+ " ::group::Parameters" | Out-Host
53
+ [PSCustomObject ]$PSBoundParameters | Format-List | Out-Host
54
+ " ::endgroup::" | Out-Host
55
+
56
+ $gitHubEvent =
57
+ if ($env: GITHUB_EVENT_PATH ) {
58
+ [IO.File ]::ReadAllText($env: GITHUB_EVENT_PATH ) | ConvertFrom-Json
59
+ } else { $null }
60
+
61
+ $anyFilesChanged = $false
62
+ $moduleName = ' PSJekyll'
63
+ $actorInfo = $null
64
+
65
+ " ::group::Parameters" | Out-Host
66
+ [PSCustomObject ]$PSBoundParameters | Format-List | Out-Host
67
+ " ::endgroup::" | Out-Host
68
+
69
+ function InstallActionModule {
70
+ param ([string ]$ModuleToInstall )
71
+ $moduleInWorkspace = Get-ChildItem - Path $env: GITHUB_WORKSPACE - Recurse - File |
72
+ Where-Object Name -eq " $ ( $moduleToInstall ) .psd1" |
73
+ Where-Object {
74
+ $ (Get-Content $_.FullName - Raw) -match ' ModuleVersion'
75
+ }
76
+ if (-not $moduleInWorkspace ) {
77
+ Install-Module $moduleToInstall - Scope CurrentUser - Force
78
+ Import-Module $moduleToInstall - Force - PassThru | Out-Host
79
+ }
80
+ }
81
+ function ImportActionModule {
82
+ # region -InstallModule
83
+ if ($InstallModule ) {
84
+ " ::group::Installing Modules" | Out-Host
85
+ foreach ($moduleToInstall in $InstallModule ) {
86
+ InstallActionModule - ModuleToInstall $moduleToInstall
87
+ }
88
+ " ::endgroup::" | Out-Host
89
+ }
90
+ # endregion -InstallModule
91
+
92
+ if ($env: GITHUB_ACTION_PATH ) {
93
+ $LocalModulePath = Join-Path $env: GITHUB_ACTION_PATH " $moduleName .psd1"
94
+ if (Test-path $LocalModulePath ) {
95
+ Import-Module $LocalModulePath - Force - PassThru | Out-String
96
+ } else {
97
+ throw " Module '$moduleName ' not found"
98
+ }
99
+ } elseif (-not (Get-Module $moduleName )) {
100
+ throw " Module '$ModuleName ' not found"
101
+ }
102
+
103
+ " ::notice title=ModuleLoaded::$ModuleName Loaded from Path - $ ( $LocalModulePath ) " | Out-Host
104
+ if ($env: GITHUB_STEP_SUMMARY ) {
105
+ " # $ ( $moduleName ) " |
106
+ Out-File - Append - FilePath $env: GITHUB_STEP_SUMMARY
107
+ }
108
+ }
109
+ function InitializeAction {
110
+ # region Custom
111
+ # endregion Custom
112
+
113
+ # Configure git based on the $env:GITHUB_ACTOR
114
+ if (-not $UserName ) { $UserName = $env: GITHUB_ACTOR }
115
+ if (-not $actorID ) { $actorID = $env: GITHUB_ACTOR_ID }
116
+ if (-not $UserEmail ) { $UserEmail = " $UserName @noreply.github.com" }
117
+ git config -- global user.email $UserEmail
118
+ git config -- global user.name $env: GITHUB_ACTOR
119
+
120
+ # Pull down any changes
121
+ git pull | Out-Host
122
+
123
+ if ($TargetBranch ) {
124
+ " ::notice title=Expanding target branch string $targetBranch " | Out-Host
125
+ $TargetBranch = $ExecutionContext.SessionState.InvokeCommand.ExpandString ($TargetBranch )
126
+ " ::notice title=Checking out target branch::$targetBranch " | Out-Host
127
+ git checkout - b $TargetBranch | Out-Host
128
+ git pull | Out-Host
129
+ }
130
+ }
131
+
132
+ function InvokeActionModule {
133
+ $myScriptStart = [DateTime ]::Now
134
+ $myScript = $ExecutionContext.SessionState.PSVariable.Get (" ${ModuleName} Script" ).Value
135
+ if ($myScript ) {
136
+ Invoke-Expression - Command $myScript |
137
+ . ProcessOutput |
138
+ Out-Host
139
+ }
140
+ $myScriptTook = [Datetime ]::Now - $myScriptStart
141
+ $MyScriptFilesStart = [DateTime ]::Now
142
+
143
+ $myScriptList = @ ()
144
+ $shouldSkip = $ExecutionContext.SessionState.PSVariable.Get (" Skip${ModuleName} PS1" ).Value
145
+ if (-not $shouldSkip ) {
146
+ 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
160
+ }
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
+ }
169
+ }
170
+ $scriptFileOutputs = . $scriptCmd
171
+ $scriptFileOutputs |
172
+ . ProcessOutput |
173
+ Out-Host
174
+ }
175
+ }
176
+
177
+ $MyScriptFilesTook = [Datetime ]::Now - $MyScriptFilesStart
178
+ $SummaryOfMyScripts = " $myScriptCount $moduleName scripts took $ ( $MyScriptFilesTook.TotalSeconds ) seconds"
179
+ $SummaryOfMyScripts |
180
+ Out-Host
181
+ if ($env: GITHUB_STEP_SUMMARY ) {
182
+ $SummaryOfMyScripts |
183
+ Out-File - Append - FilePath $env: GITHUB_STEP_SUMMARY
184
+ }
185
+ # region Custom
186
+ # endregion Custom
187
+ }
188
+
189
+ function OutError {
190
+ $anyRuntimeExceptions = $false
191
+ foreach ($err in $error ) {
192
+ $errParts = @ (
193
+ " ::error "
194
+ @ (
195
+ if ($err.InvocationInfo.ScriptName ) {
196
+ " file=$ ( $err.InvocationInfo.ScriptName ) "
197
+ }
198
+ if ($err.InvocationInfo.ScriptLineNumber -ge 1 ) {
199
+ " line=$ ( $err.InvocationInfo.ScriptLineNumber ) "
200
+ if ($err.InvocationInfo.OffsetInLine -ge 1 ) {
201
+ " col=$ ( $err.InvocationInfo.OffsetInLine ) "
202
+ }
203
+ }
204
+ if ($err.CategoryInfo.Activity ) {
205
+ " title=$ ( $err.CategoryInfo.Activity ) "
206
+ }
207
+ ) -join ' ,'
208
+ " ::"
209
+ $err.Exception.Message
210
+ if ($err.CategoryInfo.Category -eq ' OperationStopped' -and
211
+ $err.CategoryInfo.Reason -eq ' RuntimeException' ) {
212
+ $anyRuntimeExceptions = $true
213
+ }
214
+ ) -join ' '
215
+ $errParts | Out-Host
216
+ if ($anyRuntimeExceptions ) {
217
+ exit 1
218
+ }
219
+ }
220
+ }
221
+
222
+ function PushActionOutput {
223
+ if ($anyFilesChanged ) {
224
+ " ::notice::$ ( $anyFilesChanged ) Files Changed" | Out-Host
225
+ }
226
+ if ($CommitMessage -or $anyFilesChanged ) {
227
+ if ($CommitMessage ) {
228
+ Get-ChildItem $env: GITHUB_WORKSPACE - Recurse |
229
+ ForEach-Object {
230
+ $gitStatusOutput = git status $_.Fullname - s
231
+ if ($gitStatusOutput ) {
232
+ git add $_.Fullname
233
+ }
234
+ }
235
+
236
+ git commit - m $ExecutionContext.SessionState.InvokeCommand.ExpandString ($CommitMessage )
237
+ }
238
+
239
+ $checkDetached = git symbolic- ref - q HEAD
240
+ if (-not $LASTEXITCODE ) {
241
+ " ::notice::Pushing Changes" | Out-Host
242
+ if ($TargetBranch -and $anyFilesChanged ) {
243
+ git push -- set-upstream origin $TargetBranch
244
+ } elseif ($anyFilesChanged ) {
245
+ git push
246
+ }
247
+ " Git Push Output: $ ( $gitPushed | Out-String ) "
248
+ } else {
249
+ " ::notice::Not pushing changes (on detached head)" | Out-Host
250
+ $LASTEXITCODE = 0
251
+ exit 0
252
+ }
253
+ }
254
+ }
255
+
256
+ filter ProcessOutput {
257
+ $out = $_
258
+ $outItem = Get-Item - Path $out - ErrorAction Ignore
259
+ if (-not $outItem -and $out -is [string ]) {
260
+ $out | Out-Host
261
+ if ($env: GITHUB_STEP_SUMMARY ) {
262
+ " > $out " | Out-File - Append - FilePath $env: GITHUB_STEP_SUMMARY
263
+ }
264
+ return
265
+ }
266
+ $fullName , $shouldCommit =
267
+ if ($out -is [IO.FileInfo ]) {
268
+ $out.FullName , (git status $out.Fullname - s)
269
+ } elseif ($outItem ) {
270
+ $outItem.FullName , (git status $outItem.Fullname - s)
271
+ }
272
+ if ($shouldCommit ) {
273
+ " $fullName has changed, and should be committed" | Out-Host
274
+ git add $fullName
275
+ if ($out.Message ) {
276
+ git commit - m " $ ( $out.Message ) " | Out-Host
277
+ } elseif ($out.CommitMessage ) {
278
+ git commit - m " $ ( $out.CommitMessage ) " | Out-Host
279
+ } elseif ($gitHubEvent.head_commit.message ) {
280
+ git commit - m " $ ( $gitHubEvent.head_commit.message ) " | Out-Host
281
+ }
282
+ $anyFilesChanged = $true
283
+ }
284
+ $out
285
+ }
286
+
287
+ . ImportActionModule
288
+ . InitializeAction
289
+ . InvokeActionModule
290
+ . PushActionOutput
291
+ . OutError
0 commit comments