From 72233a8674e37b2652c137b5b3cdd7462f4e8387 Mon Sep 17 00:00:00 2001 From: James Brundage <+@noreply.github.com> Date: Sat, 21 Sep 2024 21:36:13 -0700 Subject: [PATCH] Fix: Irregular Action Refactoring ( Fixes #235, Fixes #236 ) --- Build/GitHub/Actions/Irregular.ps1 | 261 +++++++++++++++++++--------- action.yml | 263 ++++++++++++++++++++--------- 2 files changed, 357 insertions(+), 167 deletions(-) diff --git a/Build/GitHub/Actions/Irregular.ps1 b/Build/GitHub/Actions/Irregular.ps1 index 4994516..e621884 100644 --- a/Build/GitHub/Actions/Irregular.ps1 +++ b/Build/GitHub/Actions/Irregular.ps1 @@ -46,28 +46,180 @@ $ErrorActionPreference = 'continue' "::endgroup::" | Out-Host -$PSD1Found = Get-ChildItem -Recurse -Filter "*.psd1" | Where-Object Name -eq 'Irregular.psd1' | Select-Object -First 1 - -if ($PSD1Found) { - $irregularModulePath = $PSD1Found - Import-Module $PSD1Found -Force -PassThru | Out-Host -} if ($env:GITHUB_ACTION_PATH) { - $irregularModulePath = Join-Path $env:GITHUB_ACTION_PATH 'Irregular.psd1' - if (Test-path $irregularModulePath) { - Import-Module $irregularModulePath -Force -PassThru | Out-String - } else { - throw "Irregular not found" +$anyFilesChanged = $false +$moduleName = 'Irregular' +$actorInfo = $null + +"::group::Parameters" | Out-Host +[PSCustomObject]$PSBoundParameters | Format-List | Out-Host +"::endgroup::" | Out-Host + +function InstallActionModule { + param([string]$ModuleToInstall) + $moduleInWorkspace = Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse -File | + Where-Object Name -eq "$($moduleToInstall).psd1" | + Where-Object { + $(Get-Content $_.FullName -Raw) -match 'ModuleVersion' + } + if (-not $moduleInWorkspace) { + Install-Module $moduleToInstall -Scope CurrentUser -Force + Import-Module $moduleToInstall -Force -PassThru | Out-Host } -} elseif (-not (Get-Module Irregular)) { - throw "Action Path not found" } +function ImportActionModule { + #region -InstallModule + if ($InstallModule) { + "::group::Installing Modules" | Out-Host + foreach ($moduleToInstall in $InstallModule) { + InstallActionModule -ModuleToInstall $moduleToInstall + } + "::endgroup::" | Out-Host + } + #endregion -InstallModule + + if ($env:GITHUB_ACTION_PATH) { + $LocalModulePath = Join-Path $env:GITHUB_ACTION_PATH "$moduleName.psd1" + if (Test-path $LocalModulePath) { + Import-Module $LocalModulePath -Force -PassThru | Out-String + } else { + throw "Module '$moduleName' not found" + } + } elseif (-not (Get-Module $moduleName)) { + throw "Module '$ModuleName' not found" + } -"::notice title=ModuleLoaded::Irregular Loaded from Path - $($irregularModulePath)" | Out-Host + "::notice title=ModuleLoaded::$ModuleName Loaded from Path - $($LocalModulePath)" | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "# $($moduleName)" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } +} +function InitializeAction { + #region Custom + #endregion Custom + + # Configure git based on the $env:GITHUB_ACTOR + if (-not $UserName) { $UserName = $env:GITHUB_ACTOR } + if (-not $actorID) { $actorID = $env:GITHUB_ACTOR_ID } + $actorInfo = Invoke-RestMethod -Uri "https://api.github.com/user/$actorID" + if (-not $UserEmail) { $UserEmail = "$UserName@noreply.github.com" } + git config --global user.email $UserEmail + git config --global user.name $actorInfo.name + + # Pull down any changes + git pull | Out-Host +} -$anyFilesChanged = $false -$processScriptOutput = { process { +function InvokeActionModule { + $myScriptStart = [DateTime]::Now + $myScript = $ExecutionContext.SessionState.PSVariable.Get("${ModuleName}Script").Value + if ($myScript) { + Invoke-Expression -Command $myScript | + . ProcessOutput | + Out-Host + } + $myScriptTook = [Datetime]::Now - $myScriptStart + $MyScriptFilesStart = [DateTime]::Now + + $myScriptList = @() + $shouldSkip = $ExecutionContext.SessionState.PSVariable.Get("Skip${ModuleName}PS1").Value + if (-not $shouldSkip) { + Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | + Where-Object Name -Match "\.$($moduleName)\.ps1$" | + ForEach-Object -Begin { + if ($env:GITHUB_STEP_SUMMARY) { + "## $ModuleName Scripts" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + } -Process { + $myScriptList += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/') + $myScriptCount++ + $scriptFile = $_ + if ($env:GITHUB_STEP_SUMMARY) { + "### $($scriptFile.Fullname)" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + $scriptCmd = $ExecutionContext.SessionState.InvokeCommand.GetCommand($scriptFile.FullName, 'ExternalScript') + foreach ($requiredModule in $CommandInfo.ScriptBlock.Ast.ScriptRequirements.RequiredModules) { + if ($requiredModule.Name -and + (-not $requiredModule.MaximumVersion) -and + (-not $requiredModule.RequiredVersion) + ) { + InstallActionModule $requiredModule.Name + } + } + $scriptFileOutputs = . $scriptCmd + if ($env:GITHUB_STEP_SUMMARY) { + "$(@($scriptFileOutputs).Length) Outputs" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + "$(@($scriptFileOutputs).Length) Outputs" | Out-Host + } + $scriptFileOutputs | + . ProcessOutput | + Out-Host + } + } + + $MyScriptFilesTook = [Datetime]::Now - $MyScriptFilesStart + $SummaryOfMyScripts = "$myScriptCount $moduleName scripts took $($MyScriptFilesTook.TotalSeconds) seconds" + $SummaryOfMyScripts | + Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + $SummaryOfMyScripts | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + #region Custom + if (-not $SkipRegexSource) { + Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | + Where-Object Name -Match '\.regex\.source\.ps1$' | + ForEach-Object { + Write-Information "::notice file=$($_.FullName)::Running $($_.Name)" + . $_.FullName | + Get-Item -LiteralPath ($_.FullName -replace '\.regex\.source\.ps1$', '\regex\.txt') | + . $processScriptOutput | + Out-Host + } + } + #endregion Custom +} + +function PushActionOutput { + if ($CommitMessage -or $anyFilesChanged) { + if ($CommitMessage) { + Get-ChildItem $env:GITHUB_WORKSPACE -Recurse | + ForEach-Object { + $gitStatusOutput = git status $_.Fullname -s + if ($gitStatusOutput) { + git add $_.Fullname + } + } + + git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage) + } + + $checkDetached = git symbolic-ref -q HEAD + if (-not $LASTEXITCODE) { + "::notice::Pushing Changes" | Out-Host + git push + "Git Push Output: $($gitPushed | Out-String)" + } else { + "::notice::Not pushing changes (on detached head)" | Out-Host + $LASTEXITCODE = 0 + exit 0 + } + } +} + +filter ProcessOutput { $out = $_ - $outItem = Get-Item -Path $out -ErrorAction SilentlyContinue + $outItem = Get-Item -Path $out -ErrorAction Ignore + if (-not $outItem -and $out -is [string]) { + $out | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "> $out" | Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + return + } $fullName, $shouldCommit = if ($out -is [IO.FileInfo]) { $out.FullName, (git status $out.Fullname -s) @@ -77,75 +229,18 @@ $processScriptOutput = { process { if ($shouldCommit) { git add $fullName if ($out.Message) { - git commit -m "$($out.Message)" + git commit -m "$($out.Message)" | Out-Host } elseif ($out.CommitMessage) { - git commit -m "$($out.CommitMessage)" + git commit -m "$($out.CommitMessage)" | Out-Host + } elseif ($gitHubEvent.head_commit.message) { + git commit -m "$($gitHubEvent.head_commit.message)" | Out-Host } $anyFilesChanged = $true - } + } $out -} } - -"::notice title=ModuleLoaded,file=$irregularModulePath::Irregular Loaded from Path" | Out-Host - -if (-not $UserName) { $UserName = $env:GITHUB_ACTOR } -if (-not $UserEmail) { $UserEmail = "$UserName@github.com" } -git config --global user.email $UserEmail -git config --global user.name $UserName - - -if (-not $env:GITHUB_WORKSPACE) { throw "No GitHub workspace" } - -if ($IrregularScript) { - "::notice::Running Irregular Script" | Out-Host - Invoke-Expression -Command $IrregularScript | - . $processScriptOutput | - Out-Host -} - -if (-not $SkipIrregularPS1) { - "::notice::Running Irregular .ps1" | Out-Host - Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | - Where-Object Name -Match '\.Irregular\.ps1$' | - ForEach-Object { - Write-Information "::notice file=$($_.FullName)::Running $($_.Name)" - $irregularPs1File = $_ - try { - . $irregularPs1File.FullName | - . $processScriptOutput | - Out-Host - } catch { - "::error::$($_ | Out-String)" | Out-Host - } - } } -if (-not $SkipRegexSource) { - Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | - Where-Object Name -Match '\.regex\.source\.ps1$' | - ForEach-Object { - Write-Information "::notice file=$($_.FullName)::Running $($_.Name)" - . $_.FullName | - . $processScriptOutput | - Out-Host - } -} - -if ($CommitMessage -or $anyFilesChanged) { - if ($CommitMessage) { - dir $env:GITHUB_WORKSPACE -Recurse | - ForEach-Object { - $gitStatusOutput = git status $_.Fullname -s - if ($gitStatusOutput) { - git add $_.Fullname - } - } - - git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage) - } - - "::notice::Pushing" | Out-Host - $gitPushed = git push 2>&1 - - "Git Push Output: $($gitPushed | Out-String)" -} \ No newline at end of file +. ImportActionModule +. InitializeAction +. InvokeActionModule +. PushActionOutput \ No newline at end of file diff --git a/action.yml b/action.yml index fe3cde3..ed0e5eb 100644 --- a/action.yml +++ b/action.yml @@ -33,12 +33,12 @@ runs: id: Irregular shell: pwsh env: - IrregularScript: ${{inputs.IrregularScript}} CommitMessage: ${{inputs.CommitMessage}} - SkipIrregularPS1: ${{inputs.SkipIrregularPS1}} UserEmail: ${{inputs.UserEmail}} + SkipIrregularPS1: ${{inputs.SkipIrregularPS1}} UserName: ${{inputs.UserName}} SkipRegexSource: ${{inputs.SkipRegexSource}} + IrregularScript: ${{inputs.IrregularScript}} run: | $Parameters = @{} $Parameters.IrregularScript = ${env:IrregularScript} @@ -103,28 +103,180 @@ runs: "::endgroup::" | Out-Host - $PSD1Found = Get-ChildItem -Recurse -Filter "*.psd1" | Where-Object Name -eq 'Irregular.psd1' | Select-Object -First 1 + $anyFilesChanged = $false + $moduleName = 'Irregular' + $actorInfo = $null + + "::group::Parameters" | Out-Host + [PSCustomObject]$PSBoundParameters | Format-List | Out-Host + "::endgroup::" | Out-Host - if ($PSD1Found) { - $irregularModulePath = $PSD1Found - Import-Module $PSD1Found -Force -PassThru | Out-Host - } if ($env:GITHUB_ACTION_PATH) { - $irregularModulePath = Join-Path $env:GITHUB_ACTION_PATH 'Irregular.psd1' - if (Test-path $irregularModulePath) { - Import-Module $irregularModulePath -Force -PassThru | Out-String - } else { - throw "Irregular not found" + function InstallActionModule { + param([string]$ModuleToInstall) + $moduleInWorkspace = Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse -File | + Where-Object Name -eq "$($moduleToInstall).psd1" | + Where-Object { + $(Get-Content $_.FullName -Raw) -match 'ModuleVersion' + } + if (-not $moduleInWorkspace) { + Install-Module $moduleToInstall -Scope CurrentUser -Force + Import-Module $moduleToInstall -Force -PassThru | Out-Host } - } elseif (-not (Get-Module Irregular)) { - throw "Action Path not found" } + function ImportActionModule { + #region -InstallModule + if ($InstallModule) { + "::group::Installing Modules" | Out-Host + foreach ($moduleToInstall in $InstallModule) { + InstallActionModule -ModuleToInstall $moduleToInstall + } + "::endgroup::" | Out-Host + } + #endregion -InstallModule - "::notice title=ModuleLoaded::Irregular Loaded from Path - $($irregularModulePath)" | Out-Host + if ($env:GITHUB_ACTION_PATH) { + $LocalModulePath = Join-Path $env:GITHUB_ACTION_PATH "$moduleName.psd1" + if (Test-path $LocalModulePath) { + Import-Module $LocalModulePath -Force -PassThru | Out-String + } else { + throw "Module '$moduleName' not found" + } + } elseif (-not (Get-Module $moduleName)) { + throw "Module '$ModuleName' not found" + } - $anyFilesChanged = $false - $processScriptOutput = { process { + "::notice title=ModuleLoaded::$ModuleName Loaded from Path - $($LocalModulePath)" | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "# $($moduleName)" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + } + function InitializeAction { + #region Custom + #endregion Custom + + # Configure git based on the $env:GITHUB_ACTOR + if (-not $UserName) { $UserName = $env:GITHUB_ACTOR } + if (-not $actorID) { $actorID = $env:GITHUB_ACTOR_ID } + $actorInfo = Invoke-RestMethod -Uri "https://api.github.com/user/$actorID" + if (-not $UserEmail) { $UserEmail = "$UserName@noreply.github.com" } + git config --global user.email $UserEmail + git config --global user.name $actorInfo.name + + # Pull down any changes + git pull | Out-Host + } + + function InvokeActionModule { + $myScriptStart = [DateTime]::Now + $myScript = $ExecutionContext.SessionState.PSVariable.Get("${ModuleName}Script").Value + if ($myScript) { + Invoke-Expression -Command $myScript | + . ProcessOutput | + Out-Host + } + $myScriptTook = [Datetime]::Now - $myScriptStart + $MyScriptFilesStart = [DateTime]::Now + + $myScriptList = @() + $shouldSkip = $ExecutionContext.SessionState.PSVariable.Get("Skip${ModuleName}PS1").Value + if (-not $shouldSkip) { + Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | + Where-Object Name -Match "\.$($moduleName)\.ps1$" | + ForEach-Object -Begin { + if ($env:GITHUB_STEP_SUMMARY) { + "## $ModuleName Scripts" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + } -Process { + $myScriptList += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/') + $myScriptCount++ + $scriptFile = $_ + if ($env:GITHUB_STEP_SUMMARY) { + "### $($scriptFile.Fullname)" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + $scriptCmd = $ExecutionContext.SessionState.InvokeCommand.GetCommand($scriptFile.FullName, 'ExternalScript') + foreach ($requiredModule in $CommandInfo.ScriptBlock.Ast.ScriptRequirements.RequiredModules) { + if ($requiredModule.Name -and + (-not $requiredModule.MaximumVersion) -and + (-not $requiredModule.RequiredVersion) + ) { + InstallActionModule $requiredModule.Name + } + } + $scriptFileOutputs = . $scriptCmd + if ($env:GITHUB_STEP_SUMMARY) { + "$(@($scriptFileOutputs).Length) Outputs" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + "$(@($scriptFileOutputs).Length) Outputs" | Out-Host + } + $scriptFileOutputs | + . ProcessOutput | + Out-Host + } + } + + $MyScriptFilesTook = [Datetime]::Now - $MyScriptFilesStart + $SummaryOfMyScripts = "$myScriptCount $moduleName scripts took $($MyScriptFilesTook.TotalSeconds) seconds" + $SummaryOfMyScripts | + Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + $SummaryOfMyScripts | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + #region Custom + if (-not $SkipRegexSource) { + Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | + Where-Object Name -Match '\.regex\.source\.ps1$' | + ForEach-Object { + Write-Information "::notice file=$($_.FullName)::Running $($_.Name)" + . $_.FullName | + Get-Item -LiteralPath ($_.FullName -replace '\.regex\.source\.ps1$', '\regex\.txt') | + . $processScriptOutput | + Out-Host + } + } + #endregion Custom + } + + function PushActionOutput { + if ($CommitMessage -or $anyFilesChanged) { + if ($CommitMessage) { + Get-ChildItem $env:GITHUB_WORKSPACE -Recurse | + ForEach-Object { + $gitStatusOutput = git status $_.Fullname -s + if ($gitStatusOutput) { + git add $_.Fullname + } + } + + git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage) + } + + $checkDetached = git symbolic-ref -q HEAD + if (-not $LASTEXITCODE) { + "::notice::Pushing Changes" | Out-Host + git push + "Git Push Output: $($gitPushed | Out-String)" + } else { + "::notice::Not pushing changes (on detached head)" | Out-Host + $LASTEXITCODE = 0 + exit 0 + } + } + } + + filter ProcessOutput { $out = $_ - $outItem = Get-Item -Path $out -ErrorAction SilentlyContinue + $outItem = Get-Item -Path $out -ErrorAction Ignore + if (-not $outItem -and $out -is [string]) { + $out | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "> $out" | Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + return + } $fullName, $shouldCommit = if ($out -is [IO.FileInfo]) { $out.FullName, (git status $out.Fullname -s) @@ -134,76 +286,19 @@ runs: if ($shouldCommit) { git add $fullName if ($out.Message) { - git commit -m "$($out.Message)" + git commit -m "$($out.Message)" | Out-Host } elseif ($out.CommitMessage) { - git commit -m "$($out.CommitMessage)" + git commit -m "$($out.CommitMessage)" | Out-Host + } elseif ($gitHubEvent.head_commit.message) { + git commit -m "$($gitHubEvent.head_commit.message)" | Out-Host } $anyFilesChanged = $true - } + } $out - } } - - "::notice title=ModuleLoaded,file=$irregularModulePath::Irregular Loaded from Path" | Out-Host - - if (-not $UserName) { $UserName = $env:GITHUB_ACTOR } - if (-not $UserEmail) { $UserEmail = "$UserName@github.com" } - git config --global user.email $UserEmail - git config --global user.name $UserName - - - if (-not $env:GITHUB_WORKSPACE) { throw "No GitHub workspace" } - - if ($IrregularScript) { - "::notice::Running Irregular Script" | Out-Host - Invoke-Expression -Command $IrregularScript | - . $processScriptOutput | - Out-Host } - if (-not $SkipIrregularPS1) { - "::notice::Running Irregular .ps1" | Out-Host - Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | - Where-Object Name -Match '\.Irregular\.ps1$' | - ForEach-Object { - Write-Information "::notice file=$($_.FullName)::Running $($_.Name)" - $irregularPs1File = $_ - try { - . $irregularPs1File.FullName | - . $processScriptOutput | - Out-Host - } catch { - "::error::$($_ | Out-String)" | Out-Host - } - } - } - - if (-not $SkipRegexSource) { - Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | - Where-Object Name -Match '\.regex\.source\.ps1$' | - ForEach-Object { - Write-Information "::notice file=$($_.FullName)::Running $($_.Name)" - . $_.FullName | - . $processScriptOutput | - Out-Host - } - } - - if ($CommitMessage -or $anyFilesChanged) { - if ($CommitMessage) { - dir $env:GITHUB_WORKSPACE -Recurse | - ForEach-Object { - $gitStatusOutput = git status $_.Fullname -s - if ($gitStatusOutput) { - git add $_.Fullname - } - } - - git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage) - } - - "::notice::Pushing" | Out-Host - $gitPushed = git push 2>&1 - - "Git Push Output: $($gitPushed | Out-String)" - }} @Parameters + . ImportActionModule + . InitializeAction + . InvokeActionModule + . PushActionOutput} @Parameters