You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(scale-down): idle confirmation window before terminating not-busy runners
GitHub's busy flag can be stale: it reads false for runners that are actively
executing a job, both shortly after job assignment (observed 25-60s lag) and
deep into a running job (observed 12+ minutes). See #5085. A single busy=false
reading is therefore not sufficient evidence that a runner is idle, and
scale-down can terminate a runner mid-job.
SCALE_DOWN_IDLE_CONFIRMATION_SECONDS (default 0, previous behaviour) requires
busy=false readings spanning at least that window before terminating. Any
busy=true reading in between clears the marker and restarts the window.
Ported onto the compute-provider plugin framework introduced in #5234:
- core: RunnerInfo gains `idleDetectedAt`; ScaleDownComputeProvider gains
`markIdle` / `unmarkIdle`. Both are OPTIONAL, so this is not a breaking
change for provider plugins -- a provider with nowhere to persist per-runner
state stays type-valid, and scale-down skips the window for it rather than
failing. Only providers implementing them opt into the behaviour.
- aws/ec2: implements both via instance tags (`ghr:idle_detected_at`), the same
mechanism `ghr:orphan` already uses, so no new state store is needed.
- templates/provider: the scaffold documents both as optional.
- The orchestration in scale-runners/scale-down.ts is provider-agnostic and
calls through the interface rather than tagging EC2 directly.
Tests: 5 cases covering window start, deferral, elapse-then-terminate, the
disabled (0) path, and a provider that implements neither method. Verified the
tests bite by stubbing idleConfirmed to always confirm -- the window-start and
deferral cases fail as expected. Full scale-runners suite: 265 passed.
runner_additional_security_group_ids: "List of additional security groups IDs to apply to the runner. If added outside the multi_runner_config block, the additional security group(s) will be applied to all runner configs. If added inside the multi_runner_config, the additional security group(s) will be applied to the individual runner."
282
283
runner_as_root: "Run the action runner under the root user. Variable `runner_run_as` will be ignored."
283
284
runner_boot_time_in_minutes: "The minimum time for an EC2 runner to boot and register as a runner."
285
+
scale_down_idle_confirmation_seconds: "Number of seconds a runner must consistently report not-busy before scale-down terminates it. GitHub's busy flag can be stale, so a single not-busy reading is not sufficient evidence a runner is idle. 0 keeps the previous single-reading behaviour."
284
286
runner_disable_default_labels: "Disable default labels for the runners (os, architecture and `self-hosted`). If enabled, the runner will only have the extra labels provided in `runner_extra_labels`. In case you on own start script is used, this configuration parameter needs to be parsed via SSM."
285
287
runner_extra_labels: "Extra (custom) labels for the runners (GitHub). Separate each label by a comma. Labels checks on the webhook can be enforced by setting `multi_runner_config.matcherConfig.exactMatch`. GitHub read-only labels should not be provided."
0 commit comments