From 7008b0c2576ec3bab426cdf4e2adf4363a9e7b7f Mon Sep 17 00:00:00 2001 From: Tarasovych <24782123+Tarasovych@users.noreply.github.com> Date: Tue, 31 Aug 2021 03:46:36 +0300 Subject: [PATCH] feat: Organization RunnerDeployment with webhook-based autoscaling only for certain repositories (#766) Resolves #765 Co-authored-by: Yusuke Kuoka --- README.md | 24 +++++++++++++++++++ .../horizontalrunnerautoscaler_types.go | 4 ++++ api/v1alpha1/zz_generated.deepcopy.go | 5 ++++ charts/actions-runner-controller/Chart.yaml | 2 +- ...rwind.dev_horizontalrunnerautoscalers.yaml | 7 ++++++ ...rwind.dev_horizontalrunnerautoscalers.yaml | 7 ++++++ config/manager/kustomization.yaml | 2 +- ..._runner_autoscaler_webhook_on_check_run.go | 10 ++++++++ controllers/integration_test.go | 22 +++++++++++++---- 9 files changed, 76 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6522db14..eae48936 100644 --- a/README.md +++ b/README.md @@ -577,6 +577,30 @@ spec: duration: "5m" ``` +To scale up replicas of the runners for `myorg` organization by 1 for 5 minutes on each `check_run`, you write manifests like the below: + +```yaml +kind: RunnerDeployment +metadata: + name: myrunners +spec: + organization: myorg +--- +kind: HorizontalRunnerAutoscaler +spec: + scaleTargetRef: + name: myrunners + scaleUpTriggers: + - githubEvent: + checkRun: + types: ["created"] + status: "queued" + # allow only certain repositories within your organization to trigger autoscaling + # repositories: ["myrepo", "myanotherrepo"] + amount: 1 + duration: "5m" +``` + ###### Example 2: Scale on each `pull_request` event against `develop` or `main` branches ```yaml diff --git a/api/v1alpha1/horizontalrunnerautoscaler_types.go b/api/v1alpha1/horizontalrunnerautoscaler_types.go index f4ccb4ca..89a23584 100644 --- a/api/v1alpha1/horizontalrunnerautoscaler_types.go +++ b/api/v1alpha1/horizontalrunnerautoscaler_types.go @@ -84,6 +84,10 @@ type CheckRunSpec struct { // Note that check_run name seem to equal to the job name you've defined in your actions workflow yaml file. // So it is very likely that you can utilize this to trigger depending on the job. Names []string `json:"names,omitempty"` + + // Repositories is a list of GitHub repositories. + // Any check_run event whose repository matches one of repositories in the list can trigger autoscaling. + Repositories []string `json:"repositories,omitempty"` } // https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 290e6a4c..9d1976b9 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -71,6 +71,11 @@ func (in *CheckRunSpec) DeepCopyInto(out *CheckRunSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Repositories != nil { + in, out := &in.Repositories, &out.Repositories + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheckRunSpec. diff --git a/charts/actions-runner-controller/Chart.yaml b/charts/actions-runner-controller/Chart.yaml index c110508d..0d1a4e4b 100644 --- a/charts/actions-runner-controller/Chart.yaml +++ b/charts/actions-runner-controller/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.12.7 +version: 0.12.8 # Used as the default manager tag value when no tag property is provided in the values.yaml appVersion: 0.19.0 diff --git a/charts/actions-runner-controller/crds/actions.summerwind.dev_horizontalrunnerautoscalers.yaml b/charts/actions-runner-controller/crds/actions.summerwind.dev_horizontalrunnerautoscalers.yaml index 198b1ea3..2e559225 100644 --- a/charts/actions-runner-controller/crds/actions.summerwind.dev_horizontalrunnerautoscalers.yaml +++ b/charts/actions-runner-controller/crds/actions.summerwind.dev_horizontalrunnerautoscalers.yaml @@ -173,6 +173,13 @@ spec: items: type: string type: array + repositories: + description: Repositories is a list of GitHub repositories. + Any check_run event whose repository matches one of + repositories in the list can trigger autoscaling. + items: + type: string + type: array status: type: string types: diff --git a/config/crd/bases/actions.summerwind.dev_horizontalrunnerautoscalers.yaml b/config/crd/bases/actions.summerwind.dev_horizontalrunnerautoscalers.yaml index 198b1ea3..2e559225 100644 --- a/config/crd/bases/actions.summerwind.dev_horizontalrunnerautoscalers.yaml +++ b/config/crd/bases/actions.summerwind.dev_horizontalrunnerautoscalers.yaml @@ -173,6 +173,13 @@ spec: items: type: string type: array + repositories: + description: Repositories is a list of GitHub repositories. + Any check_run event whose repository matches one of + repositories in the list can trigger autoscaling. + items: + type: string + type: array status: type: string types: diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 5e1845da..847ec4e0 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -5,4 +5,4 @@ kind: Kustomization images: - name: controller newName: summerwind/actions-runner-controller - newTag: dnsconfig-9fe31ba8 + newTag: latest diff --git a/controllers/horizontal_runner_autoscaler_webhook_on_check_run.go b/controllers/horizontal_runner_autoscaler_webhook_on_check_run.go index 4153cd8e..5fdfcc55 100644 --- a/controllers/horizontal_runner_autoscaler_webhook_on_check_run.go +++ b/controllers/horizontal_runner_autoscaler_webhook_on_check_run.go @@ -38,6 +38,16 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) MatchCheckRunEvent(ev return false } + if len(scaleUpTrigger.GitHubEvent.CheckRun.Repositories) > 0 { + for _, repository := range scaleUpTrigger.GitHubEvent.CheckRun.Repositories { + if repository == *event.Repo.Name { + return true + } + } + + return false + } + return true } } diff --git a/controllers/integration_test.go b/controllers/integration_test.go index deadc086..b9d07a85 100644 --- a/controllers/integration_test.go +++ b/controllers/integration_test.go @@ -486,8 +486,9 @@ var _ = Context("INTEGRATION: Inside of a new namespace", func() { { GitHubEvent: &actionsv1alpha1.GitHubEventScaleUpTriggerSpec{ CheckRun: &actionsv1alpha1.CheckRunSpec{ - Types: []string{"created"}, - Status: "pending", + Types: []string{"created"}, + Status: "pending", + Repositories: []string{"valid", "foo", "bar"}, }, }, Amount: 1, @@ -517,12 +518,23 @@ var _ = Context("INTEGRATION: Inside of a new namespace", func() { } // Scale-up to 5 replicas on second check_run create webhook event + replicasAfterSecondWebhook := 5 { env.SendOrgCheckRunEvent("test", "valid", "pending", "created") - ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 5, "runners after second webhook event") - env.ExpectRegisteredNumberCountEventuallyEquals(5, "count of fake list runners") + ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, replicasAfterSecondWebhook, "runners after second webhook event") + env.ExpectRegisteredNumberCountEventuallyEquals(replicasAfterSecondWebhook, "count of fake list runners") env.SyncRunnerRegistrations() - ExpectRunnerCountEventuallyEquals(ctx, ns.Name, 5) + ExpectRunnerCountEventuallyEquals(ctx, ns.Name, replicasAfterSecondWebhook) + } + + // Do not scale-up on third check_run create webhook event + // example repo is not in specified in actionsv1alpha1.CheckRunSpec.Repositories + { + env.SendOrgCheckRunEvent("test", "example", "pending", "created") + ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, replicasAfterSecondWebhook, "runners after third webhook event") + env.ExpectRegisteredNumberCountEventuallyEquals(replicasAfterSecondWebhook, "count of fake list runners") + env.SyncRunnerRegistrations() + ExpectRunnerCountEventuallyEquals(ctx, ns.Name, replicasAfterSecondWebhook) } })