Kelly Norton 11 kuukautta sitten
vanhempi
sitoutus
2812f3e95f
2 muutettua tiedostoa jossa 165 lisäystä ja 7 poistoa
  1. 11 7
      Makefile
  2. 154 0
      cmd/publish/main.go

+ 11 - 7
Makefile

@@ -35,10 +35,14 @@ clean:
 bin/buildimg:
 	GOBIN="$(CURDIR)/bin" go install github.com/kellegous/buildimg@latest
 
-publish: bin/buildimg
-	bin/buildimg --tag=$(shell git rev-parse --short $(SHA)) \
-		--target=linux/arm64 --target=linux/amd64 \
-		--build-arg=SHA=${SHA} kellegous/go
-	bin/buildimg --tag=latest \
-		--target=linux/arm64 --target=linux/amd64 \
-		--build-arg=SHA=${SHA} kellegous/go
+bin/publish: cmd/publish/main.go
+	go build -o $@ ./cmd/publish
+
+publish: bin/publish
+	bin/publish \
+		--tag=latest \
+		--tag=$(shell git rev-parse --short $(SHA))
+		--platform=linux/arm64 \
+		--platform=linux/amd64 \
+		--build-arg=SHA=${SHA} \
+		--image=kellegous/go

+ 154 - 0
cmd/publish/main.go

@@ -0,0 +1,154 @@
+package main
+
+import (
+	"context"
+	"crypto/rand"
+	"encoding/hex"
+	"fmt"
+	"log"
+	"os"
+	"os/exec"
+	"strings"
+
+	"github.com/spf13/pflag"
+)
+
+type Builder struct {
+	Name string
+}
+
+func (b *Builder) Shutdown(ctx context.Context) error {
+	cmd := exec.CommandContext(
+		ctx,
+		"docker",
+		"buildx",
+		"rm",
+		b.Name)
+
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+
+	return cmd.Run()
+}
+
+func StartBuilder(ctx context.Context) (*Builder, error) {
+	var key [8]byte
+	if _, err := rand.Read(key[:]); err != nil {
+		return nil, err
+	}
+	name := fmt.Sprintf("go-build-%s", hex.EncodeToString(key[:]))
+
+	cmd := exec.CommandContext(
+		ctx,
+		"docker",
+		"buildx",
+		"create",
+		"--name",
+		name)
+
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+
+	if err := cmd.Run(); err != nil {
+		return nil, err
+	}
+
+	return &Builder{Name: name}, nil
+}
+
+func (b *Builder) Build(
+	ctx context.Context,
+	image string,
+	tags []string,
+	platforms []string,
+	buildArgs []string,
+) error {
+	args := []string{
+		"buildx",
+		"build",
+		"--builder",
+		b.Name,
+		"--platform",
+		strings.Join(platforms, ","),
+	}
+
+	for _, arg := range buildArgs {
+		args = append(args, "--build-arg", arg)
+	}
+
+	for _, tag := range tags {
+		args = append(args,
+			"-t",
+			fmt.Sprintf("%s:%s", image, tag))
+	}
+
+	args = append(args, "--push", ".")
+
+	cmd := exec.CommandContext(
+		ctx,
+		"docker",
+		args...)
+
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+
+	return cmd.Run()
+}
+
+func run(
+	ctx context.Context,
+	image string,
+	tags []string,
+	platforms []string,
+	buildArgs []string,
+) error {
+	builder, err := StartBuilder(ctx)
+	if err != nil {
+		return err
+	}
+	defer builder.Shutdown(ctx)
+
+	if err := builder.Build(ctx, image, tags, platforms, buildArgs); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func main() {
+	var tags []string
+	var platforms []string
+	var buildArgs []string
+	var image string
+
+	pflag.StringSliceVar(
+		&tags,
+		"tag",
+		[]string{"latest"},
+		"tags to apply to the image")
+	pflag.StringSliceVar(
+		&platforms,
+		"platform",
+		[]string{"linux/amd64", "linux/arm64"},
+		"platforms to build for")
+	pflag.StringSliceVar(
+		&buildArgs,
+		"build-arg",
+		[]string{},
+		"build arguments to pass to the image")
+	pflag.StringVar(
+		&image,
+		"image",
+		"kellegous/go",
+		"the name of the image to build")
+	pflag.Parse()
+
+	if err := run(
+		context.Background(),
+		image, tags,
+		platforms,
+		buildArgs,
+	); err != nil {
+		log.Panic(err)
+	}
+}