From 0e93cc08b4d9765d361b207aadee72a9ce09aaaa Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Tue, 14 Apr 2026 11:06:36 -0700 Subject: [PATCH] Build forgejo-runner container locally (#334) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add native Dagger `container.py` for forgejo-runner (Go + Alpine runtime, static binary with CGO for SQLite) - Update kustomization to point to local registry image (tag is placeholder until CI builds) - Uses existing `clone_from_forge("forgejo-runner", ...)` mirror ## Test plan - [x] `dagger call build --src=. --container-name=forgejo-runner` passes locally - [ ] CI container build from branch succeeds - [ ] Update kustomization tag to built image, deploy from branch via ArgoCD `--revision` - [ ] Verify runner registers and picks up jobs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: https://forge.eblu.me/eblume/blumeops/pulls/334 --- .../forgejo-runner/kustomization.yaml | 3 +- containers/forgejo-runner/container.py | 67 +++++++++++++++++++ .../changelog.d/local-forgejo-runner.infra.md | 1 + 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 containers/forgejo-runner/container.py create mode 100644 docs/changelog.d/local-forgejo-runner.infra.md diff --git a/argocd/manifests/forgejo-runner/kustomization.yaml b/argocd/manifests/forgejo-runner/kustomization.yaml index 2c845ee..b652821 100644 --- a/argocd/manifests/forgejo-runner/kustomization.yaml +++ b/argocd/manifests/forgejo-runner/kustomization.yaml @@ -10,7 +10,8 @@ resources: images: - name: code.forgejo.org/forgejo/runner - newTag: "12.7.3" + newName: registry.ops.eblu.me/blumeops/forgejo-runner + newTag: v12.7.3-12d83ba - name: docker newTag: 27-dind diff --git a/containers/forgejo-runner/container.py b/containers/forgejo-runner/container.py new file mode 100644 index 0000000..16f6986 --- /dev/null +++ b/containers/forgejo-runner/container.py @@ -0,0 +1,67 @@ +"""Forgejo Runner — native Dagger build. + +Two-stage build: Go (static binary with CGO for SQLite), Alpine (runtime). +Source cloned from forge mirror. +""" + +import dagger +from dagger import dag + +from blumeops.containers import ( + alpine_runtime, + clone_from_forge, + oci_labels, +) + +VERSION = "12.7.3" + + +async def build(src: dagger.Directory) -> dagger.Container: + source = clone_from_forge("forgejo-runner", f"v{VERSION}") + + # Stage 1: Build Go binary (static, CGO enabled for SQLite) + ldflags = ( + '-extldflags "-static" -s -w' + f' -X "code.forgejo.org/forgejo/runner/v12/internal/pkg/ver.version=v{VERSION}"' + ) + backend = ( + dag.container() + .from_("golang:alpine3.22") + .with_exec(["apk", "add", "--no-cache", "build-base", "git"]) + .with_directory("/app", source) + .with_workdir("/app") + .with_env_variable("CGO_ENABLED", "1") + .with_env_variable("CGO_CFLAGS", "-DSQLITE_MAX_VARIABLE_NUMBER=32766") + .with_exec( + [ + "go", + "build", + "-tags=netgo osusergo", + f"-ldflags={ldflags}", + "-o", + "/forgejo-runner", + ".", + ] + ) + ) + + # Stage 2: Runtime + runtime = alpine_runtime( + extra_apk=["git", "bash", "ca-certificates"], + uid=1000, + gid=1000, + username="runner", + ) + runtime = oci_labels( + runtime, + title="Forgejo Runner", + description="A runner for Forgejo Actions", + version=VERSION, + ) + return ( + runtime.with_file("/bin/forgejo-runner", backend.file("/forgejo-runner")) + .with_env_variable("HOME", "/data") + .with_user("1000:1000") + .with_workdir("/data") + .with_default_args(args=["/bin/forgejo-runner"]) + ) diff --git a/docs/changelog.d/local-forgejo-runner.infra.md b/docs/changelog.d/local-forgejo-runner.infra.md new file mode 100644 index 0000000..ffef62e --- /dev/null +++ b/docs/changelog.d/local-forgejo-runner.infra.md @@ -0,0 +1 @@ +Build forgejo-runner container locally via native Dagger pipeline instead of pulling from upstream.