Skip to content

Shutdown the scaleset when runner is deprecated#4404

Open
nikola-jokic wants to merge 1 commit intomasterfrom
nikola-jokic/scaleset-shutdown
Open

Shutdown the scaleset when runner is deprecated#4404
nikola-jokic wants to merge 1 commit intomasterfrom
nikola-jokic/scaleset-shutdown

Conversation

@nikola-jokic
Copy link
Collaborator

The runner PR exiting with exit code 7 when ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE=1: actions/runner#4285

This should propagate stops to the scaleset and set it to outdated, cleaning up resources.

@nikola-jokic nikola-jokic added the gha-runner-scale-set Related to the gha-runner-scale-set mode label Mar 13, 2026
@github-actions
Copy link
Contributor

Hello! Thank you for your contribution.

Please review our contribution guidelines to understand the project's testing and code conventions.

@nikola-jokic nikola-jokic force-pushed the nikola-jokic/scaleset-shutdown branch from 1911774 to 2e58744 Compare March 17, 2026 10:30
@nikola-jokic nikola-jokic force-pushed the nikola-jokic/scaleset-shutdown branch from 89ac578 to 2a8056e Compare March 17, 2026 18:33
@nikola-jokic nikola-jokic marked this pull request as ready for review March 17, 2026 18:57
Copilot AI review requested due to automatic review settings March 17, 2026 18:57
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds “runner deprecation” handling so that when the runner exits with the version-deprecated signal (exit code 7, enabled via ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE=1), the controller marks the involved resources as Outdated and begins tearing down the scale set resources to clean up.

Changes:

  • Inject ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE=1 into ephemeral runner pods and treat runner exit code 7 as “Outdated”.
  • Introduce Phase fields and enums for EphemeralRunner, EphemeralRunnerSet, and AutoscalingRunnerSet, and propagate “Outdated” from runner → runnerset → autoscaling runnerset cleanup.
  • Update controllers/tests/CRDs to use the new status field names (RunnerID, WorkflowRunID, etc.) and new phase types.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
controllers/actions.github.com/resourcebuilder.go Adds deprecated-exit-code env var to ephemeral runner container.
controllers/actions.github.com/constants.go Introduces env var constant for deprecated version exit-code behavior.
controllers/actions.github.com/ephemeralrunner_controller.go Detects exit code 7, marks EphemeralRunner as Outdated, and removes it from the service.
controllers/actions.github.com/ephemeralrunner_controller_test.go Updates tests to use EphemeralRunnerPhase and renamed status fields.
controllers/actions.github.com/ephemeralrunnerset_controller.go Tracks Outdated runners, adds runnerset phase, and short-circuits reconciliation when Outdated.
controllers/actions.github.com/ephemeralrunnerset_controller_test.go Updates tests for renamed status fields and new phase types/values.
controllers/actions.github.com/autoscalingrunnerset_controller.go Detects outdated runnerset and triggers full scale set cleanup; adds change-hash annotation.
controllers/actions.github.com/autoscalingrunnerset_controller_test.go Updates expected status to use Phase instead of State and formatting changes.
cmd/ghalistener/scaler/scaler.go Updates patched EphemeralRunner status field names (JobRequestID, WorkflowRunID).
apis/actions.github.com/v1alpha1/ephemeralrunner_types.go Renames status fields (e.g., RunnerID) and introduces EphemeralRunnerPhase including Outdated.
apis/actions.github.com/v1alpha1/ephemeralrunnerset_types.go Adds EphemeralRunnerSetStatus.Phase and phase enum (Running/Outdated).
apis/actions.github.com/v1alpha1/autoscalingrunnerset_types.go Replaces status State with Phase, adds phase enum, and adds Hash() helper.
config/crd/bases/actions.github.com_ephemeralrunnersets.yaml Adds .status.phase to the EphemeralRunnerSet CRD schema.
config/crd/bases/actions.github.com_autoscalingrunnersets.yaml Replaces .status.state with .status.phase in the AutoscalingRunnerSet CRD schema.
charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunnersets.yaml Mirrors EphemeralRunnerSet CRD schema update for Helm chart.
charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalingrunnersets.yaml Mirrors AutoscalingRunnerSet CRD schema update for Helm chart.
charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunnersets.yaml Mirrors EphemeralRunnerSet CRD schema update for experimental chart.
charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalingrunnersets.yaml Mirrors AutoscalingRunnerSet CRD schema update for experimental chart.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.


case cs.State.Terminated.ExitCode == 7: // outdated
if err := r.markAsOutdated(ctx, ephemeralRunner, log); err != nil {
log.Error(err, "Failed to set ephemeral runner to phase Outdated")
Comment on lines +344 to +350
Phase AutoscalingRunnerSetPhase
}

d := &data{
Spec: ars.Spec.DeepCopy(),
Labels: ars.Labels,
Phase: ars.Status.Phase,
Comment on lines +243 to +246
case ephemeralRunnerSet.Status.Phase == "":
phase = v1alpha1.EphemeralRunnerSetPhaseRunning
case len(state.outdated) > 0:
phase = v1alpha1.EphemeralRunnerSetPhaseOutdated
"finished", len(ephemeralRunnerState.finished),
"failed", len(ephemeralRunnerState.failed),
"deleting", len(ephemeralRunnerState.deleting),
"outdated", ephemeralRunnersByState.outdated,
if ephemeralRunnerSet.Status != desiredStatus {
log.Info("Updating status with current runners count", "count", total)
ephemeralRunnerSet := ephemeralRunnerSet.DeepCopy()
ephemeralRunnerSet.Status.CurrentReplicas = -1 // ALWAYS update current replicas
return ctrl.Result{}, nil
case 7:
if err := r.markAsOutdated(ctx, ephemeralRunner, log); err != nil {
log.Error(err, "Failed to set ephemeral runner to phase Outdated")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gha-runner-scale-set Related to the gha-runner-scale-set mode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants