diff options
| author | Xe Iaso <me@xeiaso.net> | 2025-03-19 09:12:21 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-19 09:12:21 -0400 |
| commit | c8252d6da6ab799195919882d8fd7087c863c723 (patch) | |
| tree | 16ced941f86d0923623e0ae5fb53e4977f1ecb2c | |
| parent | 1a13292c2deed38dac8a307ed2cae43bba355b5b (diff) | |
| parent | 1efcb882619a90ed0f9355cd8485f7aa80ebb324 (diff) | |
| download | anubis-c8252d6da6ab799195919882d8fd7087c863c723.tar.xz anubis-c8252d6da6ab799195919882d8fd7087c863c723.zip | |
Merge pull request #13 from TecharoHQ/Xe/ko
Try using ko to build images
| -rw-r--r-- | .github/workflows/docker.yml | 24 | ||||
| -rw-r--r-- | .ko.yaml | 13 | ||||
| -rw-r--r-- | Brewfile | 3 | ||||
| -rw-r--r-- | CHANGELOG.md | 3 | ||||
| -rw-r--r-- | cmd/containerbuild/.gitignore | 1 | ||||
| -rw-r--r-- | cmd/containerbuild/main.go | 133 |
6 files changed, 166 insertions, 11 deletions
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 958f9eb..5aa85db 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -8,6 +8,9 @@ on: pull_request: branches: [ "main" ] +env: + DOCKER_METADATA_SET_OUTPUT_ENV: "true" + permissions: contents: read packages: write @@ -20,6 +23,9 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-tags: true + fetch-depth: 0 - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -27,6 +33,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - uses: actions/setup-go@v5 + with: + go-version: '1.24.x' + + - uses: ko-build/setup-ko@v0.8 + - name: Log into registry uses: docker/login-action@v3 with: @@ -42,16 +54,8 @@ jobs: - name: Build and push id: build - uses: docker/build-push-action@v6 - with: - context: . - cache-to: type=gha - cache-from: type=gha - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/arm64/v8,linux/amd64 - sbom: true - push: true + run: | + go run ./cmd/containerbuild --docker-repo ghcr.io/techarohq/anubis --slog-level debug - name: Generate artifact attestation uses: actions/attest-build-provenance@v2 diff --git a/.ko.yaml b/.ko.yaml new file mode 100644 index 0000000..35c1fa0 --- /dev/null +++ b/.ko.yaml @@ -0,0 +1,13 @@ +defaultBaseImage: cgr.dev/chainguard/static +defaultPlatforms: +- linux/arm64 +- linux/amd64 +- linux/arm/v7 + +builds: +- id: anubis + main: ./cmd/anubis + ldflags: + - -s -w + - -extldflags "-static" + - -X github.com/TecharoHQ/anubis.Version={{.Env.VERSION}} @@ -1,3 +1,4 @@ # programming languages brew "go@1.24" -brew "node"
\ No newline at end of file +brew "node" +brew "ko"
\ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d6a37f..c530507 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Images are built using ko instead of `docker buildx build` + [#13](https://github.com/TecharoHQ/anubis/pull/13) + ## 1.12.1 - Phrasing in the `<noscript>` warning was replaced from its original placeholder text to diff --git a/cmd/containerbuild/.gitignore b/cmd/containerbuild/.gitignore new file mode 100644 index 0000000..5e798fa --- /dev/null +++ b/cmd/containerbuild/.gitignore @@ -0,0 +1 @@ +images
\ No newline at end of file diff --git a/cmd/containerbuild/main.go b/cmd/containerbuild/main.go new file mode 100644 index 0000000..4eeae4c --- /dev/null +++ b/cmd/containerbuild/main.go @@ -0,0 +1,133 @@ +package main + +import ( + "flag" + "fmt" + "log" + "log/slog" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/TecharoHQ/anubis/internal" + "github.com/facebookgo/flagenv" +) + +var ( + dockerAnnotations = flag.String("docker-annotations", os.Getenv("DOCKER_METADATA_OUTPUT_ANNOTATIONS"), "Docker image annotations") + dockerLabels = flag.String("docker-labels", os.Getenv("DOCKER_METADATA_OUTPUT_LABELS"), "Docker image labels") + dockerRepo = flag.String("docker-repo", "registry.int.xeserv.us/techaro/anubis", "Docker image repository for Anubis") + dockerTags = flag.String("docker-tags", os.Getenv("DOCKER_METADATA_OUTPUT_TAGS"), "newline separated docker tags including the registry name") + slogLevel = flag.String("slog-level", "INFO", "logging level (see https://pkg.go.dev/log/slog#hdr-Levels)") +) + +func main() { + flagenv.Parse() + flag.Parse() + + internal.InitSlog(*slogLevel) + + koDockerRepo := strings.TrimRight(*dockerRepo, "/"+filepath.Base(*dockerRepo)) + version, err := run("git describe --tags --always --dirty") + + slog.Debug( + "ko env", + "KO_DOCKER_REPO", koDockerRepo, + "VERSION", version, + ) + + os.Setenv("KO_DOCKER_REPO", koDockerRepo) + os.Setenv("VERSION", version) + + setOutput("version", version) + + if *dockerTags == "" { + log.Fatal("Must set --docker-tags or DOCKER_METADATA_OUTPUT_TAGS") + } + + images, err := parseImageList(*dockerTags) + if err != nil { + log.Fatalf("can't parse images: %v", err) + } + + for _, img := range images { + if img.repository != *dockerRepo { + slog.Error( + "Something weird is going on. Wanted docker repo differs from contents of --docker-tags. Did a flag get set incorrectly?", + "wanted", *dockerRepo, + "got", img.repository, + "docker-tags", *dockerTags, + ) + os.Exit(2) + } + } + + var tags []string + for _, img := range images { + tags = append(tags, img.tag) + } + + output, err := run(fmt.Sprintf("ko build --platform=all --base-import-paths --tags=%q --image-user=1000 --image-annotation=%q --image-label=%q ./cmd/anubis | tail -n1", strings.Join(tags, ","), *dockerAnnotations, *dockerLabels)) + if err != nil { + log.Fatalf("can't run ko build, check stderr: %v", err) + } + + sp := strings.SplitN(output, "@", 2) + + setOutput("digest", sp[1]) +} + +type image struct { + repository string + tag string +} + +func newlineSep2Comma(inp string) string { + lines := strings.Split(inp, "\n") + return strings.Join(lines, ",") +} + +func parseImageList(imageList string) ([]image, error) { + images := strings.Split(imageList, "\n") + var result []image + for _, img := range images { + if img == "" { + continue + } + + // reg.xeiaso.net/techaro/anubis:latest + // repository: reg.xeiaso.net/techaro/anubis + // tag: latest + parts := strings.SplitN(img, ":", 2) + result = append(result, image{ + repository: parts[0], + tag: parts[1], + }) + } + + if len(result) == 0 { + return nil, fmt.Errorf("no images provided, bad flags??") + } + + return result, nil +} + +// run executes a command and returns the trimmed output. +func run(command string) (string, error) { + bin, err := exec.LookPath("sh") + if err != nil { + return "", err + } + cmd := exec.Command(bin, "-c", command) + cmd.Stderr = os.Stderr + out, err := cmd.Output() + if err != nil { + return "", err + } + return strings.TrimSpace(string(out)), nil +} + +func setOutput(key, val string) { + fmt.Printf("::set-output name=%s::%s\n", key, val) +} |
