From 3b3b4e6fce70e0779e9b77d831860711f2e1f402 Mon Sep 17 00:00:00 2001 From: Zack Hubert Date: Wed, 11 Mar 2026 08:57:02 -0700 Subject: [PATCH 1/2] fix: add v prefix to version in container build download URL GoReleaser sets main.version without the "v" prefix (e.g. "1.2.0"), but GitHub release tags include it (e.g. "v1.2.0"). This caused container image builds to fail with "tar: invalid magic" because curl was silently downloading a 404 page instead of the tarball. Co-Authored-By: Claude Opus 4.6 --- internal/container/build.go | 8 ++++++-- internal/container/build_test.go | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/container/build.go b/internal/container/build.go index d6eb8dd..fc189f0 100644 --- a/internal/container/build.go +++ b/internal/container/build.go @@ -235,8 +235,12 @@ func pluralDownloadBlock(version, arch string) string { b.WriteString(" mv /tmp/plural /usr/local/bin/plural && \\\n") b.WriteString(" chmod +x /usr/local/bin/plural\n\n") } else { - // Exact version download - fmt.Fprintf(&b, "RUN curl -sfL \"https://github.com/zhubert/plural/releases/download/%s/plural_Linux_%s.tar.gz\" | tar -xz -C /tmp plural && \\\n", version, arch) + // Exact version download — ensure "v" prefix for GitHub release tag + tag := version + if !strings.HasPrefix(tag, "v") { + tag = "v" + tag + } + fmt.Fprintf(&b, "RUN curl -sfL \"https://github.com/zhubert/plural/releases/download/%s/plural_Linux_%s.tar.gz\" | tar -xz -C /tmp plural && \\\n", tag, arch) b.WriteString(" mv /tmp/plural /usr/local/bin/plural && \\\n") b.WriteString(" chmod +x /usr/local/bin/plural\n\n") } diff --git a/internal/container/build_test.go b/internal/container/build_test.go index a84710d..e8a926e 100644 --- a/internal/container/build_test.go +++ b/internal/container/build_test.go @@ -416,6 +416,13 @@ func TestPluralDownloadBlock(t *testing.T) { t.Error("release version should not use /latest/download/") } }) + + t.Run("version without v prefix gets v added", func(t *testing.T) { + block := pluralDownloadBlock("1.2.0", "arm64") + if !strings.Contains(block, "/download/v1.2.0/") { + t.Errorf("version without v prefix should get v added, got: %s", block) + } + }) } func TestMiseInstallBlock_RubyAndPython(t *testing.T) { From 64d282343b21407466f4d80178105d9dedfe1d2e Mon Sep 17 00:00:00 2001 From: Zack Hubert Date: Wed, 11 Mar 2026 09:05:22 -0700 Subject: [PATCH 2/2] fix: download plural binary to file before extracting in container build Download to a temp file first so curl failures (e.g. 404) surface clearly instead of producing misleading tar errors like "invalid magic". Co-Authored-By: Claude Opus 4.6 --- internal/container/build.go | 17 +++++++++++------ internal/container/build_test.go | 10 ++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/internal/container/build.go b/internal/container/build.go index fc189f0..a8cb5bb 100644 --- a/internal/container/build.go +++ b/internal/container/build.go @@ -229,22 +229,27 @@ func miseInstallBlock(langs []DetectedLang) string { func pluralDownloadBlock(version, arch string) string { var b strings.Builder + var url string if version == "" || version == "dev" { // Use latest release URL pattern (no API call needed) - fmt.Fprintf(&b, "RUN curl -sfL \"https://github.com/zhubert/plural/releases/latest/download/plural_Linux_%s.tar.gz\" | tar -xz -C /tmp plural && \\\n", arch) - b.WriteString(" mv /tmp/plural /usr/local/bin/plural && \\\n") - b.WriteString(" chmod +x /usr/local/bin/plural\n\n") + url = fmt.Sprintf("https://github.com/zhubert/plural/releases/latest/download/plural_Linux_%s.tar.gz", arch) } else { // Exact version download — ensure "v" prefix for GitHub release tag tag := version if !strings.HasPrefix(tag, "v") { tag = "v" + tag } - fmt.Fprintf(&b, "RUN curl -sfL \"https://github.com/zhubert/plural/releases/download/%s/plural_Linux_%s.tar.gz\" | tar -xz -C /tmp plural && \\\n", tag, arch) - b.WriteString(" mv /tmp/plural /usr/local/bin/plural && \\\n") - b.WriteString(" chmod +x /usr/local/bin/plural\n\n") + url = fmt.Sprintf("https://github.com/zhubert/plural/releases/download/%s/plural_Linux_%s.tar.gz", tag, arch) } + // Download to file first so curl failures surface clearly instead of + // producing misleading tar errors (e.g. "invalid magic" on a 404). + fmt.Fprintf(&b, "RUN curl -sfL -o /tmp/plural.tar.gz \"%s\" && \\\n", url) + b.WriteString(" tar -xz -C /tmp plural -f /tmp/plural.tar.gz && \\\n") + b.WriteString(" rm /tmp/plural.tar.gz && \\\n") + b.WriteString(" mv /tmp/plural /usr/local/bin/plural && \\\n") + b.WriteString(" chmod +x /usr/local/bin/plural\n\n") + return b.String() } diff --git a/internal/container/build_test.go b/internal/container/build_test.go index e8a926e..e3910fb 100644 --- a/internal/container/build_test.go +++ b/internal/container/build_test.go @@ -423,6 +423,16 @@ func TestPluralDownloadBlock(t *testing.T) { t.Errorf("version without v prefix should get v added, got: %s", block) } }) + + t.Run("downloads to file before extracting", func(t *testing.T) { + block := pluralDownloadBlock("v1.0.0", "arm64") + if !strings.Contains(block, "-o /tmp/plural.tar.gz") { + t.Error("should download to file first") + } + if !strings.Contains(block, "-f /tmp/plural.tar.gz") { + t.Error("should extract from downloaded file") + } + }) } func TestMiseInstallBlock_RubyAndPython(t *testing.T) {