1+ <# 
2+ . Synopsis 
3+     GitHub Action for WebSocket 
4+ . Description 
5+     GitHub Action for WebSocket.  This will: 
6+ 
7+     * Import WebSocket 
8+     * If `-Run` is provided, run that script 
9+     * Otherwise, unless `-SkipScriptFile` is passed, run all *.WebSocket.ps1 files beneath the workflow directory 
10+       * If any `-ActionScript` was provided, run scripts from the action path that match a wildcard pattern. 
11+ 
12+     If you will be making changes using the GitHubAPI, you should provide a -GitHubToken 
13+     If none is provided, and ENV:GITHUB_TOKEN is set, this will be used instead. 
14+     Any files changed can be outputted by the script, and those changes can be checked back into the repo. 
15+     Make sure to use the "persistCredentials" option with checkout. 
16+ #> 
17+ 
18+ param (
19+ #  A PowerShell Script that uses WebSocket.  
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+ $Run , 
24+ 
25+ #  If set, will not process any files named *.WebSocket.ps1
26+ [switch ]
27+ $SkipScriptFile , 
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 commit any remaining changes made to the workspace with this commit message.
34+ [string ]
35+ $CommitMessage , 
36+ 
37+ #  If provided, will checkout a new branch before making the changes.
38+ #  If not provided, will use the current branch.
39+ [string ]
40+ $TargetBranch , 
41+ 
42+ #  The name of one or more scripts to run, from this action's path.
43+ [string []]
44+ $ActionScript , 
45+ 
46+ #  The github token to use for requests.
47+ [string ]
48+ $GitHubToken  =  ' {{ secrets.GITHUB_TOKEN }}' , 
49+ 
50+ #  The user email associated with a git commit.  If this is not provided, it will be set to the [email protected] .51+ [string ]
52+ $UserEmail , 
53+ 
54+ #  The user name associated with a git commit.
55+ [string ]
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 
67+ )
68+ 
69+ $ErrorActionPreference  =  ' continue' 
70+ " ::group::Parameters" |  Out-Host 
71+ [PSCustomObject ]$PSBoundParameters  |  Format-List  |  Out-Host 
72+ " ::endgroup::" |  Out-Host 
73+ 
74+ $gitHubEventJson  =  [IO.File ]::ReadAllText($env: GITHUB_EVENT_PATH )
75+ $gitHubEvent  =  
76+     if  ($env: GITHUB_EVENT_PATH ) {
77+         $gitHubEventJson  |  ConvertFrom-Json 
78+     } else  { $null  }
79+ " ::group::Parameters" |  Out-Host 
80+ $gitHubEvent    |  Format-List  |  Out-Host 
81+ " ::endgroup::" |  Out-Host 
82+ 
83+ 
84+ $anyFilesChanged  =  $false 
85+ $ActionModuleName  =  ' PSJekyll' 
86+ $actorInfo  =  $null 
87+ 
88+ 
89+ $checkDetached  =  git symbolic- ref - q HEAD
90+ if  ($LASTEXITCODE ) {
91+     " ::warning::On detached head, skipping action" |  Out-Host 
92+     exit  0 
93+ }
94+ 
95+ function  InstallActionModule  {
96+     param ([string ]$ModuleToInstall )
97+     $moduleInWorkspace  =  Get-ChildItem  - Path $env: GITHUB_WORKSPACE  - Recurse - File | 
98+         Where-Object  Name -eq  " $ ( $moduleToInstall ) .psd1" | 
99+         Where-Object  { 
100+             $ (Get-Content  $_.FullName   - Raw) -match  ' ModuleVersion' 
101+         }
102+     if  (-not  $moduleInWorkspace ) {
103+         $availableModules  =  Get-Module  - ListAvailable
104+         if  ($availableModules.Name   -notcontains  $moduleToInstall ) {
105+             Install-Module  $moduleToInstall  - Scope CurrentUser - Force - AcceptLicense - AllowClobber
106+         }
107+         Import-Module  $moduleToInstall  - Force - PassThru |  Out-Host 
108+     } else  {
109+         Import-Module  $moduleInWorkspace.FullName   - Force - PassThru |  Out-Host 
110+     }
111+ }
112+ function  ImportActionModule  {
113+     # region -InstallModule
114+     if  ($InstallModule ) {
115+         " ::group::Installing Modules" |  Out-Host 
116+         foreach  ($moduleToInstall  in  $InstallModule ) {
117+             InstallActionModule - ModuleToInstall $moduleToInstall 
118+         }
119+         " ::endgroup::" |  Out-Host 
120+     }
121+     # endregion -InstallModule
122+ 
123+     if  ($env: GITHUB_ACTION_PATH ) {
124+         $LocalModulePath  =  Join-Path  $env: GITHUB_ACTION_PATH  " $ActionModuleName .psd1" 
125+         if  (Test-path  $LocalModulePath ) {
126+             Import-Module  $LocalModulePath  - Force - PassThru |  Out-String 
127+         } else  {
128+             throw  " Module '$ActionModuleName ' not found" 
129+         }
130+     } elseif  (-not  (Get-Module  $ActionModuleName )) {    
131+         throw  " Module '$ActionModuleName ' not found" 
132+     }
133+ 
134+     " ::notice title=ModuleLoaded::$ActionModuleName  Loaded from Path - $ ( $LocalModulePath ) " |  Out-Host 
135+     if  ($env: GITHUB_STEP_SUMMARY ) {
136+         " # $ ( $ActionModuleName ) " | 
137+             Out-File  - Append - FilePath $env: GITHUB_STEP_SUMMARY 
138+     }
139+ }
140+ function  InitializeAction  {
141+     # region Custom 
142+     # endregion Custom
143+ 
144+     #  Configure git based on the $env:GITHUB_ACTOR
145+     if  (-not  $UserName ) { $UserName  =  $env: GITHUB_ACTOR  }
146+     if  (-not  $actorID )  { $actorID  =  $env: GITHUB_ACTOR_ID  }
147+     $actorInfo  =  
148+         if  ($GitHubToken  -notmatch  ' ^\{{2}' -and  $GitHubToken  -notmatch  ' \}{2}$' 
149+             Invoke-RestMethod  - Uri " https://api.github.com/user/$actorID " - Headers @ { Authorization  =  " token $GitHubToken " 
150+         } else  {
151+             Invoke-RestMethod  - Uri " https://api.github.com/user/$actorID " 
152+         }
153+     
154+     if  (-not  $UserEmail ) { $UserEmail  =  " $UserName @noreply.github.com" 
155+     git config -- global user.email $UserEmail 
156+     git config -- global user.name  $actorInfo.name  
157+ 
158+     #  Pull down any changes
159+     git pull |  Out-Host 
160+ 
161+     if  ($TargetBranch ) {
162+         " ::notice title=Expanding target branch string $targetBranch " |  Out-Host 
163+         $TargetBranch  =  $ExecutionContext.SessionState.InvokeCommand.ExpandString  ($TargetBranch )
164+         " ::notice title=Checking out target branch::$targetBranch " |  Out-Host 
165+         git checkout - b $TargetBranch  |  Out-Host     
166+         git pull |  Out-Host 
167+     }
168+ }
169+ 
170+ function  InvokeActionModule  {
171+     $myScriptStart  =  [DateTime ]::Now
172+     $myScript  =  $ExecutionContext.SessionState.PSVariable.Get  (" Run" 
173+     if  ($myScript ) {
174+         Invoke-Expression  - Command $myScript  | 
175+             .  ProcessOutput | 
176+             Out-Host 
177+         return 
178+     }
179+     $myScriptTook  =  [Datetime ]::Now -  $myScriptStart 
180+     $MyScriptFilesStart  =  [DateTime ]::Now
181+ 
182+     $myScriptList   =  @ ()
183+     $shouldSkip  =  $ExecutionContext.SessionState.PSVariable.Get  (" SkipScriptFile" 
184+     if  ($shouldSkip ) {
185+         return  
186+     }
187+     $scriptFiles  =  @ (
188+         Get-ChildItem  - Recurse - Path $env: GITHUB_WORKSPACE  | 
189+             Where-Object  Name -Match  " \.$ ( $ActionModuleName ) \.ps1$" 
190+         if  ($ActionScript ) {
191+             if  ($ActionScript  -match  ' ^\s{0,}/' -and  $ActionScript  -match  ' /\s{0,}$' 
192+                 $ActionScriptPattern  =  $ActionScript.Trim  (' /' -as  [regex ]
193+                 if  ($ActionScriptPattern ) {
194+                     $ActionScriptPattern  =  [regex ]::new($ActionScript.Trim  (' /' ,  ' IgnoreCase,IgnorePatternWhitespace' ,  [timespan ]::FromSeconds(0.5 ))
195+                     Get-ChildItem  - Recurse - Path $env: GITHUB_ACTION_PATH  | 
196+                         Where-Object  { $_.Name   -Match  " \.$ ( $ActionModuleName ) \.ps1$" -and  $_.FullName   -match  $ActionScriptPattern  }
197+                 }
198+             } else  {
199+                 Get-ChildItem  - Recurse - Path $env: GITHUB_ACTION_PATH  | 
200+                     Where-Object  Name -Match  " \.$ ( $ActionModuleName ) \.ps1$" | 
201+                     Where-Object  FullName -Like  $ActionScript 
202+             }
203+         }
204+     ) |  Select-Object  - Unique
205+     $scriptFiles  | 
206+         ForEach-Object  - Begin {
207+             if  ($env: GITHUB_STEP_SUMMARY ) {
208+                 " ## $ActionModuleName  Scripts" | 
209+                     Out-File  - Append - FilePath $env: GITHUB_STEP_SUMMARY 
210+             } 
211+         } - Process {
212+             $myScriptList  +=  $_.FullName.Replace  ($env: GITHUB_WORKSPACE ,  ' ' ' /' 
213+             $myScriptCount ++ 
214+             $scriptFile  =  $_ 
215+             if  ($env: GITHUB_STEP_SUMMARY ) {
216+                 " ### $ ( $scriptFile.Fullname   -replace  [Regex ]::Escape($env: GITHUB_WORKSPACE )) " | 
217+                     Out-File  - Append - FilePath $env: GITHUB_STEP_SUMMARY 
218+             }
219+             $scriptCmd  =  $ExecutionContext.SessionState.InvokeCommand.GetCommand  ($scriptFile.FullName  ,  ' ExternalScript' 
220+             foreach  ($requiredModule  in  $CommandInfo.ScriptBlock.Ast.ScriptRequirements.RequiredModules  ) {
221+                 if  ($requiredModule.Name   -and  
222+                     (-not  $requiredModule.MaximumVersion  ) -and 
223+                     (-not  $requiredModule.RequiredVersion  )
224+                 ) {
225+                     InstallActionModule $requiredModule.Name  
226+                 }
227+             }
228+             $scriptFileOutputs  =  .  $scriptCmd 
229+             $scriptFileOutputs  | 
230+                 .  ProcessOutput  |  
231+                 Out-Host 
232+         }    
233+     
234+     $MyScriptFilesTook  =  [Datetime ]::Now -  $MyScriptFilesStart 
235+     $SummaryOfMyScripts  =  " $myScriptCount  $ActionModuleName  scripts took $ ( $MyScriptFilesTook.TotalSeconds  )  seconds" 
236+     $SummaryOfMyScripts  |  
237+         Out-Host 
238+     if  ($env: GITHUB_STEP_SUMMARY ) {
239+         $SummaryOfMyScripts  |  
240+             Out-File  - Append - FilePath $env: GITHUB_STEP_SUMMARY 
241+     }
242+     # region Custom    
243+     # endregion Custom
244+ }
245+ 
246+ function  OutError  {
247+     $anyRuntimeExceptions  =  $false 
248+     foreach  ($err  in  $error ) {        
249+         $errParts  =  @ (
250+             " ::error " 
251+             @ (
252+                 if  ($err.InvocationInfo.ScriptName  ) {
253+                 " file=$ ( $err.InvocationInfo.ScriptName  ) " 
254+             }
255+             if  ($err.InvocationInfo.ScriptLineNumber   -ge  1 ) {
256+                 " line=$ ( $err.InvocationInfo.ScriptLineNumber  ) " 
257+                 if  ($err.InvocationInfo.OffsetInLine   -ge  1 ) {
258+                     " col=$ ( $err.InvocationInfo.OffsetInLine  ) " 
259+                 }
260+             }
261+             if  ($err.CategoryInfo.Activity  ) {
262+                 " title=$ ( $err.CategoryInfo.Activity  ) " 
263+             }
264+             ) -join  ' ,' 
265+             " ::" 
266+             $err.Exception.Message  
267+             if  ($err.CategoryInfo.Category   -eq  ' OperationStopped' -and  
268+                 $err.CategoryInfo.Reason   -eq  ' RuntimeException' 
269+                 $anyRuntimeExceptions  =  $true 
270+             }
271+         ) -join  ' ' 
272+         $errParts  |  Out-Host 
273+         if  ($anyRuntimeExceptions ) {
274+             exit  1 
275+         }
276+     }
277+ }
278+ 
279+ function  PushActionOutput  {
280+     if  ($anyFilesChanged ) {
281+         " ::notice::$ ( $anyFilesChanged )  Files Changed" |  Out-Host         
282+     }
283+     if  ($CommitMessage  -or  $anyFilesChanged ) {
284+         if  ($CommitMessage ) {
285+             Get-ChildItem  $env: GITHUB_WORKSPACE  - Recurse | 
286+                 ForEach-Object  {
287+                     $gitStatusOutput  =  git status $_.Fullname   - s
288+                     if  ($gitStatusOutput ) {
289+                         git add $_.Fullname  
290+                     }
291+                 }
292+     
293+             git commit - m $ExecutionContext.SessionState.InvokeCommand.ExpandString  ($CommitMessage )
294+         }
295+     
296+         $checkDetached  =  git symbolic- ref - q HEAD
297+         if  (-not  $LASTEXITCODE  -and  -not  $NoPush  -and  -not  $noCommit ) {            
298+             if  ($TargetBranch  -and  $anyFilesChanged ) {
299+                 " ::notice::Pushing Changes to $targetBranch " |  Out-Host 
300+                 git push -- set-upstream  origin $TargetBranch 
301+             } elseif  ($anyFilesChanged ) {
302+                 " ::notice::Pushing Changes" |  Out-Host 
303+                 git push
304+             }
305+             " Git Push Output: $ ( $gitPushed   |  Out-String ) " 
306+         } else  {
307+             " ::notice::Not pushing changes (on detached head)" |  Out-Host 
308+             $LASTEXITCODE  =  0 
309+             exit  0 
310+         }
311+     }
312+ }
313+ 
314+ filter  ProcessOutput  {
315+     $out  =  $_ 
316+     $outItem  =  Get-Item  - Path $out  - ErrorAction Ignore
317+     if  (-not  $outItem  -and  $out  -is  [string ]) {
318+         $out  |  Out-Host 
319+         if  ($env: GITHUB_STEP_SUMMARY ) {
320+             " > $out " |  Out-File  - Append - FilePath $env: GITHUB_STEP_SUMMARY 
321+         }
322+         return 
323+     }
324+     $fullName ,  $shouldCommit  =  
325+         if  ($out  -is  [IO.FileInfo ]) {
326+             $out.FullName  ,  (git status $out.Fullname   - s)
327+         } elseif  ($outItem ) {
328+             $outItem.FullName  ,  (git status $outItem.Fullname   - s)
329+         }
330+     if  ($shouldCommit  -and  -not  $NoCommit ) {
331+         " $fullName  has changed, and should be committed" |  Out-Host 
332+         git add $fullName 
333+         if  ($out.Message  ) {
334+             git commit - m " $ ( $out.Message  ) " |  Out-Host 
335+         } elseif  ($out.CommitMessage  ) {
336+             git commit - m " $ ( $out.CommitMessage  ) " |  Out-Host 
337+         }  elseif  ($gitHubEvent.head_commit.message  ) {
338+             git commit - m " $ ( $gitHubEvent.head_commit.message  ) " |  Out-Host 
339+         }
340+         $anyFilesChanged  =  $true 
341+     }    
342+     $out 
343+ }
344+ 
345+ .  ImportActionModule
346+ .  InitializeAction
347+ .  InvokeActionModule
348+ .  PushActionOutput
349+ .  OutError
0 commit comments