Skip to content

feat: switch container builds from Docker to ko#280

Merged
intel352 merged 2 commits intomainfrom
feat/ko-build
Mar 8, 2026
Merged

feat: switch container builds from Docker to ko#280
intel352 merged 2 commits intomainfrom
feat/ko-build

Conversation

@intel352
Copy link
Contributor

@intel352 intel352 commented Mar 8, 2026

Summary

  • Replace multi-stage Dockerfile with ko for production container builds
  • Produces smaller distroless images (~2MB base vs ~7MB alpine) with built-in SBOM generation
  • Native Go cross-compilation eliminates QEMU and Docker Buildx in CI (faster builds)
  • Dockerfile renamed to Dockerfile.legacy for local docker-compose development

Changes

  • .ko.yaml — ko config using Chainguard static base image, CGO_ENABLED=0, stripped binary
  • Dockerfile.legacy — renamed from Dockerfile, still works for docker-compose
  • .github/workflows/release.yml — docker job now uses ko-build/setup-ko@v0.9 + ko build with semver tags and SPDX SBOM
  • .github/workflows/pre-release.yml — docker-snapshot job uses ko for snapshot/sha tags
  • deploy/docker-compose/docker-compose.yml — references Dockerfile.legacy
  • Makefile — added ko-build target for local builds

What doesn't change

  • Helm chart (image repo stays ghcr.io/gocodealong/workflow)
  • Binary releases (Go cross-compile, not container-related)
  • wfctl templates (user-facing scaffolds keep Dockerfiles)
  • Other project Dockerfiles (workflow-cloud, ratchet, buymywishlist have non-Go stages)

Test plan

  • Local ko build ./cmd/server produces working image
  • Image is distroless (no shell — docker run --entrypoint sh fails as expected)
  • CI workflows pass on this branch
  • docker-compose still builds with Dockerfile.legacy

🤖 Generated with Claude Code

Replace the multi-stage Dockerfile with ko for production container
builds. ko produces smaller distroless images with built-in SBOM
generation and native multi-platform support, eliminating the need
for QEMU and Docker Buildx in CI.

- Add .ko.yaml with Chainguard static base image
- Rename Dockerfile to Dockerfile.legacy for local docker-compose dev
- Update release.yml and pre-release.yml CI workflows to use ko
- Add ko-build Makefile target for local builds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 8, 2026 16:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the project’s production container build pipeline from a multi-stage Dockerfile to ko, while keeping a legacy Dockerfile for local docker-compose development.

Changes:

  • Add .ko.yaml to define ko build settings (static Chainguard base, CGO_ENABLED=0, stripped binary).
  • Update GitHub Actions release/snapshot workflows to build and push images via ko (including SPDX SBOM generation).
  • Keep local compose working by referencing Dockerfile.legacy and add a make ko-build helper target.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
deploy/docker-compose/docker-compose.yml Switch compose build to Dockerfile.legacy for local dev.
Makefile Add ko-build target for local image builds.
Dockerfile.legacy Rebrand Dockerfile as legacy/local-dev oriented.
.ko.yaml Introduce ko build configuration for the server image.
.github/workflows/release.yml Replace Docker Buildx flow with ko build + SBOM for releases.
.github/workflows/pre-release.yml Replace snapshot Docker build with ko build + SBOM.

Comment on lines +132 to +136
ko build ./cmd/server \
--platform=linux/amd64,linux/arm64 \
--tags="${TAG_NAME},${VERSION},${MAJOR_MINOR},sha-${SHA_SHORT}" \
--sbom=spdx \
--image-refs=/tmp/image-refs.txt
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ko build ./cmd/server invocation likely publishes the image under a path-suffixed repository (e.g. ${KO_DOCKER_REPO}/cmd/server or ${KO_DOCKER_REPO}/server, depending on ko config), which would contradict the stated goal of keeping the Helm image repository as ghcr.io/.../workflow. Adjust the ko invocation/config so the pushed image name remains the existing repo (no extra suffix).

