Files
gpt-load/internal/webui/workflow_test.go
T

1593 lines
51 KiB
Go

package webui
import (
"encoding/json"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"testing"
)
const (
checkoutActionRef = "actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1"
setupGoActionRef = "actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e"
setupNodeActionRef = "actions/setup-node@820762786026740c76f36085b0efc47a31fe5020"
pnpmSetupActionRef = "pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271"
uploadArtifactActionRef = "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"
downloadArtifactActionRef = "actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c"
qemuActionRef = "docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8"
buildxActionRef = "docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c"
dockerLoginActionRef = "docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c"
dockerMetadataActionRef = "docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302"
dockerBuildActionRef = "docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a"
githubReleaseActionRef = "softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228"
)
func TestWebCICompositeActionRunsCompleteFrontendGate(t *testing.T) {
content := readRepositoryFile(t, ".github/actions/web-ci/action.yml")
for _, required := range []string{
pnpmSetupActionRef,
"version: 11.17.0",
setupNodeActionRef,
"node-version: 24.18.0",
} {
if !strings.Contains(content, required) {
t.Fatalf("web-ci action does not contain %q", required)
}
}
previousIndex := -1
for _, command := range []string{
"pnpm --dir web install --frozen-lockfile",
"pnpm --dir web audit --audit-level high",
"pnpm --dir web run lint",
"pnpm --dir web run format",
"pnpm --dir web run type-check",
"pnpm --dir web run build",
} {
if count := strings.Count(content, command); count != 1 {
t.Fatalf("web-ci action contains %q %d times, want exactly once", command, count)
}
commandIndex := strings.Index(content, command)
if commandIndex <= previousIndex {
t.Fatalf("web-ci action does not run %q in the required order", command)
}
previousIndex = commandIndex
}
}
func TestBranchCIContainsStaticGoAndRaceEnabledBackendGates(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/ci.yml")
testJob := workflowJobBlock(t, content, "test")
workflowGoFormattingScript(t, content, "test")
for _, test := range []struct {
name string
run string
}{
{name: "Check module graph", run: "go mod tidy -diff"},
{name: "Audit Go dependencies", run: "go run golang.org/x/vuln/cmd/govulncheck@v1.1.4 ./..."},
{name: "Run Go vet", run: "go vet ./..."},
{name: "Run race-enabled tests", run: "go test -race -count=1 -timeout=15m . ./internal/..."},
{name: "Check repository invariants", run: "git diff --check"},
} {
assertWorkflowGateStep(t, testJob, test.name, test.run)
}
releaseJob := workflowJobBlock(
t,
readRepositoryFile(t, ".github/workflows/release.yml"),
"verify-and-build-web",
)
assertWorkflowGateStep(
t,
releaseJob,
"Run race-enabled tests",
"go test -race -count=1 -timeout=15m . ./internal/...",
)
}
func TestWindowsCIExecutesManagedStorageACLTests(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/ci.yml")
job := workflowJobBlock(t, content, "windows-encryption-acl")
if count := strings.Count(job, "runs-on: windows-2025"); count != 1 {
t.Fatalf("Windows ACL job contains runs-on declaration %d times, want exactly once", count)
}
assertWorkflowGateStep(
t,
job,
"Test Windows secure file and storage ACLs",
"go test -v -count=1 ./internal/platform/securefile ./internal/platform/encryption ./internal/storage",
)
}
func TestWorkflowsPinExternalActionsAndHostedRunners(t *testing.T) {
actionRef := regexp.MustCompile(`(?m)^\s*uses:\s+([^#\s]+)`)
immutableRef := regexp.MustCompile(`^[^@\s]+@[0-9a-f]{40}$`)
for _, name := range []string{
".github/actions/web-ci/action.yml",
".github/workflows/ci.yml",
".github/workflows/release.yml",
} {
content := readRepositoryFile(t, name)
for _, match := range actionRef.FindAllStringSubmatch(content, -1) {
ref := match[1]
if strings.HasPrefix(ref, "./") {
continue
}
if !immutableRef.MatchString(ref) {
t.Errorf("%s contains mutable or invalid action reference %q", name, ref)
}
}
}
ci := readRepositoryFile(t, ".github/workflows/ci.yml")
for _, required := range []string{"runs-on: ubuntu-24.04", "runs-on: windows-2025"} {
if !strings.Contains(ci, required) {
t.Errorf("branch CI does not contain %q", required)
}
}
if strings.Contains(ci, "-latest") {
t.Error("branch CI contains a mutable hosted runner label")
}
}
func TestGoFormattingScriptsFailClosed(t *testing.T) {
for _, workflow := range []struct {
name string
file string
job string
}{
{name: "branch", file: ".github/workflows/ci.yml", job: "test"},
{name: "release", file: ".github/workflows/release.yml", job: "verify-and-build-web"},
} {
t.Run(workflow.name, func(t *testing.T) {
script := workflowGoFormattingScript(
t,
readRepositoryFile(t, workflow.file),
workflow.job,
)
scriptPath := filepath.Join(t.TempDir(), "check-go-format.sh")
if err := os.WriteFile(
scriptPath,
[]byte("#!/usr/bin/env bash\nset -e\n"+script),
0o700,
); err != nil {
t.Fatalf("write Go formatting script: %v", err)
}
fakeBin := t.TempDir()
fakeGofmt := filepath.Join(fakeBin, "gofmt")
if err := os.WriteFile(fakeGofmt, []byte(`#!/usr/bin/env bash
case "${GOFMT_TEST_MODE}" in
clean) exit 0 ;;
unformatted) printf 'unformatted.go\n'; exit 0 ;;
failed) exit 2 ;;
*) exit 64 ;;
esac
`), 0o700); err != nil {
t.Fatalf("write fake gofmt: %v", err)
}
for _, test := range []struct {
name string
mode string
wantErr bool
}{
{name: "clean", mode: "clean"},
{name: "unformatted", mode: "unformatted", wantErr: true},
{name: "formatter failure", mode: "failed", wantErr: true},
} {
t.Run(test.name, func(t *testing.T) {
command := exec.Command("bash", scriptPath)
command.Env = append(
os.Environ(),
"GOFMT_TEST_MODE="+test.mode,
"PATH="+fakeBin+string(os.PathListSeparator)+os.Getenv("PATH"),
)
output, err := command.CombinedOutput()
if (err != nil) != test.wantErr {
t.Fatalf("Go formatting check error = %v, want error %t\n%s", err, test.wantErr, output)
}
})
}
})
}
}
func TestReleaseWorkflowUsesTagOnlyTriggerAndStrictSemverGuard(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
trigger := workflowTopLevelBlock(t, content, "on")
for _, required := range []string{"push:", "tags:", `- "v2.*"`} {
if !strings.Contains(trigger, required) {
t.Fatalf("release trigger does not contain %q:\n%s", required, trigger)
}
}
for _, forbidden := range []string{"branches:", "pull_request:", "workflow_dispatch:"} {
if strings.Contains(trigger, forbidden) {
t.Fatalf("release trigger contains forbidden %q:\n%s", forbidden, trigger)
}
}
script := workflowMarkedScript(t, content, "release-tag-validation")
scriptPath := filepath.Join(t.TempDir(), "validate-release-tag.sh")
if err := os.WriteFile(scriptPath, []byte("#!/usr/bin/env bash\nset -euo pipefail\n"+script), 0o700); err != nil {
t.Fatalf("write tag validation script: %v", err)
}
for _, test := range []struct {
tag string
valid bool
wantOutput []string
}{
{
tag: "v2.0.0",
valid: true,
wantOutput: []string{
"version=v2.0.0", "prerelease=false", "image_exact=v2.0.0",
"image_minor=2.0", "image_major=2",
},
},
{
tag: "v2.0.0-rc.1",
valid: true,
wantOutput: []string{
"version=v2.0.0-rc.1", "prerelease=true", "image_exact=v2.0.0-rc.1",
"image_minor=2.0", "image_major=2",
},
},
{
tag: "v2.10.3-alpha-1.0",
valid: true,
wantOutput: []string{
"version=v2.10.3-alpha-1.0", "prerelease=true",
"image_exact=v2.10.3-alpha-1.0", "image_minor=2.10", "image_major=2",
},
},
{tag: "v2.0.0.1", valid: false},
{tag: "v2.01.0", valid: false},
{tag: "v2.0.01", valid: false},
{tag: "v2.0.0-", valid: false},
{tag: "v2.0.0-rc..1", valid: false},
{tag: "v2.0.0-01", valid: false},
{tag: "v2.0.0+build.1", valid: false},
{tag: "v1.4.0", valid: false},
} {
t.Run(test.tag, func(t *testing.T) {
outputPath := filepath.Join(t.TempDir(), "github-output")
command := exec.Command("bash", scriptPath)
command.Env = append(
os.Environ(),
"GITHUB_REF_NAME="+test.tag,
"GITHUB_OUTPUT="+outputPath,
)
output, err := command.CombinedOutput()
if test.valid && err != nil {
t.Fatalf("tag %s rejected: %v\n%s", test.tag, err, output)
}
if !test.valid && err == nil {
t.Fatalf("tag %s accepted, want rejection\n%s", test.tag, output)
}
if test.valid {
githubOutput, readErr := os.ReadFile(outputPath)
if readErr != nil {
t.Fatalf("read tag outputs: %v", readErr)
}
for _, expected := range test.wantOutput {
if !strings.Contains(string(githubOutput), expected+"\n") {
t.Fatalf("tag %s outputs do not contain %q:\n%s", test.tag, expected, githubOutput)
}
}
}
})
}
}
func TestReleasePublicationStateClassifiesFreshConsistentConflictAndPartial(t *testing.T) {
script := filepath.Join("..", "..", ".github", "scripts", "release-publication-state.sh")
expectedSHA := "0123456789abcdef0123456789abcdef01234567"
base := map[string]string{
"RELEASE_EXPECTED_SHA": expectedSHA,
"RELEASE_GITHUB_STATE": "absent",
"RELEASE_GITHUB_TARGET_SHA": "",
"RELEASE_GITHUB_ASSETS": "absent",
"RELEASE_GHCR_STATE": "absent",
"RELEASE_GHCR_DIGEST": "absent",
"RELEASE_GHCR_REVISION": "",
"RELEASE_DOCKERHUB_STATE": "absent",
"RELEASE_DOCKERHUB_DIGEST": "absent",
"RELEASE_DOCKERHUB_REVISION": "",
}
clone := func(overrides map[string]string) map[string]string {
values := make(map[string]string, len(base))
for key, value := range base {
values[key] = value
}
for key, value := range overrides {
values[key] = value
}
return values
}
run := func(t *testing.T, values map[string]string) (string, error) {
t.Helper()
command := exec.Command("bash", script)
command.Env = []string{"PATH=" + os.Getenv("PATH")}
for key, value := range values {
command.Env = append(command.Env, key+"="+value)
}
output, err := command.CombinedOutput()
return string(output), err
}
allPresent := map[string]string{
"RELEASE_GITHUB_STATE": "present",
"RELEASE_GITHUB_TARGET_SHA": expectedSHA,
"RELEASE_GITHUB_ASSETS": "match",
"RELEASE_GHCR_STATE": "present",
"RELEASE_GHCR_DIGEST": "sha256:aaaaaaaa",
"RELEASE_GHCR_REVISION": expectedSHA,
"RELEASE_DOCKERHUB_STATE": "present",
"RELEASE_DOCKERHUB_DIGEST": "sha256:aaaaaaaa",
"RELEASE_DOCKERHUB_REVISION": expectedSHA,
}
present := func(overrides map[string]string) map[string]string {
values := clone(allPresent)
for key, value := range overrides {
values[key] = value
}
return values
}
for _, test := range []struct {
name string
values map[string]string
want string
}{
{
name: "fresh",
values: clone(nil),
want: "publication_state=fresh\nwrite_mode=publish\n",
},
{
name: "consistent",
values: present(nil),
want: "publication_state=consistent\nwrite_mode=verify\n",
},
{
name: "conflict/GitHub target",
values: present(map[string]string{
"RELEASE_GITHUB_TARGET_SHA": "fedcba9876543210fedcba9876543210fedcba98",
}),
want: "publication_state=conflict\nwrite_mode=blocked\n",
},
{
name: "conflict/GitHub assets or checksum",
values: present(map[string]string{
"RELEASE_GITHUB_ASSETS": "mismatch",
}),
want: "publication_state=conflict\nwrite_mode=blocked\n",
},
{
name: "conflict/GHCR revision",
values: present(map[string]string{
"RELEASE_GHCR_REVISION": "fedcba9876543210fedcba9876543210fedcba98",
}),
want: "publication_state=conflict\nwrite_mode=blocked\n",
},
{
name: "conflict/Docker Hub revision",
values: present(map[string]string{
"RELEASE_DOCKERHUB_REVISION": "fedcba9876543210fedcba9876543210fedcba98",
}),
want: "publication_state=conflict\nwrite_mode=blocked\n",
},
{
name: "conflict/registry digest",
values: present(map[string]string{
"RELEASE_DOCKERHUB_DIGEST": "sha256:bbbbbbbb",
}),
want: "publication_state=conflict\nwrite_mode=blocked\n",
},
{
name: "partial",
values: clone(map[string]string{
"RELEASE_GITHUB_STATE": "present",
"RELEASE_GITHUB_TARGET_SHA": expectedSHA,
"RELEASE_GITHUB_ASSETS": "match",
}),
want: "publication_state=partial\nwrite_mode=blocked\n",
},
} {
t.Run(test.name, func(t *testing.T) {
output, err := run(t, test.values)
if err != nil {
t.Fatalf("classifier rejected legal state: %v\n%s", err, output)
}
if output != test.want {
t.Fatalf("classifier output = %q, want %q", output, test.want)
}
})
}
for _, test := range []struct {
name string
values map[string]string
}{
{
name: "missing expected sha",
values: map[string]string{},
},
{
name: "invalid state enum",
values: clone(map[string]string{
"RELEASE_GHCR_STATE": "unknown",
}),
},
{
name: "absent channel with digest",
values: clone(map[string]string{
"RELEASE_GHCR_DIGEST": "sha256:aaaaaaaa",
}),
},
{
name: "present channel without revision",
values: clone(map[string]string{
"RELEASE_GHCR_STATE": "present",
"RELEASE_GHCR_DIGEST": "sha256:aaaaaaaa",
}),
},
} {
t.Run(test.name, func(t *testing.T) {
output, err := run(t, test.values)
if err == nil {
t.Fatalf("classifier accepted invalid input:\n%s", output)
}
})
}
}
func TestReleaseWorkflowDoesNotRequireUntrackedAgentInstructionFiles(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
verifyJob := workflowJobBlock(t, content, "verify-and-build-web")
if !strings.Contains(verifyJob, "git diff --check") {
t.Fatal("release verification does not run git diff --check")
}
for _, untracked := range []string{"AGENTS.md", "CLAUDE.md"} {
if strings.Contains(verifyJob, untracked) {
t.Fatalf("release verification requires untracked %s", untracked)
}
}
}
func TestReleaseWorkflowBuildsOneWebDistAndFiveVersionedBinaries(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
if count := strings.Count(content, "uses: ./.github/actions/web-ci"); count != 1 {
t.Fatalf("release workflow invokes web-ci %d times, want exactly once", count)
}
for _, required := range []string{
checkoutActionRef,
setupGoActionRef,
uploadArtifactActionRef,
downloadArtifactActionRef,
"name: verified-web-dist",
"path: internal/webui/dist",
"CGO_ENABLED: 0",
"go build -trimpath",
`gpt-load/internal/platform/version.Version=${{ github.ref_name }}`,
"gpt-load-linux-amd64",
"gpt-load-linux-arm64",
"gpt-load-macos-amd64",
"gpt-load-macos-arm64",
"gpt-load-windows-amd64.exe",
"SHA256SUMS",
} {
if !strings.Contains(content, required) {
t.Fatalf("release workflow does not contain %q", required)
}
}
for _, forbidden := range []string{"actions/checkout@v6", "actions/setup-go@v6"} {
if strings.Contains(content, forbidden) {
t.Fatalf("release workflow contains unavailable action major %q", forbidden)
}
}
if strings.Count(content, "pnpm --dir web run build") != 0 {
t.Fatal("release workflow rebuilds web outside the shared web-ci action")
}
}
func TestReleaseWorkflowGatesSingleReleaseWriterAndImagePublication(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
preflight := workflowJobBlock(t, content, "publication-preflight")
for _, dependency := range []string{
"validate-tag",
"verify-and-build-web",
"build-binaries",
"package-checksums",
"native-artifact-smoke",
"docker-smoke",
} {
if !strings.Contains(preflight, dependency) {
t.Fatalf("publication preflight does not need %s:\n%s", dependency, preflight)
}
}
if count := strings.Count(content, "softprops/action-gh-release@"); count != 1 {
t.Fatalf("release writer count = %d, want exactly 1", count)
}
releaseJob := workflowJobBlock(t, content, "publish-github")
if !strings.Contains(releaseJob, "contents: write") || strings.Contains(releaseJob, "packages: write") {
t.Fatalf("GitHub release permissions are not least privilege:\n%s", releaseJob)
}
imageJob := workflowJobBlock(t, content, "publish-images")
if !strings.Contains(imageJob, "packages: write") || strings.Contains(imageJob, "contents: write") {
t.Fatalf("image publication permissions are not least privilege:\n%s", imageJob)
}
}
func TestReleaseWorkflowUsesOneSharedPublicationPreflight(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
if count := strings.Count(content, " publication-preflight:"); count != 1 {
t.Fatalf("publication preflight job count = %d, want exactly 1", count)
}
if strings.Contains(content, " capture-channel-baseline:") {
t.Fatal("release workflow keeps a separate channel-baseline path")
}
preflight := workflowJobBlock(t, content, "publication-preflight")
for _, required := range []string{
"name: release-assets",
"sha256sum --check SHA256SUMS",
"git merge-base --is-ancestor",
"DOCKERHUB_READ_TOKEN",
"DOCKERHUB_TOKEN",
"ghcr.io/tbphp/gpt-load:latest",
"tbphp/gpt-load:latest",
".github/scripts/release-publication-state.sh",
"publication_state:",
"write_mode:",
`test "${write_mode}" != "blocked"`,
} {
if !strings.Contains(preflight, required) {
t.Fatalf("publication preflight does not contain %q:\n%s", required, preflight)
}
}
for _, jobName := range []string{"publish-images", "publish-github"} {
job := workflowJobBlock(t, content, jobName)
if !strings.Contains(job, "publication-preflight") {
t.Fatalf("%s does not depend on the shared preflight:\n%s", jobName, job)
}
}
}
func TestReleaseWorkflowUsesTrustedCurrentRunChecksumForExistingRelease(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
for _, test := range []struct {
job string
step string
}{
{
job: "publication-preflight",
step: "Inventory publication channels",
},
{
job: "publish-github",
step: "Verify existing GitHub Release",
},
} {
step := workflowStepBlock(
t,
workflowJobBlock(t, content, test.job),
test.step,
)
compare := strings.Index(
step,
"cmp release/SHA256SUMS existing-release/SHA256SUMS",
)
trustedCheck := strings.Index(
step,
"sha256sum --check ../release/SHA256SUMS",
)
if compare < 0 || trustedCheck < 0 || compare >= trustedCheck {
t.Fatalf(
"%s does not compare the checksum identity before using the trusted checksum: cmp=%d check=%d\n%s",
test.step,
compare,
trustedCheck,
step,
)
}
if strings.Contains(step, "sha256sum --check SHA256SUMS") {
t.Fatalf("%s executes the untrusted remote checksum:\n%s", test.step, step)
}
}
}
func TestReleaseWorkflowKeepsUntrustedImageRevisionInsideJQComparison(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
expectedSHA := "0123456789abcdef0123456789abcdef01234567"
validation := workflowMarkedScript(t, content, "release-image-revision-validation")
scriptPath := filepath.Join(t.TempDir(), "validate-image-revision.sh")
script := "#!/usr/bin/env bash\nset -euo pipefail\n" +
"GITHUB_SHA=" + expectedSHA + "\n" +
"inspection=\"${RELEASE_TEST_INSPECTION}\"\n" +
"revision=mismatch\n" +
validation +
"printf '%s\\n' \"${revision}\"\n"
if err := os.WriteFile(scriptPath, []byte(script), 0o700); err != nil {
t.Fatalf("write image revision validation script: %v", err)
}
inspection := func(amd64, arm64 any) string {
value := map[string]any{
"image": map[string]any{
"linux/amd64": map[string]any{
"config": map[string]any{
"Labels": map[string]any{
"org.opencontainers.image.revision": amd64,
},
},
},
"linux/arm64": map[string]any{
"config": map[string]any{
"Labels": map[string]any{
"org.opencontainers.image.revision": arm64,
},
},
},
},
}
encoded, err := json.Marshal(value)
if err != nil {
t.Fatalf("marshal image inspection: %v", err)
}
return string(encoded)
}
for _, test := range []struct {
name string
inspection string
want string
}{
{
name: "exact",
inspection: inspection(expectedSHA, expectedSHA),
want: expectedSHA,
},
{
name: "newline",
inspection: inspection(expectedSHA+"\ninjected", expectedSHA),
want: "mismatch",
},
{
name: "pipe",
inspection: inspection(expectedSHA+"|injected", expectedSHA),
want: "mismatch",
},
{
name: "NUL",
inspection: inspection(expectedSHA+"\x00injected", expectedSHA),
want: "mismatch",
},
{
name: "unequal",
inspection: inspection("other", expectedSHA),
want: "mismatch",
},
{
name: "missing",
inspection: `{}`,
want: "mismatch",
},
{
name: "non-string",
inspection: inspection(123, expectedSHA),
want: "mismatch",
},
{
name: "malformed",
inspection: `{`,
want: "mismatch",
},
} {
t.Run(test.name, func(t *testing.T) {
command := exec.Command("bash", scriptPath)
command.Env = []string{
"PATH=" + os.Getenv("PATH"),
"RELEASE_TEST_INSPECTION=" + test.inspection,
}
output, err := command.Output()
if err != nil {
t.Fatalf("image revision validation failed: %v", err)
}
if got := strings.TrimSpace(string(output)); got != test.want {
t.Fatalf("revision = %q, want %q", got, test.want)
}
})
}
inventoryStep := workflowStepBlock(
t,
workflowJobBlock(t, content, "publication-preflight"),
"Inventory publication channels",
)
functionStart := strings.Index(inventoryStep, "inventory_image() {")
functionEnd := strings.Index(inventoryStep, "\n IFS='|' read -r")
if functionStart < 0 || functionEnd <= functionStart {
t.Fatalf("cannot isolate inventory_image:\n%s", inventoryStep)
}
inventoryFunction := inventoryStep[functionStart:functionEnd]
for _, required := range []string{
"jq -e",
`--arg expected "${GITHUB_SHA}"`,
`local revision=mismatch`,
`revision="${GITHUB_SHA}"`,
`linux/amd64`,
`linux/arm64`,
`org.opencontainers.image.revision`,
`. == $expected`,
} {
if !strings.Contains(inventoryFunction, required) {
t.Fatalf("inventory_image does not contain %q:\n%s", required, inventoryFunction)
}
}
for _, forbidden := range []string{
"child_revision",
`revision="$(`,
`revision="${child_revision`,
} {
if strings.Contains(inventoryFunction, forbidden) {
t.Fatalf("inventory_image exposes raw revision via %q:\n%s", forbidden, inventoryFunction)
}
}
for _, test := range []struct {
job string
step string
}{
{
job: "publish-images",
step: "Verify exact published images",
},
{
job: "post-publish-verify",
step: "Verify published image manifests",
},
} {
step := workflowStepBlock(
t,
workflowJobBlock(t, content, test.job),
test.step,
)
for _, required := range []string{
"jq -e",
`--arg expected "${GITHUB_SHA}"`,
`linux/amd64`,
`linux/arm64`,
`org.opencontainers.image.revision`,
`. == $expected`,
} {
if !strings.Contains(step, required) {
t.Fatalf("%s does not contain %q:\n%s", test.step, required, step)
}
}
if strings.Contains(step, `revision="$(`) {
t.Fatalf("%s transfers a raw revision into shell:\n%s", test.step, step)
}
}
}
func TestReleaseWorkflowPublishesImagesBeforeGitHubRelease(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
imageJob := workflowJobBlock(t, content, "publish-images")
releaseJob := workflowJobBlock(t, content, "publish-github")
if strings.Contains(imageJob, "publish-github") {
t.Fatalf("image publication depends on GitHub publication:\n%s", imageJob)
}
for _, dependency := range []string{"publication-preflight", "publish-images"} {
if !strings.Contains(releaseJob, dependency) {
t.Fatalf("GitHub publication does not need %s:\n%s", dependency, releaseJob)
}
}
}
func TestReleaseWorkflowUpdatesAliasesOnlyAfterExactVerification(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
imageJob := workflowJobBlock(t, content, "publish-images")
exactVerification := strings.Index(imageJob, "name: Verify exact published images")
aliasUpdate := strings.Index(imageJob, "name: Update stable major and minor aliases")
if exactVerification < 0 || aliasUpdate < 0 || exactVerification >= aliasUpdate {
t.Fatalf(
"alias update is not ordered after exact verification: exact=%d alias=%d\n%s",
exactVerification,
aliasUpdate,
imageJob,
)
}
exactStep := workflowStepBlock(t, imageJob, "Verify exact published images")
for _, required := range []string{
"linux/amd64",
"linux/arm64",
"org.opencontainers.image.revision",
"GITHUB_SHA",
"ghcr_exact_digest",
"dockerhub_exact_digest",
`test "${ghcr_exact_digest}" = "${dockerhub_exact_digest}"`,
} {
if !strings.Contains(exactStep, required) {
t.Fatalf("exact image verification does not contain %q:\n%s", required, exactStep)
}
}
metadataStep := workflowStepBlock(t, imageJob, "Generate exact image metadata")
if !strings.Contains(metadataStep, "needs.validate-tag.outputs.image_exact") {
t.Fatalf("exact image metadata does not contain the exact tag:\n%s", metadataStep)
}
for _, forbidden := range []string{
"needs.validate-tag.outputs.image_minor",
"needs.validate-tag.outputs.image_major",
"latest",
} {
if strings.Contains(metadataStep, forbidden) {
t.Fatalf("exact image metadata contains non-exact tag %q:\n%s", forbidden, metadataStep)
}
}
aliasStep := workflowStepBlock(t, imageJob, "Update stable major and minor aliases")
for _, required := range []string{
"needs.publication-preflight.outputs.write_mode == 'publish'",
"needs.validate-tag.outputs.prerelease == 'false'",
"docker buildx imagetools create",
"image_minor",
"image_major",
} {
if !strings.Contains(aliasStep, required) {
t.Fatalf("alias update does not contain %q:\n%s", required, aliasStep)
}
}
if strings.Contains(strings.ToLower(aliasStep), "latest") {
t.Fatalf("alias update writes latest:\n%s", aliasStep)
}
}
func TestReleaseWorkflowConsistentRerunIsVerifyOnly(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
for _, test := range []struct {
job string
step string
call string
}{
{
job: "publish-images",
step: "Build and publish exact multi-platform images",
call: dockerBuildActionRef,
},
{
job: "publish-github",
step: "Publish one GitHub Release",
call: githubReleaseActionRef,
},
} {
job := workflowJobBlock(t, content, test.job)
step := workflowStepBlock(t, job, test.step)
for _, required := range []string{
"needs.publication-preflight.outputs.write_mode == 'publish'",
test.call,
} {
if !strings.Contains(step, required) {
t.Fatalf("%s write step does not contain %q:\n%s", test.job, required, step)
}
}
}
imageVerification := workflowStepBlock(
t,
workflowJobBlock(t, content, "publish-images"),
"Verify exact published images",
)
if strings.Contains(imageVerification, "write_mode == 'publish'") {
t.Fatalf("exact image verification is disabled in consistent mode:\n%s", imageVerification)
}
releaseVerification := workflowStepBlock(
t,
workflowJobBlock(t, content, "publish-github"),
"Verify existing GitHub Release",
)
if !strings.Contains(releaseVerification, "write_mode == 'verify'") {
t.Fatalf("consistent GitHub writer does not use verify-only mode:\n%s", releaseVerification)
}
}
func TestReleaseWorkflowAlwaysReconcilesWriterAndPostPublishResults(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
job := workflowJobBlock(t, content, "reconcile-publication")
if !strings.Contains(job, "if: ${{ always() }}") {
t.Fatalf("publication reconciliation does not always run:\n%s", job)
}
for _, dependency := range []string{
"publication-preflight",
"publish-images",
"publish-github",
"post-publish-native-smoke",
"post-publish-verify",
} {
if !strings.Contains(job, dependency) {
t.Fatalf("publication reconciliation does not need %s:\n%s", dependency, job)
}
}
for _, result := range []string{
"needs.publication-preflight.result",
"needs.publish-images.result",
"needs.publish-github.result",
"needs.post-publish-native-smoke.result",
"needs.post-publish-verify.result",
} {
if !strings.Contains(job, result) {
t.Fatalf("publication reconciliation does not summarize %s:\n%s", result, job)
}
}
}
func TestReleaseWorkflowReconciliationIsReadOnly(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
job := workflowJobBlock(t, content, "reconcile-publication")
for _, required := range []string{
"contents: read",
"packages: read",
"DOCKERHUB_READ_TOKEN",
"manual recovery",
"gh release view",
".github/scripts/release-image-digest.sh",
} {
if !strings.Contains(job, required) {
t.Fatalf("publication reconciliation does not contain %q:\n%s", required, job)
}
}
lower := strings.ToLower(job)
for _, forbidden := range []string{
"contents: write",
"packages: write",
"softprops/action-gh-release",
"docker/build-push-action",
"buildx imagetools create",
"gh release delete",
"gh release create",
"gh release upload",
"docker push",
} {
if strings.Contains(lower, forbidden) {
t.Fatalf("publication reconciliation contains write/delete operation %q:\n%s", forbidden, job)
}
}
}
func TestReleaseWorkflowPublishesStable2xTagsWithoutLatest(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
imageJob := workflowJobBlock(t, content, "publish-images")
for _, required := range []string{
dockerMetadataActionRef,
dockerLoginActionRef,
qemuActionRef,
buildxActionRef,
dockerBuildActionRef,
"linux/amd64,linux/arm64",
`value=${{ needs.validate-tag.outputs.image_exact }}`,
"docker buildx imagetools create",
`needs.validate-tag.outputs.image_minor`,
`needs.validate-tag.outputs.image_major`,
} {
if !strings.Contains(imageJob, required) {
t.Fatalf("image publication job does not contain %q:\n%s", required, imageJob)
}
}
if strings.Contains(strings.ToLower(imageJob), "latest") {
t.Fatalf("image publication job contains latest:\n%s", imageJob)
}
}
func TestReleaseWorkflowIncludesCompleteS5Notes(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
releaseJob := workflowJobBlock(t, content, "publish-github")
for _, required := range []string{
"public operations baseline",
"1.x cutover and rollback",
"https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/README.md#public-operations-baseline",
"five raw binaries",
"SHA256SUMS",
"Stop cleanly",
"`-wal`/`-shm`",
"recovery set",
"missing",
"partial",
"unpriced",
"compatible upstream",
"encryption key rotation",
"2026-07-27",
"https://developers.openai.com/api/docs/pricing",
"https://platform.claude.com/docs/en/about-claude/pricing",
"https://ai.google.dev/gemini-api/docs/pricing",
"unified data/control dual-plane architecture",
"Groups",
"AccessKeys",
"model discovery",
} {
if !strings.Contains(releaseJob, required) {
t.Fatalf("release notes do not contain %q:\n%s", required, releaseJob)
}
}
if strings.Contains(releaseJob, "app.notion.com") {
t.Fatalf("public release notes depend on a private Notion page:\n%s", releaseJob)
}
}
func TestReleaseWorkflowVerifiesDownloadedNativeChecksumsAndGeneratedKeys(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
nativeJob := workflowJobBlock(t, content, "native-artifact-smoke")
for _, scriptPath := range []string{
".github/scripts/release-native-smoke.sh",
".github/scripts/release-native-smoke.ps1",
} {
if !strings.Contains(nativeJob, scriptPath) {
t.Fatalf("native smoke does not invoke %s:\n%s", scriptPath, nativeJob)
}
}
nativeShellImplementation := readRepositoryFile(t, ".github/scripts/release-native-smoke.sh")
nativePowerShellImplementation := readRepositoryFile(t, ".github/scripts/release-native-smoke.ps1")
nativeImplementation := nativeJob + nativeShellImplementation + nativePowerShellImplementation
for _, required := range []string{
"name: release-assets",
"SHA256SUMS",
"sha256sum",
"shasum -a 256",
"Get-FileHash",
"auth.key",
"encryption.key",
"AreAccessRulesProtected",
"WindowsIdentity]::GetCurrent().User",
"CreateProcessW",
"CREATE_NEW_PROCESS_GROUP",
"GenerateConsoleCtrlEvent",
"CTRL_BREAK_EVENT",
"GetConsoleCP",
"AllocConsole",
"ERROR_ACCESS_DENIED",
"$process.WaitForExit(15000)",
"$process.ExitCode -ne 0",
"if (-not $process.HasExited)",
} {
if !strings.Contains(nativeImplementation, required) {
t.Fatalf("native smoke does not contain %q", required)
}
}
for name, implementation := range map[string]string{
"POSIX": nativeShellImplementation,
"Windows": nativePowerShellImplementation,
} {
if !strings.Contains(implementation, "Idempotency-Key") {
t.Fatalf("%s native smoke does not send Idempotency-Key", name)
}
if strings.Contains(implementation, "00000000-0000-4000-8000-") {
t.Fatalf("%s native smoke reuses a fixed Idempotency-Key", name)
}
}
if !strings.Contains(nativeShellImplementation, "uuid.uuid4()") {
t.Fatal("POSIX native smoke does not generate a UUIDv4 for its write")
}
if !strings.Contains(nativePowerShellImplementation, "[guid]::NewGuid()") {
t.Fatal("Windows native smoke does not generate a GUID for its write")
}
if strings.Contains(nativeImplementation, "AUTH_KEY=release-native-smoke") ||
strings.Contains(nativeImplementation, `$env:AUTH_KEY = "release-native-smoke"`) {
t.Fatal("native smoke bypasses generated auth.key with an explicit AUTH_KEY")
}
if strings.Contains(nativeImplementation, "$process = Start-Process") {
t.Fatal("Windows native smoke uses Start-Process without a new console process group")
}
if strings.Contains(nativeImplementation, "CREATE_NEW_CONSOLE") {
t.Fatal("Windows native smoke gives the child a separate console that cannot receive the targeted CTRL_BREAK")
}
}
func TestReleaseWorkflowRunsCompleteLocalDockerSmoke(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
dockerJob := workflowJobBlock(t, content, "docker-smoke")
if !strings.Contains(dockerJob, ".github/scripts/release-docker-smoke.sh") {
t.Fatalf("Docker smoke job does not invoke the focused script:\n%s", dockerJob)
}
script := readRepositoryFile(t, ".github/scripts/release-docker-smoke.sh")
for _, required := range []string{
"RELEASE_SMOKE_TRIVY_IMAGE",
"--severity CRITICAL,HIGH",
"--ignore-unfixed",
"--exit-code 1",
"10001:10001",
"/app/data",
"auth.key",
"encryption.key",
"gpt-load.db",
"/api/usage",
"/api/model-prices",
"/api/groups",
"/api/access-keys",
"value.data.items.some(item=>item.name===\"Task13 Release Smoke Access\")",
"/v1/chat/completions",
"finish_reason",
"prompt_tokens",
"completion_tokens",
"docker stop --time 15",
"container-first.log",
"container-second.log",
"secret_free=true",
"Idempotency-Key",
} {
if !strings.Contains(script, required) {
t.Fatalf("release Docker smoke does not contain %q", required)
}
}
if strings.Contains(script, "00000000-0000-4000-8000-") {
t.Fatal("release Docker smoke reuses fixed Idempotency-Keys")
}
if strings.Count(script, "uuid.uuid4()") < 2 {
t.Fatal("release Docker smoke does not generate independent UUIDv4 keys for its writes")
}
}
func TestReleaseDockerSmokeDefersOwnedResourceCleanupUntilAfterConflictChecks(t *testing.T) {
script := readRepositoryFile(t, ".github/scripts/release-docker-smoke.sh")
tempTrapIndex := strings.Index(script, "trap cleanup_temp EXIT")
containerCheckIndex := strings.Index(script, `for target in "${container}" "${probe}"; do`)
conflictExitIndex := strings.Index(script, "task image or volume already exists")
fullTrapIndex := strings.Index(script, "trap cleanup EXIT")
workStartIndex := strings.Index(script, `cat >"${task_tmp}/fake_upstream.py"`)
preflightExitIndex := -1
if workStartIndex >= 0 {
preflightExitIndex = strings.LastIndex(script[:workStartIndex], "exit 1")
}
for name, index := range map[string]int{
"temporary cleanup trap": tempTrapIndex,
"container conflict check": containerCheckIndex,
"image or volume conflict exit": conflictExitIndex,
"completed conflict exit": preflightExitIndex,
"owned-resource cleanup trap": fullTrapIndex,
"owned-resource work": workStartIndex,
} {
if index < 0 {
t.Fatalf("release Docker smoke is missing %s", name)
}
}
if !(tempTrapIndex < containerCheckIndex &&
containerCheckIndex < conflictExitIndex &&
conflictExitIndex < preflightExitIndex &&
preflightExitIndex < fullTrapIndex &&
fullTrapIndex < workStartIndex) {
t.Fatalf(
"cleanup ownership order is unsafe: temp=%d container=%d conflict=%d exit=%d full=%d work=%d",
tempTrapIndex,
containerCheckIndex,
conflictExitIndex,
preflightExitIndex,
fullTrapIndex,
workStartIndex,
)
}
}
func TestReleaseWorkflowPostPublishVerifiesAliasesAndExactDigests(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
job := workflowJobBlock(t, content, "post-publish-verify")
for _, required := range []string{
"packages: read",
dockerLoginActionRef,
"registry: ghcr.io",
"image_minor",
"image_major",
"exact_digest",
"alias_digest",
"ghcr.io/tbphp/gpt-load",
"tbphp/gpt-load",
} {
if !strings.Contains(job, required) {
t.Fatalf("post-publish verification does not contain %q:\n%s", required, job)
}
}
}
func TestReleaseWorkflowPostPublishDownloadsExactAssetsAndRunsFiveNativeSmokes(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
inventoryJob := workflowJobBlock(t, content, "post-publish-verify")
for _, required := range []string{
"gh release download",
"public-release",
"SHA256SUMS",
"sha256sum --check",
"asset_count",
`test "${asset_count}" = "10"`,
} {
if !strings.Contains(inventoryJob, required) {
t.Fatalf("post-publish asset inventory does not contain %q:\n%s", required, inventoryJob)
}
}
nativeJob := workflowJobBlock(t, content, "post-publish-native-smoke")
for _, required := range []string{
"publish-github",
"publish-images",
"ubuntu-24.04",
"ubuntu-24.04-arm",
"macos-15-intel",
"macos-15",
"windows-2025",
"gpt-load-linux-amd64",
"gpt-load-linux-arm64",
"gpt-load-macos-amd64",
"gpt-load-macos-arm64",
"gpt-load-windows-amd64.exe",
"gh release download",
".github/scripts/release-native-smoke.sh",
".github/scripts/release-native-smoke.ps1",
} {
if !strings.Contains(nativeJob, required) {
t.Fatalf("post-publish native smoke does not contain %q:\n%s", required, nativeJob)
}
}
}
func TestReleaseWorkflowRunsBothPublishedImagesAndPreservesLatest(t *testing.T) {
content := readRepositoryFile(t, ".github/workflows/release.yml")
snapshotJob := workflowJobBlock(t, content, "publication-preflight")
for _, required := range []string{
"ghcr_latest_digest",
"dockerhub_latest_digest",
"ghcr.io/tbphp/gpt-load:latest",
"tbphp/gpt-load:latest",
".github/scripts/release-image-digest.sh",
} {
if !strings.Contains(snapshotJob, required) {
t.Fatalf("latest digest snapshot does not contain %q:\n%s", required, snapshotJob)
}
}
imagePublication := workflowJobBlock(t, content, "publish-images")
if !strings.Contains(imagePublication, "publication-preflight") {
t.Fatal("image publication is not ordered after the latest digest snapshot")
}
postPublish := workflowJobBlock(t, content, "post-publish-verify")
for _, required := range []string{
"publication-preflight",
"RELEASE_SMOKE_SOURCE_IMAGE",
`ghcr.io/tbphp/gpt-load:${{ needs.validate-tag.outputs.image_exact }}`,
`tbphp/gpt-load:${{ needs.validate-tag.outputs.image_exact }}`,
".github/scripts/release-docker-smoke.sh",
".github/scripts/release-image-digest.sh",
"ghcr_latest_digest",
"dockerhub_latest_digest",
} {
if !strings.Contains(postPublish, required) {
t.Fatalf("published image runtime verification does not contain %q:\n%s", required, postPublish)
}
}
for name, block := range map[string]string{
"publication-preflight": snapshotJob,
"post-publish-verify": postPublish,
} {
for _, required := range []string{
"Log in to Docker Hub",
"username: ${{ secrets.DOCKERHUB_USERNAME }}",
"password: ${{ secrets.DOCKERHUB_READ_TOKEN }}",
} {
if !strings.Contains(block, required) {
t.Fatalf("%s does not contain authenticated Docker Hub read %q", name, required)
}
}
if strings.Contains(block, "password: ${{ secrets.DOCKERHUB_TOKEN }}") {
t.Fatalf("%s exposes the Docker Hub write token to a read-only job", name)
}
}
imageReadLogin := workflowStepBlock(
t,
imagePublication,
"Log in to Docker Hub for exact verification",
)
for _, required := range []string{
"write_mode == 'verify'",
"password: ${{ secrets.DOCKERHUB_READ_TOKEN }}",
} {
if !strings.Contains(imageReadLogin, required) {
t.Fatalf("consistent image verification login does not contain %q", required)
}
}
if strings.Contains(imageReadLogin, "DOCKERHUB_TOKEN }}") {
t.Fatal("consistent image verification receives the Docker Hub write token")
}
imageWriteLogin := workflowStepBlock(
t,
imagePublication,
"Log in to Docker Hub for publication",
)
for _, required := range []string{
"write_mode == 'publish'",
"password: ${{ secrets.DOCKERHUB_TOKEN }}",
} {
if !strings.Contains(imageWriteLogin, required) {
t.Fatalf("fresh image publication login does not contain %q", required)
}
}
if strings.Contains(imageWriteLogin, "DOCKERHUB_READ_TOKEN") {
t.Fatal("fresh image publication unexpectedly uses the Docker Hub read-only token")
}
if !strings.Contains(
postPublish,
`test "${latest_digest}" != "${exact_digest}"`,
) {
t.Fatal("post-publication verification does not reject latest pointing at the exact 2.x image")
}
}
func TestReleaseImageDigestFailsClosedOnOperationalInspectionErrors(t *testing.T) {
for _, message := range []string{"rate limit exceeded", "docker: command not found"} {
t.Run(message, func(t *testing.T) {
script := filepath.Join("..", "..", ".github", "scripts", "release-image-digest.sh")
fakeBin := t.TempDir()
fakeDocker := filepath.Join(fakeBin, "docker")
if err := os.WriteFile(
fakeDocker,
[]byte("#!/usr/bin/env sh\nprintf '"+message+"\\n' >&2\nexit 1\n"),
0o700,
); err != nil {
t.Fatalf("write fake docker: %v", err)
}
command := exec.Command("bash", script, "example.test/gpt-load:latest")
command.Env = append(os.Environ(), "PATH="+fakeBin+":"+os.Getenv("PATH"))
output, err := command.CombinedOutput()
if err == nil {
t.Fatalf("operational inspect failure returned success: %s", output)
}
if !strings.Contains(string(output), message) {
t.Fatalf("operational inspect failure output = %q", output)
}
})
}
}
func TestReleaseImageDigestReturnsAbsentOnlyForMissingManifest(t *testing.T) {
script := filepath.Join("..", "..", ".github", "scripts", "release-image-digest.sh")
fakeBin := t.TempDir()
fakeDocker := filepath.Join(fakeBin, "docker")
if err := os.WriteFile(
fakeDocker,
[]byte("#!/usr/bin/env sh\nprintf 'manifest unknown\\n' >&2\nexit 1\n"),
0o700,
); err != nil {
t.Fatalf("write fake docker: %v", err)
}
command := exec.Command("bash", script, "example.test/gpt-load:latest")
command.Env = append(os.Environ(), "PATH="+fakeBin+":"+os.Getenv("PATH"))
output, err := command.CombinedOutput()
if err != nil {
t.Fatalf("missing manifest returned error: %v\n%s", err, output)
}
if strings.TrimSpace(string(output)) != "absent" {
t.Fatalf("missing manifest output = %q, want absent", output)
}
}
func TestReleaseDockerSmokeCanUsePublishedSourceWithoutDeletingIt(t *testing.T) {
script := readRepositoryFile(t, ".github/scripts/release-docker-smoke.sh")
for _, required := range []string{
"RELEASE_SMOKE_SOURCE_IMAGE",
`docker pull --platform "${platform}" "${source_image}"`,
`docker image tag "${source_image}" "${image}"`,
`docker image rm "${image}"`,
`model_price_list_path="/api/model-prices?usage=in_use&status=all&page=1&page_size=100"`,
`api_write PUT "/api/model-prices/${model_price_id}"`,
`item.channel_id==="openai_compatible"&&item.model_id===modelID`,
`item.model_id===modelID`,
`!Number.isSafeInteger(matches[0].id)||matches[0].id<=0`,
`api_get "${model_price_list_path}" >"${task_tmp}/prices-second.json"`,
`matches[0].id!==priceID`,
`matches[0].method!=="user_set"||matches[0].pricing_status!=="configured"`,
`persisted.input!=="1"||persisted.output!=="2"`,
`persisted.cache_read!=="3"||persisted.cache_write!=="4"`,
} {
if !strings.Contains(script, required) {
t.Fatalf("release Docker smoke source-image mode does not contain %q", required)
}
}
for _, legacy := range []string{
"prices.data.overrides",
`"pattern":"task13-release-model"`,
`"cache_write_5m"`,
`"cache_write_1h"`,
} {
if strings.Contains(script, legacy) {
t.Fatalf("release Docker smoke retains legacy model-price contract %q", legacy)
}
}
if strings.Contains(script, `docker image rm "${source_image}"`) {
t.Fatal("release Docker smoke deletes the externally owned source image")
}
}
func TestReleaseWorkflowRemovesObsoletePublishers(t *testing.T) {
for _, name := range []string{
".github/workflows/docker-build.yml",
".github/workflows/release-linux.yml",
".github/workflows/release-macos.yml",
".github/workflows/release-windows.yml",
} {
if _, err := os.Stat(filepath.Join("..", "..", name)); !os.IsNotExist(err) {
t.Fatalf("obsolete publisher still exists: %s", name)
}
}
}
func TestReadmesDoNotExposeInternalReleaseTaskNames(t *testing.T) {
for _, name := range []string{"README.md", "README_CN.md", "README_JP.md"} {
content := readRepositoryFile(t, name)
if strings.Contains(content, "T18") {
t.Fatalf("%s exposes the completed internal T18 task name", name)
}
}
}
func TestDockerfileCopiesWebInstallPolicyBeforeInstalling(t *testing.T) {
content := readRepositoryFile(t, "Dockerfile")
copyInputs := "COPY web/package.json web/pnpm-lock.yaml web/pnpm-workspace.yaml ./web/"
install := "RUN pnpm --dir web install --frozen-lockfile"
copyIndex := strings.Index(content, copyInputs)
if copyIndex < 0 {
t.Fatalf("Dockerfile does not copy the complete web install policy")
}
installIndex := strings.Index(content, install)
if installIndex < 0 {
t.Fatalf("Dockerfile does not install frozen web dependencies")
}
if copyIndex >= installIndex {
t.Fatal("Dockerfile copies the web install policy after installing dependencies")
}
}
func TestDockerfilePinsBuildAndRuntimeImagesByVersionAndDigest(t *testing.T) {
content := readRepositoryFile(t, "Dockerfile")
for _, required := range []string{
"node:24.18.0-alpine3.24@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd",
"pnpm@11.17.0",
"golang:1.26.5-alpine3.24@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2",
"alpine:3.24.1@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b",
} {
if !strings.Contains(content, required) {
t.Errorf("Dockerfile does not contain %q", required)
}
}
}
func readRepositoryFile(t *testing.T, name string) string {
t.Helper()
content, err := os.ReadFile(filepath.Join("..", "..", name))
if err != nil {
t.Fatalf("read %s: %v", name, err)
}
return string(content)
}
func workflowTopLevelBlock(t *testing.T, content, key string) string {
t.Helper()
lines := strings.Split(content, "\n")
start := -1
for index, line := range lines {
if line == key+":" {
start = index
break
}
}
if start < 0 {
t.Fatalf("workflow does not contain top-level %s", key)
}
end := len(lines)
for index := start + 1; index < len(lines); index++ {
if lines[index] != "" && !strings.HasPrefix(lines[index], " ") {
end = index
break
}
}
return strings.Join(lines[start:end], "\n")
}
func workflowJobBlock(t *testing.T, content, name string) string {
t.Helper()
lines := strings.Split(content, "\n")
start := -1
for index, line := range lines {
if line == " "+name+":" {
start = index
break
}
}
if start < 0 {
t.Fatalf("workflow does not contain job %s", name)
}
end := len(lines)
for index := start + 1; index < len(lines); index++ {
line := lines[index]
if strings.HasPrefix(line, " ") && !strings.HasPrefix(line, " ") {
end = index
break
}
}
return strings.Join(lines[start:end], "\n")
}
func workflowStepBlock(t *testing.T, job, name string) string {
t.Helper()
lines := strings.Split(job, "\n")
start := -1
for index, line := range lines {
if line == " - name: "+name {
start = index
break
}
}
if start < 0 {
t.Fatalf("workflow job does not contain step %s", name)
}
end := len(lines)
for index := start + 1; index < len(lines); index++ {
if strings.HasPrefix(lines[index], " - name: ") {
end = index
break
}
}
return strings.Join(lines[start:end], "\n")
}
func assertWorkflowGateStep(t *testing.T, job, name, wantRun string) {
t.Helper()
step := strings.TrimSuffix(workflowStepBlock(t, job, name), "\n")
want := " - name: " + name + "\n run: " + wantRun
if step != want {
t.Fatalf("workflow gate %s block does not match strict allowlist:\ngot:\n%s\nwant:\n%s", name, step, want)
}
}
func workflowGoFormattingScript(t *testing.T, content, job string) string {
t.Helper()
const marker = "go-format-check"
startMarker := "# " + marker + ":start"
endMarker := "# " + marker + ":end"
jobBlock := workflowJobBlock(t, content, job)
step := workflowStepBlock(t, jobBlock, "Check Go formatting")
for scope, block := range map[string]string{
"formatting step": step,
"workflow": content,
} {
if startCount, endCount := strings.Count(block, startMarker), strings.Count(block, endMarker); startCount != 1 || endCount != 1 {
t.Fatalf("%s contains format markers start=%d end=%d, want exactly one pair", scope, startCount, endCount)
}
}
want := strings.Join([]string{
" - name: Check Go formatting",
" run: |",
" # go-format-check:start",
` formatted_files="$(gofmt -l .)"`,
` test -z "${formatted_files}"`,
" # go-format-check:end",
}, "\n")
if got := strings.TrimSuffix(step, "\n"); got != want {
t.Fatalf("workflow %s formatting step does not match strict allowlist:\ngot:\n%s\nwant:\n%s", job, got, want)
}
return workflowMarkedScript(t, step, marker)
}
func workflowMarkedScript(t *testing.T, content, marker string) string {
t.Helper()
startMarker := "# " + marker + ":start"
endMarker := "# " + marker + ":end"
start := strings.Index(content, startMarker)
end := strings.Index(content, endMarker)
if start < 0 || end <= start {
t.Fatalf("workflow does not contain marked script %s", marker)
}
body := content[start+len(startMarker) : end]
lines := strings.Split(body, "\n")
for index, line := range lines {
lines[index] = strings.TrimPrefix(line, " ")
}
return strings.TrimSpace(strings.Join(lines, "\n")) + "\n"
}