Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cmd/github-actions-runner-job/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestT915CommandRunsDynamicProviderEnvelopeThroughSidecarAndRunner(t *testin
if body.Ref != "main" {
t.Fatalf("dispatch ref: got %q", body.Ref)
}
wantLabels := `["self-hosted","linux","wfc-stg-ghp-linux-01234567-abcdef98","wfc-ghp-stg","wfc-ghp-ephemeral"]`
wantLabels := `["self-hosted","linux","wfc-stg-ghp-linux-abcdef987249-543210f71ee4","wfc-ghp-stg","wfc-ghp-ephemeral"]`
for key, want := range map[string]string{
"runner_profile": "provider",
"allow_github_hosted_fallback": "false",
Expand Down Expand Up @@ -103,9 +103,9 @@ func TestT915CommandRunsDynamicProviderEnvelopeThroughSidecarAndRunner(t *testin
for _, want := range []string{
"--url\nhttps://github.com/GoCodeAlone",
"--token\nrunner-registration-token",
"--name\nwfc-stg-ghp-linux-01234567-abcdef98",
"--name\nwfc-stg-ghp-linux-abcdef987249-543210f71ee4",
"--runnergroup\nephemeral",
"--labels\nself-hosted,linux,wfc-stg-ghp-linux-01234567-abcdef98,wfc-ghp-stg,wfc-ghp-ephemeral",
"--labels\nself-hosted,linux,wfc-stg-ghp-linux-abcdef987249-543210f71ee4,wfc-ghp-stg,wfc-ghp-ephemeral",
"--ephemeral",
} {
if !strings.Contains(configArgs, want) {
Expand All @@ -125,7 +125,7 @@ func TestT915CommandRunsDynamicProviderEnvelopeThroughSidecarAndRunner(t *testin
t.Fatalf("artifacts = %#v", result.Artifacts)
}
proof := readFile(t, filepath.Join(workspace, "github-runner-proof.json"))
for _, want := range []string{"wfc-stg-ghp-linux-01234567-abcdef98", "task-abcdef9876543210", "removed"} {
for _, want := range []string{"wfc-stg-ghp-linux-abcdef987249-543210f71ee4", "task-abcdef9876543210", "removed"} {
if !strings.Contains(proof, want) {
t.Fatalf("proof missing %q:\n%s", want, proof)
}
Expand Down
29 changes: 24 additions & 5 deletions internal/ephemeral_runner_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package internal

import (
"context"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"strings"
Expand Down Expand Up @@ -180,11 +182,28 @@ func shortEphemeralID(value string) string {
if value == "" {
return ""
}
if _, suffix, ok := strings.Cut(value, "-"); ok && suffix != "" {
value = suffix
canonical := strings.ToLower(value)
var safe strings.Builder
for _, r := range canonical {
switch {
case r >= 'a' && r <= 'z':
safe.WriteRune(r)
case r >= '0' && r <= '9':
safe.WriteRune(r)
}
}
token := safe.String()
if token == "" {
return ""
}
if len(token) <= 8 && token == canonical {
return token
}
if len(value) > 8 {
return value[:8]
sum := sha256.Sum256([]byte(canonical))
hash := hex.EncodeToString(sum[:])[:6]
tail := token
if len(tail) > 6 {
tail = tail[len(tail)-6:]
}
return value
return tail + hash
}
64 changes: 56 additions & 8 deletions internal/ephemeral_runner_job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ func TestT594EphemeralRunnerJobBuildsDeterministicNameAndLabels(t *testing.T) {
t.Fatalf("build spec: %v", err)
}

if spec.RunnerName != "wfc-stg-ghp-linux-01234567-abcdef98" {
if spec.RunnerName != "wfc-stg-ghp-linux-abcdef987249-543210f71ee4" {
t.Fatalf("runner name: got %q", spec.RunnerName)
}
wantLabels := []string{
"self-hosted",
"linux",
"wfc-stg-ghp-linux-01234567-abcdef98",
"wfc-stg-ghp-linux-abcdef987249-543210f71ee4",
"wfc-ghp-stg",
"wfc-ghp-ephemeral",
}
Expand All @@ -39,14 +39,62 @@ func TestT594EphemeralRunnerJobBuildsDeterministicNameAndLabels(t *testing.T) {
}
}

func TestT594EphemeralRunnerJobSpecKeepsTimestampedDogfoodTasksUnique(t *testing.T) {
base := EphemeralRunnerJobRequest{
Environment: "stg",
OS: "linux",
WorkerID: "github-runner-linux-stg-am5-2-20260629",
Organization: "GoCodeAlone",
RunnerGroup: "ephemeral",
}
first := base
first.TaskID = "github-provider-dogfood-linux-20260630061427"
second := base
second.TaskID = "github-provider-dogfood-linux-20260630064133"

firstSpec, err := BuildEphemeralRunnerJobSpec(first)
if err != nil {
t.Fatalf("build first spec: %v", err)
}
secondSpec, err := BuildEphemeralRunnerJobSpec(second)
if err != nil {
t.Fatalf("build second spec: %v", err)
}

if firstSpec.RunnerName == secondSpec.RunnerName {
t.Fatalf("runner names must be unique across timestamped dogfood tasks, both got %q", firstSpec.RunnerName)
}
if firstSpec.Labels[2] == secondSpec.Labels[2] {
t.Fatalf("runner dispatch labels must be unique across timestamped dogfood tasks, both got %q", firstSpec.Labels[2])
}
if firstSpec.RunnerName != "wfc-stg-ghp-linux-260629fabb6f-061427fb2c0e" {
t.Fatalf("first runner name: got %q", firstSpec.RunnerName)
}
if secondSpec.RunnerName != "wfc-stg-ghp-linux-260629fabb6f-064133cf86b4" {
t.Fatalf("second runner name: got %q", secondSpec.RunnerName)
}
}

func TestT594ShortEphemeralIDKeepsSanitizedShortIDsUnique(t *testing.T) {
if got := shortEphemeralID("abcd"); got != "abcd" {
t.Fatalf("unchanged short ID: got %q", got)
}
if got := shortEphemeralID("ab-cd"); got != "abcd5db3d8" {
t.Fatalf("sanitized short ID: got %q", got)
}
if shortEphemeralID("abcd") == shortEphemeralID("ab-cd") {
t.Fatal("sanitized short IDs must not collide with already-safe short IDs")
}
}

func TestT594EphemeralRunnerJobUsesExactLabelsForDispatchAndAttachModes(t *testing.T) {
for _, mode := range []EphemeralRunnerJobMode{EphemeralRunnerJobModeDispatchThenWait, EphemeralRunnerJobModeAttachToQueued} {
t.Run(string(mode), func(t *testing.T) {
driver := &fakeEphemeralRunnerDriver{
result: EphemeralRunnerJobResult{
RunnerID: 42,
RunnerName: "wfc-stg-ghp-linux-01234567-abcdef98",
Labels: []string{"self-hosted", "linux", "wfc-stg-ghp-linux-01234567-abcdef98", "wfc-ghp-stg", "wfc-ghp-ephemeral"},
RunnerName: "wfc-stg-ghp-linux-abcdef987249-543210f71ee4",
Labels: []string{"self-hosted", "linux", "wfc-stg-ghp-linux-abcdef987249-543210f71ee4", "wfc-ghp-stg", "wfc-ghp-ephemeral"},
WorkflowRunID: 1001,
WorkflowJobID: 2002,
CleanupStatus: "removed",
Expand Down Expand Up @@ -81,7 +129,7 @@ func TestT594EphemeralRunnerJobCleansUpRunnerOnTimeout(t *testing.T) {
driver := &fakeEphemeralRunnerDriver{
result: EphemeralRunnerJobResult{
RunnerID: 42,
RunnerName: "wfc-stg-ghp-linux-01234567-abcdef98",
RunnerName: "wfc-stg-ghp-linux-abcdef987249-543210f71ee4",
CleanupStatus: "pending",
},
blockUntilDone: true,
Expand Down Expand Up @@ -117,8 +165,8 @@ func TestT594EphemeralRunnerJobProofIncludesAssignmentCleanupAndArtifacts(t *tes
driver := &fakeEphemeralRunnerDriver{
result: EphemeralRunnerJobResult{
RunnerID: 42,
RunnerName: "wfc-stg-ghp-linux-01234567-abcdef98",
Labels: []string{"self-hosted", "linux", "wfc-stg-ghp-linux-01234567-abcdef98", "wfc-ghp-stg", "wfc-ghp-ephemeral"},
RunnerName: "wfc-stg-ghp-linux-abcdef987249-543210f71ee4",
Labels: []string{"self-hosted", "linux", "wfc-stg-ghp-linux-abcdef987249-543210f71ee4", "wfc-ghp-stg", "wfc-ghp-ephemeral"},
WorkflowRunID: 1001,
WorkflowJobID: 2002,
WorkerID: "worker-0123456789abcdef",
Expand Down Expand Up @@ -197,7 +245,7 @@ func TestT594RunnerProviderInvokesEphemeralRunnerJobSpec(t *testing.T) {
if err != nil {
t.Fatalf("invoke ephemeral_runner_job: %v", err)
}
if result["runner_name"] != "wfc-stg-ghp-linux-01234567-abcdef98" {
if result["runner_name"] != "wfc-stg-ghp-linux-abcdef987249-543210f71ee4" {
t.Fatalf("runner name: got %+v", result)
}
if labels, ok := result["labels"].([]string); !ok || len(labels) != 5 || labels[3] != "wfc-ghp-stg" {
Expand Down