Copilot uses AI. Check for mistakes.
Comment on lines +168 to +171
ko build ./cmd/server \
--platform=linux/amd64,linux/arm64 \
--tags="snapshot,main-sha-${SHA_SHORT}" \
--sbom=spdx
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern as release.yml: ko build ./cmd/server will typically publish to a path-suffixed image name under ${KO_DOCKER_REPO}. If the intent is to keep publishing ghcr.io/.../workflow (as referenced by the Helm chart), ensure the ko config/flags produce the existing image name without an extra suffix.

Copilot uses AI. Check for mistakes.
Comment on lines +82 to +85
# Build container image with ko (requires ko: brew install ko)
ko-build:
KO_DOCKER_REPO=ko.local ko build ./cmd/server --platform=linux/$(shell go env GOARCH)

Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ko-build runs ko build ./cmd/server, which typically results in an image name that includes a package/id suffix under KO_DOCKER_REPO (e.g. ko.local/cmd/server). If this target is meant to mirror the production image name (ko.local/workflow-server or similar), consider adjusting the ko flags/config so the local image name matches expectations.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

github-actions bot commented Mar 8, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:243: parsing iteration count: invalid syntax
baseline-bench.txt:310651: parsing iteration count: invalid syntax
baseline-bench.txt:618086: parsing iteration count: invalid syntax
baseline-bench.txt:903672: parsing iteration count: invalid syntax
baseline-bench.txt:1194913: parsing iteration count: invalid syntax
baseline-bench.txt:1505783: parsing iteration count: invalid syntax
benchmark-results.txt:243: parsing iteration count: invalid syntax
benchmark-results.txt:306151: parsing iteration count: invalid syntax
benchmark-results.txt:602117: parsing iteration count: invalid syntax
benchmark-results.txt:873360: parsing iteration count: invalid syntax
benchmark-results.txt:1156513: parsing iteration count: invalid syntax
benchmark-results.txt:1436009: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ baseline-bench.txt │       benchmark-results.txt        │
                            │       sec/op       │    sec/op     vs base              │
InterpreterCreation-4               6.664m ± 55%   6.921m ± 55%       ~ (p=0.485 n=6)
ComponentLoad-4                     3.463m ±  1%   3.554m ±  1%  +2.62% (p=0.002 n=6)
ComponentExecute-4                  1.987µ ±  1%   2.016µ ±  3%  +1.46% (p=0.015 n=6)
PoolContention/workers-1-4          1.098µ ±  2%   1.105µ ±  2%       ~ (p=0.310 n=6)
PoolContention/workers-2-4          1.093µ ±  2%   1.096µ ±  1%       ~ (p=0.416 n=6)
PoolContention/workers-4-4          1.088µ ±  1%   1.095µ ±  5%  +0.74% (p=0.037 n=6)
PoolContention/workers-8-4          1.089µ ±  3%   1.114µ ±  1%  +2.34% (p=0.022 n=6)
PoolContention/workers-16-4         1.091µ ±  6%   1.114µ ±  2%       ~ (p=0.065 n=6)
ComponentLifecycle-4                3.471m ±  1%   3.621m ±  2%  +4.29% (p=0.002 n=6)
SourceValidation-4                  2.313µ ±  0%   2.357µ ±  2%  +1.92% (p=0.004 n=6)
RegistryConcurrent-4                778.7n ±  3%   813.3n ±  4%  +4.44% (p=0.015 n=6)
LoaderLoadFromString-4              3.510m ±  1%   3.734m ±  2%  +6.39% (p=0.002 n=6)
geomean                             18.45µ         18.93µ        +2.58%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               1.944Mi ± 0%   1.944Mi ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                     2.097Mi ± 0%   2.097Mi ± 0%       ~ (p=0.699 n=6)
ComponentExecute-4                  1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4         1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                2.099Mi ± 0%   2.099Mi ± 0%       ~ (p=0.970 n=6)
SourceValidation-4                  1.984Ki ± 0%   1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                1.133Ki ± 0%   1.133Ki ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4              2.099Mi ± 0%   2.099Mi ± 0%       ~ (p=1.000 n=6)
geomean                             15.05Ki        15.05Ki       -0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.09k ± 0%   15.09k ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                      17.43k ± 0%   17.43k ± 0%       ~ (p=1.000 n=6)
ComponentExecute-4                    25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4           25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                 17.48k ± 0%   17.48k ± 0%       ~ (p=1.000 n=6) ¹
SourceValidation-4                    32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                  2.000 ± 0%    2.000 ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4               17.47k ± 0%   17.47k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               181.2         181.2       +0.00%
¹ all samples are equal

