diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 148cd3a..e98edbb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,11 +47,71 @@ jobs: - run: node packages/sandbox-image/test/sandbox-image-smoke.mjs + # The E2B template is built from the same Dockerfile on a plain Node base. + - run: docker build -f Dockerfile.sandbox --build-arg SANDBOX_BASE=node:22-slim -t codevil-sandbox-e2b:ci . + + - run: node packages/sandbox-image/test/sandbox-image-smoke.mjs + env: + CODEVIL_SANDBOX_IMAGE: codevil-sandbox-e2b:ci + + # Like wrangler's container build for Cloudflare: when wrangler.toml selects + # E2B, build this commit's sandbox image and publish it as the E2B template + # the deployed Worker is pinned to. A failed publish blocks the deploy. This is + # its own job so the GITHUB_TOKEN that E2B receives as registry credentials + # (it can also push packages) expires as soon as the publish finishes, and the + # Cloudflare deploy job never holds packages: write. + e2b-template: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: + - verify + - sandbox-image + runs-on: ubuntu-latest + timeout-minutes: 45 + environment: production + permissions: + contents: read + packages: write + concurrency: + group: production-e2b-template + cancel-in-progress: false + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 + with: + version: 10.28.1 + + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22.19.0 + cache: pnpm + + - run: pnpm install --frozen-lockfile + + - name: Read sandbox provider + id: sandbox + run: pnpm --filter @codevil/worker exec node scripts/sandbox-deploy-settings.mjs + + - name: Publish E2B sandbox template + if: steps.sandbox.outputs.sandbox_provider == 'e2b' + run: | + export CODEVIL_SANDBOX_IMAGE="ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/codevil-sandbox:${GITHUB_SHA}" + pnpm --filter @codevil/sandbox-image e2b:template + env: + E2B_API_KEY: ${{ secrets.E2B_API_KEY }} + E2B_TEMPLATE_ID: ${{ steps.sandbox.outputs.e2b_template_id }} + E2B_TEMPLATE_TAG: ${{ github.sha }} + CODEVIL_REGISTRY_USERNAME: ${{ github.actor }} + CODEVIL_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + deploy: if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: - verify - sandbox-image + - e2b-template runs-on: ubuntu-latest timeout-minutes: 60 environment: production @@ -79,8 +139,12 @@ jobs: - run: pnpm install --frozen-lockfile + # With SANDBOX_PROVIDER = "e2b" this pins E2B_TEMPLATE_ID to + # "