mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
refactor: build dogfood image as base + mise oci layers (#25448)
Splits the dogfood image into two artifacts: - `ghcr.io/coder/oss-dogfood-base:<distro>-<base-sha>`: Ubuntu base with apt packages, chrome, rustup, brew, gh, and the mise binary. The base-sha is a cache key over `Dockerfile.base` and `files/`, so commits that don't touch those inputs reuse the previous build. - `codercom/oss-dogfood:<final-sha>-<distro>` and rolling tags (`:22.04`, `:26.04`, `:latest`, `:<branch>`): produced by `mise oci build` on top of the base, with one content-addressed OCI layer per mise tool. The rolling tag scheme is unchanged, so the workspace template doesn't need updating. Single-tool version bumps now invalidate only that tool's OCI layer, so workspaces re-pull just what changed instead of the entire 5-6 GB image on every recreate. Also: - Drops the build-time `pnpm dlx playwright@1.47.0 install --with-deps chromium` step (~400 MB) and the equivalent `playwright-driver.browsers` install from `flake.nix`. `@playwright/mcp` (used by the claude-code and codex MCP servers in `dogfood/coder/main.tf`) does NOT auto-install browsers, so the existing `install-deps` `coder_script` now runs two installs on workspace start: `pnpm exec playwright install chromium` for the site's pinned `@playwright/test`, and `npx --package=@playwright/mcp@latest playwright-core install --no-shell chromium` so the MCP servers find their matching browser revision. Browser revisions coexist under `~/.cache/ms-playwright/chromium-<rev>/`, which lives on the home volume so both downloads happen once per workspace recreate and persist across restarts. Net effect: same MCP behavior as before, +~1-2 min on first workspace start. Nix devshell users running site e2e tests locally now need `pnpm exec playwright install` once (instead of getting browsers via nixpkgs). - Bumps the pinned mise binary to v2026.5.12 (matching main after #25521) and adds top-level `min_version = "2026.5.12"` to `mise.toml` so every consumer (devs, CI, the embedded mise inside the dogfood image, mise oci builds) fails fast on an older mise. - Adds bison, flex, libicu-dev, libreadline-dev, uuid-dev, and zlib1g-dev to both Ubuntu base images for source-build use cases (e.g., building Postgres from source). - Replaces skopeo with crane as the registry client `mise oci push` shells out to: crane is added to `mise.toml`, the workflow drops its `apt-get install skopeo` and forces `--tool crane`, and the local wrapper image stops bundling skopeo. One source of truth for tool versions, no apt drift, smaller wrapper image, and workspace users get a registry client on PATH for free via mise oci's tool layers. - Removes `nix.hash`/`mise.hash` and their Makefile rules. The registry digest already captures every effective change since CI rebuilds when any baked-in input moves; the per-file `filesha1()` entries in `pull_triggers` are redundant. Supersedes #25400 (the `mise.hash` pull trigger landed there in `2b612abe7b`; this PR removes it as part of the broader simplification). > [!NOTE] > `mise oci build` is experimental and requires `MISE_EXPERIMENTAL=1` (set at job level in the workflow). The local-only `scripts/dogfood/mise-oci-wrapper.sh` builds a tiny `coderdev/mise-oci-wrapper:<version>` Debian image with curl-installed mise on first invocation (cached by version tag thereafter); we don't reuse `jdxcode/mise:latest` because that tag lags upstream GitHub releases by days and would defeat the `min_version` enforcement above. > [!NOTE] > `compute-base-sha.sh` and `compute-final-sha.sh` are cache keys, not strict content addresses: the base Dockerfile still pulls dynamic resources at build time (gh/buildx `releases/latest`, chrome `stable_current_amd64.deb`, apt mirror state). Two runs with identical checked-in files can produce slightly different bytes, which is acceptable here because the cache-hit savings on irrelevant commits outweigh that drift. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Thomas Kosiewski <tk@coder.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+7
-7
@@ -1,9 +1,9 @@
|
||||
# This file controls what docker/BuildKit may send to the daemon when
|
||||
# the build context is the repository root. Today only the dogfood
|
||||
# images at dogfood/coder/ubuntu-{22,26}.04/Dockerfile use the repo
|
||||
# root as context; other docker builds in this repo (scripts/Dockerfile,
|
||||
# scripts/Dockerfile.base, scripts/ironbank/Dockerfile) cd into a
|
||||
# temporary directory and have their own contexts.
|
||||
# base images at dogfood/coder/ubuntu-{22,26}.04/Dockerfile.base use the
|
||||
# repo root as context; other docker builds in this repo
|
||||
# (scripts/Dockerfile, scripts/Dockerfile.base, scripts/ironbank/Dockerfile)
|
||||
# cd into a temporary directory and have their own contexts.
|
||||
#
|
||||
# We use an allowlist so the context stays small and predictable, and
|
||||
# new top-level files added to the repo do not silently inflate every
|
||||
@@ -14,15 +14,15 @@
|
||||
# file under a directory requires re-including the directory itself.
|
||||
**
|
||||
|
||||
# Re-allow paths the dogfood Dockerfiles consume.
|
||||
!mise.toml
|
||||
!mise.lock
|
||||
# Re-allow paths the dogfood Dockerfile.base files consume.
|
||||
!dogfood
|
||||
!dogfood/coder
|
||||
!dogfood/coder/ubuntu-22.04
|
||||
!dogfood/coder/ubuntu-22.04/Dockerfile.base
|
||||
!dogfood/coder/ubuntu-22.04/configure-chrome-flags.sh
|
||||
!dogfood/coder/ubuntu-22.04/files
|
||||
!dogfood/coder/ubuntu-22.04/files/**
|
||||
!dogfood/coder/ubuntu-26.04
|
||||
!dogfood/coder/ubuntu-26.04/Dockerfile.base
|
||||
!dogfood/coder/ubuntu-26.04/files
|
||||
!dogfood/coder/ubuntu-26.04/files/**
|
||||
|
||||
+188
-97
@@ -8,21 +8,24 @@ on:
|
||||
#
|
||||
# Effects vary by event:
|
||||
#
|
||||
# PRs: `build_image` builds the image variants but never pushes
|
||||
# (each `depot/build-push-action` step's `push:` and the
|
||||
# `Push Nix image` step are gated on `github.ref ==
|
||||
# 'refs/heads/main'`). `test_image` rebuilds the Ubuntu images
|
||||
# from Depot cache with `load: true` and runs `make gen`, `fmt`,
|
||||
# `lint`, and a Linux build inside each image to validate that
|
||||
# the baked-in tooling works. `deploy_template` runs
|
||||
# `terraform init` + `validate` only; the apply step and
|
||||
# SHA/title gathering are gated on main.
|
||||
# PRs: `build_image` builds the base and runs `mise oci build`,
|
||||
# loads the result into the local Docker daemon, and runs
|
||||
# `make gen`, `fmt`, `lint`, and a Linux build inside the image
|
||||
# to validate the baked-in tooling. Only the base image is pushed
|
||||
# (to ghcr.io so the mise oci step can pull --from a real
|
||||
# registry); the Docker Hub push is gated on
|
||||
# `github.ref == 'refs/heads/main'`. Fork PRs skip the entire
|
||||
# base+mise-oci pipeline since GITHUB_TOKEN is read-only for
|
||||
# packages; the nix matrix entry still runs.
|
||||
# `deploy_template` runs `terraform init` + `validate` only; the
|
||||
# apply step and SHA/title gathering are gated on main.
|
||||
#
|
||||
# Pushes to main: `build_image` retags rolling tags on
|
||||
# `codercom/oss-dogfood` (`:latest`, `:22.04`, `:26.04`),
|
||||
# `codercom/oss-dogfood-vscode-coder` (`:latest`), and
|
||||
# `codercom/oss-dogfood-nix` (`:latest`), plus a per-branch tag on
|
||||
# each. `test_image` validates tooling as above.
|
||||
# each. The image-tooling validation runs as above before any
|
||||
# push, so a broken image never reaches Docker Hub.
|
||||
# `deploy_template` runs `terraform apply` and creates new
|
||||
# `coderd_template` versions on dev.coder.com whose `name` is the
|
||||
# commit short SHA. Content is unchanged when neither `dogfood/**`
|
||||
@@ -37,6 +40,8 @@ on:
|
||||
- "flake.nix"
|
||||
- "mise.toml"
|
||||
- "mise.lock"
|
||||
- "scripts/dogfood/**"
|
||||
- "scripts/dogfood_test_image.sh"
|
||||
pull_request:
|
||||
paths:
|
||||
- "dogfood/**"
|
||||
@@ -45,6 +50,8 @@ on:
|
||||
- "flake.nix"
|
||||
- "mise.toml"
|
||||
- "mise.lock"
|
||||
- "scripts/dogfood/**"
|
||||
- "scripts/dogfood_test_image.sh"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -58,7 +65,16 @@ jobs:
|
||||
image-version: ["22.04", "26.04", "nix"]
|
||||
|
||||
if: github.actor != 'dependabot[bot]' # Skip Dependabot PRs
|
||||
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || 'ubuntu-latest' }}
|
||||
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # push the dogfood base image to ghcr.io/coder/oss-dogfood-base
|
||||
env:
|
||||
# MISE_EXPERIMENTAL opts into the experimental `oci` subcommand.
|
||||
# Trust is set via a config file (see the Install mise step
|
||||
# below) rather than MISE_TRUSTED_CONFIG_PATHS so the workspace
|
||||
# template can keep parity with the same file-based approach.
|
||||
MISE_EXPERIMENTAL: "1"
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0
|
||||
@@ -119,6 +135,58 @@ jobs:
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
if: matrix.image-version != 'nix'
|
||||
|
||||
- name: Install mise
|
||||
if: matrix.image-version != 'nix'
|
||||
# MISE_VERSION + MISE_SHA256 match dogfood/coder/ubuntu-*/Dockerfile.base
|
||||
# so the mise binary baking the image is the same one a workspace
|
||||
# ships with. `min_version` in mise.toml catches downgrades.
|
||||
# Write trust config to ~/.config/mise/conf.d/ instead of using
|
||||
# MISE_TRUSTED_CONFIG_PATHS so the same file-based approach
|
||||
# works in workspaces (where the user owns the file).
|
||||
env:
|
||||
MISE_VERSION: v2026.5.12
|
||||
MISE_SHA256: a238972a3162d710b85b28c324372e96ca4e4b486c81fe78695000d9fbc77c48
|
||||
WORKSPACE: ${{ github.workspace }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
curl --silent --show-error --location --fail \
|
||||
"https://github.com/jdx/mise/releases/download/${MISE_VERSION}/mise-${MISE_VERSION}-linux-x64" \
|
||||
--output /tmp/mise
|
||||
echo "${MISE_SHA256} /tmp/mise" | sha256sum -c
|
||||
sudo install -m 0755 /tmp/mise /usr/local/bin/mise
|
||||
rm /tmp/mise
|
||||
mise --version
|
||||
mkdir -p "$HOME/.config/mise/conf.d"
|
||||
cat > "$HOME/.config/mise/conf.d/00-ci-trust.toml" <<EOF
|
||||
[settings]
|
||||
trusted_config_paths = ["$WORKSPACE"]
|
||||
EOF
|
||||
|
||||
- name: Compute image SHAs
|
||||
# Match the fork guard on the downstream consumers of these
|
||||
# outputs: nothing reads `steps.shas.outputs.*` outside the
|
||||
# base-push + mise-oci pipeline, which is gated below.
|
||||
if: matrix.image-version != 'nix' && !github.event.pull_request.head.repo.fork
|
||||
id: shas
|
||||
env:
|
||||
IMAGE_VERSION: ${{ matrix.image-version }}
|
||||
run: |
|
||||
base_sha="$(./scripts/dogfood/compute-base-sha.sh "$IMAGE_VERSION")"
|
||||
final_sha="$(./scripts/dogfood/compute-final-sha.sh "$IMAGE_VERSION")"
|
||||
echo "base_sha=${base_sha}" >> "$GITHUB_OUTPUT"
|
||||
echo "final_sha=${final_sha}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Login to GHCR
|
||||
# Fork PRs get a read-only GITHUB_TOKEN that cannot push to
|
||||
# ghcr.io. Skip the entire GHCR-dependent pipeline (base push +
|
||||
# mise oci build) for fork PRs; the nix matrix entry still runs.
|
||||
if: matrix.image-version != 'nix' && !github.event.pull_request.head.repo.fork
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: github.ref == 'refs/heads/main'
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
@@ -126,48 +194,122 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Build and push Ubuntu 22.04 image
|
||||
- name: Build base image
|
||||
uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0
|
||||
if: matrix.image-version != 'nix' && !github.event.pull_request.head.repo.fork
|
||||
with:
|
||||
project: b4q6ltmpzh
|
||||
token: ${{ secrets.DEPOT_TOKEN }}
|
||||
buildx-fallback: true
|
||||
# Context is the repo root so the Dockerfile can COPY the
|
||||
# project mise.toml that the image installs from. The
|
||||
# github_token secret raises aqua's GitHub API quota during
|
||||
# `mise install`.
|
||||
# Context is the repo root so Dockerfile.base can COPY the
|
||||
# distro-specific files/ tree and configure-chrome-flags.sh.
|
||||
context: "{{defaultContext}}"
|
||||
file: dogfood/coder/ubuntu-22.04/Dockerfile
|
||||
secrets: |
|
||||
github_token=${{ secrets.GITHUB_TOKEN }}
|
||||
file: dogfood/coder/ubuntu-${{ matrix.image-version }}/Dockerfile.base
|
||||
pull: true
|
||||
save: true
|
||||
push: ${{ github.ref == 'refs/heads/main' }}
|
||||
# TODO: move the `latest` tag to 26.04 soon. we don't want to transition
|
||||
# it immediately because that would make workspaces switch to it
|
||||
# automatically without any grace period.
|
||||
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:22.04,codercom/oss-dogfood:latest"
|
||||
if: matrix.image-version == '22.04'
|
||||
# Push to ghcr.io on every non-fork CI run so the downstream
|
||||
# mise oci build can --from a real registry. The base-sha tag
|
||||
# is a cache key (see scripts/dogfood/compute-base-sha.sh) so
|
||||
# commits that don't change base inputs reuse the previous
|
||||
# build.
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/coder/oss-dogfood-base:${{ matrix.image-version }}-${{ steps.shas.outputs.base_sha }}
|
||||
ghcr.io/coder/oss-dogfood-base:${{ matrix.image-version }}-${{ steps.docker-tag-name.outputs.tag }}
|
||||
|
||||
- name: Build and push Ubuntu 26.04 image
|
||||
uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0
|
||||
with:
|
||||
project: b4q6ltmpzh
|
||||
token: ${{ secrets.DEPOT_TOKEN }}
|
||||
buildx-fallback: true
|
||||
# Context is the repo root so the Dockerfile can COPY the
|
||||
# project mise.toml that the image installs from. The
|
||||
# github_token secret raises aqua's GitHub API quota during
|
||||
# `mise install`.
|
||||
context: "{{defaultContext}}"
|
||||
file: dogfood/coder/ubuntu-26.04/Dockerfile
|
||||
secrets: |
|
||||
github_token=${{ secrets.GITHUB_TOKEN }}
|
||||
pull: true
|
||||
save: true
|
||||
push: ${{ github.ref == 'refs/heads/main' }}
|
||||
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:26.04"
|
||||
if: matrix.image-version == '26.04'
|
||||
- name: Install mise tools
|
||||
if: matrix.image-version != 'nix' && !github.event.pull_request.head.repo.fork
|
||||
# `mise oci build` packages already-installed tools into OCI
|
||||
# layers; it does not install them. Run `mise install` first so
|
||||
# the tools land in MISE_DATA_DIR on the runner.
|
||||
# github_token raises aqua's API quota during tool installs.
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# --locked refuses to resolve URLs at install time and forces
|
||||
# the runner to consume what mise.lock already committed,
|
||||
# so a forgotten lockfile entry fails CI instead of silently
|
||||
# being added on next run.
|
||||
mise install --yes --locked
|
||||
# Put mise's shims dir on PATH for subsequent steps so
|
||||
# `mise oci push --tool crane` can find crane (and any other
|
||||
# mise-managed binary it shells out to).
|
||||
echo "$HOME/.local/share/mise/shims" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Build mise oci layer
|
||||
if: matrix.image-version != 'nix' && !github.event.pull_request.head.repo.fork
|
||||
env:
|
||||
IMAGE_VERSION: ${{ matrix.image-version }}
|
||||
BASE_SHA: ${{ steps.shas.outputs.base_sha }}
|
||||
FINAL_SHA: ${{ steps.shas.outputs.final_sha }}
|
||||
# --output makes the OCI layout location explicit so the later
|
||||
# `mise oci push --image-dir` steps point at the right path even
|
||||
# if mise oci's default ever changes (it's experimental).
|
||||
run: |
|
||||
mise oci build \
|
||||
--from "ghcr.io/coder/oss-dogfood-base:${IMAGE_VERSION}-${BASE_SHA}" \
|
||||
--tag "codercom/oss-dogfood:${FINAL_SHA}-${IMAGE_VERSION}" \
|
||||
--output ./mise-oci
|
||||
|
||||
# Load the OCI layout into the local Docker daemon so the next
|
||||
# step can `docker run` it. crane lacks a direct OCI-layout-to-
|
||||
# daemon command, but its built-in registry server gives us a
|
||||
# simple two-hop path with no extra dependencies.
|
||||
- name: Load mise oci image into Docker daemon
|
||||
if: matrix.image-version != 'nix' && !github.event.pull_request.head.repo.fork
|
||||
env:
|
||||
IMAGE_VERSION: ${{ matrix.image-version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
crane registry serve --address localhost:5000 &
|
||||
reg_pid=$!
|
||||
trap 'kill $reg_pid 2>/dev/null || true' EXIT
|
||||
for _ in 1 2 3 4 5; do
|
||||
curl -sf http://localhost:5000/v2/ >/dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
crane push ./mise-oci "localhost:5000/dogfood-test:${IMAGE_VERSION}"
|
||||
docker pull "localhost:5000/dogfood-test:${IMAGE_VERSION}"
|
||||
docker tag "localhost:5000/dogfood-test:${IMAGE_VERSION}" "dogfood-test:${IMAGE_VERSION}"
|
||||
|
||||
# Validate the dogfood image's tooling by running make gen, fmt,
|
||||
# lint, and a fat build inside it. Failures here block the
|
||||
# Docker Hub push below so broken images never reach workspaces.
|
||||
- name: Test image tooling
|
||||
if: matrix.image-version != 'nix' && !github.event.pull_request.head.repo.fork
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./scripts/dogfood_test_image.sh "dogfood-test:${{ matrix.image-version }}"
|
||||
|
||||
- name: Push final Ubuntu 22.04 image
|
||||
if: matrix.image-version == '22.04' && github.ref == 'refs/heads/main'
|
||||
env:
|
||||
FINAL_SHA: ${{ steps.shas.outputs.final_sha }}
|
||||
DOCKER_TAG: ${{ steps.docker-tag-name.outputs.tag }}
|
||||
# --image-dir points at the OCI layout written by the previous
|
||||
# `mise oci build` step. Without it, `mise oci push` rebuilds
|
||||
# from mise.toml and forgets the --from base. --tool crane
|
||||
# forces the registry client mise oci shells out to, so we
|
||||
# don't drift between the apt-shipped skopeo on whatever runner
|
||||
# image we land on.
|
||||
# TODO: move the `latest` tag to 26.04 soon. we don't want to
|
||||
# transition it immediately because that would make workspaces
|
||||
# switch to it automatically without any grace period.
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for tag in "${FINAL_SHA}-22.04" "$DOCKER_TAG" 22.04 latest; do
|
||||
mise oci push --tool crane --image-dir ./mise-oci "codercom/oss-dogfood:$tag"
|
||||
done
|
||||
|
||||
- name: Push final Ubuntu 26.04 image
|
||||
if: matrix.image-version == '26.04' && github.ref == 'refs/heads/main'
|
||||
env:
|
||||
FINAL_SHA: ${{ steps.shas.outputs.final_sha }}
|
||||
DOCKER_TAG: ${{ steps.docker-tag-name.outputs.tag }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for tag in "${FINAL_SHA}-26.04" "$DOCKER_TAG" 26.04; do
|
||||
mise oci push --tool crane --image-dir ./mise-oci "codercom/oss-dogfood:$tag"
|
||||
done
|
||||
|
||||
- name: Build and push vscode-coder image
|
||||
uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0
|
||||
@@ -201,59 +343,8 @@ jobs:
|
||||
env:
|
||||
DOCKER_TAG: ${{ steps.docker-tag-name.outputs.tag }}
|
||||
|
||||
# Validate that the Ubuntu dogfood images contain working tooling.
|
||||
# Failures here block template deployment (deploy_template).
|
||||
test_image:
|
||||
needs: build_image
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image-version: ["22.04", "26.04"]
|
||||
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Depot CLI
|
||||
uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
|
||||
# Near-instant cache hit from build_image; loads into local daemon
|
||||
# without pushing to a registry.
|
||||
- name: Load dogfood image from Depot cache
|
||||
uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0
|
||||
with:
|
||||
project: b4q6ltmpzh
|
||||
token: ${{ secrets.DEPOT_TOKEN }}
|
||||
buildx-fallback: true
|
||||
context: "{{defaultContext}}"
|
||||
file: dogfood/coder/ubuntu-${{ matrix.image-version }}/Dockerfile
|
||||
secrets: |
|
||||
github_token=${{ secrets.GITHUB_TOKEN }}
|
||||
pull: true
|
||||
load: true
|
||||
push: false
|
||||
tags: "dogfood-test:${{ matrix.image-version }}"
|
||||
|
||||
- name: Test image tooling
|
||||
run: ./scripts/dogfood_test_image.sh "dogfood-test:${{ matrix.image-version }}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
deploy_template:
|
||||
needs:
|
||||
- build_image
|
||||
- test_image
|
||||
needs: build_image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Necessary for GCP authentication (https://github.com/google-github-actions/setup-gcloud#usage)
|
||||
|
||||
@@ -96,6 +96,15 @@ __debug_bin*
|
||||
# Local agent configuration
|
||||
AGENTS.local.md
|
||||
|
||||
# mise local overrides
|
||||
mise.local.toml
|
||||
.mise.local.toml
|
||||
mise.*.local.toml
|
||||
.mise.*.local.toml
|
||||
|
||||
# `mise oci build` writes its OCI image layout here by default.
|
||||
mise-oci/
|
||||
|
||||
/.env
|
||||
|
||||
# Ignore plans written by AI agents.
|
||||
|
||||
@@ -1636,12 +1636,6 @@ else
|
||||
endif
|
||||
.PHONY: test-e2e
|
||||
|
||||
dogfood/coder/nix.hash: flake.nix flake.lock
|
||||
sha256sum flake.nix flake.lock >./dogfood/coder/nix.hash
|
||||
|
||||
dogfood/coder/mise.hash: mise.toml mise.lock
|
||||
sha256sum mise.toml mise.lock >./dogfood/coder/mise.hash
|
||||
|
||||
# Count the number of test databases created per test package.
|
||||
count-test-databases:
|
||||
PGPASSWORD=postgres psql -h localhost -U postgres -d coder_testing -P pager=off -c 'SELECT test_package, count(*) as count from test_databases GROUP BY test_package ORDER BY count DESC'
|
||||
|
||||
+57
-40
@@ -3,62 +3,79 @@
|
||||
# tag names.
|
||||
build_tag ?= $(shell git rev-parse --abbrev-ref HEAD | sed "s/\\//-/")
|
||||
|
||||
# The Dockerfiles consume the repo root as build context so they can
|
||||
# reach the project mise.toml. Each variant still tracks its own
|
||||
# files/ tree under dogfood/coder/ubuntu-<release>/.
|
||||
# The base Dockerfile consumes the repo root as build context so it can
|
||||
# reach the distro-specific files/ tree and configure-chrome-flags.sh
|
||||
# under dogfood/coder/ubuntu-<release>/.
|
||||
REPO_ROOT := $(shell git rev-parse --show-toplevel)
|
||||
|
||||
# Mise's aqua backend exhausts GitHub's unauthenticated API quota
|
||||
# quickly. Plumb a token through to the mise install layer when one
|
||||
# is available. Two equivalent ways to supply it:
|
||||
# GITHUB_TOKEN=ghp_... - taken straight from the environment
|
||||
# (matches GitHub Actions, where
|
||||
# secrets.GITHUB_TOKEN is auto-provided)
|
||||
# GITHUB_TOKEN_FILE=/path - read the token from a file
|
||||
# If neither is set the build still runs but may hit 403s.
|
||||
ifneq ($(GITHUB_TOKEN_FILE),)
|
||||
docker_secret_arg := --secret id=github_token,src="$(GITHUB_TOKEN_FILE)"
|
||||
else ifneq ($(GITHUB_TOKEN),)
|
||||
docker_secret_arg := --secret id=github_token,env=GITHUB_TOKEN
|
||||
# Pick a container runtime. On macOS we prefer Apple's `container` CLI
|
||||
# when present (it produces a Linux VM-backed amd64 image without
|
||||
# Docker Desktop); otherwise fall back to docker. Linux always uses
|
||||
# docker.
|
||||
OS := $(shell uname -s)
|
||||
ifeq ($(OS),Darwin)
|
||||
CONTAINER_RUNTIME ?= $(shell command -v container >/dev/null 2>&1 && echo container || echo docker)
|
||||
else
|
||||
CONTAINER_RUNTIME ?= docker
|
||||
endif
|
||||
|
||||
# Apple's `container` defaults to the host arch; the dogfood image is
|
||||
# amd64-only, so pin it.
|
||||
ifeq ($(CONTAINER_RUNTIME),container)
|
||||
PLATFORM_ARG := --platform linux/amd64
|
||||
else
|
||||
PLATFORM_ARG :=
|
||||
endif
|
||||
|
||||
ifeq ($(OS),Linux)
|
||||
# `mise oci build` packages already-installed tools; the install
|
||||
# has to run first. The macOS wrapper does this inside the
|
||||
# container; on Linux we chain it here.
|
||||
MISE_OCI := mise install --yes && MISE_EXPERIMENTAL=1 mise oci
|
||||
else
|
||||
MISE_OCI := CONTAINER_RUNTIME=$(CONTAINER_RUNTIME) $(REPO_ROOT)/scripts/dogfood/mise-oci-wrapper.sh
|
||||
endif
|
||||
|
||||
.PHONY: build build-ubuntu-22.04 build-ubuntu-26.04 \
|
||||
build-base-ubuntu-22.04 build-base-ubuntu-26.04 \
|
||||
update-keys update-keys-ubuntu-22.04 update-keys-ubuntu-26.04
|
||||
|
||||
build: build-ubuntu-22.04 build-ubuntu-26.04
|
||||
.PHONY: build
|
||||
|
||||
build-ubuntu-22.04:
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
-f dogfood/coder/ubuntu-22.04/Dockerfile \
|
||||
-t "codercom/oss-dogfood:22.04-$(build_tag)" \
|
||||
$(docker_secret_arg) \
|
||||
# Caveat: `build-ubuntu-*` requires the base image to be pullable from a
|
||||
# registry that `mise oci`'s HTTPS client can reach (ghcr.io, a local
|
||||
# `registry:2` sidecar, etc.). `--from coderdev/oss-dogfood-base:*-local`
|
||||
# only resolves when a registry mirror is set up alongside; without it,
|
||||
# `mise oci build` fails because the wrapper container cannot see the
|
||||
# host's local image store. The `build-base-ubuntu-*` targets on their
|
||||
# own work end to end without any registry. See
|
||||
# scripts/dogfood/mise-oci-wrapper.sh for the full story.
|
||||
build-base-ubuntu-22.04:
|
||||
$(CONTAINER_RUNTIME) build $(PLATFORM_ARG) \
|
||||
-f "$(REPO_ROOT)/dogfood/coder/ubuntu-22.04/Dockerfile.base" \
|
||||
-t "coderdev/oss-dogfood-base:22.04-local" \
|
||||
"$(REPO_ROOT)"
|
||||
.PHONY: build-ubuntu-22.04
|
||||
|
||||
build-ubuntu-26.04:
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
-f dogfood/coder/ubuntu-26.04/Dockerfile \
|
||||
-t "codercom/oss-dogfood:26.04-$(build_tag)" \
|
||||
$(docker_secret_arg) \
|
||||
build-base-ubuntu-26.04:
|
||||
$(CONTAINER_RUNTIME) build $(PLATFORM_ARG) \
|
||||
-f "$(REPO_ROOT)/dogfood/coder/ubuntu-26.04/Dockerfile.base" \
|
||||
-t "coderdev/oss-dogfood-base:26.04-local" \
|
||||
"$(REPO_ROOT)"
|
||||
.PHONY: build-ubuntu-26.04
|
||||
|
||||
push: push-ubuntu-22.04 push-ubuntu-26.04
|
||||
.PHONY: push
|
||||
build-ubuntu-22.04: build-base-ubuntu-22.04
|
||||
$(MISE_OCI) build \
|
||||
--from "coderdev/oss-dogfood-base:22.04-local" \
|
||||
--tag "codercom/oss-dogfood:22.04-$(build_tag)"
|
||||
|
||||
push-ubuntu-22.04: build-ubuntu-22.04
|
||||
docker push ${build_tag}
|
||||
.PHONY: push-ubuntu-22.04
|
||||
|
||||
push-ubuntu-26.04: build-ubuntu-26.04
|
||||
docker push ${build_tag}
|
||||
.PHONY: push-ubuntu-26.04
|
||||
build-ubuntu-26.04: build-base-ubuntu-26.04
|
||||
$(MISE_OCI) build \
|
||||
--from "coderdev/oss-dogfood-base:26.04-local" \
|
||||
--tag "codercom/oss-dogfood:26.04-$(build_tag)"
|
||||
|
||||
update-keys: update-keys-ubuntu-22.04 update-keys-ubuntu-26.04
|
||||
.PHONY: update-keys
|
||||
|
||||
update-keys-ubuntu-22.04:
|
||||
./ubuntu-22.04/update-keys.sh
|
||||
.PHONY: update-keys-ubuntu-22.04
|
||||
|
||||
update-keys-ubuntu-26.04:
|
||||
./ubuntu-26.04/update-keys.sh
|
||||
.PHONY: update-keys-ubuntu-26.04
|
||||
|
||||
+35
-7
@@ -687,10 +687,41 @@ resource "coder_script" "install-deps" {
|
||||
coder exp sync want install-deps git-clone
|
||||
coder exp sync start install-deps
|
||||
|
||||
# Seed a user-owned mise trust config on the persistent home
|
||||
# volume. The image ships /etc/mise/conf.d/00-coder-trust.toml as
|
||||
# a fallback, but mise's `trusted_config_paths` setting doesn't
|
||||
# merge across config layers, so anything the user adds to their
|
||||
# own file would otherwise replace the system fallback. Writing
|
||||
# this file once (if-absent) seeds the defaults under
|
||||
# ~/.config/mise/conf.d/ where the user can edit it and the edits
|
||||
# survive workspace restart.
|
||||
TRUST_FILE="$HOME/.config/mise/conf.d/00-coder-trust.toml"
|
||||
if [ ! -f "$TRUST_FILE" ]; then
|
||||
mkdir -p "$(dirname "$TRUST_FILE")"
|
||||
cat > "$TRUST_FILE" <<'TRUST'
|
||||
# mise trust paths for the dogfood workspace. Edit to add your own
|
||||
# paths; this file lives on the persistent home volume so changes
|
||||
# survive workspace restart. The install-deps coder_script only
|
||||
# writes this file when it's absent.
|
||||
[settings]
|
||||
trusted_config_paths = [
|
||||
"/home/coder/coder",
|
||||
"/etc/mise",
|
||||
]
|
||||
TRUST
|
||||
fi
|
||||
|
||||
# Install playwright dependencies
|
||||
# We want to use the playwright version from site/package.json
|
||||
cd "${local.repo_dir}" && make clean
|
||||
cd "${local.repo_dir}/site" && pnpm install
|
||||
|
||||
# Two playwright installs: site/'s @playwright/test and
|
||||
# @playwright/mcp@0.0.75 bundle different playwright-core versions
|
||||
# with different chromium revisions, and both are used at runtime
|
||||
# (site tests + the claude-code/codex MCP servers below).
|
||||
cd "${local.repo_dir}/site" && pnpm exec playwright install chromium
|
||||
npx --yes --package=@playwright/mcp@0.0.75 playwright-core install --no-shell chromium
|
||||
EOT
|
||||
}
|
||||
|
||||
@@ -823,13 +854,10 @@ data "docker_registry_image" "dogfood" {
|
||||
|
||||
resource "docker_image" "dogfood" {
|
||||
name = "${local.image_tags[data.coder_parameter.image_type.value]}@${data.docker_registry_image.dogfood.sha256_digest}"
|
||||
# CI rebuilds and pushes when any baked-in input changes, so the
|
||||
# digest captures every effective change on its own.
|
||||
pull_triggers = [
|
||||
data.docker_registry_image.dogfood.sha256_digest,
|
||||
sha1(join("", [for f in fileset(path.module, "files/*") : filesha1(f)])),
|
||||
filesha1("ubuntu-22.04/Dockerfile"),
|
||||
filesha1("ubuntu-26.04/Dockerfile"),
|
||||
filesha1("nix.hash"),
|
||||
filesha1("mise.hash"),
|
||||
]
|
||||
keep_locally = true
|
||||
}
|
||||
@@ -969,7 +997,7 @@ module "claude-code" {
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": ["--", "@playwright/mcp@latest", "--headless", "--isolated", "--no-sandbox"]
|
||||
"args": ["--", "@playwright/mcp@0.0.75", "--headless", "--isolated", "--no-sandbox"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1000,7 +1028,7 @@ module "codex" {
|
||||
mcp = <<-EOT
|
||||
[mcp_servers.playwright]
|
||||
command = "npx"
|
||||
args = ["--", "@playwright/mcp@latest", "--headless", "--isolated", "--no-sandbox"]
|
||||
args = ["--", "@playwright/mcp@0.0.75", "--headless", "--isolated", "--no-sandbox"]
|
||||
type = "stdio"
|
||||
EOT
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
b5226f4cb3256b5f67df1344f46968f7275b1b8309380506d25782168bab5622 mise.toml
|
||||
b5cf72024409932659abde978440fca1d01a75bb11f1476e2410f7d4b83aa9c0 mise.lock
|
||||
@@ -1,2 +0,0 @@
|
||||
f09cd2cbbcdf00f5e855c6ddecab6008d11d871dc4ca5e1bc90aa14d4e3a2cfd flake.nix
|
||||
0d2489a26d149dade9c57ba33acfdb309b38100ac253ed0c67a2eca04a187e37 flake.lock
|
||||
+29
-38
@@ -38,6 +38,7 @@ RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/u
|
||||
bat \
|
||||
bats \
|
||||
bind9-dnsutils \
|
||||
bison \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
containerd.io \
|
||||
@@ -50,6 +51,7 @@ RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/u
|
||||
fd-find \
|
||||
file \
|
||||
fish \
|
||||
flex \
|
||||
gettext-base \
|
||||
git \
|
||||
gnupg \
|
||||
@@ -66,6 +68,8 @@ RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/u
|
||||
language-pack-en \
|
||||
less \
|
||||
libgbm-dev \
|
||||
libicu-dev \
|
||||
libreadline-dev \
|
||||
libssl-dev \
|
||||
lsb-release \
|
||||
lsof \
|
||||
@@ -93,10 +97,12 @@ RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/u
|
||||
tmux \
|
||||
traceroute \
|
||||
unzip \
|
||||
uuid-dev \
|
||||
vim \
|
||||
wget \
|
||||
xauth \
|
||||
zip \
|
||||
zlib1g-dev \
|
||||
zsh \
|
||||
zstd && \
|
||||
# Delete package cache to avoid consuming space in layer
|
||||
@@ -183,45 +189,28 @@ RUN install --directory --owner=coder --group=coder --mode=0755 "${MISE_INSTALL_
|
||||
test -x /usr/local/bin/mise && \
|
||||
sudo --login --user=coder /bin/bash -lc 'set -euo pipefail && mise_bin="$(readlink --canonicalize /usr/local/bin/mise)" && test -w "$(dirname "$mise_bin")" && /usr/local/bin/mise --version && /usr/local/bin/mise self-update --help >/dev/null && /usr/local/bin/mise upgrade --help >/dev/null'
|
||||
|
||||
# Trusted paths skip mise's per-config trust prompt for the baked-in
|
||||
# system config and the coder repo when cloned at the canonical
|
||||
# /home/coder/coder location. Other repos a user clones still get
|
||||
# the one-time `mise trust` prompt; pre-trusting all of /home/coder
|
||||
# would let any mise.toml under the home dir auto-run [hooks]/[tasks].
|
||||
ENV MISE_DATA_DIR=/home/coder/.local/share/mise \
|
||||
MISE_TRUSTED_CONFIG_PATHS=/home/coder/coder:/etc/mise
|
||||
ENV MISE_DATA_DIR=/home/coder/.local/share/mise
|
||||
|
||||
# Bake the project manifest in as mise's system config and ship
|
||||
# the lockfile alongside it so mise verifies download checksums
|
||||
# during install. We do NOT override MISE_GLOBAL_CONFIG_FILE; that
|
||||
# would re-target `mise use --global` away from the user's
|
||||
# ~/.config/mise/config.toml (on the home volume) into this
|
||||
# image-only path, breaking the workflow.
|
||||
#
|
||||
# We pre-create /etc/mise as 0755 because COPY's implicitly-created
|
||||
# parent dirs inherit the --chmod, which would leave /etc/mise
|
||||
# without the `x` bit and unreachable to the coder user. We also
|
||||
# chown to coder so mise can write the temp lockfile it uses for
|
||||
# atomic rename when updating /etc/mise/mise.lock during installs.
|
||||
RUN install --directory --owner=coder --group=coder --mode=0755 /etc/mise
|
||||
COPY --chown=coder:coder --chmod=0644 mise.toml /etc/mise/config.toml
|
||||
COPY --chown=coder:coder --chmod=0644 mise.lock /etc/mise/mise.lock
|
||||
# Bake a system fallback for trusted_config_paths so the canonical
|
||||
# /home/coder/coder repo and the mise-oci-synthesized /etc/mise/config.toml
|
||||
# are trusted without a per-config prompt. The workspace template
|
||||
# (dogfood/coder/main.tf install-deps coder_script) seeds a matching
|
||||
# user-owned ~/.config/mise/conf.d/00-coder-trust.toml on workspace
|
||||
# start, which the user can edit to add their own paths; that file
|
||||
# lives on the persistent home volume and overrides this fallback.
|
||||
RUN install --directory --mode=0755 /etc/mise /etc/mise/conf.d
|
||||
COPY --chmod=0644 <<'EOF' /etc/mise/conf.d/00-coder-trust.toml
|
||||
[settings]
|
||||
trusted_config_paths = [
|
||||
"/home/coder/coder",
|
||||
"/etc/mise",
|
||||
]
|
||||
EOF
|
||||
|
||||
# Pre-install tools into /opt/mise/data so they survive the home
|
||||
# volume's copy-on-first-mount. MISE_SHARED_INSTALL_DIRS (set below)
|
||||
# exposes them at runtime; MISE_DATA_DIR stays on the home volume.
|
||||
# github_token authenticates aqua's API calls (optional secret).
|
||||
# Reserve the mount_point declared in mise.toml [oci]. The path is
|
||||
# duplicated below in MISE_SHARED_INSTALL_DIRS and PATH; if it ever
|
||||
# changes, update all three plus mise.toml.
|
||||
RUN install --directory --owner=coder --group=coder --mode=0755 /opt/mise /opt/mise/data
|
||||
RUN --mount=type=secret,id=github_token,required=false \
|
||||
gh_token="$(cat /run/secrets/github_token 2>/dev/null || true)" && \
|
||||
sudo --user=coder env \
|
||||
"MISE_DATA_DIR=/opt/mise/data" \
|
||||
"MISE_TRUSTED_CONFIG_PATHS=$MISE_TRUSTED_CONFIG_PATHS" \
|
||||
"GITHUB_TOKEN=$gh_token" \
|
||||
/usr/local/bin/mise install --yes && \
|
||||
PATH="/opt/mise/data/shims:$PATH" MISE_DATA_DIR=/opt/mise/data pnpm dlx playwright@1.47.0 install --with-deps chromium && \
|
||||
rm -rf /opt/mise/data/cache /opt/mise/data/downloads && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Homebrew as the coder user so the supported Linux prefix remains
|
||||
# writable after the image build.
|
||||
@@ -229,10 +218,12 @@ RUN sudo --login --user=coder env NONINTERACTIVE=1 CI=1 /bin/bash -lc 'set -euo
|
||||
test -x /home/linuxbrew/.linuxbrew/bin/brew && \
|
||||
sudo --login --user=coder /bin/bash -lc '/home/linuxbrew/.linuxbrew/bin/brew --version'
|
||||
|
||||
# Adjust OpenSSH config
|
||||
# Adjust OpenSSH config and drop the apt lists / cache that survived
|
||||
# the package installs above. No later step in this image needs apt.
|
||||
RUN echo "PermitUserEnvironment yes" >>/etc/ssh/sshd_config && \
|
||||
echo "X11Forwarding yes" >>/etc/ssh/sshd_config && \
|
||||
echo "X11UseLocalhost no" >>/etc/ssh/sshd_config
|
||||
echo "X11UseLocalhost no" >>/etc/ssh/sshd_config && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
USER coder
|
||||
|
||||
+29
-38
@@ -37,6 +37,7 @@ RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/u
|
||||
bat \
|
||||
bats \
|
||||
bind9-dnsutils \
|
||||
bison \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
containerd.io \
|
||||
@@ -49,6 +50,7 @@ RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/u
|
||||
fd-find \
|
||||
file \
|
||||
fish \
|
||||
flex \
|
||||
gettext-base \
|
||||
git \
|
||||
gnupg \
|
||||
@@ -65,6 +67,8 @@ RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/u
|
||||
language-pack-en \
|
||||
less \
|
||||
libgbm-dev \
|
||||
libicu-dev \
|
||||
libreadline-dev \
|
||||
libssl-dev \
|
||||
lsb-release \
|
||||
lsof \
|
||||
@@ -92,10 +96,12 @@ RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/u
|
||||
tmux \
|
||||
traceroute \
|
||||
unzip \
|
||||
uuid-dev \
|
||||
vim \
|
||||
wget \
|
||||
xauth \
|
||||
zip \
|
||||
zlib1g-dev \
|
||||
zsh \
|
||||
zstd && \
|
||||
# Keep Docker's engine, CLI, runtime, and plugins on the versions selected by
|
||||
@@ -193,45 +199,28 @@ RUN install --directory --owner=coder --group=coder --mode=0755 "${MISE_INSTALL_
|
||||
test -x /usr/local/bin/mise && \
|
||||
sudo --login --user=coder /bin/bash -lc 'set -euo pipefail && mise_bin="$(readlink --canonicalize /usr/local/bin/mise)" && test -w "$(dirname "$mise_bin")" && /usr/local/bin/mise --version && /usr/local/bin/mise self-update --help >/dev/null && /usr/local/bin/mise upgrade --help >/dev/null'
|
||||
|
||||
# Trusted paths skip mise's per-config trust prompt for the baked-in
|
||||
# system config and the coder repo when cloned at the canonical
|
||||
# /home/coder/coder location. Other repos a user clones still get
|
||||
# the one-time `mise trust` prompt; pre-trusting all of /home/coder
|
||||
# would let any mise.toml under the home dir auto-run [hooks]/[tasks].
|
||||
ENV MISE_DATA_DIR=/home/coder/.local/share/mise \
|
||||
MISE_TRUSTED_CONFIG_PATHS=/home/coder/coder:/etc/mise
|
||||
ENV MISE_DATA_DIR=/home/coder/.local/share/mise
|
||||
|
||||
# Bake the project manifest in as mise's system config and ship
|
||||
# the lockfile alongside it so mise verifies download checksums
|
||||
# during install. We do NOT override MISE_GLOBAL_CONFIG_FILE; that
|
||||
# would re-target `mise use --global` away from the user's
|
||||
# ~/.config/mise/config.toml (on the home volume) into this
|
||||
# image-only path, breaking the workflow.
|
||||
#
|
||||
# We pre-create /etc/mise as 0755 because COPY's implicitly-created
|
||||
# parent dirs inherit the --chmod, which would leave /etc/mise
|
||||
# without the `x` bit and unreachable to the coder user. We also
|
||||
# chown to coder so mise can write the temp lockfile it uses for
|
||||
# atomic rename when updating /etc/mise/mise.lock during installs.
|
||||
RUN install --directory --owner=coder --group=coder --mode=0755 /etc/mise
|
||||
COPY --chown=coder:coder --chmod=0644 mise.toml /etc/mise/config.toml
|
||||
COPY --chown=coder:coder --chmod=0644 mise.lock /etc/mise/mise.lock
|
||||
# Bake a system fallback for trusted_config_paths so the canonical
|
||||
# /home/coder/coder repo and the mise-oci-synthesized /etc/mise/config.toml
|
||||
# are trusted without a per-config prompt. The workspace template
|
||||
# (dogfood/coder/main.tf install-deps coder_script) seeds a matching
|
||||
# user-owned ~/.config/mise/conf.d/00-coder-trust.toml on workspace
|
||||
# start, which the user can edit to add their own paths; that file
|
||||
# lives on the persistent home volume and overrides this fallback.
|
||||
RUN install --directory --mode=0755 /etc/mise /etc/mise/conf.d
|
||||
COPY --chmod=0644 <<'EOF' /etc/mise/conf.d/00-coder-trust.toml
|
||||
[settings]
|
||||
trusted_config_paths = [
|
||||
"/home/coder/coder",
|
||||
"/etc/mise",
|
||||
]
|
||||
EOF
|
||||
|
||||
# Pre-install tools into /opt/mise/data so they survive the home
|
||||
# volume's copy-on-first-mount. MISE_SHARED_INSTALL_DIRS (set below)
|
||||
# exposes them at runtime; MISE_DATA_DIR stays on the home volume.
|
||||
# github_token authenticates aqua's API calls (optional secret).
|
||||
# Reserve the mount_point declared in mise.toml [oci]. The path is
|
||||
# duplicated below in MISE_SHARED_INSTALL_DIRS and PATH; if it ever
|
||||
# changes, update all three plus mise.toml.
|
||||
RUN install --directory --owner=coder --group=coder --mode=0755 /opt/mise /opt/mise/data
|
||||
RUN --mount=type=secret,id=github_token,required=false \
|
||||
gh_token="$(cat /run/secrets/github_token 2>/dev/null || true)" && \
|
||||
sudo --user=coder env \
|
||||
"MISE_DATA_DIR=/opt/mise/data" \
|
||||
"MISE_TRUSTED_CONFIG_PATHS=$MISE_TRUSTED_CONFIG_PATHS" \
|
||||
"GITHUB_TOKEN=$gh_token" \
|
||||
/usr/local/bin/mise install --yes && \
|
||||
PATH="/opt/mise/data/shims:$PATH" MISE_DATA_DIR=/opt/mise/data pnpm dlx playwright@1.47.0 install --with-deps chromium && \
|
||||
rm -rf /opt/mise/data/cache /opt/mise/data/downloads && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Homebrew as the coder user so the supported Linux prefix remains
|
||||
# writable after the image build.
|
||||
@@ -239,10 +228,12 @@ RUN sudo --login --user=coder env NONINTERACTIVE=1 CI=1 /bin/bash -lc 'set -euo
|
||||
test -x /home/linuxbrew/.linuxbrew/bin/brew && \
|
||||
sudo --login --user=coder /bin/bash -lc '/home/linuxbrew/.linuxbrew/bin/brew --version'
|
||||
|
||||
# Adjust OpenSSH config
|
||||
# Adjust OpenSSH config and drop the apt lists / cache that survived
|
||||
# the package installs above. No later step in this image needs apt.
|
||||
RUN echo "PermitUserEnvironment yes" >>/etc/ssh/sshd_config && \
|
||||
echo "X11Forwarding yes" >>/etc/ssh/sshd_config && \
|
||||
echo "X11UseLocalhost no" >>/etc/ssh/sshd_config
|
||||
echo "X11UseLocalhost no" >>/etc/ssh/sshd_config && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
USER coder
|
||||
|
||||
@@ -198,7 +198,6 @@
|
||||
pango
|
||||
pixman
|
||||
pkg-config
|
||||
playwright-driver.browsers
|
||||
pnpm
|
||||
postgresql_16
|
||||
proto_gen_go_1_30
|
||||
@@ -278,16 +277,6 @@
|
||||
'';
|
||||
};
|
||||
in
|
||||
# "Keep in mind that you need to use the same version of playwright in your node playwright project as in your nixpkgs, or else playwright will try to use browsers versions that aren't installed!"
|
||||
# - https://nixos.wiki/wiki/Playwright
|
||||
assert pkgs.lib.assertMsg
|
||||
(
|
||||
(pkgs.lib.importJSON ./site/package.json).devDependencies."@playwright/test"
|
||||
== pkgs.playwright-driver.version
|
||||
)
|
||||
"There is a mismatch between the playwright versions in the ./nix.flake (${pkgs.playwright-driver.version}) and the ./site/package.json (${
|
||||
(pkgs.lib.importJSON ./site/package.json).devDependencies."@playwright/test"
|
||||
}) file. Please make sure that they use the exact same version.";
|
||||
rec {
|
||||
inherit formatter;
|
||||
|
||||
@@ -301,9 +290,6 @@
|
||||
{
|
||||
buildInputs = devShellPackages;
|
||||
|
||||
PLAYWRIGHT_BROWSERS_PATH = pkgs.playwright-driver.browsers;
|
||||
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = true;
|
||||
|
||||
LOCALE_ARCHIVE =
|
||||
with pkgs;
|
||||
lib.optionalDrvAttr stdenv.isLinux "${glibcLocales}/lib/locale/locale-archive";
|
||||
|
||||
@@ -288,6 +288,54 @@ url = "https://github.com/sigstore/cosign/releases/download/v2.4.3/cosign-window
|
||||
checksum = "sha256:a2ac24e197111c9430cb2a98f10a641164381afb83df036504868e4ea5720800"
|
||||
url = "https://github.com/sigstore/cosign/releases/download/v2.4.3/cosign-windows-amd64.exe"
|
||||
|
||||
[[tools.crane]]
|
||||
version = "0.21.6"
|
||||
backend = "aqua:google/go-containerregistry"
|
||||
|
||||
[tools.crane."platforms.linux-arm64"]
|
||||
checksum = "sha256:6f61571ca0c2a5da27c2927fcb143255ccb2b74b8977dfcb44645b372ab0f951"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Linux_arm64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.linux-arm64-musl"]
|
||||
checksum = "sha256:6f61571ca0c2a5da27c2927fcb143255ccb2b74b8977dfcb44645b372ab0f951"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Linux_arm64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.linux-x64"]
|
||||
checksum = "sha256:7ebbdcd05b652345c1f5105f8475e518534b90d66f3bdb50017be63f426ea435"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Linux_x86_64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.linux-x64-baseline"]
|
||||
checksum = "sha256:7ebbdcd05b652345c1f5105f8475e518534b90d66f3bdb50017be63f426ea435"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Linux_x86_64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.linux-x64-musl"]
|
||||
checksum = "sha256:7ebbdcd05b652345c1f5105f8475e518534b90d66f3bdb50017be63f426ea435"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Linux_x86_64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.linux-x64-musl-baseline"]
|
||||
checksum = "sha256:7ebbdcd05b652345c1f5105f8475e518534b90d66f3bdb50017be63f426ea435"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Linux_x86_64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.macos-arm64"]
|
||||
checksum = "sha256:a124f297d1e63e8b6c63c2463e43565290d2fd074c1dadb5ca73d737bc7b2484"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Darwin_arm64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.macos-x64"]
|
||||
checksum = "sha256:f1e653737a1d6e8a412734d0ac25009e04eccec98853be2eb59b8c744dede834"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Darwin_x86_64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.macos-x64-baseline"]
|
||||
checksum = "sha256:f1e653737a1d6e8a412734d0ac25009e04eccec98853be2eb59b8c744dede834"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Darwin_x86_64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.windows-x64"]
|
||||
checksum = "sha256:fb78f814f68ab47266458f319ca7e642a303453ea25c8993a14eb9850c56e870"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Windows_x86_64.tar.gz"
|
||||
|
||||
[tools.crane."platforms.windows-x64-baseline"]
|
||||
checksum = "sha256:fb78f814f68ab47266458f319ca7e642a303453ea25c8993a14eb9850c56e870"
|
||||
url = "https://github.com/google/go-containerregistry/releases/download/v0.21.6/go-containerregistry_Windows_x86_64.tar.gz"
|
||||
|
||||
[[tools.doctl]]
|
||||
version = "1.158.0"
|
||||
backend = "aqua:digitalocean/doctl"
|
||||
@@ -734,6 +782,7 @@ url = "https://github.com/protocolbuffers/protobuf/releases/download/v23.4/proto
|
||||
url = "https://github.com/protocolbuffers/protobuf/releases/download/v23.4/protoc-23.4-linux-aarch_64.zip"
|
||||
|
||||
[tools.protoc."platforms.linux-x64"]
|
||||
checksum = "blake3:b1d1a517cb9c8c3cbfc98c708f93e6d3bd8b3ce0e2db1ad8c1491ae8a4067ad2"
|
||||
url = "https://github.com/protocolbuffers/protobuf/releases/download/v23.4/protoc-23.4-linux-x86_64.zip"
|
||||
|
||||
[tools.protoc."platforms.linux-x64-baseline"]
|
||||
@@ -771,6 +820,7 @@ url = "https://github.com/protocolbuffers/protobuf-go/releases/download/v1.30.0/
|
||||
url = "https://github.com/protocolbuffers/protobuf-go/releases/download/v1.30.0/protoc-gen-go.v1.30.0.linux.arm64.tar.gz"
|
||||
|
||||
[tools.protoc-gen-go."platforms.linux-x64"]
|
||||
checksum = "blake3:127ed3a8005b199a8451c258ea8fe8ae0f68dd01b4e52c21c881eb7f1d69a333"
|
||||
url = "https://github.com/protocolbuffers/protobuf-go/releases/download/v1.30.0/protoc-gen-go.v1.30.0.linux.amd64.tar.gz"
|
||||
|
||||
[tools.protoc-gen-go."platforms.linux-x64-baseline"]
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Keep in lockstep with MISE_VERSION in dogfood/coder/ubuntu-*/Dockerfile.base,
|
||||
# .github/workflows/dogfood.yaml, and scripts/dogfood/mise-oci-wrapper.sh.
|
||||
min_version = "2026.5.12"
|
||||
|
||||
[settings]
|
||||
lockfile = true
|
||||
|
||||
@@ -28,6 +32,10 @@ protoc-gen-go = "1.30.0"
|
||||
# Infrastructure, release, and lint CLIs.
|
||||
"aqua:ahmetb/kubectx/kubens" = "0.9.4"
|
||||
cosign = "2.4.3"
|
||||
# crane is the registry client `mise oci push` shells out to. Sourced
|
||||
# here so it travels with the rest of the mise toolset (one source of
|
||||
# truth, deterministic version, no apt drift across CI / wrapper).
|
||||
crane = "0.21.6"
|
||||
golangci-lint = "1.64.8"
|
||||
helm = "3.21.0"
|
||||
kubectx = "0.9.4"
|
||||
@@ -61,3 +69,16 @@ lazygit = "0.61.1"
|
||||
[tools."go:github.com/coder/sqlc/cmd/sqlc"]
|
||||
version = "337309bfb9524f38466a5090e310040fc7af0203"
|
||||
install_env = { CGO_ENABLED = "1" }
|
||||
|
||||
# Consumed by `mise oci build` to produce the dogfood image on top of
|
||||
# ghcr.io/coder/oss-dogfood-base. The `from` and `--tag` fields are
|
||||
# overridden by CLI args at build time per distro; `mount_point`,
|
||||
# `user`, and `workdir` always apply.
|
||||
#
|
||||
# mount_point MUST match the path the base image reserves and exposes
|
||||
# via `MISE_SHARED_INSTALL_DIRS`. Both Dockerfile.base files hardcode
|
||||
# /opt/mise/data in their `install --directory`, ENV, and PATH lines.
|
||||
[oci]
|
||||
mount_point = "/opt/mise/data"
|
||||
user = "coder"
|
||||
workdir = "/home/coder"
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deterministic 12-char content hash of base-image inputs for a distro.
|
||||
# Used as a cache key for the ghcr.io/coder/oss-dogfood-base tag so
|
||||
# commits that don't touch the base inputs reuse the previous build.
|
||||
#
|
||||
# This is NOT a strict content address: the base Dockerfile still
|
||||
# pulls dynamic resources at build time (gh/buildx releases/latest,
|
||||
# chrome stable_current_amd64.deb, apt mirror state, sh.rustup.rs).
|
||||
# Two runs with identical checked-in files can still produce slightly
|
||||
# different bytes. That's acceptable here because the dynamic drift
|
||||
# is small and the cache-hit savings (no full base rebuild for a
|
||||
# typo-fix commit, doc change, mise.toml bump, etc.) is large.
|
||||
set -euo pipefail
|
||||
|
||||
# 12 hex chars matches docker/OCI short-digest displays.
|
||||
HASH_LEN=12
|
||||
|
||||
distro="${1:?usage: $0 <22.04|26.04>}"
|
||||
|
||||
repo_root="$(git rev-parse --show-toplevel)"
|
||||
cd "$repo_root"
|
||||
|
||||
paths=(
|
||||
"dogfood/coder/ubuntu-${distro}/Dockerfile.base"
|
||||
"dogfood/coder/ubuntu-${distro}/files"
|
||||
)
|
||||
if [ "$distro" = "22.04" ]; then
|
||||
paths+=("dogfood/coder/ubuntu-${distro}/configure-chrome-flags.sh")
|
||||
fi
|
||||
|
||||
# Skip editor turds; .swp / ~-files / dotfiles are noise for a build
|
||||
# hash. Include symlinks too: `COPY dogfood/coder/ubuntu-*/files /`
|
||||
# bakes their target paths into the image, so swapping a symlink
|
||||
# changes base content and must invalidate the cache key.
|
||||
find "${paths[@]}" \( -type f -o -type l \) \
|
||||
! -name '.*' \
|
||||
! -name '*.swp' \
|
||||
! -name '*~' \
|
||||
-print0 |
|
||||
LC_ALL=C sort -z |
|
||||
xargs -0 sha256sum |
|
||||
sha256sum |
|
||||
cut -c"1-$HASH_LEN"
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deterministic 12-char content hash of (base inputs + mise inputs) for
|
||||
# a distro. Used as the primary tag for the dogfood image produced by
|
||||
# `mise oci build`, so re-running CI on an unchanged commit reuses the
|
||||
# previous tag. Same cache-key (not strict content address) semantics
|
||||
# as `compute-base-sha.sh`.
|
||||
set -euo pipefail
|
||||
|
||||
# 12 hex chars; see comment in compute-base-sha.sh.
|
||||
HASH_LEN=12
|
||||
|
||||
distro="${1:?usage: $0 <22.04|26.04>}"
|
||||
|
||||
repo_root="$(git rev-parse --show-toplevel)"
|
||||
cd "$repo_root"
|
||||
|
||||
base_sha="$("$repo_root/scripts/dogfood/compute-base-sha.sh" "$distro")"
|
||||
mise_hash="$(sha256sum mise.toml mise.lock | sha256sum | cut -c"1-$HASH_LEN")"
|
||||
|
||||
printf '%s\n' "$base_sha-$mise_hash" | sha256sum | cut -c"1-$HASH_LEN"
|
||||
Executable
+109
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env bash
|
||||
# Local-only helper: runs `mise oci ...` inside a Linux container so
|
||||
# macOS and Windows developers don't need a local Linux VM or a host
|
||||
# install of mise. CI runs `mise oci` directly on its Linux runner; it
|
||||
# does not use this script.
|
||||
#
|
||||
# Builds a small Debian-based wrapper image with the mise binary on
|
||||
# first invocation, then reuses it. Pinning to the same `MISE_VERSION`
|
||||
# baked into `Dockerfile.base` avoids depending on jdxcode/mise Docker
|
||||
# Hub publication cadence, which lags upstream GitHub releases by days.
|
||||
#
|
||||
# `oci build --from <ref>` requires <ref> to be a registry-resolvable
|
||||
# reference; the host's local Docker daemon images are not visible
|
||||
# inside the wrapper. See the Makefile comment.
|
||||
#
|
||||
# Honors CONTAINER_RUNTIME=docker (default) or CONTAINER_RUNTIME=container
|
||||
# (Apple's `container` CLI on macOS).
|
||||
set -euo pipefail
|
||||
|
||||
# Keep MISE_VERSION + MISE_SHA256 in lockstep with the same vars in
|
||||
# .github/workflows/dogfood.yaml and dogfood/coder/ubuntu-*/Dockerfile.base.
|
||||
# A `min_version` check in mise.toml catches downgrades.
|
||||
MISE_VERSION="v2026.5.12"
|
||||
MISE_SHA256="a238972a3162d710b85b28c324372e96ca4e4b486c81fe78695000d9fbc77c48"
|
||||
# Bump the -rN suffix when the Dockerfile heredoc below changes
|
||||
# (mise version, apt packages, trust config, etc.) so cached wrapper
|
||||
# images get rebuilt automatically.
|
||||
WRAPPER_REVISION="r2"
|
||||
RUNTIME="${CONTAINER_RUNTIME:-docker}"
|
||||
WRAPPER_IMAGE="coderdev/mise-oci-wrapper:$MISE_VERSION-$WRAPPER_REVISION"
|
||||
|
||||
# Mount the repo root rather than $PWD: `make -C dogfood/coder` invokes
|
||||
# the wrapper from dogfood/coder/, but the project mise.toml/mise.lock
|
||||
# `mise oci build` consumes live at the repo root.
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
|
||||
platform_arg=()
|
||||
if [ "$RUNTIME" = "container" ]; then
|
||||
platform_arg=(--platform linux/amd64)
|
||||
fi
|
||||
|
||||
# Build the wrapper image on first invocation. The tag includes the
|
||||
# mise version so a bump automatically invalidates the cache; the old
|
||||
# image becomes orphaned and the user can prune it manually.
|
||||
if ! "$RUNTIME" image inspect "$WRAPPER_IMAGE" >/dev/null 2>&1; then
|
||||
echo "[$0] Building $WRAPPER_IMAGE (first-time setup)..." >&2
|
||||
build_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$build_dir"' EXIT
|
||||
cat >"$build_dir/Dockerfile" <<DOCKERFILE
|
||||
FROM debian:bookworm-slim
|
||||
# crane (the registry client mise oci shells out to) is installed via
|
||||
# mise.toml at run time, not here. Keeps the image lean and avoids
|
||||
# version drift between this base layer and what mise oci uses.
|
||||
RUN apt-get update -qq && \\
|
||||
apt-get install -y -qq --no-install-recommends \\
|
||||
ca-certificates curl && \\
|
||||
rm -rf /var/lib/apt/lists/* && \\
|
||||
curl -sSLf "https://github.com/jdx/mise/releases/download/${MISE_VERSION}/mise-${MISE_VERSION}-linux-x64" -o /usr/local/bin/mise && \\
|
||||
echo "${MISE_SHA256} /usr/local/bin/mise" | sha256sum -c && \\
|
||||
chmod +x /usr/local/bin/mise && \\
|
||||
install --directory --mode=0755 /etc/mise /etc/mise/conf.d && \\
|
||||
printf '[settings]\\ntrusted_config_paths = ["/src"]\\n' > /etc/mise/conf.d/00-trust.toml
|
||||
DOCKERFILE
|
||||
"$RUNTIME" build ${platform_arg[@]+"${platform_arg[@]}"} -t "$WRAPPER_IMAGE" "$build_dir"
|
||||
rm -rf "$build_dir"
|
||||
trap - EXIT
|
||||
fi
|
||||
|
||||
token_arg=()
|
||||
if [ -n "${GITHUB_TOKEN:-}" ]; then
|
||||
token_arg=(-e "GITHUB_TOKEN=$GITHUB_TOKEN")
|
||||
fi
|
||||
|
||||
# Mount ~/.docker when present so crane can find registry creds.
|
||||
# Apple `container` CLI users without Docker Desktop won't have it;
|
||||
# local builds don't push, so the skip is fine.
|
||||
docker_config_arg=()
|
||||
if [ -d "$HOME/.docker" ]; then
|
||||
docker_config_arg=(-v "$HOME/.docker:/root/.docker:ro")
|
||||
fi
|
||||
|
||||
# `oci build` needs all mise tools installed so it can package them
|
||||
# into layers. `oci push` needs crane on PATH (mise oci shells out to
|
||||
# it). Both end up running `mise install` first; build installs every
|
||||
# tool, push only crane. The `export PATH=...` exposes mise's shims
|
||||
# dir so `which crane` succeeds when mise oci spawns it as a child.
|
||||
# Single quotes are intentional: $HOME and $@ expand inside the
|
||||
# container's `sh -c`, not in this script.
|
||||
# shellcheck disable=SC2016
|
||||
inner_cmd='mise oci "$@"'
|
||||
case "${1:-}" in
|
||||
build)
|
||||
# shellcheck disable=SC2016
|
||||
inner_cmd='mise install --yes && export PATH="$HOME/.local/share/mise/shims:$PATH" && mise oci "$@"'
|
||||
;;
|
||||
push)
|
||||
# shellcheck disable=SC2016
|
||||
inner_cmd='mise install --yes crane && export PATH="$HOME/.local/share/mise/shims:$PATH" && mise oci "$@"'
|
||||
;;
|
||||
esac
|
||||
|
||||
exec "$RUNTIME" run --rm ${platform_arg[@]+"${platform_arg[@]}"} \
|
||||
-v "$REPO_ROOT":/src -w /src \
|
||||
${docker_config_arg[@]+"${docker_config_arg[@]}"} \
|
||||
-e MISE_EXPERIMENTAL=1 \
|
||||
${token_arg[@]+"${token_arg[@]}"} \
|
||||
--entrypoint /bin/sh \
|
||||
"$WRAPPER_IMAGE" \
|
||||
-c "$inner_cmd" -- "$@"
|
||||
@@ -50,17 +50,21 @@ else
|
||||
fi
|
||||
|
||||
# Helper: run a make target inside the image.
|
||||
# Caches are persisted in named Docker volumes so that subsequent steps (and
|
||||
# repeated local runs) reuse downloaded modules and compiled artifacts.
|
||||
#
|
||||
# Mounts /home/coder/ as a single named volume to mirror the dogfood
|
||||
# workspace template (dogfood/coder/main.tf), so caches (Go modules,
|
||||
# Go build, pnpm store, mise data, etc.) persist the same way they do
|
||||
# in real workspaces. Per-cache subpath volumes would come up
|
||||
# root-owned on first mount because Docker creates non-existent
|
||||
# subpaths root-owned; the home-level volume inherits coder:coder
|
||||
# from the image's existing /home/coder (`useradd --create-home`).
|
||||
run_make() {
|
||||
docker run --rm \
|
||||
--volume coder-dogfood-home:/home/coder \
|
||||
--volume "$(pwd)":/home/coder/coder \
|
||||
--env GIT_CONFIG_COUNT=1 \
|
||||
--env GIT_CONFIG_KEY_0=safe.directory \
|
||||
--env GIT_CONFIG_VALUE_0=/home/coder/coder \
|
||||
--volume coder-dogfood-gomod:/home/coder/go/pkg/mod \
|
||||
--volume coder-dogfood-gobuild:/home/coder/.cache/go-build \
|
||||
--volume coder-dogfood-pnpm:/home/coder/.local/share/pnpm/store \
|
||||
--workdir /home/coder/coder \
|
||||
--network=host \
|
||||
--env GITHUB_TOKEN \
|
||||
|
||||
@@ -37,6 +37,4 @@ echo "protoc-gen-go version: $PROTOC_GEN_GO_REV"
|
||||
PROTOC_GEN_GO_SHA256=$(nix-prefetch-git https://github.com/protocolbuffers/protobuf-go --rev "$PROTOC_GEN_GO_REV" | jq -r .hash)
|
||||
sed -i "s#\(sha256 = \"\)[^\"]*#\1${PROTOC_GEN_GO_SHA256}#" ./flake.nix
|
||||
|
||||
make dogfood/coder/nix.hash
|
||||
|
||||
echo "Flake updated successfully!"
|
||||
|
||||
Reference in New Issue
Block a user