pkg: github.com/GoCodeAlone/workflow/middleware
                                  │ baseline-bench.txt │       benchmark-results.txt       │
                                  │       sec/op       │   sec/op     vs base              │
CircuitBreakerDetection-4                  287.8n ± 6%   303.8n ± 3%  +5.54% (p=0.013 n=6)
CircuitBreakerExecution_Success-4          22.53n ± 2%   22.57n ± 0%       ~ (p=0.351 n=6)
CircuitBreakerExecution_Failure-4          66.28n ± 1%   66.30n ± 1%       ~ (p=0.390 n=6)
geomean                                    75.46n        76.89n       +1.89%

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │        B/op        │    B/op     vs base                │
CircuitBreakerDetection-4                 144.0 ± 0%     144.0 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │     allocs/op      │ allocs/op   vs base                │
CircuitBreakerDetection-4                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
                                 │ baseline-bench.txt │        benchmark-results.txt        │
                                 │       sec/op       │    sec/op     vs base               │
JQTransform_Simple-4                     886.6n ± 27%   908.7n ± 33%        ~ (p=0.132 n=6)
JQTransform_ObjectConstruction-4         1.460µ ±  0%   1.519µ ±  1%   +4.01% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.316µ ±  0%   3.764µ ±  7%  +13.50% (p=0.002 n=6)
JQTransform_Complex-4                    37.75µ ±  1%   40.76µ ±  4%   +7.97% (p=0.002 n=6)
JQTransform_Throughput-4                 1.809µ ±  2%   1.901µ ±  2%   +5.09% (p=0.002 n=6)
SSEPublishDelivery-4                     65.77n ±  0%   65.96n ±  1%        ~ (p=0.093 n=6)
geomean                                  1.637µ         1.727µ         +5.47%

                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │        B/op        │     B/op      vs base                │
