feat: split-base build pipeline (parallel, manual-trigger only)
Validate / docs-check (push) Successful in 15s
Validate / validate-base (push) Successful in 12m13s
Validate / validate-omos (push) Failing after 15m48s
Validate / validate-with-pi (push) Successful in 13m43s
Validate / validate-omos-with-pi (push) Has been cancelled
Validate / docs-check (push) Successful in 15s
Validate / validate-base (push) Successful in 12m13s
Validate / validate-omos (push) Failing after 15m48s
Validate / validate-with-pi (push) Successful in 13m43s
Validate / validate-omos-with-pi (push) Has been cancelled
Two-Dockerfile split-base build alongside the existing single-Dockerfile
pipeline. Goal: cut CI wall clock from ~165-180min to ~30-40min on
typical version-bump-only releases by reusing a base image across the
four variants.
Files added:
- Dockerfile.base variant-independent layers (apt, locales, AWS
CLI, Node.js, mempalace, gitea-mcp, user setup,
chromadb prewarm, ENVs, entrypoints).
- Dockerfile.variant FROMs ${BASE_IMAGE} and adds opencode / pi /
omos / Go installs gated by INSTALL_* args.
Each npm install -g uses NPM_CONFIG_PREFIX=/usr
per-RUN to keep baked binaries off the volume-
shadowed ~/.pi/npm-global path inherited from
base.
- .gitea/workflows/docker-publish-split.yml
workflow_dispatch-only pipeline:
base-decide -> build-base (conditional) ->
smoke-* (4 parallel) -> build-variant-*
(4 parallel) -> promote-base-latest ->
update-description. Hash-driven base reuse:
if base-<sha> already exists on Docker Hub,
the build is skipped entirely. Inputs:
release_tag (test tag suffix, default
v0.0.0-split-test) and promote_latest
(default false; gates latest-* aliases and
Hub description update).
Files unchanged:
- Dockerfile, docker-publish.yml, validate.yml all left in place so
the production tag-push pipeline keeps working untouched.
Migration plan (in CHANGELOG Unreleased):
1. workflow_dispatch test run with promote_latest=false; verify the
four variant images smoke-pass and have plausible sizes.
2. Compare manifest digests against the same-version output from the
production pipeline (independent test run on the same commit).
3. Once verified across 1-2 release cycles, swap docker-publish-split.yml
to on: push: tags: v* and retire docker-publish.yml.
AGENTS.md and CHANGELOG.md updated with file roles and the migration
plan. Production pipeline behavior is bit-for-bit unchanged on this
branch.
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
# opencode-devbox — variant image
|
||||
#
|
||||
# FROMs a base-<hash> image produced by Dockerfile.base and adds only
|
||||
# the variant-specific tools (opencode, pi, oh-my-opencode-slim, Go).
|
||||
#
|
||||
# The four published variants are produced from THIS Dockerfile by
|
||||
# varying build args:
|
||||
#
|
||||
# variant INSTALL_OPENCODE INSTALL_OMOS INSTALL_PI
|
||||
# ───────────────── ──────────────── ──────────── ──────────
|
||||
# base true false false
|
||||
# omos true true false
|
||||
# with-pi true false true
|
||||
# omos-with-pi true true true
|
||||
#
|
||||
# Pass `--build-arg BASE_IMAGE=<repo>:base-<hash>` to select the base.
|
||||
# The CI workflow computes the base hash from Dockerfile.base + rootfs/
|
||||
# + entrypoint*.sh and feeds it in.
|
||||
#
|
||||
# IMPORTANT: the base image sets NPM_CONFIG_PREFIX to
|
||||
# /home/developer/.pi/npm-global so runtime `pi install npm:...` and
|
||||
# `npm install -g` by the developer user lands on the named volume.
|
||||
# At BUILD time we want the baked binaries on /usr so they survive the
|
||||
# volume mount. Each `npm install -g` below therefore prefixes the
|
||||
# command with `NPM_CONFIG_PREFIX=/usr`.
|
||||
|
||||
ARG BASE_IMAGE
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
ARG TARGETARCH
|
||||
ARG USER_NAME=developer
|
||||
|
||||
# ── Install opencode via npm ─────────────────────────────────────────
|
||||
ARG INSTALL_OPENCODE=true
|
||||
ARG OPENCODE_VERSION=1.14.41
|
||||
RUN if [ "${INSTALL_OPENCODE}" = "true" ]; then \
|
||||
NPM_CONFIG_PREFIX=/usr npm install -g opencode-ai@${OPENCODE_VERSION} && \
|
||||
opencode --version ; \
|
||||
fi
|
||||
|
||||
# ── Optional: pi coding-agent ────────────────────────────────────────
|
||||
# pi-toolkit and pi-extensions are cloned into /opt/. entrypoint-user.sh
|
||||
# runs each repo's install.sh on container start so symlinks land under
|
||||
# ~/.pi/agent/ on the named volume.
|
||||
ARG INSTALL_PI=false
|
||||
ARG PI_VERSION=latest
|
||||
ARG PI_TOOLKIT_REF=main
|
||||
ARG PI_EXTENSIONS_REF=main
|
||||
RUN if [ "${INSTALL_PI}" = "true" ]; then \
|
||||
if [ "${PI_VERSION}" = "latest" ]; then \
|
||||
NPM_CONFIG_PREFIX=/usr npm install -g @mariozechner/pi-coding-agent ; \
|
||||
else \
|
||||
NPM_CONFIG_PREFIX=/usr npm install -g @mariozechner/pi-coding-agent@${PI_VERSION} ; \
|
||||
fi && \
|
||||
pi --version && \
|
||||
git clone --depth 1 --branch "${PI_TOOLKIT_REF}" \
|
||||
https://gitea.jordbo.se/joakimp/pi-toolkit.git /opt/pi-toolkit && \
|
||||
git clone --depth 1 --branch "${PI_EXTENSIONS_REF}" \
|
||||
https://gitea.jordbo.se/joakimp/pi-extensions.git /opt/pi-extensions && \
|
||||
echo "pi-toolkit at $(cd /opt/pi-toolkit && git rev-parse --short HEAD)" && \
|
||||
echo "pi-extensions at $(cd /opt/pi-extensions && git rev-parse --short HEAD)" ; \
|
||||
fi
|
||||
|
||||
# ── Optional: Go ─────────────────────────────────────────────────────
|
||||
ARG INSTALL_GO=false
|
||||
ARG GO_VERSION=latest
|
||||
RUN if [ "${INSTALL_GO}" = "true" ]; then \
|
||||
GOARCH=$(case "${TARGETARCH}" in amd64) echo "amd64" ;; arm64) echo "arm64" ;; *) echo "amd64" ;; esac) && \
|
||||
V="${GO_VERSION}" && \
|
||||
if [ "$V" = "latest" ]; then \
|
||||
V=$(curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "https://go.dev/dl/?mode=json" | \
|
||||
awk -F'"' '/"version":/ { sub(/^go/,"",$4); print $4; exit }'); \
|
||||
fi && \
|
||||
[ -n "$V" ] && \
|
||||
echo "Installing Go ${V}" && \
|
||||
curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "https://go.dev/dl/go${V}.linux-${GOARCH}.tar.gz" | tar -C /usr/local -xz && \
|
||||
ln -s /usr/local/go/bin/go /usr/local/bin/go && \
|
||||
ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt; \
|
||||
fi
|
||||
|
||||
# ── Optional: oh-my-opencode-slim (multi-agent orchestration) ────────
|
||||
# Installs Bun runtime and the oh-my-opencode-slim npm package.
|
||||
ARG INSTALL_OMOS=false
|
||||
ARG OMOS_VERSION=latest
|
||||
RUN if [ "${INSTALL_OMOS}" = "true" ]; then \
|
||||
ARCH=$(uname -m) && \
|
||||
if [ "$ARCH" = "x86_64" ]; then \
|
||||
BUN_ARCH="x64-baseline"; \
|
||||
elif [ "$ARCH" = "aarch64" ]; then \
|
||||
BUN_ARCH="aarch64"; \
|
||||
fi && \
|
||||
curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "https://github.com/oven-sh/bun/releases/latest/download/bun-linux-${BUN_ARCH}.zip" -o /tmp/bun.zip && \
|
||||
unzip -o /tmp/bun.zip -d /tmp/bun && \
|
||||
mv /tmp/bun/bun-linux-${BUN_ARCH}/bun /usr/local/bin/bun && \
|
||||
chmod +x /usr/local/bin/bun && \
|
||||
ln -sf bun /usr/local/bin/bunx && \
|
||||
rm -rf /tmp/bun /tmp/bun.zip && \
|
||||
bun --version && \
|
||||
test -L /usr/local/bin/bunx && \
|
||||
NPM_CONFIG_PREFIX=/usr npm install -g oh-my-opencode-slim@${OMOS_VERSION}; \
|
||||
fi
|
||||
|
||||
# WORKDIR / ENTRYPOINT / CMD inherited from base.
|
||||
Reference in New Issue
Block a user