summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gcp/dogfood.yaml25
-rw-r--r--Dockerfile2
-rw-r--r--package.json11
-rw-r--r--packages/cli/Dockerfile.sandbox28
-rw-r--r--packages/cli/package.json6
-rwxr-xr-xscripts/build_sandbox.sh2
-rw-r--r--scripts/prepare-cli-packagejson.js66
-rwxr-xr-xscripts/publish-sandbox.sh41
8 files changed, 140 insertions, 41 deletions
diff --git a/.gcp/dogfood.yaml b/.gcp/dogfood.yaml
index 911fdf46..01eddded 100644
--- a/.gcp/dogfood.yaml
+++ b/.gcp/dogfood.yaml
@@ -1,8 +1,10 @@
steps:
+ # Step 1: Install root dependencies (includes workspaces)
- name: 'us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-builder'
entrypoint: 'npm'
args: ['install']
+ # Step 2: Update version with build suffix
- name: 'us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-builder'
entrypoint: 'npm'
args:
@@ -14,22 +16,33 @@ steps:
'--suffix="$SHORT_SHA.$_REVISION"',
]
+ # Step 3: Bind dependencies to the new versions
- name: 'us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-builder'
entrypoint: 'npm'
args: ['run', 'prerelease:deps', '--workspaces']
- # A bit of a hack to get the .npmrc into the Dockerfile.sandbox. Should probably streamline this.
- - name: 'us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-builder'
- entrypoint: 'cp'
- args: ['/workspace/.npmrc', '/builder/home/.npmrc']
-
+ # Step 4: Authenticate for Docker and NPM
- name: 'us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-builder'
entrypoint: 'npm'
args: ['run', 'auth']
+ # Step 5: Run the master release script
- name: 'us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-builder'
entrypoint: 'npm'
- args: ['publish', '--tag=head', '--workspace=@gemini-code/cli']
+ args: ['run', 'publish:release']
+ env:
+ - 'GEMINI_SANDBOX=$_CONTAINER_TOOL'
+ - 'SANDBOX_IMAGE_REGISTRY=$_SANDBOX_IMAGE_REGISTRY'
+ - 'SANDBOX_IMAGE_NAME=$_SANDBOX_IMAGE_NAME'
+ - 'NPM_PUBLISH_TAG=$_NPM_PUBLISH_TAG'
options:
defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
+ dynamicSubstitutions: true
+
+substitutions:
+ _REVISION: '0'
+ _SANDBOX_IMAGE_REGISTRY: 'us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers'
+ _SANDBOX_IMAGE_NAME: 'gemini-cli-sandbox'
+ _NPM_PUBLISH_TAG: 'head'
+ _CONTAINER_TOOL: 'docker'
diff --git a/Dockerfile b/Dockerfile
index 3cabc24b..695e4691 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -36,3 +36,5 @@ COPY packages/server/dist/gemini-code-server-*.tgz /usr/local/share/npm-global/g
RUN npm install -g /usr/local/share/npm-global/gemini-code-cli.tgz /usr/local/share/npm-global/gemini-code-server.tgz \
&& npm cache clean --force \
&& rm -f /usr/local/share/npm-global/gemini-code-{cli,server}.tgz
+
+ENTRYPOINT ["gemini"]
diff --git a/package.json b/package.json
index b84a4b77..30f6b988 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,16 @@
"auth:docker": "gcloud auth configure-docker us-west1-docker.pkg.dev",
"auth": "npm run auth:npm && npm run auth:docker",
"prerelease:dev": "npm run prerelease:version --workspaces && npm run prerelease:deps --workspaces",
- "bundle": "npm run generate && node_modules/.bin/esbuild packages/cli/index.ts --bundle --outfile=bundle/gemini.js --platform=node --format=esm --banner:js=\"import { createRequire } from 'module'; const require = createRequire(import.meta.url); globalThis.__filename = require('url').fileURLToPath(import.meta.url); globalThis.__dirname = require('path').dirname(globalThis.__filename);\" && bash scripts/copy_bundle_assets.sh"
+ "bundle": "npm run generate && node_modules/.bin/esbuild packages/cli/index.ts --bundle --outfile=bundle/gemini.js --platform=node --format=esm --banner:js=\"import { createRequire } from 'module'; const require = createRequire(import.meta.url); globalThis.__filename = require('url').fileURLToPath(import.meta.url); globalThis.__dirname = require('path').dirname(globalThis.__filename);\" && bash scripts/copy_bundle_assets.sh",
+ "build:cli": "npm run build --workspace packages/cli",
+ "build:server": "npm run build --workspace packages/server",
+ "build:packages": "npm run build:server && npm run build:cli",
+ "build:docker": "scripts/build_sandbox.sh -s",
+ "tag:docker": "docker tag gemini-code-sandbox:latest ${SANDBOX_IMAGE_REGISTRY:?SANDBOX_IMAGE_REGISTRY not set}/${SANDBOX_IMAGE_NAME:?SANDBOX_IMAGE_NAME not set}:$npm_package_version",
+ "prepare:cli-packagejson": "node scripts/prepare-cli-packagejson.js",
+ "publish:sandbox": "scripts/publish-sandbox.sh",
+ "publish:npm": "npm publish --workspace @gemini-code/cli ${NPM_PUBLISH_TAG:+--tag=$NPM_PUBLISH_TAG} ${NPM_DRY_RUN:+--dry-run}",
+ "publish:release": "npm run build:packages && npm run build:docker && npm run tag:docker && npm run prepare:cli-packagejson && npm run publish:sandbox && npm run publish:npm"
},
"bin": {
"gemini": "bundle/gemini.js"
diff --git a/packages/cli/Dockerfile.sandbox b/packages/cli/Dockerfile.sandbox
deleted file mode 100644
index 7250bbf3..00000000
--- a/packages/cli/Dockerfile.sandbox
+++ /dev/null
@@ -1,28 +0,0 @@
-FROM docker.io/library/node:20-slim
-
-ARG CLI_VERSION
-ENV SANDBOX=${CLI_VERSION}
-
-# install minimal set of packages, then clean up
-RUN apt-get update && apt-get install -y --no-install-recommends \
- man-db \
- curl \
- dnsutils \
- less \
- jq \
- bc \
- gh \
- git \
- unzip \
- rsync \
- ripgrep \
- procps \
- psmisc \
- lsof \
- socat \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/*
-
-RUN --mount=type=secret,id=npmrc,dst=/root/.npmrc npm install -g @gemini-code/cli@${CLI_VERSION} --verbose
-
-ENTRYPOINT 'gemini'
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 6ae1bd40..486ca50e 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -7,11 +7,8 @@
"bin": {
"gemini": "dist/index.js"
},
- "image": "us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-cli",
"scripts": {
- "build:sandbox": "DOCKER_BUILDKIT=1 docker build --build-arg CLI_VERSION=$npm_package_version --no-cache --secret id=npmrc,src=$HOME/.npmrc -t us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-cli:$npm_package_version -f Dockerfile.sandbox .",
"build": "../../scripts/build_package.sh",
- "publish:sandbox": "docker push us-west1-docker.pkg.dev/gemini-code-dev/gemini-code-containers/gemini-code-cli:$npm_package_version",
"clean": "rm -rf dist",
"start": "node dist/index.js",
"debug": "node --inspect-brk dist/index.js",
@@ -23,8 +20,7 @@
"prerelease:version": "node ../../scripts/bind_package_version.js",
"prerelease:deps": "node ../../scripts/bind_package_dependencies.js",
"prepublishOnly": "npm publish --workspace=@gemini-code/server",
- "prepack": "npm run build",
- "postpublish": "npm run build:sandbox && npm run publish:sandbox"
+ "prepack": "npm run build"
},
"files": [
"dist"
diff --git a/scripts/build_sandbox.sh b/scripts/build_sandbox.sh
index 58ad6d03..5997e201 100755
--- a/scripts/build_sandbox.sh
+++ b/scripts/build_sandbox.sh
@@ -26,7 +26,7 @@ fi
CMD=$(scripts/sandbox_command.sh)
echo "using $CMD for sandboxing"
-IMAGE=gemini-code-sandbox
+IMAGE=gemini-code-sandbox:latest
DOCKERFILE=Dockerfile
SKIP_NPM_INSTALL_BUILD=false
diff --git a/scripts/prepare-cli-packagejson.js b/scripts/prepare-cli-packagejson.js
new file mode 100644
index 00000000..8e0efff1
--- /dev/null
+++ b/scripts/prepare-cli-packagejson.js
@@ -0,0 +1,66 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+// ES module equivalent of __dirname
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+const cliPackageJsonPath = path.resolve(
+ __dirname,
+ '../packages/cli/package.json',
+);
+const cliPackageJson = JSON.parse(fs.readFileSync(cliPackageJsonPath, 'utf8'));
+
+// Get version from root package.json (accessible via env var in npm scripts)
+const version = process.env.npm_package_version;
+
+// Get Docker registry and image name directly from PUBLISH_ environment variables.
+// These are expected to be set by the CI/build environment.
+const dockerRegistry = process.env.SANDBOX_IMAGE_REGISTRY;
+const dockerImageName = process.env.SANDBOX_IMAGE_NAME;
+
+if (!version || !dockerRegistry || !dockerImageName) {
+ console.error(
+ 'Error: Missing required environment variables. Need: ' +
+ 'npm_package_version, SANDBOX_IMAGE_REGISTRY, and SANDBOX_IMAGE_NAME.',
+ );
+ console.error(
+ 'These should be passed from the CI environment (e.g., Cloud Build substitutions) ' +
+ 'to the npm publish:release script.',
+ );
+ process.exit(1);
+}
+
+const dockerImageUri = `${dockerRegistry}/${dockerImageName}:${version}`;
+
+// Add or update fields in cliPackageJson.config to store this information
+if (!cliPackageJson.config) {
+ cliPackageJson.config = {};
+}
+cliPackageJson.config.dockerImageUri = dockerImageUri;
+cliPackageJson.config.dockerRegistry = dockerRegistry;
+cliPackageJson.config.dockerImageName = dockerImageName;
+
+// Remove 'prepublishOnly' from scripts if it exists
+if (cliPackageJson.scripts && cliPackageJson.scripts.prepublishOnly) {
+ delete cliPackageJson.scripts.prepublishOnly;
+ console.log('Removed prepublishOnly script from packages/cli/package.json');
+}
+
+fs.writeFileSync(
+ cliPackageJsonPath,
+ JSON.stringify(cliPackageJson, null, 2) + '\n',
+);
+console.log(
+ `Updated ${path.relative(process.cwd(), cliPackageJsonPath)} with Docker image details:`,
+);
+console.log(` URI: ${dockerImageUri}`);
+console.log(` Registry: ${dockerRegistry}`);
+console.log(` Image Name: ${dockerImageName}`);
diff --git a/scripts/publish-sandbox.sh b/scripts/publish-sandbox.sh
new file mode 100755
index 00000000..dfc16353
--- /dev/null
+++ b/scripts/publish-sandbox.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -euo pipefail
+
+# Ensure required environment variables are set
+if [ -z "${SANDBOX_IMAGE_REGISTRY}" ]; then
+ echo "Error: SANDBOX_IMAGE_REGISTRY environment variable is not set." >&2
+ exit 1
+fi
+
+if [ -z "${SANDBOX_IMAGE_NAME}" ]; then
+ echo "Error: SANDBOX_IMAGE_NAME environment variable is not set." >&2
+ exit 1
+fi
+
+if [ -z "${npm_package_version}" ]; then
+ echo "Error: npm_package_version environment variable is not set (should be run via npm)." >&2
+ exit 1
+fi
+
+IMAGE_URI="${SANDBOX_IMAGE_REGISTRY}/${SANDBOX_IMAGE_NAME}:${npm_package_version}"
+
+if [ -n "${DOCKER_DRY_RUN:-}" ]; then
+ echo "DRY RUN: Would execute: docker push \"${IMAGE_URI}\""
+else
+ echo "Executing: docker push \"${IMAGE_URI}\""
+ docker push "${IMAGE_URI}"
+fi