diff --git a/client.go b/client.go index 7775443..91429de 100644 --- a/client.go +++ b/client.go @@ -314,6 +314,35 @@ func (c *Client) GetRunnerScaleSet(ctx context.Context, runnerGroupID int, runne } } +// ListRunnerScaleSets returns every runner scale set in the given runner group. +func (c *Client) ListRunnerScaleSets(ctx context.Context, runnerGroupID int) ([]RunnerScaleSet, error) { + c.mu.Lock() + defer c.mu.Unlock() + + path := fmt.Sprintf("/%s?runnerGroupId=%d", scaleSetEndpoint, runnerGroupID) + req, err := c.newActionsServiceRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, fmt.Errorf("failed to create new actions service request: %w", err) + } + + resp, err := c.do(req) + if err != nil { + return nil, fmt.Errorf("failed to issue the request: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, newRequestResponseError(req, resp, fmt.Errorf("unexpected status code: %d", resp.StatusCode)) + } + + var list runnerScaleSetsResponse + if err := json.NewDecoder(resp.Body).Decode(&list); err != nil { + return nil, newRequestResponseError(req, resp, fmt.Errorf("failed to decode runner scale set list: %w", err)) + } + + return list.RunnerScaleSets, nil +} + // GetRunnerScaleSetByID fetches a runner scale set by its ID. func (c *Client) GetRunnerScaleSetByID(ctx context.Context, runnerScaleSetID int) (*RunnerScaleSet, error) { c.mu.Lock() diff --git a/client_test.go b/client_test.go index 69f24b0..747741b 100644 --- a/client_test.go +++ b/client_test.go @@ -1362,3 +1362,39 @@ kBxfaf3g7iFnl3u8+7Z/7Cb4ZqFcw0bRJseKuR9mFvBhcZxSErbMDEYrevefU9aM APeCxEyw6hJXgbWKoG7Fw2g2HP3ytCJ4YzH0zNitHjk/1h4BG7z8cEQILCSv5mN2 etFcaQuTHEZyRhhJ4BU= -----END PRIVATE KEY-----` + +func TestListRunnerScaleSets(t *testing.T) { + ctx := context.Background() + auth := actionsAuth{token: "token"} + + expected := runnerScaleSetsResponse{ + Count: 2, + RunnerScaleSets: []RunnerScaleSet{ + {ID: 1, Name: "alpha", RunnerGroupID: 1}, + {ID: 2, Name: "beta", RunnerGroupID: 1}, + }, + } + + server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/tenant/123/_apis/runtime/runnerscalesets" { + t.Errorf("path = %q", r.URL.Path) + } + if r.URL.Query().Get("runnerGroupId") != "1" { + t.Errorf("runnerGroupId = %q", r.URL.Query().Get("runnerGroupId")) + } + if r.URL.Query().Get("name") != "" { + t.Errorf("expected no name filter, got %q", r.URL.Query().Get("name")) + } + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(expected) + })) + + client, err := newClient(testSystemInfo, server.configURLForOrg("my-org"), auth) + require.NoError(t, err) + + got, err := client.ListRunnerScaleSets(ctx, 1) + require.NoError(t, err) + require.Len(t, got, 2) + assert.Equal(t, "alpha", got[0].Name) + assert.Equal(t, "beta", got[1].Name) +}