Cherrypick extensions changes to v0.6.0 (#9179)

Co-authored-by: hritan <48129645+hritan@users.noreply.github.com>
Co-authored-by: Taneja Hriday <hridayt@google.com>
Co-authored-by: shishu314 <shishu_1998@yahoo.com>
Co-authored-by: Shi Shu <shii@google.com>
Co-authored-by: Jacob MacDonald <jakemac@google.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
christine betts
2025-09-23 13:35:18 -04:00
committed by GitHub
parent 3477abd296
commit 4a92f938e1
40 changed files with 3125 additions and 925 deletions

121
docs/extension-releasing.md Normal file
View File

@@ -0,0 +1,121 @@
# Extension Releasing
There are two primary ways of releasing extensions to users:
- [Git repository](#releasing-through-a-git-repository)
- [Github Releases](#releasing-through-github-releases)
Git repository releases tend to be the simplest and most flexible approach, while GitHub releases can be more efficient on initial install as they are shipped as single archives instead of requiring a git clone which downloads each file individually. Github releases may also contain platform specific archives if you need to ship platform specific binary files.
## Releasing through a git repository
This is the most flexible and simple option. All you need to do us create a publicly accessible git repo (such as a public github repository) and then users can install your extension using `gemini extensions install <your-repo-uri>`, or for a GitHub repository they can use the simplified `gemini extensions install <org>/<repo>` format. They can optionally depend on a specific ref (branch/tag/commit) using the `--ref=<some-ref>` argument, this defaults to the default branch.
Whenever commits are pushed to the ref that a user depends on, they will be prompted to update the extension. Note that this also allows for easy rollbacks, the HEAD commit is always treated as the latest version regardless of the actual version in the `gemini-extension.json` file.
### Managing release channels using a git repository
Users can depend on any ref from your git repo, such as a branch or tag, which allows you to manage multiple release channels.
For instance, you can maintain a `stable` branch, which users can install this way `gemini extensions install <your-repo-uri> --ref=stable`. Or, you could make this the default by treating your default branch as your stable release branch, and doing development in a different branch (for instance called `dev`). You can maintain as many branches or tags as you like, providing maximum flexibility for you and your users.
Note that these `ref` arguments can be tags, branches, or even specific commits, which allows users to depend on a specific version of your extension. It is up to you how you want to manage your tags and branches.
### Example releasing flow using a git repo
While there are many options for how you want to manage releases using a git flow, we recommend treating your default branch as your "stable" release branch. This means that the default behavior for `gemini extensions install <your-repo-uri>` is to be on the stable release branch.
Lets say you want to maintain three standard release channels, `stable`, `preview`, and `dev`. You would do all your standard development in the `dev` branch. When you are ready to do a preview release, you merge that branch into your `preview` branch. When you are ready to promote your preview branch to stable, you merge `preview` into your stable branch (which might be your default branch or a different branch).
You can also cherry pick changes from one branch into another using `git cherry-pick`, but do note that this will result in your branches having a slightly divergent history from each other, unless you force push changes to your branches on each release to restore the history to a clean slate (which may not be possible for the default branch depending on your repository settings). If you plan on doing cherry picks, you may want to avoid having your default branch be the stable branch to avoid force-pushing to the default branch which should generally be avoided.
## Releasing through Github releases
Gemini CLI extensions can be distributed through [GitHub Releases](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases). This provides a faster and more reliable initial installation experience for users, as it avoids the need to clone the repository.
Each release includes at least one archive file, which contains the full contents of the repo at the tag that it was linked to. Releases may also include [pre-built archives](#custom-pre-built-archives) if your extension requires some build step or has platform specific binaries attached to it.
When checking for updates, gemini will just look for the latest release on github (you must mark it as such when creating the release), unless the user installed a specific release by passing `--ref=<some-release-tag>`. We do not at this time support opting in to pre-release releases or semver.
### Custom pre-built archives
Custom archives must be attached directly to the github release as assets and must be fully self-contained. This means they should include the entire extension, see [archive structure](#archive-structure).
If your extension is platform-independent, you can provide a single generic asset. In this case, there should be only one asset attached to the release.
Custom archives may also be used if you want to develop your extension within a larger repository, you can build an archive which has a different layout from the repo itself (for instance it might just be an archive of a subdirectory containing the extension).
#### Platform specific archives
To ensure Gemini CLI can automatically find the correct release asset for each platform, you must follow this naming convention. The CLI will search for assets in the following order:
1. **Platform and Architecture-Specific:** `{platform}.{arch}.{name}.{extension}`
2. **Platform-Specific:** `{platform}.{name}.{extension}`
3. **Generic:** If only one asset is provided, it will be used as a generic fallback.
- `{name}`: The name of your extension.
- `{platform}`: The operating system. Supported values are:
- `darwin` (macOS)
- `linux`
- `win32` (Windows)
- `{arch}`: The architecture. Supported values are:
- `x64`
- `arm64`
- `{extension}`: The file extension of the archive (e.g., `.tar.gz` or `.zip`).
**Examples:**
- `darwin.arm64.my-tool.tar.gz` (specific to Apple Silicon Macs)
- `darwin.my-tool.tar.gz` (for all Macs)
- `linux.x64.my-tool.tar.gz`
- `win32.my-tool.zip`
#### Archive structure
Archives must be fully contained extensions and have all the standard requirements - specifically the `gemini-extension.json` file must be at the root of the archive.
The rest of the layout should look exactly the same as a typical extension, see [extensions.md](extension.md).
#### Example GitHub Actions workflow
Here is an example of a GitHub Actions workflow that builds and releases a Gemini CLI extension for multiple platforms:
```yaml
name: Release Extension
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build extension
run: npm run build
- name: Create release assets
run: |
npm run package -- --platform=darwin --arch=arm64
npm run package -- --platform=linux --arch=x64
npm run package -- --platform=win32 --arch=x64
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
release/darwin.arm64.my-tool.tar.gz
release/linux.arm64.my-tool.tar.gz
release/win32.arm64.my-tool.zip
```

View File

@@ -36,11 +36,13 @@ gemini extensions uninstall gemini-cli-security
Extensions are, by default, enabled across all workspaces. You can disable an extension entirely or for specific workspace.
For example, `gemini extensions disable extension-name` will disable the extension at the user level, so it will be disabled everywhere. `gemini extensions disable extension-name --scope=Workspace` will only disable the extension in the current workspace.
For example, `gemini extensions disable extension-name` will disable the extension at the user level, so it will be disabled everywhere. `gemini extensions disable extension-name --scope=workspace` will only disable the extension in the current workspace.
### Enabling an extension
You can re-enable extensions using `gemini extensions enable extension-name`. Note that if an extension is disabled at the user-level, enabling it at the workspace level will not do anything.
You can enable extensions using `gemini extensions enable extension-name`. You can also enable an extension for a specific workspace using `gemini extensions enable extension-name --scope=workspace` from within that workspace.
This is useful if you have an extension disabled at the top-level and only enabled in specific places.
### Updating an extension
@@ -105,8 +107,9 @@ The `gemini-extension.json` file contains the configuration for the extension. T
- `name`: The name of the extension. This is used to uniquely identify the extension and for conflict resolution when extension commands have the same name as user or project commands. The name should be lowercase and use dashes instead of underscores or spaces. This is how users will refer to your extension in the CLI. Note that we expect this name to match the extension directory name.
- `version`: The version of the extension.
- `mcpServers`: A map of MCP servers to configure. The key is the name of the server, and the value is the server configuration. These servers will be loaded on startup just like MCP servers configured in a [`settings.json` file](./cli/configuration.md). If both an extension and a `settings.json` file configure an MCP server with the same name, the server defined in the `settings.json` file takes precedence.
- Note that all MCP server configuration options are supported except for `trust`.
- `contextFileName`: The name of the file that contains the context for the extension. This will be used to load the context from the extension directory. If this property is not used but a `GEMINI.md` file is present in your extension directory, then that file will be loaded.
- `excludeTools`: An array of tool names to exclude from the model. You can also specify command-specific restrictions for tools that support it, like the `run_shell_command` tool. For example, `"excludeTools": ["run_shell_command(rm -rf)"]` will block the `rm -rf` command.
- `excludeTools`: An array of tool names to exclude from the model. You can also specify command-specific restrictions for tools that support it, like the `run_shell_command` tool. For example, `"excludeTools": ["run_shell_command(rm -rf)"]` will block the `rm -rf` command. Note that this differs from the MCP server `excludeTools` functionality, which can be listed in the MCP server config.
When Gemini CLI starts, it loads all the extensions and merges their configurations. If there are any conflicts, the workspace configuration takes precedence.

View File

@@ -307,6 +307,15 @@ for Gemini CLI:
- `command` (string)
- `subcommand` (string, if applicable)
- `gemini_cli.extension_enable`: This event occurs when an extension is enabled
- `gemini_cli.extension_install`: This event occurs when an extension is installed
- **Attributes**:
- `extension_name` (string)
- `extension_version` (string)
- `extension_source` (string)
- `status` (string)
- `gemini_cli.extension_uninstall`: This event occurs when an extension is uninstalled
### Metrics
Metrics are numerical measurements of behavior over time. The following metrics are collected for Gemini CLI: