c05ec7503c
Bump OPENCODE_VERSION ARG from 1.14.19 to 1.14.20 to track the new
upstream release on npm.
Clarify the tagging convention in AGENTS.md: the first build on a new
opencode version uses the bare 'v{opencode_version}' tag (no letter
suffix). Letter suffixes (a, b, c, ...) are reserved for container-
level rebuilds on the same opencode version (CVE fixes, doc changes,
entrypoint bugs). The previous wording implied a letter was always
required, which was never the actual behaviour.
56 lines
4.2 KiB
Markdown
56 lines
4.2 KiB
Markdown
# AGENTS.md
|
|
|
|
## Project overview
|
|
|
|
Docker image packaging [opencode](https://opencode.ai) into a production-ready dev container. Two image variants (base and omos) are published to Docker Hub via Gitea Actions CI. Not a library or application — this is infrastructure (Dockerfile, entrypoint scripts, docker-compose, documentation).
|
|
|
|
## File roles
|
|
|
|
- `Dockerfile` — single multi-stage build for both variants. OMOS variant is controlled by `INSTALL_OMOS=true` build arg. All GitHub-sourced binaries are pinned with version ARGs.
|
|
- `entrypoint.sh` — runs as root: UID/GID adjustment, SSH permissions, volume ownership fixes. Then drops to developer via gosu.
|
|
- `entrypoint-user.sh` — runs as developer: git config, opencode.json generation from env vars, OMOS setup.
|
|
- `DOCKER_HUB.md` — pushed to Docker Hub description via CI API call. Must stay under 25KB. Short description field must be ≤100 bytes.
|
|
- `README.md` — source repo documentation. Must stay in sync with DOCKER_HUB.md (both describe the same features but for different audiences).
|
|
- `.gitea/workflows/docker-publish.yml` — CI pipeline: three parallel jobs (build-base, build-omos, update-description). Triggered by tag push only.
|
|
|
|
## Versioning scheme
|
|
|
|
Tags follow `v{opencode_version}[letter]` — e.g. `v1.14.20` for the first build on a new opencode release, and `v1.14.20a`, `v1.14.20b`, … for subsequent rebuilds on the same opencode version.
|
|
|
|
- The number tracks the opencode npm version (see `OPENCODE_VERSION` ARG in `Dockerfile`).
|
|
- **No letter suffix** on the first build of a new opencode version — the bare `v{opencode_version}` tag is the canonical release.
|
|
- **Letter suffix** (`a`, `b`, `c`, …) increments for container-level rebuilds — tooling changes, CVE fixes, doc-driven rebuilds, entrypoint bugfixes — that don't change the underlying opencode version.
|
|
|
|
CI produces four Docker Hub tags per release: `vX.Y.Z[n]`, `latest`, `vX.Y.Z[n]-omos`, `latest-omos`.
|
|
|
|
When bumping the opencode version, also bump `OPENCODE_VERSION` in `Dockerfile` and update the comment in `.env.example` if it names a specific model/version for context.
|
|
|
|
## Critical conventions
|
|
|
|
- **entrypoint.sh volume ownership loop** — when adding a new named volume mount point, add it to the `for dir in ...` loop in `entrypoint.sh` so root-owned volumes get chowned on startup.
|
|
- **Three docs to keep in sync** — Dockerfile changes that add tools or features must be reflected in `README.md`, `DOCKER_HUB.md`, and `.env.example`. The docker-compose examples in both docs must match the source `docker-compose.yml` pattern.
|
|
- **GitHub-sourced binaries** — fzf, gosu, git-lfs, neovim, bat, eza, zoxide, uv, rustup are installed from upstream releases (not apt) with pinned versions. Use the same `ARCH` case-switch pattern for multi-arch support (amd64/arm64).
|
|
- **Shell scripts use `set -euo pipefail`** — both entrypoints are strict. Errors in volume chown or SSH permission operations are intentionally suppressed with `|| true`.
|
|
- **Docker Hub description update** — uses `/v2/auth/token` endpoint (not the deprecated `/v2/users/login`). Auth uses `identifier`/`secret` fields, returns `access_token`, sent as `Bearer`. Short description must be ≤100 bytes.
|
|
|
|
## CI quirks
|
|
|
|
- Both build jobs include an IPv4 preference step (`gai.conf` + `driver-opts: network=host` for buildx) to work around intermittent IPv6 failures on the Gitea runners.
|
|
- `update-description` job runs only when both builds succeed (`needs: [build-base, build-omos]`).
|
|
- Tags must be pushed to trigger CI. Pushing to `main` alone does not build images.
|
|
|
|
## Testing changes
|
|
|
|
No test suite. Verify by:
|
|
1. Building locally: `docker compose build`
|
|
2. Running: `docker compose run --rm devbox bash`
|
|
3. Checking tool availability inside container: `nvim --version`, `bat --version`, `uv --version`, etc.
|
|
4. For entrypoint changes: test with a non-1000 UID workspace to verify UID adjustment and volume ownership fixes.
|
|
|
|
## Commit style
|
|
|
|
Imperative mood, first line summarizes the change. Multi-line body explains "why" when non-obvious. Examples from history:
|
|
- `Fix ownership of named volume mount points in entrypoint`
|
|
- `Add uv package manager to base image for on-demand Python support`
|
|
- `Upgrade base image from Debian bookworm to trixie (current stable)`
|