From 14232eec68d2f2e21cbd6f8ee8f323969d5e80e2 Mon Sep 17 00:00:00 2001 From: logikonline Date: Sun, 15 Feb 2026 12:36:06 -0500 Subject: [PATCH] fix(actions): ignore label scheme suffix in runner matching Update runner label matching to strip ":scheme" suffixes (e.g., ":host", ":docker") before comparison. This allows runners with "germany-linux:host" to match jobs with "runs-on: germany-linux" and vice versa. Previously, exact label match was required, causing runners with scheme-qualified labels to fail matching jobs without schemes. --- models/actions/runner.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/models/actions/runner.go b/models/actions/runner.go index 09e009320d..1b83280307 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -191,9 +191,26 @@ func (r *ActionRunner) GenerateToken() (err error) { // CanMatchLabels checks whether the runner's labels can match a job's "runs-on" // See https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idruns-on +// +// Labels are matched by name, ignoring any ":scheme" suffix (e.g., ":host", ":docker"). +// This means a runner with label "germany-linux:host" will match runs-on "germany-linux", +// and a job with runs-on "germany-linux:host" will also match. func (r *ActionRunner) CanMatchLabels(jobRunsOn []string) bool { - runnerLabelSet := container.SetOf(r.AgentLabels...) - return runnerLabelSet.Contains(jobRunsOn...) // match all labels + // Build a set of runner label names (stripped of :scheme suffix) + runnerNames := make(container.Set[string], len(r.AgentLabels)) + for _, label := range r.AgentLabels { + name, _, _ := strings.Cut(label, ":") + runnerNames.Add(name) + } + + // Check that every runs-on label (also stripped of :scheme) is in the runner set + for _, requiredLabel := range jobRunsOn { + name, _, _ := strings.Cut(requiredLabel, ":") + if !runnerNames.Contains(name) { + return false + } + } + return true } func init() {