From f46c4ed017612b042a7597c3556294faee18fe14 Mon Sep 17 00:00:00 2001 From: Joakim Persson Date: Fri, 8 May 2026 13:53:08 +0200 Subject: [PATCH] CI matrix: add with-pi and omos-with-pi build variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .gitea/workflows/validate.yml: Adds validate-with-pi (INSTALL_PI=true) and validate-omos-with-pi (INSTALL_OMOS=true + INSTALL_PI=true). amd64 single-arch with smoke test, no push. .gitea/workflows/docker-publish.yml: Adds smoke-with-pi → build-with-pi and smoke-omos-with-pi → build-omos-with-pi job pairs. Each push-by-digest multi-arch (amd64+arm64) to Docker Hub with two tags: ${VERSION}-with-pi + latest-with-pi ${VERSION}-omos-with-pi + latest-omos-with-pi update-description.needs[] extended to wait on both new build jobs. scripts/smoke-test.sh: bun-presence check now treats omos and omos-with-pi as the bun variants. Pi state assertions wait up to 30s for entrypoint-user.sh to finish deploying pi-toolkit + extensions (omos-with-pi has more setup work than the base+pi path; the previous sleep-1 was too short and caused empty-error assertion failures on cold starts). Local verification (arm64 via OrbStack): base → 1871 MB, all checks PASS omos → 2813 MB, all checks PASS with-pi → 2277 MB, all checks PASS omos-with-pi → 3030 MB, all checks PASS CI now produces 8 Docker Hub tags per release: vX.Y.Z[n], latest vX.Y.Z[n]-omos, latest-omos vX.Y.Z[n]-with-pi, latest-with-pi vX.Y.Z[n]-omos-with-pi, latest-omos-with-pi --- .gitea/workflows/docker-publish.yml | 246 +++++++++++++++++++++++++++- .gitea/workflows/validate.yml | 113 +++++++++++++ scripts/smoke-test.sh | 15 +- 3 files changed, 370 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/docker-publish.yml b/.gitea/workflows/docker-publish.yml index 27eddd0..465dde6 100644 --- a/.gitea/workflows/docker-publish.yml +++ b/.gitea/workflows/docker-publish.yml @@ -164,6 +164,115 @@ jobs: - name: Smoke test (amd64) run: bash scripts/smoke-test.sh opencode-devbox:smoke-omos --variant omos + smoke-with-pi: + runs-on: ubuntu-latest + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Force IPv4 for Docker Hub + run: echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf + + - name: Reclaim runner disk + run: | + set -x + df -h / || true + rm -rf \ + /opt/hostedtoolcache \ + /opt/microsoft \ + /opt/az \ + /opt/ghc \ + /usr/local/.ghcup \ + /usr/share/dotnet \ + /usr/share/swift \ + /usr/local/lib/android \ + /usr/local/share/powershell \ + /usr/local/share/chromium \ + /usr/local/share/boost \ + /usr/lib/jvm 2>/dev/null || true + apt-get clean || true + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* || true + docker system df || true + docker system prune -af --volumes || true + docker builder prune -af || true + df -h / || true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + with: + driver-opts: network=host + + - name: Build and load amd64 image for smoke test + uses: docker/build-push-action@v7 + with: + context: . + platforms: linux/amd64 + push: false + load: true + build-args: | + INSTALL_PI=true + tags: opencode-devbox:smoke-with-pi + + - name: Smoke test (amd64) + run: bash scripts/smoke-test.sh opencode-devbox:smoke-with-pi --variant with-pi + + smoke-omos-with-pi: + runs-on: ubuntu-latest + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Force IPv4 for Docker Hub + run: echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf + + - name: Reclaim runner disk + run: | + set -x + df -h / || true + rm -rf \ + /opt/hostedtoolcache \ + /opt/microsoft \ + /opt/az \ + /opt/ghc \ + /usr/local/.ghcup \ + /usr/share/dotnet \ + /usr/share/swift \ + /usr/local/lib/android \ + /usr/local/share/powershell \ + /usr/local/share/chromium \ + /usr/local/share/boost \ + /usr/lib/jvm 2>/dev/null || true + apt-get clean || true + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* || true + docker system df || true + docker system prune -af --volumes || true + docker builder prune -af || true + df -h / || true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + with: + driver-opts: network=host + + - name: Build and load amd64 image for smoke test + uses: docker/build-push-action@v7 + with: + context: . + platforms: linux/amd64 + push: false + load: true + build-args: | + INSTALL_OMOS=true + INSTALL_PI=true + tags: opencode-devbox:smoke-omos-with-pi + + - name: Smoke test (amd64) + run: bash scripts/smoke-test.sh opencode-devbox:smoke-omos-with-pi --variant omos-with-pi + # ── Multi-arch push (single job per variant, comma-separated platforms) ─ build-base: runs-on: ubuntu-latest @@ -300,9 +409,144 @@ jobs: ${{ vars.DOCKERHUB_USERNAME }}/opencode-devbox:${{ steps.version.outputs.version }}-omos ${{ vars.DOCKERHUB_USERNAME }}/opencode-devbox:latest-omos + build-with-pi: + runs-on: ubuntu-latest + needs: smoke-with-pi + timeout-minutes: 90 + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Force IPv4 for Docker Hub + run: echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf + + - name: Reclaim runner disk + run: | + set -x + df -h / || true + rm -rf \ + /opt/hostedtoolcache \ + /opt/microsoft \ + /opt/az \ + /opt/ghc \ + /usr/local/.ghcup \ + /usr/share/dotnet \ + /usr/share/swift \ + /usr/local/lib/android \ + /usr/local/share/powershell \ + /usr/local/share/chromium \ + /usr/local/share/boost \ + /usr/lib/jvm 2>/dev/null || true + apt-get clean || true + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* || true + docker builder prune -af || true + df -h / || true + + - name: Set up QEMU + uses: docker/setup-qemu-action@v4 + with: + platforms: arm64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + with: + driver-opts: network=host + + - name: Login to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract version from tag + id: version + run: echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + + - name: Build and push (multi-arch) + uses: docker/build-push-action@v7 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + build-args: | + INSTALL_PI=true + tags: | + ${{ vars.DOCKERHUB_USERNAME }}/opencode-devbox:${{ steps.version.outputs.version }}-with-pi + ${{ vars.DOCKERHUB_USERNAME }}/opencode-devbox:latest-with-pi + + build-omos-with-pi: + runs-on: ubuntu-latest + needs: smoke-omos-with-pi + timeout-minutes: 90 + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Force IPv4 for Docker Hub + run: echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf + + - name: Reclaim runner disk + run: | + set -x + df -h / || true + rm -rf \ + /opt/hostedtoolcache \ + /opt/microsoft \ + /opt/az \ + /opt/ghc \ + /usr/local/.ghcup \ + /usr/share/dotnet \ + /usr/share/swift \ + /usr/local/lib/android \ + /usr/local/share/powershell \ + /usr/local/share/chromium \ + /usr/local/share/boost \ + /usr/lib/jvm 2>/dev/null || true + apt-get clean || true + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* || true + docker builder prune -af || true + df -h / || true + + - name: Set up QEMU + uses: docker/setup-qemu-action@v4 + with: + platforms: arm64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + with: + driver-opts: network=host + + - name: Login to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract version from tag + id: version + run: echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + + - name: Build and push (multi-arch) + uses: docker/build-push-action@v7 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + build-args: | + INSTALL_OMOS=true + INSTALL_PI=true + tags: | + ${{ vars.DOCKERHUB_USERNAME }}/opencode-devbox:${{ steps.version.outputs.version }}-omos-with-pi + ${{ vars.DOCKERHUB_USERNAME }}/opencode-devbox:latest-omos-with-pi + update-description: runs-on: ubuntu-latest - needs: [build-base, build-omos] + needs: [build-base, build-omos, build-with-pi, build-omos-with-pi] container: image: catthehacker/ubuntu:act-latest steps: diff --git a/.gitea/workflows/validate.yml b/.gitea/workflows/validate.yml index aeb626c..2be1d5c 100644 --- a/.gitea/workflows/validate.yml +++ b/.gitea/workflows/validate.yml @@ -147,3 +147,116 @@ jobs: - name: Smoke test run: | bash scripts/smoke-test.sh opencode-devbox:ci-omos --variant omos + + validate-with-pi: + runs-on: ubuntu-latest + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Force IPv4 for Docker Hub + run: | + echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf + + - name: Reclaim runner disk + run: | + set -x + df -h / || true + rm -rf \ + /opt/hostedtoolcache \ + /opt/microsoft \ + /opt/az \ + /opt/ghc \ + /usr/local/.ghcup \ + /usr/share/dotnet \ + /usr/share/swift \ + /usr/local/lib/android \ + /usr/local/share/powershell \ + /usr/local/share/chromium \ + /usr/local/share/boost \ + /usr/lib/jvm 2>/dev/null || true + apt-get clean || true + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* || true + docker system df || true + docker system prune -af --volumes || true + docker builder prune -af || true + df -h / || true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + with: + driver-opts: network=host + + - name: Build with-pi image (amd64, load to local daemon) + uses: docker/build-push-action@v7 + with: + context: . + platforms: linux/amd64 + push: false + load: true + build-args: | + INSTALL_PI=true + tags: opencode-devbox:ci-with-pi + + - name: Smoke test + run: | + bash scripts/smoke-test.sh opencode-devbox:ci-with-pi --variant with-pi + + validate-omos-with-pi: + runs-on: ubuntu-latest + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Force IPv4 for Docker Hub + run: | + echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf + + - name: Reclaim runner disk + run: | + set -x + df -h / || true + rm -rf \ + /opt/hostedtoolcache \ + /opt/microsoft \ + /opt/az \ + /opt/ghc \ + /usr/local/.ghcup \ + /usr/share/dotnet \ + /usr/share/swift \ + /usr/local/lib/android \ + /usr/local/share/powershell \ + /usr/local/share/chromium \ + /usr/local/share/boost \ + /usr/lib/jvm 2>/dev/null || true + apt-get clean || true + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* || true + docker system df || true + docker system prune -af --volumes || true + docker builder prune -af || true + df -h / || true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + with: + driver-opts: network=host + + - name: Build omos+with-pi image (amd64, load to local daemon) + uses: docker/build-push-action@v7 + with: + context: . + platforms: linux/amd64 + push: false + load: true + build-args: | + INSTALL_OMOS=true + INSTALL_PI=true + tags: opencode-devbox:ci-omos-with-pi + + - name: Smoke test + run: | + bash scripts/smoke-test.sh opencode-devbox:ci-omos-with-pi --variant omos-with-pi diff --git a/scripts/smoke-test.sh b/scripts/smoke-test.sh index ce235e0..ca39497 100755 --- a/scripts/smoke-test.sh +++ b/scripts/smoke-test.sh @@ -144,7 +144,16 @@ if docker run --rm --entrypoint="" "$IMAGE" sh -c "command -v pi" >/dev/null 2>& # and has no docker CLI to nest with. CID=$(docker run -d --rm "$IMAGE" tail -f /dev/null) trap 'docker rm -f "$CID" >/dev/null 2>&1 || true' EXIT - sleep 1 # entrypoint runs synchronously; container ready when running + + # Wait for entrypoint-user.sh to finish deploying pi-toolkit + extensions. + # Marker: keybindings.json symlink lands once pi-toolkit/install.sh has run. + # Up to 30s — omos-with-pi has more setup work than base+pi. + for _ in $(seq 1 30); do + if docker exec "$CID" test -L /home/developer/.pi/agent/keybindings.json 2>/dev/null; then + break + fi + sleep 1 + done exec_test() { local label="$1"; shift @@ -171,8 +180,8 @@ else echo " - pi not installed (INSTALL_PI=false)" fi -# bun: only in the omos variant -if [ "$VARIANT" = "omos" ]; then +# bun: only in the omos and omos-with-pi variants +if [ "$VARIANT" = "omos" ] || [ "$VARIANT" = "omos-with-pi" ]; then run "bun (omos)" "bun --version" run "bunx symlink (omos)" "test -L /usr/local/bin/bunx && readlink /usr/local/bin/bunx" # oh-my-opencode-slim is npm-installed globally (not a bun install);