Skip to content

Commit e8beb9c

Browse files
committed
ci: add docker context guardrails for pre-commit and CI
1 parent 05b1ddf commit e8beb9c

7 files changed

Lines changed: 94 additions & 5 deletions

File tree

.dockerignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ target
1111
# OS noise
1212
.DS_Store
1313

14-
# Submodule checkout is not needed in Docker build context
15-
packages/opencode
14+
# Keep the submodule directory path available for Dockerfile COPY in remote mode,
15+
# but exclude all nested content from the default repo-root build context.
16+
# Local opencode dev builds use the custom context packer in
17+
# packages/core/src/docker/image.rs instead of .dockerignore.
1618
packages/opencode/**

.github/workflows/ci.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,23 @@ jobs:
5757
- name: Packer validate
5858
run: packer validate -var-file=infra/digitalocean/packer/variables.pkr.hcl infra/digitalocean/packer/opencode-marketplace.pkr.hcl
5959

60+
docker-context-guard:
61+
name: Docker Context Guard
62+
runs-on: ubuntu-latest
63+
steps:
64+
- uses: actions/checkout@v6
65+
66+
- name: Ensure opencode placeholder path exists for Docker context
67+
run: mkdir -p packages/opencode
68+
69+
- name: Build Docker target stage
70+
run: |
71+
DOCKER_BUILDKIT=1 docker build \
72+
--file packages/core/src/docker/Dockerfile \
73+
--target opencode-build \
74+
--tag opencode-cloud-sandbox:ci-check \
75+
.
76+
6077
# Build, lint, and test on multiple platforms
6178
# Clippy/build/test must run on each platform because #[cfg(target_os)] causes
6279
# different code to compile (e.g., systemd.rs on Linux, launchd.rs on macOS)

.github/workflows/docker-publish.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ jobs:
6060
# when called via workflow_call, defaults to the commit that triggered the workflow
6161
ref: ${{ inputs.ref }}
6262

63+
- name: Ensure opencode placeholder path exists for Docker context
64+
run: mkdir -p packages/opencode
65+
6366
# NOTE: We parse the description label from the Dockerfile so the
6467
# multi-arch manifest annotation stays in sync and GHCR shows a description.
6568
# If you change the label format or quoting, update the extraction logic.

.github/workflows/dockerfile-updates.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ jobs:
2020
steps:
2121
- uses: actions/checkout@v6
2222

23+
- name: Ensure opencode placeholder path exists for Docker context
24+
run: mkdir -p packages/opencode
25+
2326
- name: Install jq
2427
run: sudo apt-get update && sudo apt-get install -y jq
2528

justfile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,15 @@ do-marketplace-build:
291291
packer build -var-file=infra/digitalocean/packer/variables.pkr.hcl \
292292
infra/digitalocean/packer/opencode-marketplace.pkr.hcl
293293

294-
# Pre-commit checks (without Docker build - faster, works without Docker)
294+
# Pre-commit checks with conditional Docker stage build for Docker-risk changes.
295+
# This keeps routine commits fast while still catching Docker context regressions.
295296
pre-commit: check-opencode-submodule-published fmt lint build test-all-fast
297+
@if ./scripts/should-run-docker-check.sh; then \
298+
echo "Running Docker stage check because Docker-risk files changed..."; \
299+
just check-docker; \
300+
else \
301+
echo "Skipping Docker stage check (no Docker-risk file changes)."; \
302+
fi
296303

297304
# Pre-commit checks including Docker build (requires Docker)
298305
pre-commit-full: check-opencode-submodule-published fmt lint build test-all-fast build-docker

packages/core/src/docker/Dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,10 @@ ARG OPENCODE_SOURCE=remote
511511
ARG OPENCODE_COMMIT
512512
ARG OPENCODE_LOCAL_REF
513513

514-
# The custom build-context generator always adds packages/opencode. In remote mode
515-
# this is just a tiny placeholder; in local dev mode it contains the full submodule.
514+
# CLI builds use a custom build-context generator that always adds
515+
# packages/opencode. Repo-root Docker builds rely on checkout + .dockerignore to
516+
# keep this path as a tiny placeholder in remote mode.
517+
# In local dev mode it contains the full submodule.
516518
COPY --chown=opencoder:opencoder packages/opencode /tmp/opencode-local
517519

518520
# Clone the fork and build opencode from source (as non-root user)

scripts/should-run-docker-check.sh

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Decide whether local pre-commit should run the Docker stage check.
5+
# Exit 0 when Docker-risk files changed, otherwise exit 1.
6+
7+
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
8+
echo "Not inside a git worktree; running Docker check."
9+
exit 0
10+
fi
11+
12+
changed_paths="$(
13+
{
14+
git diff --name-only
15+
git diff --name-only --cached
16+
git ls-files --others --exclude-standard
17+
} | sed '/^$/d' | sort -u
18+
)"
19+
20+
if [ -z "${changed_paths}" ]; then
21+
echo "No file changes detected."
22+
exit 1
23+
fi
24+
25+
is_docker_risk_path() {
26+
case "$1" in
27+
.dockerignore) return 0 ;;
28+
packages/core/src/docker/*) return 0 ;;
29+
.github/workflows/ci.yml) return 0 ;;
30+
.github/workflows/docker-publish.yml) return 0 ;;
31+
.github/workflows/dockerfile-updates.yml) return 0 ;;
32+
.github/workflows/version-bump.yml) return 0 ;;
33+
scripts/check-dockerfile-updates.sh) return 0 ;;
34+
scripts/extract-oci-description.py) return 0 ;;
35+
scripts/should-run-docker-check.sh) return 0 ;;
36+
esac
37+
return 1
38+
}
39+
40+
matched_paths=()
41+
while IFS= read -r path; do
42+
[ -n "${path}" ] || continue
43+
if is_docker_risk_path "${path}"; then
44+
matched_paths+=("${path}")
45+
fi
46+
done <<< "${changed_paths}"
47+
48+
if [ "${#matched_paths[@]}" -eq 0 ]; then
49+
echo "No Docker-risk file changes detected."
50+
exit 1
51+
fi
52+
53+
printf 'Docker-risk file changes detected:\n'
54+
printf ' - %s\n' "${matched_paths[@]}"
55+
exit 0

0 commit comments

Comments
 (0)