fix(labels): return empty string on label mismatch instead of fallback
Some checks failed
Release / build (amd64, darwin) (push) Successful in 53s
Release / build (amd64, linux) (push) Successful in 1m8s
Release / build (amd64, windows) (push) Successful in 50s
Release / build (arm64, darwin) (push) Successful in 1m1s
Release / build (arm64, linux) (push) Successful in 53s
Release / release (push) Successful in 21s
CI / build-and-test (push) Failing after 45s
Some checks failed
Release / build (amd64, darwin) (push) Successful in 53s
Release / build (amd64, linux) (push) Successful in 1m8s
Release / build (amd64, windows) (push) Successful in 50s
Release / build (arm64, darwin) (push) Successful in 1m1s
Release / build (arm64, linux) (push) Successful in 53s
Release / release (push) Successful in 21s
CI / build-and-test (push) Failing after 45s
Changes PickPlatform to return empty string when no matching label is found, causing the job to fail with a clear error rather than silently falling back to ubuntu-latest. This prevents jobs from running in incorrect environments when runner labels are edited in Gitea admin UI after registration. Adds comprehensive test coverage for label matching scenarios including exact matches, no matches, empty labels, and multiple runsOn values.
This commit is contained in:
@@ -56,6 +56,7 @@ func (l Labels) RequireDocker() bool {
|
||||
}
|
||||
|
||||
// PickPlatform selects the appropriate platform based on the runsOn requirements.
|
||||
// Returns empty string if no matching label is found, which will cause the job to fail.
|
||||
func (l Labels) PickPlatform(runsOn []string) string {
|
||||
platforms := make(map[string]string, len(l))
|
||||
for _, label := range l {
|
||||
@@ -76,17 +77,12 @@ func (l Labels) PickPlatform(runsOn []string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: support multiple labels
|
||||
// like:
|
||||
// ["ubuntu-22.04"] => "ubuntu:22.04"
|
||||
// ["with-gpu"] => "linux:with-gpu"
|
||||
// ["ubuntu-22.04", "with-gpu"] => "ubuntu:22.04_with-gpu"
|
||||
|
||||
// return default.
|
||||
// So the runner receives a task with a label that the runner doesn't have,
|
||||
// it happens when the user have edited the label of the runner in the web UI.
|
||||
// TODO: it may be not correct, what if the runner is used as host mode only?
|
||||
return "docker.gitea.com/runner-images:ubuntu-latest"
|
||||
// No matching label found. This indicates a mismatch between server's view
|
||||
// of runner labels and the runner's local configuration (e.g., labels were
|
||||
// edited in Gitea admin UI after runner registered). Return empty string
|
||||
// to cause the job to fail with a clear error rather than silently running
|
||||
// in the wrong environment.
|
||||
return ""
|
||||
}
|
||||
|
||||
// Names returns the names of all labels.
|
||||
|
||||
@@ -10,6 +10,64 @@ import (
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestPickPlatform(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
labels []string
|
||||
runsOn []string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "exact match host label",
|
||||
labels: []string{"linux-latest:host", "ubuntu:host"},
|
||||
runsOn: []string{"linux-latest"},
|
||||
want: "-self-hosted",
|
||||
},
|
||||
{
|
||||
name: "exact match docker label",
|
||||
labels: []string{"ubuntu:docker://node:18"},
|
||||
runsOn: []string{"ubuntu"},
|
||||
want: "node:18",
|
||||
},
|
||||
{
|
||||
name: "no match returns empty string to fail job",
|
||||
labels: []string{"linux:host", "debian:host"},
|
||||
runsOn: []string{"unknown-label"},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "no match on docker runner returns empty string",
|
||||
labels: []string{"ubuntu:docker://node:18", "linux:host"},
|
||||
runsOn: []string{"unknown-label"},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "empty labels returns empty string",
|
||||
labels: []string{},
|
||||
runsOn: []string{"anything"},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "multiple runsOn matches first available",
|
||||
labels: []string{"linux:host", "ubuntu:docker://node:18"},
|
||||
runsOn: []string{"windows", "ubuntu"},
|
||||
want: "node:18",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ls := Labels{}
|
||||
for _, l := range tt.labels {
|
||||
label, err := Parse(l)
|
||||
require.NoError(t, err)
|
||||
ls = append(ls, label)
|
||||
}
|
||||
got := ls.PickPlatform(tt.runsOn)
|
||||
assert.Equal(t, got, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
args string
|
||||
|
||||
Reference in New Issue
Block a user