From e314fb5c6bf66b78444b0132525c223f7ea6b87d Mon Sep 17 00:00:00 2001 From: Yusuke Kuoka Date: Sun, 7 Feb 2021 17:56:12 +0900 Subject: [PATCH] fix: Paginate ListRepositoryWorkflowRuns When we used `QueuedAndInProgressWorkflowRuns`-based autoscaling, it only fetched and considered only the first 30 workflow runs at the reconcilation time. This may have resulted in unreliable scaling behaviour, like scale-in/out not happening when it was expected. --- controllers/autoscaling.go | 4 ++-- github/github.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/controllers/autoscaling.go b/controllers/autoscaling.go index 526ada57e8..f87d692381 100644 --- a/controllers/autoscaling.go +++ b/controllers/autoscaling.go @@ -138,12 +138,12 @@ func (r *HorizontalRunnerAutoscalerReconciler) calculateReplicasByQueuedAndInPro for _, repo := range repos { user, repoName := repo[0], repo[1] - list, _, err := r.GitHubClient.Actions.ListRepositoryWorkflowRuns(context.TODO(), user, repoName, nil) + workflowRuns, err := r.GitHubClient.ListRepositoryWorkflowRuns(context.TODO(), user, repoName) if err != nil { return nil, err } - for _, run := range list.WorkflowRuns { + for _, run := range workflowRuns { total++ // In May 2020, there are only 3 statuses. diff --git a/github/github.go b/github/github.go index 327c2efc9a..9bd4b73a60 100644 --- a/github/github.go +++ b/github/github.go @@ -207,6 +207,34 @@ func (c *Client) listRunners(ctx context.Context, enterprise, org, repo string, return c.Client.Enterprise.ListRunners(ctx, enterprise, opts) } +func (c *Client) ListRepositoryWorkflowRuns(ctx context.Context, user string, repoName string) ([]*github.WorkflowRun, error) { + c.Client.Actions.ListRepositoryWorkflowRuns(ctx, user, repoName, nil) + + var workflowRuns []*github.WorkflowRun + + opts := github.ListWorkflowRunsOptions{ + ListOptions: github.ListOptions{ + PerPage: 100, + }, + } + + for { + list, res, err := c.Client.Actions.ListRepositoryWorkflowRuns(ctx, user, repoName, &opts) + + if err != nil { + return workflowRuns, fmt.Errorf("failed to list workflow runs: %v", err) + } + + workflowRuns = append(workflowRuns, list.WorkflowRuns...) + if res.NextPage == 0 { + break + } + opts.Page = res.NextPage + } + + return workflowRuns, nil +} + // Validates enterprise, organisation and repo arguments. Both are optional, but at least one should be specified func getEnterpriseOrganisationAndRepo(enterprise, org, repo string) (string, string, string, error) { if len(repo) > 0 {