From ad113a711d0f238e0941c0abaf168fe96633bc1e Mon Sep 17 00:00:00 2001 From: Ninad Sutrave Date: Sat, 17 Oct 2026 11:56:54 +0530 Subject: [PATCH 1/2] feat: Add support for Actions concurrency groups --- github/actions_concurrency_groups.go | 155 ++++++++++++ github/actions_concurrency_groups_test.go | 289 ++++++++++++++++++++++ github/github-accessors.go | 200 +++++++++++++++ github/github-accessors_test.go | 236 ++++++++++++++++++ github/github-iterators.go | 70 ++++++ github/github-iterators_test.go | 144 +++++++++++ 6 files changed, 1094 insertions(+) create mode 100644 github/actions_concurrency_groups.go create mode 100644 github/actions_concurrency_groups_test.go diff --git a/github/actions_concurrency_groups.go b/github/actions_concurrency_groups.go new file mode 100644 index 00000000000..2a7de1f6bde --- /dev/null +++ b/github/actions_concurrency_groups.go @@ -0,0 +1,155 @@ +// Copyright 2026 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/url" +) + +// ConcurrencyGroup represents a GitHub Actions concurrency group. +type ConcurrencyGroup struct { + GroupName string `json:"group_name"` + GroupURL string `json:"group_url"` + TotalCount *int `json:"total_count,omitempty"` + LastAcquiredAt *Timestamp `json:"last_acquired_at,omitempty"` + GroupMembers []*ConcurrencyGroupMember `json:"group_members,omitzero"` +} + +// ConcurrencyGroupMember represents a workflow run or job that is holding or waiting for a concurrency group. +type ConcurrencyGroupMember struct { + RunID int64 `json:"run_id"` + RunName string `json:"run_name"` + RunURL *string `json:"run_url,omitempty"` + RunHTMLURL *string `json:"run_html_url,omitempty"` + JobID *int64 `json:"job_id,omitempty"` + JobName *string `json:"job_name,omitempty"` + JobURL *string `json:"job_url,omitempty"` + JobHTMLURL *string `json:"job_html_url,omitempty"` + Status string `json:"status"` + Position *int `json:"position,omitempty"` + PositionURL *string `json:"position_url,omitempty"` +} + +// ConcurrencyGroupList represents a list of GitHub Actions concurrency groups. +type ConcurrencyGroupList struct { + TotalCount int `json:"total_count"` + ConcurrencyGroups []*ConcurrencyGroup `json:"concurrency_groups"` +} + +// ListConcurrencyGroupsOptions specifies the optional parameters to the +// ActionsService.ListConcurrencyGroups method. +type ListConcurrencyGroupsOptions struct { + // A cursor, as given in the Link header. If specified, the query only searches for concurrency groups after this cursor. + After string `url:"after,omitempty"` + + // For paginated result sets, the number of results to include per page. + PerPage int `url:"per_page,omitempty"` +} + +// GetConcurrencyGroupOptions specifies the optional parameters to the +// ActionsService.GetConcurrencyGroup method. +type GetConcurrencyGroupOptions struct { + // AheadOfRun filters the results to the items ahead of this workflow run ID, plus the run itself. + AheadOfRun int64 `url:"ahead_of_run,omitempty"` + + // AheadOfJob filters the results to the items ahead of this job ID, plus the job itself. + AheadOfJob int64 `url:"ahead_of_job,omitempty"` +} + +// ListWorkflowRunConcurrencyGroupsOptions specifies the optional parameters to the +// ActionsService.ListWorkflowRunConcurrencyGroups method. +type ListWorkflowRunConcurrencyGroupsOptions struct { + // A cursor, as given in the Link header. If specified, the query only searches for concurrency groups before this cursor. + Before string `url:"before,omitempty"` + + // A cursor, as given in the Link header. If specified, the query only searches for concurrency groups after this cursor. + After string `url:"after,omitempty"` + + // For paginated result sets, the number of results to include per page. + PerPage int `url:"per_page,omitempty"` +} + +// ListConcurrencyGroups lists the active concurrency groups for a repository. +// +// GitHub API docs: https://docs.github.com/rest/actions/concurrency-groups?apiVersion=2022-11-28#list-concurrency-groups-for-a-repository +// +//meta:operation GET /repos/{owner}/{repo}/actions/concurrency_groups +func (s *ActionsService) ListConcurrencyGroups(ctx context.Context, owner, repo string, opts *ListConcurrencyGroupsOptions) (*ConcurrencyGroupList, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/concurrency_groups", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", u, nil) + if err != nil { + return nil, nil, err + } + + var groups *ConcurrencyGroupList + resp, err := s.client.Do(req, &groups) + if err != nil { + return nil, resp, err + } + + return groups, resp, nil +} + +// GetConcurrencyGroup gets a concurrency group for a repository, including the items in its queue. +// +// Note: the concurrency group name is URL path escaped for you. See: https://pkg.go.dev/net/url#PathEscape . +// +// GitHub API docs: https://docs.github.com/rest/actions/concurrency-groups?apiVersion=2022-11-28#get-a-concurrency-group-for-a-repository +// +//meta:operation GET /repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name} +func (s *ActionsService) GetConcurrencyGroup(ctx context.Context, owner, repo, groupName string, opts *GetConcurrencyGroupOptions) (*ConcurrencyGroup, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/concurrency_groups/%v", owner, repo, url.PathEscape(groupName)) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", u, nil) + if err != nil { + return nil, nil, err + } + + var group *ConcurrencyGroup + resp, err := s.client.Do(req, &group) + if err != nil { + return nil, resp, err + } + + return group, resp, nil +} + +// ListWorkflowRunConcurrencyGroups lists the concurrency groups associated with a workflow run or its jobs. +// +// GitHub API docs: https://docs.github.com/rest/actions/concurrency-groups?apiVersion=2022-11-28#list-concurrency-groups-for-a-workflow-run +// +//meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups +func (s *ActionsService) ListWorkflowRunConcurrencyGroups(ctx context.Context, owner, repo string, runID int64, opts *ListWorkflowRunConcurrencyGroupsOptions) (*ConcurrencyGroupList, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/concurrency_groups", owner, repo, runID) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", u, nil) + if err != nil { + return nil, nil, err + } + + var groups *ConcurrencyGroupList + resp, err := s.client.Do(req, &groups) + if err != nil { + return nil, resp, err + } + + return groups, resp, nil +} diff --git a/github/actions_concurrency_groups_test.go b/github/actions_concurrency_groups_test.go new file mode 100644 index 00000000000..8998facae4c --- /dev/null +++ b/github/actions_concurrency_groups_test.go @@ -0,0 +1,289 @@ +// Copyright 2026 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestActionsService_ListConcurrencyGroups(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/actions/concurrency_groups", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "after": "abc", + "per_page": "2", + }) + fmt.Fprint(w, `{ + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod", + "last_acquired_at": `+referenceTimeStr+` + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/o/r/actions/concurrency_groups/ci-build", + "last_acquired_at": null + } + ] + }`) + }) + + ctx := t.Context() + opts := &ListConcurrencyGroupsOptions{After: "abc", PerPage: 2} + groups, _, err := client.Actions.ListConcurrencyGroups(ctx, "o", "r", opts) + if err != nil { + t.Errorf("Actions.ListConcurrencyGroups returned error: %v", err) + } + + want := &ConcurrencyGroupList{ + TotalCount: 2, + ConcurrencyGroups: []*ConcurrencyGroup{ + { + GroupName: "deploy-prod", + GroupURL: "https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod", + LastAcquiredAt: &referenceTimestamp, + }, + { + GroupName: "ci-build", + GroupURL: "https://api.github.com/repos/o/r/actions/concurrency_groups/ci-build", + }, + }, + } + if !cmp.Equal(groups, want) { + t.Errorf("Actions.ListConcurrencyGroups returned %+v, want %+v", groups, want) + } + + const methodName = "ListConcurrencyGroups" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Actions.ListConcurrencyGroups(ctx, "\n", "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Actions.ListConcurrencyGroups(ctx, "o", "r", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestActionsService_GetConcurrencyGroup(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/actions/concurrency_groups/deploy-prod", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "ahead_of_job": "2", + }) + fmt.Fprint(w, `{ + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod", + "total_count": 2, + "group_members": [ + { + "run_id": 1, + "run_name": "Deploy", + "run_url": "https://api.github.com/repos/o/r/actions/runs/1", + "run_html_url": "https://github.com/o/r/actions/runs/1", + "status": "in_progress" + }, + { + "run_id": 3, + "run_name": "Deploy hotfix", + "run_url": "https://api.github.com/repos/o/r/actions/runs/3", + "run_html_url": "https://github.com/o/r/actions/runs/3", + "job_id": 2, + "job_name": "deploy", + "job_url": "https://api.github.com/repos/o/r/actions/jobs/2", + "job_html_url": "https://github.com/o/r/actions/runs/3/job/2", + "status": "pending" + } + ] + }`) + }) + + ctx := t.Context() + opts := &GetConcurrencyGroupOptions{AheadOfJob: 2} + group, _, err := client.Actions.GetConcurrencyGroup(ctx, "o", "r", "deploy-prod", opts) + if err != nil { + t.Errorf("Actions.GetConcurrencyGroup returned error: %v", err) + } + + want := &ConcurrencyGroup{ + GroupName: "deploy-prod", + GroupURL: "https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod", + TotalCount: new(2), + GroupMembers: []*ConcurrencyGroupMember{ + { + RunID: 1, + RunName: "Deploy", + RunURL: new("https://api.github.com/repos/o/r/actions/runs/1"), + RunHTMLURL: new("https://github.com/o/r/actions/runs/1"), + Status: "in_progress", + }, + { + RunID: 3, + RunName: "Deploy hotfix", + RunURL: new("https://api.github.com/repos/o/r/actions/runs/3"), + RunHTMLURL: new("https://github.com/o/r/actions/runs/3"), + JobID: new(int64(2)), + JobName: new("deploy"), + JobURL: new("https://api.github.com/repos/o/r/actions/jobs/2"), + JobHTMLURL: new("https://github.com/o/r/actions/runs/3/job/2"), + Status: "pending", + }, + }, + } + if !cmp.Equal(group, want) { + t.Errorf("Actions.GetConcurrencyGroup returned %+v, want %+v", group, want) + } + + const methodName = "GetConcurrencyGroup" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Actions.GetConcurrencyGroup(ctx, "\n", "\n", "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Actions.GetConcurrencyGroup(ctx, "o", "r", "deploy-prod", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestActionsService_GetConcurrencyGroup_EscapeGroupName(t *testing.T) { + t.Parallel() + for _, tt := range []struct { + groupName string + escapedGroupName string + }{ + {groupName: "deploy-prod", escapedGroupName: "deploy-prod"}, + {groupName: "CI-refs/heads/main", escapedGroupName: "CI-refs%2Fheads%2Fmain"}, + } { + t.Run(tt.groupName, func(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + if got, want := r.URL.EscapedPath(), "/repos/o/r/actions/concurrency_groups/"+tt.escapedGroupName; got != want { + t.Errorf("Request path = %q, want %q", got, want) + } + if got, want := r.URL.Path, "/repos/o/r/actions/concurrency_groups/"+tt.groupName; got != want { + t.Errorf("Decoded request path = %q, want %q", got, want) + } + fmt.Fprint(w, `{}`) + }) + + ctx := t.Context() + _, _, err := client.Actions.GetConcurrencyGroup(ctx, "o", "r", tt.groupName, nil) + if err != nil { + t.Fatalf("Actions.GetConcurrencyGroup returned error: %v", err) + } + }) + } +} + +func TestActionsService_ListWorkflowRunConcurrencyGroups(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/actions/runs/1/concurrency_groups", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "before": "xyz", + "per_page": "2", + }) + fmt.Fprint(w, `{ + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod", + "group_members": [ + { + "run_id": 1, + "run_name": "Deploy", + "run_url": "https://api.github.com/repos/o/r/actions/runs/1", + "run_html_url": "https://github.com/o/r/actions/runs/1", + "status": "in_progress", + "position": 0, + "position_url": "https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod?ahead_of_run=1" + } + ] + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/o/r/actions/concurrency_groups/ci-build", + "group_members": [] + } + ] + }`) + }) + + ctx := t.Context() + opts := &ListWorkflowRunConcurrencyGroupsOptions{Before: "xyz", PerPage: 2} + groups, _, err := client.Actions.ListWorkflowRunConcurrencyGroups(ctx, "o", "r", 1, opts) + if err != nil { + t.Errorf("Actions.ListWorkflowRunConcurrencyGroups returned error: %v", err) + } + + want := &ConcurrencyGroupList{ + TotalCount: 2, + ConcurrencyGroups: []*ConcurrencyGroup{ + { + GroupName: "deploy-prod", + GroupURL: "https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod", + GroupMembers: []*ConcurrencyGroupMember{ + { + RunID: 1, + RunName: "Deploy", + RunURL: new("https://api.github.com/repos/o/r/actions/runs/1"), + RunHTMLURL: new("https://github.com/o/r/actions/runs/1"), + Status: "in_progress", + Position: new(0), + PositionURL: new("https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod?ahead_of_run=1"), + }, + }, + }, + { + GroupName: "ci-build", + GroupURL: "https://api.github.com/repos/o/r/actions/concurrency_groups/ci-build", + GroupMembers: []*ConcurrencyGroupMember{}, + }, + }, + } + if !cmp.Equal(groups, want) { + t.Errorf("Actions.ListWorkflowRunConcurrencyGroups returned %+v, want %+v", groups, want) + } + + const methodName = "ListWorkflowRunConcurrencyGroups" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Actions.ListWorkflowRunConcurrencyGroups(ctx, "\n", "\n", -1, opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Actions.ListWorkflowRunConcurrencyGroups(ctx, "o", "r", 1, opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 952d3d8fea0..f24b09f17d0 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7814,6 +7814,150 @@ func (c *CommunityHealthMetrics) GetUpdatedAt() Timestamp { return *c.UpdatedAt } +// GetGroupMembers returns the GroupMembers slice if it's non-nil, nil otherwise. +func (c *ConcurrencyGroup) GetGroupMembers() []*ConcurrencyGroupMember { + if c == nil || c.GroupMembers == nil { + return nil + } + return c.GroupMembers +} + +// GetGroupName returns the GroupName field. +func (c *ConcurrencyGroup) GetGroupName() string { + if c == nil { + return "" + } + return c.GroupName +} + +// GetGroupURL returns the GroupURL field. +func (c *ConcurrencyGroup) GetGroupURL() string { + if c == nil { + return "" + } + return c.GroupURL +} + +// GetLastAcquiredAt returns the LastAcquiredAt field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroup) GetLastAcquiredAt() Timestamp { + if c == nil || c.LastAcquiredAt == nil { + return Timestamp{} + } + return *c.LastAcquiredAt +} + +// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroup) GetTotalCount() int { + if c == nil || c.TotalCount == nil { + return 0 + } + return *c.TotalCount +} + +// GetConcurrencyGroups returns the ConcurrencyGroups slice if it's non-nil, nil otherwise. +func (c *ConcurrencyGroupList) GetConcurrencyGroups() []*ConcurrencyGroup { + if c == nil || c.ConcurrencyGroups == nil { + return nil + } + return c.ConcurrencyGroups +} + +// GetTotalCount returns the TotalCount field. +func (c *ConcurrencyGroupList) GetTotalCount() int { + if c == nil { + return 0 + } + return c.TotalCount +} + +// GetJobHTMLURL returns the JobHTMLURL field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroupMember) GetJobHTMLURL() string { + if c == nil || c.JobHTMLURL == nil { + return "" + } + return *c.JobHTMLURL +} + +// GetJobID returns the JobID field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroupMember) GetJobID() int64 { + if c == nil || c.JobID == nil { + return 0 + } + return *c.JobID +} + +// GetJobName returns the JobName field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroupMember) GetJobName() string { + if c == nil || c.JobName == nil { + return "" + } + return *c.JobName +} + +// GetJobURL returns the JobURL field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroupMember) GetJobURL() string { + if c == nil || c.JobURL == nil { + return "" + } + return *c.JobURL +} + +// GetPosition returns the Position field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroupMember) GetPosition() int { + if c == nil || c.Position == nil { + return 0 + } + return *c.Position +} + +// GetPositionURL returns the PositionURL field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroupMember) GetPositionURL() string { + if c == nil || c.PositionURL == nil { + return "" + } + return *c.PositionURL +} + +// GetRunHTMLURL returns the RunHTMLURL field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroupMember) GetRunHTMLURL() string { + if c == nil || c.RunHTMLURL == nil { + return "" + } + return *c.RunHTMLURL +} + +// GetRunID returns the RunID field. +func (c *ConcurrencyGroupMember) GetRunID() int64 { + if c == nil { + return 0 + } + return c.RunID +} + +// GetRunName returns the RunName field. +func (c *ConcurrencyGroupMember) GetRunName() string { + if c == nil { + return "" + } + return c.RunName +} + +// GetRunURL returns the RunURL field if it's non-nil, zero value otherwise. +func (c *ConcurrencyGroupMember) GetRunURL() string { + if c == nil || c.RunURL == nil { + return "" + } + return *c.RunURL +} + +// GetStatus returns the Status field. +func (c *ConcurrencyGroupMember) GetStatus() string { + if c == nil { + return "" + } + return c.Status +} + // GetNodes returns the Nodes slice if it's non-nil, nil otherwise. func (c *ConfigApplyEvents) GetNodes() []*ConfigApplyEventsNode { if c == nil || c.Nodes == nil { @@ -19430,6 +19574,22 @@ func (g *GetCodeownersErrorsOptions) GetRef() string { return g.Ref } +// GetAheadOfJob returns the AheadOfJob field. +func (g *GetConcurrencyGroupOptions) GetAheadOfJob() int64 { + if g == nil { + return 0 + } + return g.AheadOfJob +} + +// GetAheadOfRun returns the AheadOfRun field. +func (g *GetConcurrencyGroupOptions) GetAheadOfRun() int64 { + if g == nil { + return 0 + } + return g.AheadOfRun +} + // GetFields returns the Fields slice if it's non-nil, nil otherwise. func (g *GetProjectItemOptions) GetFields() []int64 { if g == nil || g.Fields == nil { @@ -24998,6 +25158,22 @@ func (l *ListCollaboratorsOptions) GetPermission() string { return l.Permission } +// GetAfter returns the After field. +func (l *ListConcurrencyGroupsOptions) GetAfter() string { + if l == nil { + return "" + } + return l.After +} + +// GetPerPage returns the PerPage field. +func (l *ListConcurrencyGroupsOptions) GetPerPage() int { + if l == nil { + return 0 + } + return l.PerPage +} + // GetAnon returns the Anon field. func (l *ListContributorsOptions) GetAnon() string { if l == nil { @@ -25798,6 +25974,30 @@ func (l *ListWorkflowJobsOptions) GetFilter() string { return l.Filter } +// GetAfter returns the After field. +func (l *ListWorkflowRunConcurrencyGroupsOptions) GetAfter() string { + if l == nil { + return "" + } + return l.After +} + +// GetBefore returns the Before field. +func (l *ListWorkflowRunConcurrencyGroupsOptions) GetBefore() string { + if l == nil { + return "" + } + return l.Before +} + +// GetPerPage returns the PerPage field. +func (l *ListWorkflowRunConcurrencyGroupsOptions) GetPerPage() int { + if l == nil { + return 0 + } + return l.PerPage +} + // GetActor returns the Actor field. func (l *ListWorkflowRunsOptions) GetActor() string { if l == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 7e9ad6671c9..6f4f35381b9 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -9876,6 +9876,186 @@ func TestCommunityHealthMetrics_GetUpdatedAt(tt *testing.T) { c.GetUpdatedAt() } +func TestConcurrencyGroup_GetGroupMembers(tt *testing.T) { + tt.Parallel() + zeroValue := []*ConcurrencyGroupMember{} + c := &ConcurrencyGroup{GroupMembers: zeroValue} + c.GetGroupMembers() + c = &ConcurrencyGroup{} + c.GetGroupMembers() + c = nil + c.GetGroupMembers() +} + +func TestConcurrencyGroup_GetGroupName(tt *testing.T) { + tt.Parallel() + c := &ConcurrencyGroup{} + c.GetGroupName() + c = nil + c.GetGroupName() +} + +func TestConcurrencyGroup_GetGroupURL(tt *testing.T) { + tt.Parallel() + c := &ConcurrencyGroup{} + c.GetGroupURL() + c = nil + c.GetGroupURL() +} + +func TestConcurrencyGroup_GetLastAcquiredAt(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + c := &ConcurrencyGroup{LastAcquiredAt: &zeroValue} + c.GetLastAcquiredAt() + c = &ConcurrencyGroup{} + c.GetLastAcquiredAt() + c = nil + c.GetLastAcquiredAt() +} + +func TestConcurrencyGroup_GetTotalCount(tt *testing.T) { + tt.Parallel() + var zeroValue int + c := &ConcurrencyGroup{TotalCount: &zeroValue} + c.GetTotalCount() + c = &ConcurrencyGroup{} + c.GetTotalCount() + c = nil + c.GetTotalCount() +} + +func TestConcurrencyGroupList_GetConcurrencyGroups(tt *testing.T) { + tt.Parallel() + zeroValue := []*ConcurrencyGroup{} + c := &ConcurrencyGroupList{ConcurrencyGroups: zeroValue} + c.GetConcurrencyGroups() + c = &ConcurrencyGroupList{} + c.GetConcurrencyGroups() + c = nil + c.GetConcurrencyGroups() +} + +func TestConcurrencyGroupList_GetTotalCount(tt *testing.T) { + tt.Parallel() + c := &ConcurrencyGroupList{} + c.GetTotalCount() + c = nil + c.GetTotalCount() +} + +func TestConcurrencyGroupMember_GetJobHTMLURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &ConcurrencyGroupMember{JobHTMLURL: &zeroValue} + c.GetJobHTMLURL() + c = &ConcurrencyGroupMember{} + c.GetJobHTMLURL() + c = nil + c.GetJobHTMLURL() +} + +func TestConcurrencyGroupMember_GetJobID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + c := &ConcurrencyGroupMember{JobID: &zeroValue} + c.GetJobID() + c = &ConcurrencyGroupMember{} + c.GetJobID() + c = nil + c.GetJobID() +} + +func TestConcurrencyGroupMember_GetJobName(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &ConcurrencyGroupMember{JobName: &zeroValue} + c.GetJobName() + c = &ConcurrencyGroupMember{} + c.GetJobName() + c = nil + c.GetJobName() +} + +func TestConcurrencyGroupMember_GetJobURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &ConcurrencyGroupMember{JobURL: &zeroValue} + c.GetJobURL() + c = &ConcurrencyGroupMember{} + c.GetJobURL() + c = nil + c.GetJobURL() +} + +func TestConcurrencyGroupMember_GetPosition(tt *testing.T) { + tt.Parallel() + var zeroValue int + c := &ConcurrencyGroupMember{Position: &zeroValue} + c.GetPosition() + c = &ConcurrencyGroupMember{} + c.GetPosition() + c = nil + c.GetPosition() +} + +func TestConcurrencyGroupMember_GetPositionURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &ConcurrencyGroupMember{PositionURL: &zeroValue} + c.GetPositionURL() + c = &ConcurrencyGroupMember{} + c.GetPositionURL() + c = nil + c.GetPositionURL() +} + +func TestConcurrencyGroupMember_GetRunHTMLURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &ConcurrencyGroupMember{RunHTMLURL: &zeroValue} + c.GetRunHTMLURL() + c = &ConcurrencyGroupMember{} + c.GetRunHTMLURL() + c = nil + c.GetRunHTMLURL() +} + +func TestConcurrencyGroupMember_GetRunID(tt *testing.T) { + tt.Parallel() + c := &ConcurrencyGroupMember{} + c.GetRunID() + c = nil + c.GetRunID() +} + +func TestConcurrencyGroupMember_GetRunName(tt *testing.T) { + tt.Parallel() + c := &ConcurrencyGroupMember{} + c.GetRunName() + c = nil + c.GetRunName() +} + +func TestConcurrencyGroupMember_GetRunURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &ConcurrencyGroupMember{RunURL: &zeroValue} + c.GetRunURL() + c = &ConcurrencyGroupMember{} + c.GetRunURL() + c = nil + c.GetRunURL() +} + +func TestConcurrencyGroupMember_GetStatus(tt *testing.T) { + tt.Parallel() + c := &ConcurrencyGroupMember{} + c.GetStatus() + c = nil + c.GetStatus() +} + func TestConfigApplyEvents_GetNodes(tt *testing.T) { tt.Parallel() zeroValue := []*ConfigApplyEventsNode{} @@ -24288,6 +24468,22 @@ func TestGetCodeownersErrorsOptions_GetRef(tt *testing.T) { g.GetRef() } +func TestGetConcurrencyGroupOptions_GetAheadOfJob(tt *testing.T) { + tt.Parallel() + g := &GetConcurrencyGroupOptions{} + g.GetAheadOfJob() + g = nil + g.GetAheadOfJob() +} + +func TestGetConcurrencyGroupOptions_GetAheadOfRun(tt *testing.T) { + tt.Parallel() + g := &GetConcurrencyGroupOptions{} + g.GetAheadOfRun() + g = nil + g.GetAheadOfRun() +} + func TestGetProjectItemOptions_GetFields(tt *testing.T) { tt.Parallel() zeroValue := []int64{} @@ -31314,6 +31510,22 @@ func TestListCollaboratorsOptions_GetPermission(tt *testing.T) { l.GetPermission() } +func TestListConcurrencyGroupsOptions_GetAfter(tt *testing.T) { + tt.Parallel() + l := &ListConcurrencyGroupsOptions{} + l.GetAfter() + l = nil + l.GetAfter() +} + +func TestListConcurrencyGroupsOptions_GetPerPage(tt *testing.T) { + tt.Parallel() + l := &ListConcurrencyGroupsOptions{} + l.GetPerPage() + l = nil + l.GetPerPage() +} + func TestListContributorsOptions_GetAnon(tt *testing.T) { tt.Parallel() l := &ListContributorsOptions{} @@ -32240,6 +32452,30 @@ func TestListWorkflowJobsOptions_GetFilter(tt *testing.T) { l.GetFilter() } +func TestListWorkflowRunConcurrencyGroupsOptions_GetAfter(tt *testing.T) { + tt.Parallel() + l := &ListWorkflowRunConcurrencyGroupsOptions{} + l.GetAfter() + l = nil + l.GetAfter() +} + +func TestListWorkflowRunConcurrencyGroupsOptions_GetBefore(tt *testing.T) { + tt.Parallel() + l := &ListWorkflowRunConcurrencyGroupsOptions{} + l.GetBefore() + l = nil + l.GetBefore() +} + +func TestListWorkflowRunConcurrencyGroupsOptions_GetPerPage(tt *testing.T) { + tt.Parallel() + l := &ListWorkflowRunConcurrencyGroupsOptions{} + l.GetPerPage() + l = nil + l.GetPerPage() +} + func TestListWorkflowRunsOptions_GetActor(tt *testing.T) { tt.Parallel() l := &ListWorkflowRunsOptions{} diff --git a/github/github-iterators.go b/github/github-iterators.go index 3413ef22f63..c98b886614c 100644 --- a/github/github-iterators.go +++ b/github/github-iterators.go @@ -119,6 +119,41 @@ func (s *ActionsService) ListCachesIter(ctx context.Context, owner string, repo } } +// ListConcurrencyGroupsIter returns an iterator that paginates through all results of ListConcurrencyGroups. +func (s *ActionsService) ListConcurrencyGroupsIter(ctx context.Context, owner string, repo string, opts *ListConcurrencyGroupsOptions) iter.Seq2[*ConcurrencyGroup, error] { + return func(yield func(*ConcurrencyGroup, error) bool) { + // Create a copy of opts to avoid mutating the caller's struct + if opts == nil { + opts = &ListConcurrencyGroupsOptions{} + } else { + opts = new(*opts) + } + + for { + results, resp, err := s.ListConcurrencyGroups(ctx, owner, repo, opts) + if err != nil { + yield(nil, err) + return + } + + var iterItems []*ConcurrencyGroup + if results != nil { + iterItems = results.ConcurrencyGroups + } + for _, item := range iterItems { + if !yield(item, nil) { + return + } + } + + if resp.After == "" { + break + } + opts.After = resp.After + } + } +} + // ListEnabledOrgsInEnterpriseIter returns an iterator that paginates through all results of ListEnabledOrgsInEnterprise. func (s *ActionsService) ListEnabledOrgsInEnterpriseIter(ctx context.Context, owner string, opts *ListOptions) iter.Seq2[*Organization, error] { return func(yield func(*Organization, error) bool) { @@ -1029,6 +1064,41 @@ func (s *ActionsService) ListWorkflowRunArtifactsIter(ctx context.Context, owner } } +// ListWorkflowRunConcurrencyGroupsIter returns an iterator that paginates through all results of ListWorkflowRunConcurrencyGroups. +func (s *ActionsService) ListWorkflowRunConcurrencyGroupsIter(ctx context.Context, owner string, repo string, runID int64, opts *ListWorkflowRunConcurrencyGroupsOptions) iter.Seq2[*ConcurrencyGroup, error] { + return func(yield func(*ConcurrencyGroup, error) bool) { + // Create a copy of opts to avoid mutating the caller's struct + if opts == nil { + opts = &ListWorkflowRunConcurrencyGroupsOptions{} + } else { + opts = new(*opts) + } + + for { + results, resp, err := s.ListWorkflowRunConcurrencyGroups(ctx, owner, repo, runID, opts) + if err != nil { + yield(nil, err) + return + } + + var iterItems []*ConcurrencyGroup + if results != nil { + iterItems = results.ConcurrencyGroups + } + for _, item := range iterItems { + if !yield(item, nil) { + return + } + } + + if resp.After == "" { + break + } + opts.After = resp.After + } + } +} + // ListWorkflowRunsByFileNameIter returns an iterator that paginates through all results of ListWorkflowRunsByFileName. func (s *ActionsService) ListWorkflowRunsByFileNameIter(ctx context.Context, owner string, repo string, workflowFileName string, opts *ListWorkflowRunsOptions) iter.Seq2[*WorkflowRun, error] { return func(yield func(*WorkflowRun, error) bool) { diff --git a/github/github-iterators_test.go b/github/github-iterators_test.go index ebbf921315d..044b5ad4ce7 100644 --- a/github/github-iterators_test.go +++ b/github/github-iterators_test.go @@ -231,6 +231,78 @@ func TestActionsService_ListCachesIter(t *testing.T) { } } +func TestActionsService_ListConcurrencyGroupsIter(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + var callNum int + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + callNum++ + switch callNum { + case 1: + w.Header().Set("Link", `; rel="next"`) + fmt.Fprint(w, `{"concurrency_groups": [{},{},{}]}`) + case 2: + fmt.Fprint(w, `{"concurrency_groups": [{},{},{},{}]}`) + case 3: + fmt.Fprint(w, `{"concurrency_groups": [{},{}]}`) + case 4: + w.WriteHeader(http.StatusNotFound) + case 5: + fmt.Fprint(w, `{"concurrency_groups": [{},{}]}`) + } + }) + + iter := client.Actions.ListConcurrencyGroupsIter(t.Context(), "", "", nil) + var gotItems int + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 7; gotItems != want { + t.Errorf("client.Actions.ListConcurrencyGroupsIter call 1 got %v items; want %v", gotItems, want) + } + + opts := &ListConcurrencyGroupsOptions{} + iter = client.Actions.ListConcurrencyGroupsIter(t.Context(), "", "", opts) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 2; gotItems != want { + t.Errorf("client.Actions.ListConcurrencyGroupsIter call 2 got %v items; want %v", gotItems, want) + } + + iter = client.Actions.ListConcurrencyGroupsIter(t.Context(), "", "", nil) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err == nil { + t.Error("expected error; got nil") + } + } + if gotItems != 1 { + t.Errorf("client.Actions.ListConcurrencyGroupsIter call 3 got %v items; want 1 (an error)", gotItems) + } + + iter = client.Actions.ListConcurrencyGroupsIter(t.Context(), "", "", nil) + gotItems = 0 + iter(func(item *ConcurrencyGroup, err error) bool { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + return false + }) + if gotItems != 1 { + t.Errorf("client.Actions.ListConcurrencyGroupsIter call 4 got %v items; want 1 (an error)", gotItems) + } +} + func TestActionsService_ListEnabledOrgsInEnterpriseIter(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -2103,6 +2175,78 @@ func TestActionsService_ListWorkflowRunArtifactsIter(t *testing.T) { } } +func TestActionsService_ListWorkflowRunConcurrencyGroupsIter(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + var callNum int + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + callNum++ + switch callNum { + case 1: + w.Header().Set("Link", `; rel="next"`) + fmt.Fprint(w, `{"concurrency_groups": [{},{},{}]}`) + case 2: + fmt.Fprint(w, `{"concurrency_groups": [{},{},{},{}]}`) + case 3: + fmt.Fprint(w, `{"concurrency_groups": [{},{}]}`) + case 4: + w.WriteHeader(http.StatusNotFound) + case 5: + fmt.Fprint(w, `{"concurrency_groups": [{},{}]}`) + } + }) + + iter := client.Actions.ListWorkflowRunConcurrencyGroupsIter(t.Context(), "", "", 0, nil) + var gotItems int + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 7; gotItems != want { + t.Errorf("client.Actions.ListWorkflowRunConcurrencyGroupsIter call 1 got %v items; want %v", gotItems, want) + } + + opts := &ListWorkflowRunConcurrencyGroupsOptions{} + iter = client.Actions.ListWorkflowRunConcurrencyGroupsIter(t.Context(), "", "", 0, opts) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 2; gotItems != want { + t.Errorf("client.Actions.ListWorkflowRunConcurrencyGroupsIter call 2 got %v items; want %v", gotItems, want) + } + + iter = client.Actions.ListWorkflowRunConcurrencyGroupsIter(t.Context(), "", "", 0, nil) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err == nil { + t.Error("expected error; got nil") + } + } + if gotItems != 1 { + t.Errorf("client.Actions.ListWorkflowRunConcurrencyGroupsIter call 3 got %v items; want 1 (an error)", gotItems) + } + + iter = client.Actions.ListWorkflowRunConcurrencyGroupsIter(t.Context(), "", "", 0, nil) + gotItems = 0 + iter(func(item *ConcurrencyGroup, err error) bool { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + return false + }) + if gotItems != 1 { + t.Errorf("client.Actions.ListWorkflowRunConcurrencyGroupsIter call 4 got %v items; want 1 (an error)", gotItems) + } +} + func TestActionsService_ListWorkflowRunsByFileNameIter(t *testing.T) { t.Parallel() client, mux, _ := setup(t) From 51ee94831f4575665dee4ff34b9b87259eea236a Mon Sep 17 00:00:00 2001 From: Ninad Sutrave Date: Sun, 18 Oct 2026 21:01:35 +0530 Subject: [PATCH 2/2] Use ListCursorOptions and make run URLs required --- github/actions_concurrency_groups.go | 31 ++------------ github/actions_concurrency_groups_test.go | 16 +++---- github/github-accessors.go | 52 +++-------------------- github/github-accessors_test.go | 50 +--------------------- github/github-iterators.go | 8 ++-- github/github-iterators_test.go | 4 +- 6 files changed, 26 insertions(+), 135 deletions(-) diff --git a/github/actions_concurrency_groups.go b/github/actions_concurrency_groups.go index 2a7de1f6bde..42a8e7b7ba2 100644 --- a/github/actions_concurrency_groups.go +++ b/github/actions_concurrency_groups.go @@ -24,8 +24,8 @@ type ConcurrencyGroup struct { type ConcurrencyGroupMember struct { RunID int64 `json:"run_id"` RunName string `json:"run_name"` - RunURL *string `json:"run_url,omitempty"` - RunHTMLURL *string `json:"run_html_url,omitempty"` + RunURL string `json:"run_url"` + RunHTMLURL string `json:"run_html_url"` JobID *int64 `json:"job_id,omitempty"` JobName *string `json:"job_name,omitempty"` JobURL *string `json:"job_url,omitempty"` @@ -41,16 +41,6 @@ type ConcurrencyGroupList struct { ConcurrencyGroups []*ConcurrencyGroup `json:"concurrency_groups"` } -// ListConcurrencyGroupsOptions specifies the optional parameters to the -// ActionsService.ListConcurrencyGroups method. -type ListConcurrencyGroupsOptions struct { - // A cursor, as given in the Link header. If specified, the query only searches for concurrency groups after this cursor. - After string `url:"after,omitempty"` - - // For paginated result sets, the number of results to include per page. - PerPage int `url:"per_page,omitempty"` -} - // GetConcurrencyGroupOptions specifies the optional parameters to the // ActionsService.GetConcurrencyGroup method. type GetConcurrencyGroupOptions struct { @@ -61,25 +51,12 @@ type GetConcurrencyGroupOptions struct { AheadOfJob int64 `url:"ahead_of_job,omitempty"` } -// ListWorkflowRunConcurrencyGroupsOptions specifies the optional parameters to the -// ActionsService.ListWorkflowRunConcurrencyGroups method. -type ListWorkflowRunConcurrencyGroupsOptions struct { - // A cursor, as given in the Link header. If specified, the query only searches for concurrency groups before this cursor. - Before string `url:"before,omitempty"` - - // A cursor, as given in the Link header. If specified, the query only searches for concurrency groups after this cursor. - After string `url:"after,omitempty"` - - // For paginated result sets, the number of results to include per page. - PerPage int `url:"per_page,omitempty"` -} - // ListConcurrencyGroups lists the active concurrency groups for a repository. // // GitHub API docs: https://docs.github.com/rest/actions/concurrency-groups?apiVersion=2022-11-28#list-concurrency-groups-for-a-repository // //meta:operation GET /repos/{owner}/{repo}/actions/concurrency_groups -func (s *ActionsService) ListConcurrencyGroups(ctx context.Context, owner, repo string, opts *ListConcurrencyGroupsOptions) (*ConcurrencyGroupList, *Response, error) { +func (s *ActionsService) ListConcurrencyGroups(ctx context.Context, owner, repo string, opts *ListCursorOptions) (*ConcurrencyGroupList, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/concurrency_groups", owner, repo) u, err := addOptions(u, opts) if err != nil { @@ -133,7 +110,7 @@ func (s *ActionsService) GetConcurrencyGroup(ctx context.Context, owner, repo, g // GitHub API docs: https://docs.github.com/rest/actions/concurrency-groups?apiVersion=2022-11-28#list-concurrency-groups-for-a-workflow-run // //meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups -func (s *ActionsService) ListWorkflowRunConcurrencyGroups(ctx context.Context, owner, repo string, runID int64, opts *ListWorkflowRunConcurrencyGroupsOptions) (*ConcurrencyGroupList, *Response, error) { +func (s *ActionsService) ListWorkflowRunConcurrencyGroups(ctx context.Context, owner, repo string, runID int64, opts *ListCursorOptions) (*ConcurrencyGroupList, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/concurrency_groups", owner, repo, runID) u, err := addOptions(u, opts) if err != nil { diff --git a/github/actions_concurrency_groups_test.go b/github/actions_concurrency_groups_test.go index 8998facae4c..6589c9ef722 100644 --- a/github/actions_concurrency_groups_test.go +++ b/github/actions_concurrency_groups_test.go @@ -41,7 +41,7 @@ func TestActionsService_ListConcurrencyGroups(t *testing.T) { }) ctx := t.Context() - opts := &ListConcurrencyGroupsOptions{After: "abc", PerPage: 2} + opts := &ListCursorOptions{After: "abc", PerPage: 2} groups, _, err := client.Actions.ListConcurrencyGroups(ctx, "o", "r", opts) if err != nil { t.Errorf("Actions.ListConcurrencyGroups returned error: %v", err) @@ -131,15 +131,15 @@ func TestActionsService_GetConcurrencyGroup(t *testing.T) { { RunID: 1, RunName: "Deploy", - RunURL: new("https://api.github.com/repos/o/r/actions/runs/1"), - RunHTMLURL: new("https://github.com/o/r/actions/runs/1"), + RunURL: "https://api.github.com/repos/o/r/actions/runs/1", + RunHTMLURL: "https://github.com/o/r/actions/runs/1", Status: "in_progress", }, { RunID: 3, RunName: "Deploy hotfix", - RunURL: new("https://api.github.com/repos/o/r/actions/runs/3"), - RunHTMLURL: new("https://github.com/o/r/actions/runs/3"), + RunURL: "https://api.github.com/repos/o/r/actions/runs/3", + RunHTMLURL: "https://github.com/o/r/actions/runs/3", JobID: new(int64(2)), JobName: new("deploy"), JobURL: new("https://api.github.com/repos/o/r/actions/jobs/2"), @@ -238,7 +238,7 @@ func TestActionsService_ListWorkflowRunConcurrencyGroups(t *testing.T) { }) ctx := t.Context() - opts := &ListWorkflowRunConcurrencyGroupsOptions{Before: "xyz", PerPage: 2} + opts := &ListCursorOptions{Before: "xyz", PerPage: 2} groups, _, err := client.Actions.ListWorkflowRunConcurrencyGroups(ctx, "o", "r", 1, opts) if err != nil { t.Errorf("Actions.ListWorkflowRunConcurrencyGroups returned error: %v", err) @@ -254,8 +254,8 @@ func TestActionsService_ListWorkflowRunConcurrencyGroups(t *testing.T) { { RunID: 1, RunName: "Deploy", - RunURL: new("https://api.github.com/repos/o/r/actions/runs/1"), - RunHTMLURL: new("https://github.com/o/r/actions/runs/1"), + RunURL: "https://api.github.com/repos/o/r/actions/runs/1", + RunHTMLURL: "https://github.com/o/r/actions/runs/1", Status: "in_progress", Position: new(0), PositionURL: new("https://api.github.com/repos/o/r/actions/concurrency_groups/deploy-prod?ahead_of_run=1"), diff --git a/github/github-accessors.go b/github/github-accessors.go index f24b09f17d0..7a55b999a8c 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7918,12 +7918,12 @@ func (c *ConcurrencyGroupMember) GetPositionURL() string { return *c.PositionURL } -// GetRunHTMLURL returns the RunHTMLURL field if it's non-nil, zero value otherwise. +// GetRunHTMLURL returns the RunHTMLURL field. func (c *ConcurrencyGroupMember) GetRunHTMLURL() string { - if c == nil || c.RunHTMLURL == nil { + if c == nil { return "" } - return *c.RunHTMLURL + return c.RunHTMLURL } // GetRunID returns the RunID field. @@ -7942,12 +7942,12 @@ func (c *ConcurrencyGroupMember) GetRunName() string { return c.RunName } -// GetRunURL returns the RunURL field if it's non-nil, zero value otherwise. +// GetRunURL returns the RunURL field. func (c *ConcurrencyGroupMember) GetRunURL() string { - if c == nil || c.RunURL == nil { + if c == nil { return "" } - return *c.RunURL + return c.RunURL } // GetStatus returns the Status field. @@ -25158,22 +25158,6 @@ func (l *ListCollaboratorsOptions) GetPermission() string { return l.Permission } -// GetAfter returns the After field. -func (l *ListConcurrencyGroupsOptions) GetAfter() string { - if l == nil { - return "" - } - return l.After -} - -// GetPerPage returns the PerPage field. -func (l *ListConcurrencyGroupsOptions) GetPerPage() int { - if l == nil { - return 0 - } - return l.PerPage -} - // GetAnon returns the Anon field. func (l *ListContributorsOptions) GetAnon() string { if l == nil { @@ -25974,30 +25958,6 @@ func (l *ListWorkflowJobsOptions) GetFilter() string { return l.Filter } -// GetAfter returns the After field. -func (l *ListWorkflowRunConcurrencyGroupsOptions) GetAfter() string { - if l == nil { - return "" - } - return l.After -} - -// GetBefore returns the Before field. -func (l *ListWorkflowRunConcurrencyGroupsOptions) GetBefore() string { - if l == nil { - return "" - } - return l.Before -} - -// GetPerPage returns the PerPage field. -func (l *ListWorkflowRunConcurrencyGroupsOptions) GetPerPage() int { - if l == nil { - return 0 - } - return l.PerPage -} - // GetActor returns the Actor field. func (l *ListWorkflowRunsOptions) GetActor() string { if l == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 6f4f35381b9..b509778d1ca 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -10012,10 +10012,7 @@ func TestConcurrencyGroupMember_GetPositionURL(tt *testing.T) { func TestConcurrencyGroupMember_GetRunHTMLURL(tt *testing.T) { tt.Parallel() - var zeroValue string - c := &ConcurrencyGroupMember{RunHTMLURL: &zeroValue} - c.GetRunHTMLURL() - c = &ConcurrencyGroupMember{} + c := &ConcurrencyGroupMember{} c.GetRunHTMLURL() c = nil c.GetRunHTMLURL() @@ -10039,10 +10036,7 @@ func TestConcurrencyGroupMember_GetRunName(tt *testing.T) { func TestConcurrencyGroupMember_GetRunURL(tt *testing.T) { tt.Parallel() - var zeroValue string - c := &ConcurrencyGroupMember{RunURL: &zeroValue} - c.GetRunURL() - c = &ConcurrencyGroupMember{} + c := &ConcurrencyGroupMember{} c.GetRunURL() c = nil c.GetRunURL() @@ -31510,22 +31504,6 @@ func TestListCollaboratorsOptions_GetPermission(tt *testing.T) { l.GetPermission() } -func TestListConcurrencyGroupsOptions_GetAfter(tt *testing.T) { - tt.Parallel() - l := &ListConcurrencyGroupsOptions{} - l.GetAfter() - l = nil - l.GetAfter() -} - -func TestListConcurrencyGroupsOptions_GetPerPage(tt *testing.T) { - tt.Parallel() - l := &ListConcurrencyGroupsOptions{} - l.GetPerPage() - l = nil - l.GetPerPage() -} - func TestListContributorsOptions_GetAnon(tt *testing.T) { tt.Parallel() l := &ListContributorsOptions{} @@ -32452,30 +32430,6 @@ func TestListWorkflowJobsOptions_GetFilter(tt *testing.T) { l.GetFilter() } -func TestListWorkflowRunConcurrencyGroupsOptions_GetAfter(tt *testing.T) { - tt.Parallel() - l := &ListWorkflowRunConcurrencyGroupsOptions{} - l.GetAfter() - l = nil - l.GetAfter() -} - -func TestListWorkflowRunConcurrencyGroupsOptions_GetBefore(tt *testing.T) { - tt.Parallel() - l := &ListWorkflowRunConcurrencyGroupsOptions{} - l.GetBefore() - l = nil - l.GetBefore() -} - -func TestListWorkflowRunConcurrencyGroupsOptions_GetPerPage(tt *testing.T) { - tt.Parallel() - l := &ListWorkflowRunConcurrencyGroupsOptions{} - l.GetPerPage() - l = nil - l.GetPerPage() -} - func TestListWorkflowRunsOptions_GetActor(tt *testing.T) { tt.Parallel() l := &ListWorkflowRunsOptions{} diff --git a/github/github-iterators.go b/github/github-iterators.go index c98b886614c..957e6b18178 100644 --- a/github/github-iterators.go +++ b/github/github-iterators.go @@ -120,11 +120,11 @@ func (s *ActionsService) ListCachesIter(ctx context.Context, owner string, repo } // ListConcurrencyGroupsIter returns an iterator that paginates through all results of ListConcurrencyGroups. -func (s *ActionsService) ListConcurrencyGroupsIter(ctx context.Context, owner string, repo string, opts *ListConcurrencyGroupsOptions) iter.Seq2[*ConcurrencyGroup, error] { +func (s *ActionsService) ListConcurrencyGroupsIter(ctx context.Context, owner string, repo string, opts *ListCursorOptions) iter.Seq2[*ConcurrencyGroup, error] { return func(yield func(*ConcurrencyGroup, error) bool) { // Create a copy of opts to avoid mutating the caller's struct if opts == nil { - opts = &ListConcurrencyGroupsOptions{} + opts = &ListCursorOptions{} } else { opts = new(*opts) } @@ -1065,11 +1065,11 @@ func (s *ActionsService) ListWorkflowRunArtifactsIter(ctx context.Context, owner } // ListWorkflowRunConcurrencyGroupsIter returns an iterator that paginates through all results of ListWorkflowRunConcurrencyGroups. -func (s *ActionsService) ListWorkflowRunConcurrencyGroupsIter(ctx context.Context, owner string, repo string, runID int64, opts *ListWorkflowRunConcurrencyGroupsOptions) iter.Seq2[*ConcurrencyGroup, error] { +func (s *ActionsService) ListWorkflowRunConcurrencyGroupsIter(ctx context.Context, owner string, repo string, runID int64, opts *ListCursorOptions) iter.Seq2[*ConcurrencyGroup, error] { return func(yield func(*ConcurrencyGroup, error) bool) { // Create a copy of opts to avoid mutating the caller's struct if opts == nil { - opts = &ListWorkflowRunConcurrencyGroupsOptions{} + opts = &ListCursorOptions{} } else { opts = new(*opts) } diff --git a/github/github-iterators_test.go b/github/github-iterators_test.go index 044b5ad4ce7..ef1b2edc538 100644 --- a/github/github-iterators_test.go +++ b/github/github-iterators_test.go @@ -264,7 +264,7 @@ func TestActionsService_ListConcurrencyGroupsIter(t *testing.T) { t.Errorf("client.Actions.ListConcurrencyGroupsIter call 1 got %v items; want %v", gotItems, want) } - opts := &ListConcurrencyGroupsOptions{} + opts := &ListCursorOptions{} iter = client.Actions.ListConcurrencyGroupsIter(t.Context(), "", "", opts) gotItems = 0 for _, err := range iter { @@ -2208,7 +2208,7 @@ func TestActionsService_ListWorkflowRunConcurrencyGroupsIter(t *testing.T) { t.Errorf("client.Actions.ListWorkflowRunConcurrencyGroupsIter call 1 got %v items; want %v", gotItems, want) } - opts := &ListWorkflowRunConcurrencyGroupsOptions{} + opts := &ListCursorOptions{} iter = client.Actions.ListWorkflowRunConcurrencyGroupsIter(t.Context(), "", "", 0, opts) gotItems = 0 for _, err := range iter {