From 9f7772f68a2c85ba85efc437017cbc026c1b39b3 Mon Sep 17 00:00:00 2001 From: RabbITCybErSeC Date: Thu, 21 May 2026 15:19:20 +0200 Subject: [PATCH] fix: restrict init image publish platform --- .github/workflows/images.yml | 6 ++- internal/ci/images_workflow_test.go | 75 +++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 internal/ci/images_workflow_test.go diff --git a/.github/workflows/images.yml b/.github/workflows/images.yml index de15c53..bba6b16 100644 --- a/.github/workflows/images.yml +++ b/.github/workflows/images.yml @@ -27,8 +27,12 @@ jobs: include: - image: opencode-sandbox file: Containerfile + platforms: linux/amd64,linux/arm64 - image: opencode-sandbox-init file: Containerfile.init + # Apple publishes the vminit base image only for the Apple container + # runtime platform, so this image cannot be built for linux/amd64. + platforms: linux/arm64 steps: - name: Checkout @@ -53,7 +57,7 @@ jobs: with: context: . file: ./${{ matrix.file }} - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platforms }} push: true tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ matrix.image }}:${{ github.ref_name }} diff --git a/internal/ci/images_workflow_test.go b/internal/ci/images_workflow_test.go new file mode 100644 index 0000000..934a901 --- /dev/null +++ b/internal/ci/images_workflow_test.go @@ -0,0 +1,75 @@ +package ci_test + +import ( + "os" + "path/filepath" + "runtime" + "strings" + "testing" + + "gopkg.in/yaml.v3" +) + +type imagesWorkflow struct { + Jobs map[string]imagesJob `yaml:"jobs"` +} + +type imagesJob struct { + Strategy imagesStrategy `yaml:"strategy"` +} + +type imagesStrategy struct { + Matrix imagesMatrix `yaml:"matrix"` +} + +type imagesMatrix struct { + Include []publishedImage `yaml:"include"` +} + +type publishedImage struct { + Image string `yaml:"image"` + File string `yaml:"file"` + Platforms string `yaml:"platforms"` +} + +func TestPublishImagesWorkflowUsesSupportedPlatforms(t *testing.T) { + var workflow imagesWorkflow + if err := yaml.Unmarshal(readWorkflow(t), &workflow); err != nil { + t.Fatalf("parse images workflow: %v", err) + } + + images := map[string]publishedImage{} + for _, image := range workflow.Jobs["publish"].Strategy.Matrix.Include { + images[image.Image] = image + } + + runtimeImage := images["opencode-sandbox"] + if runtimeImage.Platforms != "linux/amd64,linux/arm64" { + t.Fatalf("runtime image platforms = %q, want linux/amd64,linux/arm64", runtimeImage.Platforms) + } + + initImage := images["opencode-sandbox-init"] + if initImage.File != "Containerfile.init" { + t.Fatalf("init image file = %q, want Containerfile.init", initImage.File) + } + if strings.Contains(initImage.Platforms, "linux/amd64") { + t.Fatalf("init image platforms include unsupported linux/amd64: %q", initImage.Platforms) + } + if initImage.Platforms != "linux/arm64" { + t.Fatalf("init image platforms = %q, want linux/arm64", initImage.Platforms) + } +} + +func readWorkflow(t *testing.T) []byte { + t.Helper() + _, file, _, ok := runtime.Caller(0) + if !ok { + t.Fatal("resolve test path") + } + root := filepath.Clean(filepath.Join(filepath.Dir(file), "..", "..")) + data, err := os.ReadFile(filepath.Join(root, ".github", "workflows", "images.yml")) + if err != nil { + t.Fatal(err) + } + return data +}