JQTransform_Simple-4                   1.273Ki ± 0%     1.273Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4       1.773Ki ± 0%     1.773Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4              2.625Ki ± 0%     2.625Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                  16.22Ki ± 0%     16.22Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4               1.984Ki ± 0%     1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                 +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │     allocs/op      │ allocs/op   vs base                │
JQTransform_Simple-4                     10.00 ± 0%     10.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4         15.00 ± 0%     15.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4                30.00 ± 0%     30.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                    324.0 ± 0%     324.0 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4                 17.00 ± 0%     17.00 ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │       sec/op       │    sec/op     vs base              │
SchemaValidation_Simple-4                   1.122µ ±  2%   1.127µ ± 12%       ~ (p=0.974 n=6)
SchemaValidation_AllFields-4                1.688µ ± 11%   1.751µ ±  5%       ~ (p=0.394 n=6)
SchemaValidation_FormatValidation-4         1.628µ ±  4%   1.609µ ±  1%       ~ (p=0.223 n=6)
SchemaValidation_ManySchemas-4              1.810µ ±  1%   1.829µ ±  2%       ~ (p=0.123 n=6)
geomean                                     1.537µ         1.552µ        +0.97%

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │        B/op        │    B/op     vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │     allocs/op      │ allocs/op   vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │       sec/op       │    sec/op     vs base               │
EventStoreAppend_InMemory-4                1.134µ ± 20%   1.253µ ± 12%        ~ (p=0.180 n=6)
EventStoreAppend_SQLite-4                  1.323m ±  5%   1.282m ±  4%        ~ (p=0.132 n=6)
GetTimeline_InMemory/events-10-4           14.36µ ±  4%   14.42µ ±  4%        ~ (p=1.000 n=6)
GetTimeline_InMemory/events-50-4           80.72µ ±  5%   69.07µ ± 18%  -14.43% (p=0.026 n=6)
GetTimeline_InMemory/events-100-4          132.4µ ± 26%   126.1µ ±  0%   -4.75% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          659.2µ ±  0%   654.3µ ±  2%        ~ (p=0.065 n=6)
GetTimeline_InMemory/events-1000-4         1.359m ±  0%   1.349m ±  4%        ~ (p=1.000 n=6)
GetTimeline_SQLite/events-10-4             109.3µ ±  0%   112.7µ ±  1%   +3.16% (p=0.002 n=6)
GetTimeline_SQLite/events-50-4             254.4µ ±  0%   258.8µ ±  2%   +1.72% (p=0.002 n=6)
GetTimeline_SQLite/events-100-4            430.2µ ±  0%   437.5µ ±  1%   +1.70% (p=0.004 n=6)
GetTimeline_SQLite/events-500-4            1.841m ±  0%   1.828m ±  2%        ~ (p=0.310 n=6)
GetTimeline_SQLite/events-1000-4           3.574m ±  0%   3.667m ±  3%   +2.60% (p=0.004 n=6)
geomean                                    224.3µ         223.1µ         -0.53%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                  798.5 ± 7%     746.0 ± 4%  -6.57% (p=0.024 n=6)
EventStoreAppend_SQLite-4                  1.983Ki ± 2%   1.985Ki ± 2%       ~ (p=0.455 n=6)
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%   7.953Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%   46.62Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%   94.48Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%   472.8Ki ± 0%       ~ (p=0.242 n=6)
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%   944.3Ki ± 0%       ~ (p=0.394 n=6)
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%   16.74Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%   87.14Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%   175.4Ki ± 0%       ~ (p=1.000 n=6)
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%   846.1Ki ± 0%  -0.00% (p=0.009 n=6)
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%   1.639Mi ± 0%       ~ (p=0.864 n=6)
geomean                                    67.40Ki        67.03Ki       -0.55%
¹ all samples are equal

                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │     allocs/op      │  allocs/op   vs base                │
EventStoreAppend_InMemory-4                  7.000 ± 0%    7.000 ± 0%       ~ (p=1.000 n=6) ¹
EventStoreAppend_SQLite-4                    53.00 ± 0%    53.00 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-10-4             125.0 ± 0%    125.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4             653.0 ± 0%    653.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4           1.306k ± 0%   1.306k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4           6.514k ± 0%   6.514k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-1000-4          13.02k ± 0%   13.02k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-10-4               382.0 ± 0%    382.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4              1.852k ± 0%   1.852k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4             3.681k ± 0%   3.681k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4             18.54k ± 0%   18.54k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-1000-4            37.29k ± 0%   37.29k ± 0%       ~ (p=1.000 n=6) ¹
geomean                                     1.162k        1.162k       +0.00%
¹ all samples are equal

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

- Pin base image to digest instead of mutable :latest tag
- Add --bare flag to all ko build invocations so image publishes
  to ghcr.io/<repo> without path suffix (matches Helm chart)
- Fix MAJOR_MINOR tag computation for pre-release versions
- Remove unused id-token: write permission

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@intel352 intel352 merged commit c2a06be into main Mar 8, 2026
11 checks passed
@intel352 intel352 deleted the feat/ko-build branch March 8, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants