diff --git a/.pslintrules.psd1 b/.pslintrules.psd1 index 80095b4..7958445 100644 --- a/.pslintrules.psd1 +++ b/.pslintrules.psd1 @@ -25,7 +25,7 @@ # PSUseDeclaredVarsMoreThanAssignments doesn't currently work due to: # https://github.com/PowerShell/PSScriptAnalyzer/issues/636 'PSUseDeclaredVarsMoreThanAssignments', - # `Write-Log` uses `Write-Host` currently. + # `Write-LogInfo` uses `Write-Host` currently. 'PSAvoidUsingWriteHost' ) } diff --git a/action.ps1 b/action.ps1 index 30d0a1d..7b1218c 100644 --- a/action.ps1 +++ b/action.ps1 @@ -11,15 +11,15 @@ Test-NestedBucket Initialize-NeededConfiguration git config --get user.email -Write-Log 'Importing all modules' +Write-LogInfo 'Importing all modules' # Load all scoop's modules. # Dot sourcing needs to be done on highest scope possible to propagate into lower scopes Get-ChildItem (Join-Path $env:SCOOP_HOME 'lib') '*.ps1' | ForEach-Object { . $_.FullName } -Write-Log 'FULL EVENT' $EVENT_RAW +Write-LogInfo 'FULL EVENT' $GITHUB_EVENT_RAW Invoke-Action -Write-Log 'Number of Github Requests' $env:GH_REQUEST_COUNTER +Write-LogInfo 'Number of Github Requests' $env:GH_REQUEST_COUNTER if ($env:NON_ZERO_EXIT) { exit $NON_ZERO } diff --git a/src/Action/Issue.psm1 b/src/Action/Issue.psm1 index 4f51940..d3264cc 100644 --- a/src/Action/Issue.psm1 +++ b/src/Action/Issue.psm1 @@ -29,10 +29,10 @@ function Test-Hash { $outputH = @("Exception occurred: $($_.Exception.Message)", "$($_.ScriptStackTrace)") } - Write-Log 'Output' $outputH + Write-LogInfo 'Output' $outputH if (($outputH[-2] -like 'OK') -and ($outputH[-1] -like 'Writing*')) { - Write-Log 'Cannot reproduce.' + Write-LogInfo 'Cannot reproduce.' Add-Comment -ID $IssueID -AppendLogLink -Message @( 'Cannot reproduce.' @@ -49,7 +49,7 @@ function Test-Hash { Remove-Label -ID $IssueID -Label 'hash-fix-needed' Close-Issue -ID $IssueID } elseif ($outputH[-1] -notlike 'Writing*') { - Write-Log 'Automatic hash verification encountered some problems.' + Write-LogInfo 'Automatic hash verification encountered some problems.' Add-Label -ID $IssueID -Label 'help wanted' @@ -73,7 +73,7 @@ function Test-Hash { Add-Comment -ID $IssueID -Message $message -AppendLogLink } else { - Write-Log 'Hash mismatch confirmed.' + Write-LogInfo 'Hash mismatch confirmed.' $masterBranch = ((Invoke-GithubRequest "repos/$REPOSITORY").Content | ConvertFrom-Json).default_branch $message = @('You are right. Thank you for reporting.') @@ -85,7 +85,7 @@ function Test-Hash { # There is alreay PR for if ($prs.Count -gt 0) { - Write-Log 'PR - Update description' + Write-LogInfo 'PR - Update description' # Only take latest updated $pr = $prs | Select-Object -First 1 @@ -95,12 +95,12 @@ function Test-Hash { $message += '' $message += "There is already a pull request which takes care of this issue. (#$prID)" - Write-Log 'PR ID' $prID + Write-LogInfo 'PR ID' $prID # Update PR description Invoke-GithubRequest "repos/$REPOSITORY/pulls/$prID" -Method Patch -Body @{ 'body' = (@("- Closes #$IssueID", $pr.body) -join "`r`n") } Add-Label -ID $IssueID -Label 'duplicate' } else { - Write-Log 'Git Status:' + Write-LogInfo 'Git Status:' Invoke-Git -GitArgs @('status', '--porcelain') Invoke-Git -GitArgs @('add', $gci.FullName) @@ -108,13 +108,13 @@ function Test-Hash { # Try direct push try { - Write-Log 'Commiting fix directly' + Write-LogInfo 'Commiting fix directly' Invoke-Git -GitArgs @('push') } catch { - Write-Log 'Direct push failed. Probably protected branch. Will try to create PR instead.' + Write-LogInfo 'Direct push failed. Probably protected branch. Will try to create PR instead.' $branch = "$manifestNameAsInBucket-hash-fix-$(Get-Random -Maximum 258258258)" - Write-Log 'Branch' $branch + Write-LogInfo 'Branch' $branch Invoke-Git -GitArgs @('checkout', '-B', $branch) # Amend commit with new message @@ -122,10 +122,10 @@ function Test-Hash { # Try create branch and PR try { - Write-Log 'Creating branch' + Write-LogInfo 'Creating branch' Invoke-Git -GitArgs @('push', 'origin', $branch) } catch { - Write-Log 'Create branch failed. Please check workflow permissions.' + Write-LogInfo 'Create branch failed. Please check workflow permissions.' Add-Comment -ID $IssueID -AppendLogLink -Message @( 'Hash mismatch confirmed, but the bot could not publish the fix currently.' ) @@ -133,7 +133,7 @@ function Test-Hash { } try { - Write-Log 'Creating PR' + Write-LogInfo 'Creating PR' # Create new PR Invoke-GithubRequest -Query "repos/$REPOSITORY/pulls" -Method Post -Body @{ @@ -143,12 +143,12 @@ function Test-Hash { 'body' = "- Closes #$IssueID" } } catch { - Write-Log 'Create PR failed. Please check workflow permissions.' + Write-LogInfo 'Create PR failed. Please check workflow permissions.' # Try to delete branch if PR creation failed try { Invoke-Git -GitArgs @('push', 'origin', '--delete', $branch) } catch { - Write-Log 'Failed to delete branch. Please check workflow permissions.' + Write-LogInfo 'Failed to delete branch. Please check workflow permissions.' } Add-Comment -ID $IssueID -AppendLogLink -Message @( 'Hash mismatch confirmed, but the bot could not publish the fix currently.' @@ -174,7 +174,7 @@ function Test-Downloading { $broken_urls = $outputH -match '>' -replace '.*?>', '-' if (!$broken_urls) { - Write-Log 'Cannot reproduce' + Write-LogInfo 'Cannot reproduce' Add-Comment -ID $IssueID -AppendLogLink -Message @( 'Cannot reproduce.' @@ -192,7 +192,7 @@ function Test-Downloading { Remove-Label -ID $IssueID -Label 'manifest-fix-needed' Close-Issue -ID $IssueID } else { - Write-Log 'Broken URLs' $broken_urls + Write-LogInfo 'Broken URLs' $broken_urls Add-Comment -ID $IssueID -AppendLogLink -Message (@( 'You are right. Thank you for reporting.', @@ -204,21 +204,21 @@ function Test-Downloading { } function Initialize-Issue { - Write-Log 'Issue initialized' + Write-LogInfo 'Issue initialized' - if (-not (($EVENT.action -eq 'opened') -or ($EVENT.action -eq 'labeled'))) { - Write-Log "Only actions 'opened' and 'labeled' are supported" + if (-not (($GITHUB_EVENT.action -eq 'opened') -or ($GITHUB_EVENT.action -eq 'labeled'))) { + Write-LogInfo "Only actions 'opened' and 'labeled' are supported" return } - $title = $EVENT.issue.title - $id = $EVENT.issue.number - $label = $EVENT.issue.labels.name - $body = $EVENT.issue.body + $title = $GITHUB_EVENT.issue.title + $id = $GITHUB_EVENT.issue.number + $label = $GITHUB_EVENT.issue.labels.name + $body = $GITHUB_EVENT.issue.body # Only labeled action with verify label should continue - if (($EVENT.action -eq 'labeled') -and ($label -notcontains 'verify')) { - Write-Log 'Labeled action contains wrong label' + if (($GITHUB_EVENT.action -eq 'labeled') -and ($label -notcontains 'verify')) { + Write-LogInfo 'Labeled action contains wrong label' return } @@ -227,7 +227,7 @@ function Initialize-Issue { ($null -eq $problematicVersion) -or ($null -eq $problem) ) { - Write-Log 'Not compatible issue title' + Write-LogInfo 'Not compatible issue title' return } @@ -255,22 +255,22 @@ function Initialize-Issue { switch -Regex ($problem) { 'hash check' { - Write-Log 'Detected issue type' 'Hash check failed.' + Write-LogInfo 'Detected issue type' 'Hash check failed.' Test-Hash $problematicName $id } 'download.*failed' { - Write-Log 'Detected issue type' 'Download failed.' + Write-LogInfo 'Detected issue type' 'Download failed.' Test-Downloading $problematicName $id } '(decompress|extract).*error' { - Write-Log 'Detected issue type' 'Decompression/Extraction error.' - Show-ExtractionHelpTips $problematicName $id $body + Write-LogInfo 'Detected issue type' 'Decompression/Extraction error.' + Show-ExtractionHelpDoc -IssueID $id -IssueBody $body } - default { Write-Log 'Unsupported issue type' $problem } + default { Write-LogInfo 'Unsupported issue type' $problem } } Remove-Label -ID $id -Label 'verify' - Write-Log 'Issue finished' + Write-LogInfo 'Issue finished' } Export-ModuleMember -Function Initialize-Issue diff --git a/src/Action/Issue/Extraction.psm1 b/src/Action/Issue/Extraction.psm1 index cfa5c6a..5f86a9b 100644 --- a/src/Action/Issue/Extraction.psm1 +++ b/src/Action/Issue/Extraction.psm1 @@ -15,8 +15,8 @@ function Test-ExtractDir { $urls = @(url $manifest_o $arch) $extract_dirs = @(extract_dir $manifest_o $arch) - Write-Log $urls - Write-Log $extract_dirs + Write-LogInfo $urls + Write-LogInfo $extract_dirs for ($i = 0; $i -lt $urls.Count; ++$i) { $url = $urls[$i] @@ -24,7 +24,7 @@ function Test-ExtractDir { Invoke-CachedDownload $Manifest $version $url $null $manifest_o.cookie $true $cached = cache_path $Manifest $version $url | Resolve-Path | Select-Object -ExpandProperty Path - Write-Log "FILEPATH $url, ${arch}: $cached" + Write-LogInfo "FILEPATH $url, ${arch}: $cached" $full_output = @(7z l $cached | awk '{ print $3, $6 }' | grep '^D') $output = @(7z l $cached -ir!"$dir" | awk '{ print $3, $6 }' | grep '^D') @@ -38,27 +38,27 @@ function Test-ExtractDir { # There are no files and folders like if ($files -eq 0 -and (!$folders -or $folders -eq 0)) { - Write-Log "No $dir in $url" + Write-LogInfo "No $dir in $url" $failed = $true $message += New-DetailsCommentString -Summary "Content of $arch $url" -Content $full_output - Write-Log "$dir, $arch, $url FAILED" + Write-LogInfo "$dir, $arch, $url FAILED" } else { - Write-Log "Cannot reproduce $arch $url" + Write-LogInfo "Cannot reproduce $arch $url" - Write-Log "$arch ${url}:" - Write-Log $full_output - Write-Log "$dir, $arch, $url OK" + Write-LogInfo "$arch ${url}:" + Write-LogInfo $full_output + Write-LogInfo "$dir, $arch, $url OK" } } } if ($failed) { - Write-Log 'Failed' $failed + Write-LogInfo 'Failed' $failed $message = 'You are right. Can reproduce', '', $message Add-Label -ID $IssueID -Label 'verified', 'manifest-fix-needed', 'help wanted' } else { - Write-Log 'Everything all right' $failed + Write-LogInfo 'Everything all right' $failed $message = @( 'Cannot reproduce. Are you sure your scoop is updated?' "Try to run ``scoop update; scoop uninstall $Manifest; scoop install $Manifest``" @@ -70,11 +70,11 @@ function Test-ExtractDir { Add-Comment -ID $IssueID -Message $message -AppendLogLink } -function Show-ExtractionHelpTips { +function Show-ExtractionHelpDoc { param ( [Parameter(Mandatory = $true)] - [String] $App, [Int] $IssueID, + [Parameter(Mandatory = $true)] [string] $IssueBody ) @@ -155,7 +155,7 @@ function Show-ExtractionHelpTips { 'dark' { $tipContent += $tips['dark']; $tipContent += '' } default { $tips.Values | ForEach-Object { - $tipContent += $_; + $tipContent += $_ $tipContent += '' } } @@ -166,4 +166,4 @@ function Show-ExtractionHelpTips { Add-Comment -ID $IssueID -Message $message } -Export-ModuleMember -Function Test-ExtractDir, Show-ExtractionHelpTips +Export-ModuleMember -Function Test-ExtractDir, Show-ExtractionHelpDoc diff --git a/src/Action/PR.psm1 b/src/Action/PR.psm1 index ce6b0a0..e120267 100644 --- a/src/Action/PR.psm1 +++ b/src/Action/PR.psm1 @@ -1,6 +1,6 @@ Join-Path $PSScriptRoot '..\Helpers.psm1' | Import-Module -function Start-PR { +function Resolve-PullRequestAction { <# .SYNOPSIS PR state handler. @@ -10,34 +10,34 @@ function Start-PR { #> $commented = $false - switch ($EVENT.action) { + switch ($GITHUB_EVENT.action) { 'opened' { - Write-Log 'Opened PR' + Write-LogInfo 'Opened PR' } 'created' { - Write-Log 'Commented PR' + Write-LogInfo 'Commented PR' - if ($EVENT.comment.body -like '/verify*') { - Write-Log 'Verify comment' + if ($GITHUB_EVENT.comment.body -like '/verify*') { + Write-LogInfo 'Verify comment' - if ($EVENT.issue.pull_request) { - Write-Log 'Pull request comment' + if ($GITHUB_EVENT.issue.pull_request) { + Write-LogInfo 'Pull request comment' $commented = $true # There is need to get actual pull request event - $content = Invoke-GithubRequest "repos/$REPOSITORY/pulls/$($EVENT.issue.number)" | Select-Object -ExpandProperty Content - $script:EVENT_new = ConvertFrom-Json $content + $content = Invoke-GithubRequest "repos/$REPOSITORY/pulls/$($GITHUB_EVENT.issue.number)" | Select-Object -ExpandProperty Content + $script:GITHUB_EVENT_new = ConvertFrom-Json $content } else { - Write-Log 'Issue comment' + Write-LogInfo 'Issue comment' $commented = $null # No need to do anything on issue comment } } else { - Write-Log 'Not supported comment body' + Write-LogInfo 'Not supported comment body' $commented = $null } } default { - Write-Log 'Only action ''opened'' is supported' + Write-LogInfo 'Only action ''opened'' is supported' $commented = $null } } @@ -50,18 +50,21 @@ function Set-RepositoryContext { .SYNOPSIS Repository context of commented PR is not set to correct $head.ref. #> + [CmdletBinding(SupportsShouldProcess)] param ([Parameter(Mandatory)] $Ref) - if ((git branch --show-current) -ne $Ref) { - Write-Log "Switching branch to $Ref" + if ($PSCmdlet.ShouldProcess('Repository', "Set repository context to $Ref")) { + if ((git branch --show-current) -ne $Ref) { + Write-LogInfo "Switching branch to $Ref" - git fetch --all - git checkout $Ref - git pull + git fetch --all + git checkout $Ref + git pull + } } } -function New-FinalMessage { +function Send-FinalMessage { <# .SYNOPSIS Create and post final comment with information for collaborators. @@ -75,18 +78,18 @@ function New-FinalMessage { [String[]] $Invalid ) - $prID = $EVENT.number + $prID = $GITHUB_EVENT.number $message = New-Array foreach ($ch in $Check) { Add-IntoArray $message "### $($ch.Name)" Add-IntoArray $message '' - New-CheckList $ch.Statuses | ForEach-Object { Add-IntoArray $message $_ } + ConvertTo-CheckList $ch.Statuses | ForEach-Object { Add-IntoArray $message $_ } Add-IntoArray $message '' } if ($Invalid.Count -gt 0) { - Write-Log 'PR contains invalid manifests' + Write-LogInfo 'PR contains invalid manifests' $env:NON_ZERO_EXIT = $true Add-IntoArray $message '### Invalid manifests' @@ -99,7 +102,7 @@ function New-FinalMessage { # Add some more human friendly message if ($env:NON_ZERO_EXIT) { $message.InsertRange(0, @('Your changes did not pass all [checks](https://github.com/ScoopInstaller/GithubActions/wiki/Pull-Request-Checks).', '', - 'Please address the issues in the manifest and comment starting with `/verify` to rerun the checks.')) + 'Please address the issues in the manifest and comment starting with `/verify` to rerun the checks.')) $labelsToAdd += 'manifest-fix-needed' $labelsToRemove += 'review-needed' } else { @@ -128,7 +131,7 @@ function Test-PRFile { $invalid = @() $schema = Get-Content -Path $MANIFESTS_SCHEMA -Raw foreach ($f in $File) { - Write-Log "Starting $($f.filename) checks" + Write-LogInfo "Starting $($f.filename) checks" # Reset variables from previous iteration $manifest = $null @@ -138,7 +141,7 @@ function Test-PRFile { # Convert path into gci item to hold all needed information $manifest = Get-ChildItem $BUCKET_ROOT $f.filename - Write-Log 'Manifest' $manifest + Write-LogInfo 'Manifest' $manifest # Try to parse the JSON $content = Get-Content -Path $manifest.FullName -Raw @@ -147,23 +150,23 @@ function Test-PRFile { } if ($null -eq $object) { - Write-Log 'Conversion failed' + Write-LogInfo 'Conversion failed' # Handling of configuration files (vscode, ...) will not be problem as soon as nested bucket folder is restricted - Write-Log 'Extension' $manifest.Extension + Write-LogInfo 'Extension' $manifest.Extension if ($manifest.Extension -eq '.json') { - Write-Log 'Invalid JSON' + Write-LogInfo 'Invalid JSON' $invalid += $manifest.BaseName } else { - Write-Log 'Not manifest at all' + Write-LogInfo 'Not manifest at all' } - Write-Log "Skipped $($f.filename)" + Write-LogInfo "Skipped $($f.filename)" continue } #region Lint - Write-Log 'Lint' + Write-LogInfo 'Lint' try { & (Join-Path $BINARIES_FOLDER 'formatjson.ps1') -App $manifest.Basename -Dir $MANIFESTS_LOCATION @@ -174,12 +177,12 @@ function Test-PRFile { } catch { $lint = $false - Write-Log 'Lint Checks' @("Exception occurred: $($_.Exception.Message)", "$($_.ScriptStackTrace)") + Write-LogInfo 'Lint Checks' @("Exception occurred: $($_.Exception.Message)", "$($_.ScriptStackTrace)") } $statuses.Add('Lint', $lint) - Write-Log 'Lint done' + Write-LogInfo 'Lint done' #endregion #region 1. Property checks @@ -190,7 +193,7 @@ function Test-PRFile { #region 2. Hashes if ($object.version -ne 'nightly') { - Write-Log 'Hashes' + Write-LogInfo 'Hashes' try { $outputH = @(& (Join-Path $BINARIES_FOLDER 'checkhashes.ps1') -App $manifest.Basename -Dir $MANIFESTS_LOCATION *>&1) @@ -198,41 +201,41 @@ function Test-PRFile { $outputH = @("Exception occurred: $($_.Exception.Message)", "$($_.ScriptStackTrace)") } - Write-Log 'Output' $outputH + Write-LogInfo 'Output' $outputH # Everything should be all right when latest string in array will be OK $statuses.Add('Hashes', ($outputH[-1] -like 'OK')) - Write-Log 'Hashes done' + Write-LogInfo 'Hashes done' } #endregion 2. Hashes #region 3. Checkver and 4. Autoupdate if ($object.checkver) { - Write-Log 'Checkver' + Write-LogInfo 'Checkver' $outputV = @(& (Join-Path $BINARIES_FOLDER 'checkver.ps1') -App $manifest.Basename -Dir $MANIFESTS_LOCATION -Force *>&1) - Write-log 'Output' $outputV + Write-LogInfo 'Output' $outputV $joinedOutputV = $outputV -join ' ' # Try to match ": " from outputV $checkverRegex = "$([regex]::escape($manifest.Basename)):\s*$([regex]::escape($($object.version)))" $checkver = $joinedOutputV -match $checkverRegex $statuses.Add('Checkver', $checkver) - Write-Log 'Checkver done' + Write-LogInfo 'Checkver done' #region Autoupdate if ($object.autoupdate) { - Write-Log 'Autoupdate' + Write-LogInfo 'Autoupdate' $autoupdate = $false switch -Wildcard ($outputV[-1]) { 'ERROR*' { - Write-Log 'Error in checkver' + Write-LogInfo 'Error in checkver' } "couldn't match*" { - Write-Log 'Version match fail' + Write-LogInfo 'Version match fail' } 'Writing updated*' { - Write-Log 'Autoupdate finished successfully' + Write-LogInfo 'Autoupdate finished successfully' $autoupdate = $true } default { $autoupdate = $checkver } @@ -249,29 +252,29 @@ function Test-PRFile { } $statuses.Add('Autoupdate Hash Extraction', $result) } - Write-Log 'Autoupdate done' + Write-LogInfo 'Autoupdate done' } #endregion Autoupdate } #endregion 3. Checkver and 4. Autoupdate #region 5. Manifest format - # Write-Log 'Format' + # Write-LogInfo 'Format' # TODO: implement format check using array compare if possible (or just strings with raws) # TODO: I am not sure if this will handle tabs and everything what could go wrong. #$raw = Get-Content $manifest.Fullname -Raw #$new_raw = $object | ConvertToPrettyJson #$statuses.Add('Format', ($raw -eq $new_raw)) - # Write-Log 'Format done' + # Write-LogInfo 'Format done' #endregion 4. Manifest format #region 6. Installation - # Write-Log 'Installation' + # Write-LogInfo 'Installation' # # Try catch as currently some components are throwing exceptions # try { # $outputI = @(scoop install $manifest.FullName *>&1) # } catch { - # Write-Log 'Installation failed' # Mainly due to some manifest script problem + # Write-LogInfo 'Installation failed' # Mainly due to some manifest script problem # $installation = $false # } @@ -279,17 +282,17 @@ function Test-PRFile { # } # $statuses.Add('Installation', $installation) - # Write-Log 'Installation done' + # Write-LogInfo 'Installation done' #endregion 6. Installation #region 7. Uninstallation - # Write-Log 'Uninstallation' - # Write-Log 'Uninstallation done' + # Write-LogInfo 'Uninstallation' + # Write-LogInfo 'Uninstallation done' #endregion 7. Uninstallation $check += [Ordered] @{ 'Name' = $manifest.Basename; 'Statuses' = $statuses } - Write-Log "Finished $($f.filename) checks" + Write-LogInfo "Finished $($f.filename) checks" } return $check, $invalid @@ -304,40 +307,40 @@ function Initialize-PR { 2. Validate all changed manifests 3. Post comment with check results #> - Write-Log 'PR initialized' + Write-LogInfo 'PR initialized' # required to access releases in private GitHub repos $env:SCOOP_GH_TOKEN = $env:GITHUB_TOKEN #region Stage 1 - Repository initialization - $commented = Start-PR + $commented = Resolve-PullRequestAction if ($null -eq $commented) { return } # Exit on not supported state - Write-Log 'Commented?' $commented + Write-LogInfo 'Commented?' $commented - $EVENT | ConvertTo-Json -Depth 8 -Compress | Write-Log 'Pure PR Event' - if ($EVENT_new) { - Write-Log 'There is new event available' - $EVENT = $EVENT_new - $EVENT | ConvertTo-Json -Depth 8 -Compress | Write-Log 'New Event' + $GITHUB_EVENT | ConvertTo-Json -Depth 8 -Compress | Write-LogInfo 'Pure PR Event' + if ($GITHUB_EVENT_new) { + Write-LogInfo 'There is new event available' + $GITHUB_EVENT = $GITHUB_EVENT_new + $GITHUB_EVENT | ConvertTo-Json -Depth 8 -Compress | Write-LogInfo 'New Event' } # TODO: Ternary - $head = if ($commented) { $EVENT.head } else { $EVENT.pull_request.head } + $head = if ($commented) { $GITHUB_EVENT.head } else { $GITHUB_EVENT.pull_request.head } if ($head.repo.fork) { - Write-Log 'Forked repository' + Write-LogInfo 'Forked repository' - if ($EVENT_TYPE -ne 'pull_request_target') { + if ($GITHUB_EVENT_TYPE -ne 'pull_request_target') { # There is no need to run whole action under forked repository due to permission problem if ($commented -eq $false) { - Write-Log 'Cannot comment with read only token' + Write-LogInfo 'Cannot comment with read only token' # TODO: Execute it and adopt pester like checks return } } $REPOSITORY_forked = "$($head.repo.full_name):$($head.ref)" - Write-Log 'Repo' $REPOSITORY_forked + Write-LogInfo 'Repo' $REPOSITORY_forked $cloneLocation = "${env:TMP}\forked_repository" git clone --branch $head.ref $head.repo.clone_url $cloneLocation @@ -346,7 +349,7 @@ function Initialize-PR { # TODO: Ternary $script:MANIFESTS_LOCATION = if (Test-Path $buck) { $buck } else { $BUCKET_ROOT } - Write-Log "Switching to $REPOSITORY_forked" + Write-LogInfo "Switching to $REPOSITORY_forked" Push-Location $cloneLocation } @@ -355,33 +358,33 @@ function Initialize-PR { #endregion Stage 1 - Repository initialization # In case of forked repository it needs to be '/github/forked_workspace' - Get-Location | Write-Log 'Context of action' - (Get-ChildItem $BUCKET_ROOT | Select-Object -ExpandProperty Basename) -join ', ' | Write-log 'Root Files' - (Get-ChildItem $MANIFESTS_LOCATION -Filter '*.json' -Recurse | Select-Object -ExpandProperty Basename) -join ', ' | Write-log 'Manifests' + Get-Location | Write-LogInfo 'Context of action' + (Get-ChildItem $BUCKET_ROOT | Select-Object -ExpandProperty Basename) -join ', ' | Write-LogInfo 'Root Files' + (Get-ChildItem $MANIFESTS_LOCATION -Filter '*.json' -Recurse | Select-Object -ExpandProperty Basename) -join ', ' | Write-LogInfo 'Manifests' # Do not run checks on removed files - $files = Get-AllChangedFilesInPR $EVENT.number -Filter - Write-Log 'PR Changed Files' $files + $files = Get-AllChangedFilesInPR $GITHUB_EVENT.number -Filter + Write-LogInfo 'PR Changed Files' $files $files = $files | Where-Object -Property 'filename' -Like -Value 'bucket/*' - Write-Log 'Only Changed Manifests' $files + Write-LogInfo 'Only Changed Manifests' $files # Stage 2 - Manifests validation $check, $invalid = Test-PRFile $files #region Stage 3 - Final Message - Write-Log 'Checked manifests' $check.name - Write-Log 'Invalids' $invalid + Write-LogInfo 'Checked manifests' $check.name + Write-LogInfo 'Invalids' $invalid if (($check.Count -eq 0) -and ($invalid.Count -eq 0)) { - Write-Log 'No compatible files in PR' + Write-LogInfo 'No compatible files in PR' return } # TODO: Pester like check - New-FinalMessage $check $invalid + Send-FinalMessage $check $invalid #endregion Stage 3 - Final Message - Write-Log 'PR finished' + Write-LogInfo 'PR finished' } Export-ModuleMember -Function Initialize-PR diff --git a/src/Action/Scheduled.psm1 b/src/Action/Scheduled.psm1 index d92dc3b..aad1590 100644 --- a/src/Action/Scheduled.psm1 +++ b/src/Action/Scheduled.psm1 @@ -5,7 +5,7 @@ function Initialize-Scheduled { .SYNOPSIS Excavator alternative. Based on schedule execute of auto-pr binary. #> - Write-Log 'Scheduled initialized' + Write-LogInfo 'Scheduled initialized' if ($env:GITHUB_REF_NAME) { $_BRANCH = $env:GITHUB_REF_NAME @@ -31,7 +31,7 @@ function Initialize-Scheduled { & (Join-Path $BINARIES_FOLDER 'auto-pr.ps1') @params # TODO: Post some comment?? Or other way how to publish logs for non collaborators. - Write-Log 'Scheduled finished' + Write-LogInfo 'Scheduled finished' } Export-ModuleMember -Function Initialize-Scheduled diff --git a/src/ActionWrapper.psm1 b/src/ActionWrapper.psm1 index 81c02bb..b35f7c3 100644 --- a/src/ActionWrapper.psm1 +++ b/src/ActionWrapper.psm1 @@ -6,19 +6,19 @@ function Invoke-Action { .SYNOPSIS Invoke specific action handler. #> - Write-Log -Summary 'GITHUB API RATE LIMIT' -Message (Get-RateLimit -Core | ConvertTo-Json -compress) + Write-LogInfo -Summary 'GITHUB API RATE LIMIT' -Message (Get-RateLimit -Core | ConvertTo-Json -Compress) - switch ($EVENT_TYPE) { + switch ($GITHUB_EVENT_TYPE) { 'pull_request' { Initialize-PR } 'issue_comment' { Initialize-PR } 'schedule' { Initialize-Scheduled } 'workflow_dispatch' { Initialize-Scheduled } 'repository_dispatch' { Initialize-Scheduled } 'issues' { Initialize-Issue } - default { Write-Log 'Not supported event type' } + default { Write-LogInfo 'Not supported event type' } } - Write-Log -Summary 'GITHUB API RATE LIMIT' -Message (Get-RateLimit -Core | ConvertTo-Json -compress) + Write-LogInfo -Summary 'GITHUB API RATE LIMIT' -Message (Get-RateLimit -Core | ConvertTo-Json -Compress) } Export-ModuleMember -Function Invoke-Action diff --git a/src/Github.psm1 b/src/Github.psm1 index abd5133..452c859 100644 --- a/src/Github.psm1 +++ b/src/Github.psm1 @@ -14,7 +14,7 @@ function Invoke-GithubRequest { Invoke-GithubRequest 'repos/User/Repo/pulls' -Method 'Post' -Body @{ 'body' = 'body' } #> param( - [Parameter(Mandatory, ValueFromPipeline)] + [Parameter(Mandatory)] [String] $Query, [Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'Get', [Hashtable] $Body @@ -30,11 +30,11 @@ function Invoke-GithubRequest { 'Uri' = "$baseUrl/$Query" } - Write-Log 'Github Request' $parameters + Write-LogInfo 'Github Request' $parameters if ($Body) { $parameters.Add('Body', (ConvertTo-Json $Body -Depth 8 -Compress)) } - Write-Log 'Request Body' $parameters.Body + Write-LogInfo 'Request Body' $parameters.Body $env:GH_REQUEST_COUNTER = ([int] $env:GH_REQUEST_COUNTER) + 1 @@ -54,7 +54,7 @@ function Add-Comment { If set, link to current job log will be appended to comment. #> param( - [Parameter(Mandatory, ValueFromPipeline)] + [Parameter(Mandatory)] [Int] $ID, [Alias('Comment')] [String[]] $Message, @@ -79,7 +79,7 @@ function Get-AllChangedFilesInPR { Return only files which are not 'removed'. #> param( - [Parameter(Mandatory, ValueFromPipeline)] + [Parameter(Mandatory)] [Int] $ID, [Switch] $Filter ) @@ -116,6 +116,7 @@ function New-Issue { List of user logins to be automatically assigned. Authenticated user needs push access to repository to be able to set assignees. #> + [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [String] $Title, @@ -125,15 +126,17 @@ function New-Issue { [String[]] $Assignee = @() ) - $params = @{ - 'title' = $Title - 'body' = ($Body -join "`r`n") - 'labels' = $Label - 'assignees' = $Assignee - } - if ($Milestone) { $params.Add('milestone', $Milestone) } + if ($PSCmdlet.ShouldProcess("GitHub: $REPOSITORY", 'Create New Issue')) { + $params = @{ + 'title' = $Title + 'body' = ($Body -join "`r`n") + 'labels' = $Label + 'assignees' = $Assignee + } + if ($Milestone) { $params.Add('milestone', $Milestone) } - return Invoke-GithubRequest "repos/$REPOSITORY/issues" -Method 'Post' -Body $params + return Invoke-GithubRequest "repos/$REPOSITORY/issues" -Method 'Post' -Body $params + } } function Close-Issue { @@ -144,7 +147,7 @@ function Close-Issue { .PARAMETER ID ID of issue / PR to be closed. #> - param([Parameter(Mandatory, ValueFromPipeline)][Int] $ID) + param([Parameter(Mandatory)][Int] $ID) return Invoke-GithubRequest -Query "repos/$REPOSITORY/issues/$ID" -Method Patch -Body @{ 'state' = 'closed' } } @@ -160,7 +163,7 @@ function Add-Label { Label to be set. #> param( - [Parameter(Mandatory, ValueFromPipeline)] + [Parameter(Mandatory)] [Int] $ID, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] # > Must contains at least one label @@ -180,25 +183,28 @@ function Remove-Label { .PARAMETER Label Label to be removed. #> + [CmdletBinding(SupportsShouldProcess)] param( - [Parameter(Mandatory, ValueFromPipeline)] + [Parameter(Mandatory)] [Int] $ID, [ValidateNotNullOrEmpty()] [String[]] $Label ) - $responses = New-Array - # Get all labels on specific issue - $issueLabels = (Invoke-GithubRequest -Query "repos/$REPOSITORY/issues/$ID/labels" | Select-Object -ExpandProperty Content | ConvertFrom-Json).name + if ($PSCmdlet.ShouldProcess("GitHub: $REPOSITORY", "Remove Label(s) from Issue #$ID")) { + $responses = New-Array + # Get all labels on specific issue + $issueLabels = (Invoke-GithubRequest -Query "repos/$REPOSITORY/issues/$ID/labels" | Select-Object -ExpandProperty Content | ConvertFrom-Json).name - foreach ($lab in $Label) { - if ($issueLabels -contains $lab) { - # https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue - Add-IntoArray $responses (Invoke-GithubRequest -Query "repos/$REPOSITORY/issues/$ID/labels/$label" -Method Delete) + foreach ($lab in $Label) { + if ($issueLabels -contains $lab) { + # https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue + Add-IntoArray $responses (Invoke-GithubRequest -Query "repos/$REPOSITORY/issues/$ID/labels/$label" -Method Delete) + } } - } - return $responses + return $responses + } } function Get-RateLimit { @@ -220,7 +226,7 @@ function Get-RateLimit { $rateLimit = $response.Content | ConvertFrom-Json } catch { - Write-Log -Summary "Failed to retrieve rate limit information.`n Exception occurred: $($_.Exception.Message)" + Write-LogInfo -Summary "Failed to retrieve rate limit information.`n Exception occurred: $($_.Exception.Message)" } if ($Core -and $rateLimit -and $rateLimit.resources -and $rateLimit.resources.core) { @@ -308,7 +314,7 @@ function Get-LogURL { $logURL += "/job/$job_id" } - Write-Log 'Log URL' $logURL + Write-LogInfo 'Log URL' $logURL return $logURL } diff --git a/src/Helpers.psm1 b/src/Helpers.psm1 index e9c8b81..ac83aa4 100644 --- a/src/Helpers.psm1 +++ b/src/Helpers.psm1 @@ -1,9 +1,9 @@ Join-Path $PSScriptRoot 'Variables.psm1' | Import-Module -function Write-Log { +function Write-LogInfo { <# .SYNOPSIS - Persist message in docker log. For debug mainly. Write-Host is more suitable because then write-log is not interfering with pipes. + Persist message in docker log. For debug mainly. Write-Host is more suitable because then Write-LogInfo is not interfering with pipes. .PARAMETER Summary Header of log. .PARAMETER Message @@ -15,20 +15,22 @@ function Write-Log { [Object[]] $Message ) - # If it is only summary it is informative log - if ($Summary -and ($null -eq $Message)) { - Write-Host "INFO: $Summary" - } elseif (($Message.Count -eq 1) -and ($Message[0] -isnot [Hashtable])) { - # Simple non hashtable object and summary should be one liner - Write-Host "${Summary}: $Message" - } else { - # Detailed output using format table - Write-Host "Log of ${Summary}:" - $mess = ($Message | Format-Table -HideTableHeaders -AutoSize | Out-String).Trim() -split "`r`n" - Write-Host ($mess | ForEach-Object { "`n $_" }) - } + process { + # If it is only summary it is informative log + if ($Summary -and ($null -eq $Message)) { + Write-Host "INFO: $Summary" + } elseif (($Message.Count -eq 1) -and ($Message[0] -isnot [Hashtable])) { + # Simple non hashtable object and summary should be one liner + Write-Host "${Summary}: $Message" + } else { + # Detailed output using format table + Write-Host "Log of ${Summary}:" + $mess = ($Message | Format-Table -HideTableHeaders -AutoSize | Out-String).Trim() -split "`r`n" + Write-Host ($mess | ForEach-Object { "`n $_" }) + } - Write-Host '' + Write-Host '' + } } function Get-EnvironmentVariable { @@ -45,8 +47,12 @@ function New-Array { .SYNOPSIS Create new Array list. More suitable for usage as it provides better operations. #> + [CmdletBinding(SupportsShouldProcess)] + param() - return New-Object System.Collections.ArrayList + if ($PSCmdlet.ShouldProcess('In-memory', 'Create New Array')) { + return New-Object System.Collections.ArrayList + } } function Add-IntoArray { @@ -79,7 +85,7 @@ function Expand-Property { TODO: Rework and support nested properties #> param( - [Parameter(Mandatory, ValueFromPipeline)] + [Parameter(Mandatory)] [Object] $Object, [Parameter(Mandatory)] [String] $Property @@ -115,7 +121,7 @@ function Initialize-NeededConfiguration { } # Log all environment variables - Write-Log 'Environment' (Get-EnvironmentVariable) + Write-LogInfo 'Environment' (Get-EnvironmentVariable) } function Get-Manifest { @@ -146,9 +152,16 @@ function New-DetailsCommentString { Type of code fenced block (json, yml, ...). Needs to be valid markdown code fenced block type. #> - param([Parameter(Mandatory)][String] $Summary, [String[]] $Content, [String] $Type = 'text') + [CmdletBinding(SupportsShouldProcess)] + param( + [Parameter(Mandatory)] + [String] $Summary, + [String[]] $Content, + [String] $Type = 'text' + ) - return @" + if ($PSCmdlet.ShouldProcess('In-memory', 'Create details comment string')) { + return @"
$Summary @@ -157,6 +170,7 @@ $($Content -join "`r`n") ``````
"@ + } } function New-CheckListItem { @@ -172,19 +186,28 @@ function New-CheckListItem { .PARAMETER Simple Simple list item will be used instead of check list. #> - param ([Parameter(Mandatory)][String] $Item, [Int] $IndentLevel = 0, [Switch] $OK, [Switch] $Simple) + [CmdletBinding(SupportsShouldProcess)] + param( + [Parameter(Mandatory)] + [String] $Item, + [Int] $IndentLevel = 0, + [Switch] $OK, + [Switch] $Simple + ) - $ind = ' ' * 4 * $IndentLevel - $char = if ($OK) { 'x' } else { ' ' } - $check = if ($Simple) { '' } else { "[$char] " } + if ($PSCmdlet.ShouldProcess('In-memory', "Create CheckListItem: $Item")) { + $ind = ' ' * 4 * $IndentLevel + $char = if ($OK) { 'x' } else { ' ' } + $check = if ($Simple) { '' } else { "[$char] " } - return "$ind- $check$Item" + return "$ind- $check$Item" + } } -function New-CheckList { +function ConvertTo-CheckList { <# .SYNOPSIS - Create checklist. + Create checklist from check statuses. .PARAMETER Status Hashtable/PSCustomObject with name of check as key and boolean (or other pscustomobject) as value. #> @@ -221,7 +244,7 @@ function New-CheckList { } $result | ForEach-Object { - Write-Log $_.Item $_.State + Write-LogInfo $_.Item $_.State if ($_.State -eq $false) { $env:NON_ZERO_EXIT = $true } $final += New-CheckListItem -Item $_.Item -IndentLevel $_.Indent -OK:$_.State } @@ -238,9 +261,9 @@ function Test-NestedBucket { #> if (Test-Path $MANIFESTS_LOCATION) { - Write-Log 'Bucket contains nested bucket folder' + Write-LogInfo 'Bucket contains nested bucket folder' } else { - Write-Log 'Buckets without nested bucket folder are not supported.' + Write-LogInfo 'Buckets without nested bucket folder are not supported.' $adopt = 'Adopt nested bucket structure' # Get opened issues @@ -249,7 +272,7 @@ function Test-NestedBucket { $issues = ConvertFrom-Json $req.Content | Where-Object { $_.title -eq $adopt } if ($issues -and ($issues.Count -gt 0)) { - Write-Log 'Issue already exists' + Write-LogInfo 'Issue already exists' } else { New-Issue -Title $adopt -Body @( 'Buckets without nested `bucket` folder are not supported. You will not be able to use actions without it.', @@ -283,6 +306,6 @@ function Resolve-IssueTitle { } } -Export-ModuleMember -Function Write-Log, Get-EnvironmentVariables, New-Array, Add-IntoArray, Initialize-NeededConfiguration, ` +Export-ModuleMember -Function Write-LogInfo, Get-EnvironmentVariables, New-Array, Add-IntoArray, Initialize-NeededConfiguration, ` Expand-Property, Get-Manifest, New-DetailsCommentString, New-CheckListItem, Test-NestedBucket, Resolve-IssueTitle, ` - New-CheckList + ConvertTo-CheckList diff --git a/src/Scoop.psm1 b/src/Scoop.psm1 index c4bc6cb..a5e7e0d 100644 --- a/src/Scoop.psm1 +++ b/src/Scoop.psm1 @@ -5,17 +5,17 @@ function Install-Scoop { .SYNOPSIS Install scoop using new installer. #> - Write-Log 'Installing scoop' + Write-LogInfo 'Installing scoop' $f = Join-Path $env:USERPROFILE 'install.ps1' Invoke-WebRequest 'https://raw.githubusercontent.com/ScoopInstaller/Install/master/install.ps1' -UseBasicParsing -OutFile $f & $f -RunAsAdmin if ($env:SCOOP_REPO) { - Write-Log "Switching to repository: ${env:SCOOP_REPO}" + Write-LogInfo "Switching to repository: ${env:SCOOP_REPO}" scoop config scoop_repo $env:SCOOP_REPO $needUpdate = $true } if ($env:SCOOP_BRANCH) { - Write-Log "Switching to branch: ${env:SCOOP_BRANCH}" + Write-LogInfo "Switching to branch: ${env:SCOOP_BRANCH}" scoop config scoop_branch $env:SCOOP_BRANCH $needUpdate = $true } diff --git a/src/Variables.psm1 b/src/Variables.psm1 index 29fb175..8c4f48d 100644 --- a/src/Variables.psm1 +++ b/src/Variables.psm1 @@ -13,11 +13,11 @@ $env:GH_REQUEST_COUNTER = 0 $NON_ZERO = 258 # Convert actual API response to object -$EVENT = Get-Content $env:GITHUB_EVENT_PATH -Raw | ConvertFrom-Json +$GITHUB_EVENT = Get-Content $env:GITHUB_EVENT_PATH -Raw | ConvertFrom-Json # Compressed Event -$EVENT_RAW = ConvertTo-Json $EVENT -Depth 100 -Compress +$GITHUB_EVENT_RAW = ConvertTo-Json $GITHUB_EVENT -Depth 100 -Compress # Event type for automatic handler detection -$EVENT_TYPE = $env:GITHUB_EVENT_NAME +$GITHUB_EVENT_TYPE = $env:GITHUB_EVENT_NAME # user/repo format $REPOSITORY = $env:GITHUB_REPOSITORY @@ -34,7 +34,7 @@ $MANIFESTS_LOCATION = Join-Path $BUCKET_ROOT 'bucket' $DEFAULT_EMAIL = '41898282+github-actions[bot]@users.noreply.github.com' -Export-ModuleMember -Variable EVENT, EVENT_RAW, EVENT_TYPE, ` +Export-ModuleMember -Variable GITHUB_EVENT, GITHUB_EVENT_RAW, GITHUB_EVENT_TYPE, ` REPOSITORY, JOB, RUN_ID, ` BUCKET_ROOT, BINARIES_FOLDER, ` MANIFESTS_SCHEMA, MANIFESTS_LOCATION, NON_ZERO, DEFAULT_EMAIL