Skip to content

cell serve gains OpenAI Responses API + SSE streaming, configurable s… #160

cell serve gains OpenAI Responses API + SSE streaming, configurable s…

cell serve gains OpenAI Responses API + SSE streaming, configurable s… #160

Workflow file for this run

name: Dev Build
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
on:
push:
branches:
- main
- feature/wip
- feature/add-web
- feature/web
workflow_dispatch:
inputs:
skip_nix_cache:
description: 'Skip nix cache (genesis mode — full rebuild, no pre-seeding)'
type: boolean
default: false
permissions:
contents: write
packages: write
id-token: write
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
NIX_CACHE_IMAGE: ${{ inputs.skip_nix_cache == true && 'public.ecr.aws/docker/library/debian:trixie-slim' || 'ghcr.io/dimmkirr/devcell:v0.0.0-ultimate' }}
ECR_REGISTRY: public.ecr.aws/w1l3v2k8/devcell
jobs:
secrets:
name: Detect Secrets
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
docker-build:
name: Docker Build (${{ matrix.arch }})
needs: secrets
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-latest
arch: amd64
platform: linux/amd64
- runner: ubuntu-24.04-arm
arch: arm64
platform: linux/arm64
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- name: Set lowercase image name
run: echo "IMAGE_NAME_LC=${IMAGE_NAME,,}" >> $GITHUB_ENV
- name: Free disk space
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune -af
df -h
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
buildkitd-config-inline: |
[worker.oci]
max-parallelism = 4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ECR_ROLE_ARN }}
aws-region: us-east-1
- name: Log in to ECR Public
uses: aws-actions/amazon-ecr-login@v2
with:
registry-type: public
- name: Pre-pull nix-cache as OCI layout
if: inputs.skip_nix_cache != true
run: |
skopeo copy --src-tls-verify=true \
docker://${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:v0.0.0-ultimate \
oci:/tmp/nix-cache-oci:latest
echo "NIX_CACHE_OCI=/tmp/nix-cache-oci" >> "$GITHUB_ENV"
- name: Build and push ci group (GHCR)
run: >-
docker buildx bake
--set '*.output=type=image,push=true,compression=zstd,compression-level=3,force-compression=true'
${{ env.NIX_CACHE_OCI && format('--set ultimate.contexts.nix-cache=oci-layout://{0}', env.NIX_CACHE_OCI) || '' }}
ci
env:
VERSION: v0.0.0-${{ matrix.arch }}
PLATFORMS: ${{ matrix.platform }}
REGISTRY: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}
CACHE_ARCH: -${{ matrix.arch }}
- name: Push to ECR Public
run: |
GHCR=${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}
ECR=${{ env.ECR_REGISTRY }}
V=v0.0.0-${{ matrix.arch }}
for suffix in "" "-core" "-ultimate"; do
SRC="${GHCR}:${V}${suffix}"
DST="${ECR}:${V}${suffix}"
docker buildx imagetools create -t "${DST}" "${SRC}"
done
docker-test:
name: Docker Test (${{ matrix.arch }}, ${{ matrix.variant }})
needs: docker-build
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-latest
arch: amd64
variant: base
test_run: "TestBaseImage|TestDotenv"
timeout: 600s
- runner: ubuntu-24.04-arm
arch: arm64
variant: base
test_run: "TestBaseImage|TestDotenv"
timeout: 600s
- runner: ubuntu-latest
arch: amd64
variant: ultimate
test_run: ""
timeout: 1200s
- runner: ubuntu-24.04-arm
arch: arm64
variant: ultimate
test_run: ""
timeout: 1200s
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- name: Set lowercase image name
run: echo "IMAGE_NAME_LC=${IMAGE_NAME,,}" >> $GITHUB_ENV
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache-dependency-path: go.sum
- name: Pull test images
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:v0.0.0-${{ matrix.arch }}-${{ matrix.variant }}
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:v0.0.0-${{ matrix.arch }}-core
- name: Run container tests
env:
DEVCELL_TEST_IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:v0.0.0-${{ matrix.arch }}-${{ matrix.variant }}
DEVCELL_BASE_IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:v0.0.0-${{ matrix.arch }}-core
DEVCELL_TEST_BASE_IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:v0.0.0-${{ matrix.arch }}-core
DEVCELL_USER_IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:v0.0.0-${{ matrix.arch }}-${{ matrix.variant }}
DEVCELL_TEST_PROJECT_DIR: ${{ runner.temp }}/devcell-test
MCP_SECRET_TEST_PASSWORD: fake-secret-ci-value
MCP_SECRET_GITHUB_TOKEN: fake-token-ci-value
run: |
if [ -n "${{ matrix.test_run }}" ]; then
go test -v -run "${{ matrix.test_run }}" -timeout ${{ matrix.timeout }} ./test/...
else
go test -v -timeout ${{ matrix.timeout }} ./test/...
fi
docker-manifest:
name: Docker Manifests
needs: [docker-build]
if: always() && needs.docker-build.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Set lowercase image name
run: echo "IMAGE_NAME_LC=${IMAGE_NAME,,}" >> $GITHUB_ENV
env:
IMAGE_NAME: ${{ github.repository }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ECR_ROLE_ARN }}
aws-region: us-east-1
- name: Log in to ECR Public
uses: aws-actions/amazon-ecr-login@v2
with:
registry-type: public
- name: Create GHCR manifests
run: |
R=${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}
for suffix in "" "-core" "-ultimate"; do
docker buildx imagetools create \
-t "${R}:dev${suffix}" \
-t "${R}:latest${suffix}" \
-t "${R}:v0.0.0${suffix}" \
"${R}:v0.0.0-amd64${suffix}" \
"${R}:v0.0.0-arm64${suffix}"
done
- name: Create ECR Public manifests
run: |
ECR=${{ env.ECR_REGISTRY }}
for suffix in "" "-core" "-ultimate"; do
docker buildx imagetools create \
-t "${ECR}:dev${suffix}" \
-t "${ECR}:latest${suffix}" \
-t "${ECR}:v0.0.0${suffix}" \
"${ECR}:v0.0.0-amd64${suffix}" \
"${ECR}:v0.0.0-arm64${suffix}"
done
cell-build:
name: Cell CLI Dev Build
needs: secrets
runs-on: ubuntu-latest
env:
RELEASE_VERSION: v0.0.0
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache-dependency-path: go.sum
- name: Set SHORT_SHA
run: echo "SHORT_SHA=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_ENV
- name: Delete existing tag
run: |
git config --global user.email "dmitry@atd.sh"
git config --global user.name "Dmitry Kireev"
git tag -d "${{ env.RELEASE_VERSION }}" || echo "No local tag to delete"
git push origin :refs/tags/${{ env.RELEASE_VERSION }} || echo "No remote tag to delete"
- name: Add tag
run: |
git tag -a ${{ env.RELEASE_VERSION }} -m "Development release"
git push origin ${{ github.ref_name }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: "~> v2"
args: release --clean -f .goreleaser.dev.yaml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
SHORT_SHA: ${{ env.SHORT_SHA }}
- name: Publish release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release edit "${{ env.RELEASE_VERSION }}" --draft=false --latest=false --prerelease
e2e-install:
name: E2E Install (${{ matrix.arch }})
needs: [cell-build, docker-manifest]
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-latest
arch: amd64
- runner: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
steps:
- name: Download cell binary
run: |
TARBALL="cell-linux-${{ matrix.arch }}.tar.gz"
URL="https://github.com/DimmKirr/devcell/releases/download/v0.0.0/${TARBALL}"
echo "Downloading: ${URL}"
curl -fsSL -o "${TARBALL}" "${URL}"
tar xzf "${TARBALL}"
chmod +x cell
sudo mv cell /usr/local/bin/cell
- name: Verify cell binary
run: |
cell --help
echo "--- cell binary OK ---"
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run cell claude --version (full pipeline)
env:
DEVCELL_NIXHOME_PATH: ${{ github.workspace }}/nixhome
run: |
# Simulate a new user in a fresh project dir
mkdir -p /tmp/e2e-project && cd /tmp/e2e-project
# --plain-text: disable spinners for CI
# Flow: scaffold devcell.toml → pull base image → build user image → start container → print claude version
OUTPUT=$(cell --plain-text claude --version 2>&1) || true
echo "$OUTPUT"
# Assert cell version string is present
if echo "$OUTPUT" | grep -qE "cell\s+v?[0-9]+\.[0-9]+\.[0-9]+"; then
echo "--- PASS: cell version found ---"
else
echo "--- FAIL: cell version string not found in output ---"
exit 1
fi
# Assert the image was built (user image should exist now)
if echo "$OUTPUT" | grep -qiE "(building|built|image)"; then
echo "--- PASS: image build occurred ---"
else
echo "--- WARN: no build output detected (image may have been cached) ---"
fi
brew-install:
name: Brew Install (${{ matrix.arch }})
needs: [cell-build]
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-latest
arch: amd64
- runner: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.runner }}
timeout-minutes: 15
steps:
- name: Install Homebrew
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" < /dev/null
echo "/home/linuxbrew/.linuxbrew/bin" >> $GITHUB_PATH
- name: Brew install devcell-dev
run: |
brew tap DimmKirr/tap
brew install devcell-dev || true
# Verify binary was actually linked despite potential broken pipe
if ! command -v cell &>/dev/null; then
echo "Binary not found, retrying..."
brew install devcell-dev
fi
- name: Verify version
run: |
INSTALLED=$(cell --version)
echo "Installed: ${INSTALLED}"
if echo "${INSTALLED}" | grep -qE "^cell version [0-9]+\.[0-9]+\.[0-9]+"; then
echo "--- PASS: cell version OK ---"
else
echo "--- FAIL: unexpected version output ---"
exit 1
fi