diff --git a/.github/docker/Dockerfile.ci b/.github/docker/Dockerfile.ci new file mode 100644 index 00000000..e7118cb8 --- /dev/null +++ b/.github/docker/Dockerfile.ci @@ -0,0 +1,43 @@ +# gstack CI eval runner — pre-baked toolchain + deps +# Rebuild weekly via ci-image.yml, on Dockerfile changes, or on lockfile changes +FROM ubuntu:24.04 + +ENV DEBIAN_FRONTEND=noninteractive + +# System deps +RUN apt-get update && apt-get install -y --no-install-recommends \ + git curl unzip ca-certificates jq bc gpg \ + && rm -rf /var/lib/apt/lists/* + +# GitHub CLI +RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ + | gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ + | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ + && apt-get update && apt-get install -y --no-install-recommends gh \ + && rm -rf /var/lib/apt/lists/* + +# Node.js 22 LTS (needed for claude CLI) +RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && apt-get install -y --no-install-recommends nodejs \ + && rm -rf /var/lib/apt/lists/* + +# Bun +RUN curl -fsSL https://bun.sh/install | bash +ENV BUN_INSTALL="/root/.bun" +ENV PATH="$BUN_INSTALL/bin:$PATH" + +# Claude CLI +RUN npm i -g @anthropic-ai/claude-code + +# Pre-install dependencies (cached layer — only rebuilds when lockfile changes) +COPY bun.lockb package.json /workspace/ +WORKDIR /workspace +RUN bun install --frozen-lockfile && rm -rf /tmp/* + +# Verify everything works +RUN bun --version && node --version && claude --version && jq --version && gh --version + +# At runtime: checkout overwrites /workspace, but node_modules persists +# if we move it out of the way and symlink back +RUN mv /workspace/node_modules /opt/node_modules_cache diff --git a/.github/workflows/ci-image.yml b/.github/workflows/ci-image.yml new file mode 100644 index 00000000..07b3e083 --- /dev/null +++ b/.github/workflows/ci-image.yml @@ -0,0 +1,41 @@ +name: Build CI Image +on: + # Rebuild weekly (Monday 6am UTC) to pick up CLI updates + schedule: + - cron: '0 6 * * 1' + # Rebuild on Dockerfile or lockfile changes + push: + branches: [main] + paths: + - '.github/docker/Dockerfile.ci' + - 'bun.lockb' + - 'package.json' + # Manual trigger + workflow_dispatch: + +jobs: + build: + runs-on: ubicloud-standard-2 + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + # Copy lockfile + package.json into Docker build context + - run: cp bun.lockb package.json .github/docker/ + + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/build-push-action@v6 + with: + context: .github/docker + file: .github/docker/Dockerfile.ci + push: true + tags: | + ghcr.io/${{ github.repository }}/ci:latest + ghcr.io/${{ github.repository }}/ci:${{ github.sha }}