From a5a50b4ce33663002702de63de1cffadef5e42df Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 4 Apr 2026 10:40:55 +0200 Subject: [PATCH 1/2] Fix GitHubWorkflowRun constructor and Remove-GitHubWorkflowRun error handling --- .../public/Workflows/GitHubWorkflowRun.ps1 | 50 +++++++++---------- .../Runs/Remove-GitHubWorkflowRun.ps1 | 8 ++- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/classes/public/Workflows/GitHubWorkflowRun.ps1 b/src/classes/public/Workflows/GitHubWorkflowRun.ps1 index 223434062..bca36bff5 100644 --- a/src/classes/public/Workflows/GitHubWorkflowRun.ps1 +++ b/src/classes/public/Workflows/GitHubWorkflowRun.ps1 @@ -103,34 +103,34 @@ GitHubWorkflowRun([PSCustomObject] $Object) { # From GitHubNode - $this.ID = $_.id - $this.NodeID = $_.node_id + $this.ID = $Object.id + $this.NodeID = $Object.node_id # From GitHubWorkflowRun - $this.Name = $_.name + $this.Name = $Object.name $this.Owner = [GitHubOwner]::new($Object.repository.owner) $this.Repository = [GitHubRepository]::new($Object.repository) - $this.CheckSuiteID = $_.check_suite_id - $this.CheckSuiteNodeID = $_.check_suite_node_id - $this.HeadBranch = $_.head_branch - $this.HeadSha = $_.head_sha - $this.Path = $_.path - $this.RunNumber = $_.run_number - $this.RunAttempt = $_.run_attempt - $this.ReferencedWorkflows = $_.referenced_workflows - $this.Event = $_.event - $this.Status = $_.status - $this.Conclusion = $_.conclusion - $this.WorkflowID = $_.workflow_id - $this.Url = $_.html_url - $this.PullRequests = $_.pull_requests - $this.CreatedAt = $_.created_at - $this.UpdatedAt = $_.updated_at - $this.StartedAt = $_.run_started_at - $this.Actor = [GitHubUser]::new($_.actor) - $this.TriggeringActor = [GitHubUser]::new($_.triggering_actor) - $this.HeadCommit = $_.head_commit - $this.HeadRepository = [GitHubRepository]::new($_.head_repository) - $this.DisplayTitle = $_.display_title + $this.CheckSuiteID = $Object.check_suite_id + $this.CheckSuiteNodeID = $Object.check_suite_node_id + $this.HeadBranch = $Object.head_branch + $this.HeadSha = $Object.head_sha + $this.Path = $Object.path + $this.RunNumber = $Object.run_number + $this.RunAttempt = $Object.run_attempt + $this.ReferencedWorkflows = $Object.referenced_workflows + $this.Event = $Object.event + $this.Status = $Object.status + $this.Conclusion = $Object.conclusion + $this.WorkflowID = $Object.workflow_id + $this.Url = $Object.html_url + $this.PullRequests = $Object.pull_requests + $this.CreatedAt = $Object.created_at + $this.UpdatedAt = $Object.updated_at + $this.StartedAt = $Object.run_started_at + $this.Actor = [GitHubUser]::new($Object.actor) + $this.TriggeringActor = [GitHubUser]::new($Object.triggering_actor) + $this.HeadCommit = $Object.head_commit + $this.HeadRepository = [GitHubRepository]::new($Object.head_repository) + $this.DisplayTitle = $Object.display_title } } diff --git a/src/functions/public/Workflows/Runs/Remove-GitHubWorkflowRun.ps1 b/src/functions/public/Workflows/Runs/Remove-GitHubWorkflowRun.ps1 index 1be51bea9..cc44ca5fd 100644 --- a/src/functions/public/Workflows/Runs/Remove-GitHubWorkflowRun.ps1 +++ b/src/functions/public/Workflows/Runs/Remove-GitHubWorkflowRun.ps1 @@ -59,8 +59,12 @@ } if ($PSCmdlet.ShouldProcess("$Owner/$Repository/$ID", 'Delete workflow run')) { - Write-Verbose "Deleted workflow run [$ID] in [$Owner/$Repository]" - $null = Invoke-GitHubAPI @apiParams + try { + $null = Invoke-GitHubAPI @apiParams + Write-Verbose "Deleted workflow run [$ID] in [$Owner/$Repository]" + } catch { + Write-Error "Failed to delete workflow run [$ID] in [$Owner/$Repository]: $_" + } } } From bae5ded06dfe7a697bf1032388abdd6890288b9b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 2 May 2026 21:53:20 +0200 Subject: [PATCH 2/2] Add GitHubWorkflowRun constructor regression test per review thread #3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verifies all scalar properties are populated from the $Object parameter, not from the caller's $_. Constructing outside ForEach-Object ensures is null — if the constructor incorrectly references instead of , the assertions will fail. --- tests/Actions.Tests.ps1 | 82 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/tests/Actions.Tests.ps1 b/tests/Actions.Tests.ps1 index 3bd3223db..0ca0105a6 100644 --- a/tests/Actions.Tests.ps1 +++ b/tests/Actions.Tests.ps1 @@ -27,6 +27,88 @@ BeforeAll { Describe 'Actions' { $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" + Context 'GitHubWorkflowRun' { + It 'Constructor should populate properties from $Object parameter, not from $_' { + # Build a minimal mock object matching the GitHub REST API workflow-run response shape. + # The constructor is called outside ForEach-Object so $_ is $null. + # If the constructor incorrectly references $_ instead of $Object, scalar properties will be empty. + $mockOwner = [PSCustomObject]@{ + id = 1 + node_id = 'MDQ6VXNlcjE=' + login = 'octocat' + avatar_url = 'https://github.com/images/error/octocat_happy.gif' + html_url = 'https://github.com/octocat' + type = 'User' + } + + $mockRepo = [PSCustomObject]@{ + id = 100 + node_id = 'MDEwOlJlcG9zaXRvcnkxMDA=' + name = 'hello-world' + full_name = 'octocat/hello-world' + owner = $mockOwner + html_url = 'https://github.com/octocat/hello-world' + } + + $mockUser = [PSCustomObject]@{ + id = 1 + node_id = 'MDQ6VXNlcjE=' + login = 'octocat' + avatar_url = 'https://github.com/images/error/octocat_happy.gif' + html_url = 'https://github.com/octocat' + type = 'User' + } + + $mockRun = [PSCustomObject]@{ + id = 42 + node_id = 'MDExOldvcmtmbG93UnVuNDI=' + name = 'CI Build' + check_suite_id = 99 + check_suite_node_id = 'MDEwOkNoZWNrU3VpdGU5OQ==' + head_branch = 'main' + head_sha = '009b8a3a9ccbb128af87f9b1c0f4c62e8a304f6d' + path = '.github/workflows/ci.yml' + run_number = 106 + run_attempt = 1 + event = 'push' + status = 'completed' + conclusion = 'success' + workflow_id = 5 + html_url = 'https://github.com/octocat/hello-world/actions/runs/42' + display_title = 'CI Build' + created_at = '2023-01-01T12:00:00Z' + updated_at = '2023-01-01T12:05:00Z' + run_started_at = '2023-01-01T12:01:00Z' + pull_requests = @() + referenced_workflows = @() + repository = $mockRepo + head_repository = $mockRepo + actor = $mockUser + triggering_actor = $mockUser + head_commit = [PSCustomObject]@{ id = 'abc123'; message = 'Test commit' } + } + + $result = [GitHubWorkflowRun]::new($mockRun) + + $result.ID | Should -Be 42 + $result.NodeID | Should -Be 'MDExOldvcmtmbG93UnVuNDI=' + $result.Name | Should -Be 'CI Build' + $result.CheckSuiteID | Should -Be 99 + $result.CheckSuiteNodeID | Should -Be 'MDEwOkNoZWNrU3VpdGU5OQ==' + $result.HeadBranch | Should -Be 'main' + $result.HeadSha | Should -Be '009b8a3a9ccbb128af87f9b1c0f4c62e8a304f6d' + $result.Path | Should -Be '.github/workflows/ci.yml' + $result.RunNumber | Should -Be 106 + $result.RunAttempt | Should -Be 1 + $result.Event | Should -Be 'push' + $result.Status | Should -Be 'completed' + $result.Conclusion | Should -Be 'success' + $result.WorkflowID | Should -Be 5 + $result.Url | Should -Be 'https://github.com/octocat/hello-world/actions/runs/42' + $result.DisplayTitle | Should -Be 'CI Build' + } + } + Context 'OIDC' { Context 'Get-GitHubOidcClaim' { It 'Get-GitHubOidcClaim - No context - Returns claim keys for github.com' {