[STG-2449] ci: publish browserbase/browse Docker image on browse release#2295
[STG-2449] ci: publish browserbase/browse Docker image on browse release#2295shrey150 wants to merge 3 commits into
Conversation
Build and push a minimal `browse` CLI image on every release, pinned 1:1 to the npm version. GHCR (ghcr.io/browserbase/browse) always publishes via the built-in GITHUB_TOKEN; Docker Hub (browserbase/browse) additionally publishes when DOCKERHUB_USERNAME + DOCKERHUB_TOKEN are set, so a missing secret degrades to GHCR-only instead of failing the release. This lets code sandboxes (E2B, Modal, Daytona, Vercel) consume the browse CLI by image reference with no Dockerfile -- no browser is bundled, browse connects out to a Browserbase cloud browser over CDP. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
- Remove the redundant comment block above the Docker steps (the GHCR-vs-Docker Hub behavior is already surfaced by the step names + the runtime notice). - Dockerfile: drop the verbose header, use node:20-slim to match the repo's node 20.x standard (engines ^20.19.0), and drop the non-standard WORKDIR /work (sandbox runtimes set their own working directory). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the Docker Hub path for now — the `browserbase` Docker Hub namespace is taken/unclaimed by us, so shipping the Docker Hub steps would be dead code. GHCR (ghcr.io/browserbase/browse) uses the GitHub org we own and needs no new secrets. Docker Hub is tracked as a follow-up (STG-2449). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 2 files
Confidence score: 3/5
- In
.github/workflows/release.yml, Docker/GHCR publish is gated behind the npm publish retry check, so a partial failure (npm succeeds, GHCR fails) can make reruns skip the image build/push and leave a release without the expected container artifact. Decouple GHCR publishing from the npm “already published” path (or add an explicit retry path for image publish) before merging.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/workflows/release.yml">
<violation number="1" location=".github/workflows/release.yml:168">
P2: Docker publishing is coupled to the npm publish retry gate. If the workflow fails after npm publish but before/during the GHCR push, rerunning the release will see the npm package as already published and skip building `ghcr.io/browserbase/browse:<version>`.</violation>
</file>
Architecture diagram
sequenceDiagram
participant Git as GitHub Release (tag push)
participant CI as Release Workflow
participant NPM as npm Registry
participant GHCR as GHCR (ghcr.io/browserbase/browse)
participant Sandbox as Sandbox (E2B/Modal/Daytona)
Note over Git,Sandbox: NEW: Publish browse Docker image on release
Git->>CI: Trigger release.yml (tag vX.Y.Z)
CI->>CI: Check should_publish and already_published<br/>(existing gate)
alt should_publish == true & already_published != true
CI->>NPM: Publish browse@vX.Y.Z (existing)
NPM-->>CI: Success
Note over CI: NEW: Docker image steps
CI->>CI: Set up QEMU for multi-arch build
CI->>CI: Set up Docker Buildx
CI->>GHCR: Login using GITHUB_TOKEN
CI->>CI: Build & push image (linux/amd64 + linux/arm64)
CI->>GHCR: Push ghcr.io/browserbase/browse:vX.Y.Z
CI->>GHCR: Push ghcr.io/browserbase/browse:latest
GHCR-->>CI: Publish complete
end
Note over Sandbox: Later: Consumer pulls image
Sandbox->>GHCR: Pull ghcr.io/browserbase/browse (version or latest)
GHCR-->>Sandbox: Thin client image (no bundled browser)
Sandbox->>Sandbox: Run "browse" commands (connects to Browserbase cloud CDP)
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
|
||
| - name: Build and push browse image to GHCR | ||
| if: steps.browse_cli.outputs.should_publish == 'true' && steps.browse_cli.outputs.already_published != 'true' | ||
| uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 |
There was a problem hiding this comment.
P2: Docker publishing is coupled to the npm publish retry gate. If the workflow fails after npm publish but before/during the GHCR push, rerunning the release will see the npm package as already published and skip building ghcr.io/browserbase/browse:<version>.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/release.yml, line 168:
<comment>Docker publishing is coupled to the npm publish retry gate. If the workflow fails after npm publish but before/during the GHCR push, rerunning the release will see the npm package as already published and skip building `ghcr.io/browserbase/browse:<version>`.</comment>
<file context>
@@ -146,6 +147,37 @@ jobs:
+
+ - name: Build and push browse image to GHCR
+ if: steps.browse_cli.outputs.should_publish == 'true' && steps.browse_cli.outputs.already_published != 'true'
+ uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
+ with:
+ context: packages/cli
</file context>
What
Publish the
browseCLI as a Docker image to GHCR on every release, pinned 1:1 to the npm version, so code sandboxes can consume it by image reference.ghcr.io/browserbase/browse:<version>+:latest, pushed via the built-inGITHUB_TOKEN(no new secrets).linux/amd64,linux/arm64(amd64 is required — sandbox runtimes are amd64).browseconnects out to a Browserbase cloud browser over CDP, so the image stays a thin client (~481 MB onnode:20-slim).Docker Hub (
browserbase/browse) is intentionally out of scope here — thebrowserbaseDocker Hub namespace isn't ours yet, so shipping those steps would be dead code. It's tracked as a follow-up (see below).Why
Most sandbox providers (E2B, Modal, Daytona) have no public template registry — but they can all pull a public image by reference, so one published image makes
browseconsumable with no Dockerfile:# Daytona daytona snapshot create browse --image ghcr.io/browserbase/browseHow it hooks in
Reuses the existing
Check if browse publish is neededgate inrelease.yml(should_publish/versionoutputs) — the Docker steps run under the same condition asPublish browse to npm, right after the npm publish + tag. No new version-detection logic. Image version is pinned via--build-arg BROWSE_VERSION=<version>.Conventions
node:20-slimto match the repo's node 20.x standard (engines^20.19.0 || >=22.12.0).# vX.Y.Zcomments, matching the repo's existing style.WORKDIR/ENTRYPOINT— sandbox runtimes set their own working dir and exec their own commands.Dockerfilelives inpackages/cli/but is excluded from the npm tarball by the package'sfilesallowlist.Prerequisite (one-time, maintainer)
GHCR packages default to private. After the first release pushes the package, set
ghcr.io/browserbase/browsevisibility to Public in the org package settings so sandboxes can pull it anonymously. (Requires the release job'spackages: writepermission, added here.)Follow-up (not in this PR) — STG-2449
Publish
browseto Docker Hub for the clean bare-name reference (browserbase/browse, which resolves to Docker Hub by default). Blocked on claiming the namespace: thebrowserbasename on Docker Hub is already taken by an org with no public repos and unknown owner. Options: recover it if it's an old Browserbase registration, dispute it via Docker support (trademark), or fall back tobrowserbasehq. Once the namespace + aDOCKERHUB_*token exist, adding Docker Hub tags is a small follow-up.E2E Test Matrix
docker buildx build --platform linux/amd64 --build-arg BROWSE_VERSION=0.9.1browse --version→browse/0.9.1 linux-x64 node-v20.20.2; ~481 MBbrowseruns onnode:20-slimdocker build(native arm64)browse --version→browse/0.9.1 linux-arm64;browse --helprendersactionlint .github/workflows/release.yml${{ }}expressions are valid and well-formedNot yet exercised (requires a real release run): the live GHCR push, the
should_publishgate firing on a tagged release, and GHCR org-package first-push permission.Linear: STG-2449