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 username@noreply.github.com.
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