Release and Packaging: Clean up (#3489)

This commit is contained in:
matt korwel
2025-07-07 16:36:51 -07:00
committed by GitHub
parent 4e84989d8f
commit a4097ae6f9
16 changed files with 35 additions and 463 deletions

View File

@@ -103,14 +103,12 @@ There are two distinct build processes used, depending on the distribution chann
**Docker sandbox image**
The Docker-based execution method is supported by the `gemini-cli-sandbox` container image. This image is published to a container registry and contains a pre-installed, global version of Gemini CLI. The `scripts/prepare-cli-packagejson.js` script dynamically injects the URI of this image into the CLI's `package.json` before publishing, so the CLI knows which image to pull when the `--sandbox` flag is used.
The Docker-based execution method is supported by the `gemini-cli-sandbox` container image. This image is published to a container registry and contains a pre-installed, global version of Gemini CLI.
## Release process
A unified script, `npm run publish:release`, orchestrates the release process. The script performs the following actions:
The release process is automated through GitHub Actions. The release workflow performs the following actions:
1. Build the NPM packages using `tsc`.
2. Update the CLI's `package.json` with the Docker image URI.
3. Build and tag the `gemini-cli-sandbox` Docker image.
4. Push the Docker image to the container registry.
5. Publish the NPM packages to the artifact registry.
2. Publish the NPM packages to the artifact registry.
3. Create GitHub releases with bundled assets.

View File

@@ -0,0 +1,81 @@
# Example Proxy Script
The following is an example of a proxy script that can be used with the `GEMINI_SANDBOX_PROXY_COMMAND` environment variable. This script only allows `HTTPS` connections to `example.com:443` and declines all other requests.
```javascript
#!/usr/bin/env node
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
// Example proxy server that listens on :::8877 and only allows HTTPS connections to example.com.
// Set `GEMINI_SANDBOX_PROXY_COMMAND=scripts/example-proxy.js` to run proxy alongside sandbox
// Test via `curl https://example.com` inside sandbox (in shell mode or via shell tool)
import http from 'http';
import net from 'net';
import { URL } from 'url';
import console from 'console';
const PROXY_PORT = 8877;
const ALLOWED_DOMAINS = ['example.com', 'googleapis.com'];
const ALLOWED_PORT = '443';
const server = http.createServer((req, res) => {
// Deny all requests other than CONNECT for HTTPS
console.log(
`[PROXY] Denying non-CONNECT request for: ${req.method} ${req.url}`,
);
res.writeHead(405, { 'Content-Type': 'text/plain' });
res.end('Method Not Allowed');
});
server.on('connect', (req, clientSocket, head) => {
// req.url will be in the format "hostname:port" for a CONNECT request.
const { port, hostname } = new URL(`http://${req.url}`);
console.log(`[PROXY] Intercepted CONNECT request for: ${hostname}:${port}`);
if (
ALLOWED_DOMAINS.some(
(domain) => hostname == domain || hostname.endsWith(`.${domain}`),
) &&
port === ALLOWED_PORT
) {
console.log(`[PROXY] Allowing connection to ${hostname}:${port}`);
// Establish a TCP connection to the original destination.
const serverSocket = net.connect(port, hostname, () => {
clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
// Create a tunnel by piping data between the client and the destination server.
serverSocket.write(head);
serverSocket.pipe(clientSocket);
clientSocket.pipe(serverSocket);
});
serverSocket.on('error', (err) => {
console.error(`[PROXY] Error connecting to destination: ${err.message}`);
clientSocket.end(`HTTP/1.1 502 Bad Gateway\r\n\r\n`);
});
} else {
console.log(`[PROXY] Denying connection to ${hostname}:${port}`);
clientSocket.end('HTTP/1.1 403 Forbidden\r\n\r\n');
}
clientSocket.on('error', (err) => {
// This can happen if the client hangs up.
console.error(`[PROXY] Client socket error: ${err.message}`);
});
});
server.listen(PROXY_PORT, () => {
const address = server.address();
console.log(`[PROXY] Proxy listening on ${address.address}:${address.port}`);
console.log(
`[PROXY] Allowing HTTPS connections to domains: ${ALLOWED_DOMAINS.join(', ')}`,
);
});
```

View File

@@ -183,8 +183,7 @@ This is the most critical stage where files are moved and transformed into their
`bundle` folder is created at the project root to house the final package contents.
1. The `package.json` is Transformed:
- What happens: The package.json from packages/cli/ is read, modified, and written into the root `bundle`/ directory. The
script scripts/prepare-cli-packagejson.js is responsible for this.
- What happens: The package.json from packages/cli/ is read, modified, and written into the root `bundle`/ directory.
- File movement: packages/cli/package.json -> (in-memory transformation) -> `bundle`/package.json
- Why: The final package.json must be different from the one used in development. Key changes include:
- Removing devDependencies.