From f0167e3d0dad8344a5dcea105b1d1e7e581a1aa4 Mon Sep 17 00:00:00 2001 From: James Brundage <+@noreply.github.com> Date: Tue, 24 Sep 2024 20:54:45 -0700 Subject: [PATCH] feat: Refactoring ugit action ( Fixes #289, Fixes #290 ) --- Build/GitHub/Actions/UGitAction.ps1 | 267 +++++++++++++++++---------- action.yml | 274 ++++++++++++++++++---------- 2 files changed, 349 insertions(+), 192 deletions(-) diff --git a/Build/GitHub/Actions/UGitAction.ps1 b/Build/GitHub/Actions/UGitAction.ps1 index 358d5553..619de5df 100644 --- a/Build/GitHub/Actions/UGitAction.ps1 +++ b/Build/GitHub/Actions/UGitAction.ps1 @@ -44,45 +44,182 @@ $UserEmail, $UserName ) +$ErrorActionPreference = 'continue' "::group::Parameters" | Out-Host [PSCustomObject]$PSBoundParameters | Format-List | Out-Host "::endgroup::" | Out-Host -if ($env:GITHUB_ACTION_PATH) { - $ugitModulePath = Join-Path $env:GITHUB_ACTION_PATH 'ugit.psd1' - if (Test-path $ugitModulePath) { - Import-Module $ugitModulePath -Force -PassThru | Out-String - } else { - throw "ugit not found" +$gitHubEvent = + if ($env:GITHUB_EVENT_PATH) { + [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json + } else { $null } + +$anyFilesChanged = $false +$moduleName = 'ugit' +$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 ugit)) { - 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" + } -#region -InstallModule -if ($InstallModule) { - "::group::Installing Modules" | Out-Host - foreach ($moduleToInstall in $InstallModule) { - $moduleInWorkspace = Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse -File | - Where-Object Name -eq "$($moduleToInstall).psd1" | - Where-Object { - $(Get-Content $_.FullName -Raw) -match 'ModuleVersion' + "::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 } - if (-not $moduleInWorkspace) { - Install-Module $moduleToInstall -Scope CurrentUser -Force - Import-Module $moduleToInstall -Force -PassThru | Out-Host - } } - "::endgroup::" | 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 + #endregion Custom } -#endregion -InstallModule -"::notice title=ModuleLoaded::ugit Loaded from Path - $($ugitModulePath)" | Out-Host +function PushActionOutput { + if ($anyFilesChanged) { + "::notice::$($anyFilesChanged) Files Changed" | Out-Host + } + 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 + } + } +} -$anyFilesChanged = $false -$processScriptOutput = { process { +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) @@ -90,79 +227,21 @@ $processScriptOutput = { process { $outItem.FullName, (git status $outItem.Fullname -s) } if ($shouldCommit) { + "$fullName has changed, and should be committed" | Out-Host 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 -} } - - -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" } - -git pull | Out-Host - -$ugitScriptStart = [DateTime]::Now -if ($ugitScript) { - Invoke-Expression -Command $ugitScript | - . $processScriptOutput | - Out-Host -} -$ugitScriptTook = [Datetime]::Now - $ugitScriptStart -"::notice title=ugitScriptRuntime::$($ugitScriptTook.TotalMilliseconds)" | Out-Host - -$ugitPS1Start = [DateTime]::Now -$ugitPS1List = @() -if (-not $SkipugitPS1) { - Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | - Where-Object Name -Match '\.ugit\.ps1$' | - - ForEach-Object { - $ugitPS1List += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/') - $ugitPS1Count++ - "::notice title=Running::$($_.Fullname)" | Out-Host - . $_.FullName | - . $processScriptOutput | - Out-Host - } } -$ugitPS1EndStart = [DateTime]::Now -$ugitPS1Took = [Datetime]::Now - $ugitPS1Start -"::notice title=ugitPS1Count::$($ugitPS1List.Length)" | Out-Host -"::notice title=ugitPS1Files::$($ugitPS1List -join ';')" | Out-Host -"::notice title=ugitPS1Runtime::$($ugitPS1Took.TotalMilliseconds)" | 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) - } - - - - - $checkDetached = git symbolic-ref -q HEAD - if (-not $LASTEXITCODE) { - "::notice::Pushing Changes" | Out-Host - "Git Push Output: $($gitPushed | Out-String)" - } else { - "::notice::Not pushing changes (on detached head)" | Out-Host - $LASTEXITCODE = 0 - exit 0 - } -} +. ImportActionModule +. InitializeAction +. InvokeActionModule +. PushActionOutput \ No newline at end of file diff --git a/action.yml b/action.yml index 5e008a91..69c07bab 100644 --- a/action.yml +++ b/action.yml @@ -33,11 +33,11 @@ runs: id: UGitAction shell: pwsh env: + CommitMessage: ${{inputs.CommitMessage}} + UserEmail: ${{inputs.UserEmail}} UGitScript: ${{inputs.UGitScript}} - SkipUGitPS1: ${{inputs.SkipUGitPS1}} UserName: ${{inputs.UserName}} - UserEmail: ${{inputs.UserEmail}} - CommitMessage: ${{inputs.CommitMessage}} + SkipUGitPS1: ${{inputs.SkipUGitPS1}} InstallModule: ${{inputs.InstallModule}} run: | $Parameters = @{} @@ -101,45 +101,182 @@ runs: $UserName ) + $ErrorActionPreference = 'continue' + "::group::Parameters" | Out-Host + [PSCustomObject]$PSBoundParameters | Format-List | Out-Host + "::endgroup::" | Out-Host + + $gitHubEvent = + if ($env:GITHUB_EVENT_PATH) { + [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json + } else { $null } + + $anyFilesChanged = $false + $moduleName = 'ugit' + $actorInfo = $null + "::group::Parameters" | Out-Host [PSCustomObject]$PSBoundParameters | Format-List | Out-Host "::endgroup::" | Out-Host - if ($env:GITHUB_ACTION_PATH) { - $ugitModulePath = Join-Path $env:GITHUB_ACTION_PATH 'ugit.psd1' - if (Test-path $ugitModulePath) { - Import-Module $ugitModulePath -Force -PassThru | Out-String - } else { - throw "ugit 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 ugit)) { - 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 - #region -InstallModule - if ($InstallModule) { - "::group::Installing Modules" | Out-Host - foreach ($moduleToInstall in $InstallModule) { - $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 + 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::$ModuleName Loaded from Path - $($LocalModulePath)" | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "# $($moduleName)" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY } - "::endgroup::" | Out-Host } - #endregion -InstallModule + function InitializeAction { + #region Custom + #endregion Custom - "::notice title=ModuleLoaded::ugit Loaded from Path - $($ugitModulePath)" | Out-Host + # 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 - $anyFilesChanged = $false - $processScriptOutput = { process { + # 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 + #endregion Custom + } + + function PushActionOutput { + if ($anyFilesChanged) { + "::notice::$($anyFilesChanged) Files Changed" | Out-Host + } + 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) @@ -147,81 +284,22 @@ runs: $outItem.FullName, (git status $outItem.Fullname -s) } if ($shouldCommit) { + "$fullName has changed, and should be committed" | Out-Host 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 - } } - - - 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" } - - git pull | Out-Host - - $ugitScriptStart = [DateTime]::Now - if ($ugitScript) { - Invoke-Expression -Command $ugitScript | - . $processScriptOutput | - Out-Host } - $ugitScriptTook = [Datetime]::Now - $ugitScriptStart - "::notice title=ugitScriptRuntime::$($ugitScriptTook.TotalMilliseconds)" | Out-Host - - $ugitPS1Start = [DateTime]::Now - $ugitPS1List = @() - if (-not $SkipugitPS1) { - Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | - Where-Object Name -Match '\.ugit\.ps1$' | - - ForEach-Object { - $ugitPS1List += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/') - $ugitPS1Count++ - "::notice title=Running::$($_.Fullname)" | Out-Host - . $_.FullName | - . $processScriptOutput | - Out-Host - } - } - $ugitPS1EndStart = [DateTime]::Now - $ugitPS1Took = [Datetime]::Now - $ugitPS1Start - "::notice title=ugitPS1Count::$($ugitPS1List.Length)" | Out-Host - "::notice title=ugitPS1Files::$($ugitPS1List -join ';')" | Out-Host - "::notice title=ugitPS1Runtime::$($ugitPS1Took.TotalMilliseconds)" | 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) - } - - - - - $checkDetached = git symbolic-ref -q HEAD - if (-not $LASTEXITCODE) { - "::notice::Pushing Changes" | Out-Host - "Git Push Output: $($gitPushed | Out-String)" - } else { - "::notice::Not pushing changes (on detached head)" | Out-Host - $LASTEXITCODE = 0 - exit 0 - } - } - } @Parameters + . ImportActionModule + . InitializeAction + . InvokeActionModule + . PushActionOutput} @Parameters