GitHub/Actions/Benchpress.ps1
<# .Synopsis Benchpress Action .Description Runs Benchmarks on your code. #> param( # The path to the benchmark file. # If not provided, any benchmark files in your repository will be used [string] $BenchmarkPath, # The path to the module. [string] $ModulePath, # If provided, will commit any remaining changes made to the workspace with this commit message. # If no commit message is provided, changes will not be committed. [string] $CommitMessage, # The user email associated with a git commit. [string] $UserEmail, # The user name associated with a git commit. [string] $UserName ) "::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 } @" ::group::GitHubEvent $($gitHubEvent | ConvertTo-Json -Depth 100) ::endgroup:: "@ | Out-Host $anyFilesChanged = $false $processScriptOutput = { process { $out = $_ $outItem = Get-Item -Path $out -ErrorAction SilentlyContinue $fullName, $shouldCommit = if ($out -is [IO.FileInfo]) { $out.FullName, (git status $out.Fullname -s) } elseif ($outItem) { $outItem.FullName, (git status $outItem.Fullname -s) } if ($shouldCommit) { git add $fullName if ($out.Message) { git commit -m "$($out.Message)" } elseif ($out.CommitMessage) { git commit -m "$($out.CommitMessage)" } elseif ($gitHubEvent.head_commit.message) { git commit -m "$($gitHubEvent.head_commit.message)" } $anyFilesChanged = $true } $out } } if (-not $UserName) { $UserName = if ($env:GITHUB_TOKEN) { Invoke-RestMethod -uri "https://api.github.com/user" -Headers @{ Authorization = "token $env:GITHUB_TOKEN" } | Select-Object -First 1 -ExpandProperty name } else { $env:GITHUB_ACTOR } } if (-not $UserEmail) { $GitHubUserEmail = if ($env:GITHUB_TOKEN) { Invoke-RestMethod -uri "https://api.github.com/user/emails" -Headers @{ Authorization = "token $env:GITHUB_TOKEN" } | Select-Object -First 1 -ExpandProperty email } else {''} $UserEmail = if ($GitHubUserEmail) { $GitHubUserEmail } else { "$UserName@github.com" } } git config --global user.email $UserEmail git config --global user.name $UserName if (-not $BenchmarkPath) { $BenchmarkPath = Get-ChildItem "$env:GITHUB_WORKSPACE" -Recurse | Where-Object Name -Like '*.benchmark.*' | Split-Path | Select-Object -Unique } "::warning::Benchmark Path - $($BenchmarkPath | Out-String)" $PSD1Found = Get-ChildItem -Recurse -Filter "*.psd1" | Where-Object Name -eq 'Benchpress.psd1' | Select-Object -First 1 if ($PSD1Found) { $BenchpressPath = $PSD1Found Import-Module $PSD1Found -Force -PassThru | Out-Host } elseif ($env:GITHUB_ACTION_PATH) { $benchPressPath = Join-Path $env:GITHUB_ACTION_PATH 'Benchpress.psd1' if (Test-path $benchPressPath) { Import-Module $benchPressPath -Force -PassThru | Out-String } else { throw "Benchmark not found" } } else { dir env: | Out-String throw "Action Path not found" } "::notice title=ModuleLoaded::HelpOut Loaded from Path - $($BenchpressPath)" | Out-Host if (-not $ModulePath) { Get-ChildItem -ErrorAction SilentlyContinue -Path $BenchmarkPath -Filter *.psd1 } elseif (-not (Test-Path $ModulePath) -and $env:GITHUB_WORKSPACE) { $ModulePath = Join-Path (Join-Path $env:GITHUB_WORKSPACE "RepositoryToBenchmark") $ModulePath } if ($modulePath -and (Test-Path $ModulePath -ErrorAction SilentlyContinue )) { Import-Module $ModulePath -Force -PassThru | Out-String } $benchpressModule = Get-Module Benchpress if (-not $benchpressModule) { throw "Benchpress not loaded" } $startTime = [DateTime]::Now $benchmarkOutputFiles = $BenchmarkPath | Get-ChildItem -LiteralPath {$_ } -ErrorAction SilentlyContinue | Where-Object Name -Like '*.benchmark.*' | Checkpoint-Benchmark -OutputPath { $fileName = $_.Name $fileNameMinusExtension = $fileName.Substring(0, $fileName.IndexOf($_.Extension)) $fileNameMinusExtension + '.benchmarkOutput.clixml' } $filesToCheckin = foreach ($benchOutFile in $benchmarkOutputFiles) { $newName = $benchOutFile.Fullname -replace '\.clixml$', '.md' Show-Benchmark -BenchmarkPath $benchOutFile.Fullname | Set-Content -Path $newName $benchOutFile Get-Item $newName } $filesToCheckin | . $processScriptOutput | Out-Host $benchmarkOutputFiles | Import-Clixml | Out-Host git pull | Out-Host $endTime = [DateTime]::Now "::set-output name=TotalDuration::$(($endTime - $startTime).TotalSeconds)" | 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::Pulling Changes" | Out-Host git pull | Out-Host "::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 } } return |