mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-24 22:55:13 +00:00
Release Process vNext (#8152)
Co-authored-by: gemini-cli-robot <gemini-cli-robot@google.com>
This commit is contained in:
99
.github/actions/publish-release/action.yml
vendored
Normal file
99
.github/actions/publish-release/action.yml
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
name: 'Publish Release'
|
||||||
|
description: 'Builds, prepares, and publishes the gemini-cli packages to npm and creates a GitHub release.'
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
release-version:
|
||||||
|
description: 'The version to release (e.g., 0.1.11).'
|
||||||
|
required: true
|
||||||
|
npm-tag:
|
||||||
|
description: 'The npm tag to publish with (e.g., latest, preview, nightly).'
|
||||||
|
required: true
|
||||||
|
wombat-token-core:
|
||||||
|
description: 'The npm token for the @google/gemini-cli-core package.'
|
||||||
|
required: true
|
||||||
|
wombat-token-cli:
|
||||||
|
description: 'The npm token for the @google/gemini-cli package.'
|
||||||
|
required: true
|
||||||
|
github-token:
|
||||||
|
description: 'The GitHub token for creating the release.'
|
||||||
|
required: true
|
||||||
|
dry-run:
|
||||||
|
description: 'Whether to run in dry-run mode.'
|
||||||
|
required: true
|
||||||
|
release-branch:
|
||||||
|
description: 'The branch to target for the release.'
|
||||||
|
required: true
|
||||||
|
previous-tag:
|
||||||
|
description: 'The previous tag to use for generating release notes.'
|
||||||
|
required: true
|
||||||
|
working-directory:
|
||||||
|
description: 'The working directory to run the steps in.'
|
||||||
|
required: false
|
||||||
|
default: '.'
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: 'composite'
|
||||||
|
steps:
|
||||||
|
- name: 'Build and Prepare Packages'
|
||||||
|
working-directory: '${{ inputs.working-directory }}'
|
||||||
|
run: |-
|
||||||
|
npm run build:packages
|
||||||
|
npm run prepare:package
|
||||||
|
shell: 'bash'
|
||||||
|
|
||||||
|
- name: 'Configure npm for publishing'
|
||||||
|
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
|
||||||
|
with:
|
||||||
|
node-version-file: '${{ inputs.working-directory }}/.nvmrc'
|
||||||
|
registry-url: 'https://wombat-dressing-room.appspot.com'
|
||||||
|
scope: '@google'
|
||||||
|
|
||||||
|
- name: 'Publish @google/gemini-cli-core'
|
||||||
|
working-directory: '${{ inputs.working-directory }}'
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: '${{ inputs.wombat-token-core }}'
|
||||||
|
run: |-
|
||||||
|
npm publish \
|
||||||
|
--dry-run="${{ inputs.dry-run }}" \
|
||||||
|
--workspace="@google/gemini-cli-core" \
|
||||||
|
--tag="${{ inputs.npm-tag }}"
|
||||||
|
shell: 'bash'
|
||||||
|
|
||||||
|
- name: 'Install latest core package'
|
||||||
|
working-directory: '${{ inputs.working-directory }}'
|
||||||
|
if: '${{ inputs.dry-run == "false" }}'
|
||||||
|
run: |-
|
||||||
|
npm install "@google/gemini-cli-core@${{ inputs.release-version }}" \
|
||||||
|
--workspace="@google/gemini-cli" \
|
||||||
|
--save-exact
|
||||||
|
shell: 'bash'
|
||||||
|
|
||||||
|
- name: 'Publish @google/gemini-cli'
|
||||||
|
working-directory: '${{ inputs.working-directory }}'
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: '${{ inputs.wombat-token-cli }}'
|
||||||
|
run: |-
|
||||||
|
npm publish \
|
||||||
|
--dry-run="${{ inputs.dry-run }}" \
|
||||||
|
--workspace="@google/gemini-cli" \
|
||||||
|
--tag="${{ inputs.npm-tag }}"
|
||||||
|
shell: 'bash'
|
||||||
|
|
||||||
|
- name: 'Bundle'
|
||||||
|
working-directory: '${{ inputs.working-directory }}'
|
||||||
|
run: 'npm run bundle'
|
||||||
|
shell: 'bash'
|
||||||
|
|
||||||
|
- name: 'Create GitHub Release'
|
||||||
|
working-directory: '${{ inputs.working-directory }}'
|
||||||
|
if: '${{ inputs.dry-run == "false" }}'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: '${{ inputs.github-token }}'
|
||||||
|
run: |-
|
||||||
|
gh release create "v${{ inputs.release-version }}" \
|
||||||
|
bundle/gemini.js \
|
||||||
|
--target "${{ inputs.release-branch }}" \
|
||||||
|
--title "Release v${{ inputs.release-version }}" \
|
||||||
|
--notes-start-tag "${{ inputs.previous-tag }}" \
|
||||||
|
--generate-notes
|
||||||
|
shell: 'bash'
|
||||||
53
.github/workflows/nightly-release.yml
vendored
Normal file
53
.github/workflows/nightly-release.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
name: 'Nightly Release'
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
dry_run:
|
||||||
|
description: 'Run a dry-run of the release process; no branches, npm packages or GitHub releases will be created.'
|
||||||
|
required: true
|
||||||
|
type: 'boolean'
|
||||||
|
default: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: 'ubuntu-latest'
|
||||||
|
steps:
|
||||||
|
- name: 'Checkout'
|
||||||
|
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: 'Setup Node.js'
|
||||||
|
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: 'Install Dependencies'
|
||||||
|
run: 'npm ci'
|
||||||
|
|
||||||
|
- name: 'Get Nightly Version'
|
||||||
|
id: 'nightly_version'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
run: |
|
||||||
|
VERSION_JSON=$(node scripts/get-release-version.js --type=nightly)
|
||||||
|
echo "RELEASE_TAG=$(echo "${VERSION_JSON}" | jq -r .releaseTag)" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "RELEASE_VERSION=$(echo "${VERSION_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "NPM_TAG=$(echo "${VERSION_JSON}" | jq -r .npmTag)" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "PREVIOUS_TAG=$(echo "${VERSION_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
- name: 'Publish Release'
|
||||||
|
uses: './.github/actions/publish-release'
|
||||||
|
with:
|
||||||
|
release-version: '${{ steps.nightly_version.outputs.RELEASE_VERSION }}'
|
||||||
|
npm-tag: '${{ steps.nightly_version.outputs.NPM_TAG }}'
|
||||||
|
wombat-token-core: '${{ secrets.WOMBAT_TOKEN_CORE }}'
|
||||||
|
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
|
||||||
|
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
dry-run: '${{ github.event.inputs.dry_run }}'
|
||||||
|
release-branch: 'main'
|
||||||
|
previous-tag: '${{ steps.nightly_version.outputs.PREVIOUS_TAG }}'
|
||||||
213
.github/workflows/promote-release.yml
vendored
Normal file
213
.github/workflows/promote-release.yml
vendored
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
name: 'Promote Release'
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
dry_run:
|
||||||
|
description: 'Run a dry-run of the release process; no branches, npm packages or GitHub releases will be created.'
|
||||||
|
required: true
|
||||||
|
type: 'boolean'
|
||||||
|
default: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
calculate-versions:
|
||||||
|
name: 'Calculate Versions and Plan'
|
||||||
|
runs-on: 'ubuntu-latest'
|
||||||
|
outputs:
|
||||||
|
STABLE_VERSION: '${{ steps.versions.outputs.STABLE_VERSION }}'
|
||||||
|
STABLE_SHA: '${{ steps.versions.outputs.STABLE_SHA }}'
|
||||||
|
PREVIOUS_STABLE_TAG: '${{ steps.versions.outputs.PREVIOUS_STABLE_TAG }}'
|
||||||
|
PREVIEW_VERSION: '${{ steps.versions.outputs.PREVIEW_VERSION }}'
|
||||||
|
PREVIEW_SHA: '${{ steps.versions.outputs.PREVIEW_SHA }}'
|
||||||
|
PREVIOUS_PREVIEW_TAG: '${{ steps.versions.outputs.PREVIOUS_PREVIEW_TAG }}'
|
||||||
|
NEXT_NIGHTLY_VERSION: '${{ steps.versions.outputs.NEXT_NIGHTLY_VERSION }}'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Checkout'
|
||||||
|
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: 'Setup Node.js'
|
||||||
|
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: 'Install Dependencies'
|
||||||
|
run: 'npm ci'
|
||||||
|
|
||||||
|
- name: 'Calculate Versions and SHAs'
|
||||||
|
id: 'versions'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
STABLE_JSON=$(node scripts/get-release-version.js --type=stable)
|
||||||
|
PREVIEW_JSON=$(node scripts/get-release-version.js --type=preview)
|
||||||
|
NIGHTLY_JSON=$(node scripts/get-release-version.js --type=nightly)
|
||||||
|
echo "STABLE_VERSION=$(echo "${STABLE_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
|
||||||
|
# shellcheck disable=SC1083
|
||||||
|
echo "STABLE_SHA=$(git rev-parse "$(echo "${STABLE_JSON}" | jq -r .previousReleaseTag)"^{commit})" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "PREVIOUS_STABLE_TAG=$(echo "${STABLE_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "PREVIEW_VERSION=$(echo "${PREVIEW_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
|
||||||
|
# shellcheck disable=SC1083
|
||||||
|
echo "PREVIEW_SHA=$(git rev-parse "$(echo "${PREVIEW_JSON}" | jq -r .previousReleaseTag)"^{commit})" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "PREVIOUS_PREVIEW_TAG=$(echo "${PREVIEW_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "NEXT_NIGHTLY_VERSION=$(echo "${NIGHTLY_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
promote:
|
||||||
|
name: 'Promote to ${{ matrix.channel }}'
|
||||||
|
needs: 'calculate-versions'
|
||||||
|
runs-on: 'ubuntu-latest'
|
||||||
|
permissions:
|
||||||
|
contents: 'write'
|
||||||
|
packages: 'write'
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- channel: 'stable'
|
||||||
|
version: '${{ needs.calculate-versions.outputs.STABLE_VERSION }}'
|
||||||
|
sha: '${{ needs.calculate-versions.outputs.STABLE_SHA }}'
|
||||||
|
npm-tag: 'latest'
|
||||||
|
previous-tag: '${{ needs.calculate-versions.outputs.PREVIOUS_STABLE_TAG }}'
|
||||||
|
- channel: 'preview'
|
||||||
|
version: '${{ needs.calculate-versions.outputs.PREVIEW_VERSION }}'
|
||||||
|
sha: '${{ needs.calculate-versions.outputs.PREVIEW_SHA }}'
|
||||||
|
npm-tag: 'preview'
|
||||||
|
previous-tag: '${{ needs.calculate-versions.outputs.PREVIOUS_PREVIEW_TAG }}'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Checkout main'
|
||||||
|
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
|
||||||
|
with:
|
||||||
|
ref: 'main'
|
||||||
|
|
||||||
|
- name: 'Checkout correct SHA'
|
||||||
|
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
|
||||||
|
with:
|
||||||
|
ref: '${{ matrix.sha }}'
|
||||||
|
path: 'release'
|
||||||
|
|
||||||
|
- name: 'Setup Node.js'
|
||||||
|
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: 'Install Dependencies'
|
||||||
|
working-directory: './release'
|
||||||
|
run: 'npm ci'
|
||||||
|
|
||||||
|
- name: 'Configure Git User'
|
||||||
|
working-directory: './release'
|
||||||
|
run: |-
|
||||||
|
git config user.name "gemini-cli-robot"
|
||||||
|
git config user.email "gemini-cli-robot@google.com"
|
||||||
|
|
||||||
|
- name: 'Create and switch to a release branch'
|
||||||
|
working-directory: './release'
|
||||||
|
id: 'release_branch'
|
||||||
|
run: |
|
||||||
|
BRANCH_NAME="release/v${{ matrix.version }}"
|
||||||
|
git switch -c "${BRANCH_NAME}"
|
||||||
|
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
- name: 'Update package versions'
|
||||||
|
working-directory: './release'
|
||||||
|
run: 'npm run release:version "${{ matrix.version }}"'
|
||||||
|
|
||||||
|
- name: 'Commit and Conditionally Push package versions'
|
||||||
|
working-directory: './release'
|
||||||
|
env:
|
||||||
|
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
||||||
|
DRY_RUN: '${{ github.event.inputs.dry_run }}'
|
||||||
|
RELEASE_TAG: 'v${{ matrix.version }}'
|
||||||
|
run: |-
|
||||||
|
git add package.json package-lock.json packages/*/package.json
|
||||||
|
git commit -m "chore(release): ${RELEASE_TAG}"
|
||||||
|
if [[ "${DRY_RUN}" == "false" ]]; then
|
||||||
|
echo "Pushing release branch to remote..."
|
||||||
|
git push --set-upstream origin "${BRANCH_NAME}" --follow-tags
|
||||||
|
else
|
||||||
|
echo "Dry run enabled. Skipping push."
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: 'Publish Release'
|
||||||
|
uses: './.github/actions/publish-release'
|
||||||
|
with:
|
||||||
|
release-version: '${{ matrix.version }}'
|
||||||
|
npm-tag: '${{ matrix.npm-tag }}'
|
||||||
|
wombat-token-core: '${{ secrets.WOMBAT_TOKEN_CORE }}'
|
||||||
|
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
|
||||||
|
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
dry-run: '${{ github.event.inputs.dry_run }}'
|
||||||
|
release-branch: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
||||||
|
previous-tag: '${{ matrix.previous-tag }}'
|
||||||
|
working-directory: './release'
|
||||||
|
|
||||||
|
nightly-pr:
|
||||||
|
name: 'Create Nightly PR'
|
||||||
|
needs: 'calculate-versions'
|
||||||
|
runs-on: 'ubuntu-latest'
|
||||||
|
permissions:
|
||||||
|
contents: 'write'
|
||||||
|
pull-requests: 'write'
|
||||||
|
steps:
|
||||||
|
- name: 'Checkout main'
|
||||||
|
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
|
||||||
|
with:
|
||||||
|
ref: 'main'
|
||||||
|
|
||||||
|
- name: 'Setup Node.js'
|
||||||
|
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: 'Install Dependencies'
|
||||||
|
run: 'npm ci'
|
||||||
|
|
||||||
|
- name: 'Configure Git User'
|
||||||
|
run: |-
|
||||||
|
git config user.name "gemini-cli-robot"
|
||||||
|
git config user.email "gemini-cli-robot@google.com"
|
||||||
|
|
||||||
|
- name: 'Create and switch to a new branch'
|
||||||
|
id: 'release_branch'
|
||||||
|
run: |
|
||||||
|
BRANCH_NAME="chore/nightly-version-bump-${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"
|
||||||
|
git switch -c "${BRANCH_NAME}"
|
||||||
|
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
- name: 'Update package versions'
|
||||||
|
run: 'npm run release:version "${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"'
|
||||||
|
|
||||||
|
- name: 'Commit and Push package versions'
|
||||||
|
env:
|
||||||
|
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
||||||
|
DRY_RUN: '${{ github.event.inputs.dry_run }}'
|
||||||
|
run: |-
|
||||||
|
git add package.json package-lock.json packages/*/package.json
|
||||||
|
git commit -m "chore(release): bump version to ${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"
|
||||||
|
if [[ "${DRY_RUN}" == "false" ]]; then
|
||||||
|
echo "Pushing release branch to remote..."
|
||||||
|
git push --set-upstream origin "${BRANCH_NAME}"
|
||||||
|
else
|
||||||
|
echo "Dry run enabled. Skipping push."
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: 'Create and Approve Pull Request'
|
||||||
|
if: |-
|
||||||
|
${{ github.event.inputs.dry_run == 'false' }}
|
||||||
|
env:
|
||||||
|
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
||||||
|
run: |
|
||||||
|
gh pr create \
|
||||||
|
--title "chore(release): bump version to ${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}" \
|
||||||
|
--body "Automated version bump to prepare for the next nightly release." \
|
||||||
|
--base "main" \
|
||||||
|
--head "${BRANCH_NAME}" \
|
||||||
|
--fill
|
||||||
|
gh pr merge --auto --squash
|
||||||
231
.github/workflows/release.yml
vendored
231
.github/workflows/release.yml
vendored
@@ -1,231 +0,0 @@
|
|||||||
name: 'Release'
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
# Runs every day at midnight UTC for the nightly release.
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
# Runs every Tuesday at 23:59 UTC for the preview release.
|
|
||||||
- cron: '59 23 * * 2'
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
version:
|
|
||||||
description: 'The version to release (e.g., v0.1.11). Required for manual patch releases.'
|
|
||||||
required: false # Not required for scheduled runs
|
|
||||||
type: 'string'
|
|
||||||
ref:
|
|
||||||
description: 'The branch or ref (full git sha) to release from.'
|
|
||||||
required: true
|
|
||||||
type: 'string'
|
|
||||||
default: 'main'
|
|
||||||
dry_run:
|
|
||||||
description: 'Run a dry-run of the release process; no branches, npm packages or GitHub releases will be created.'
|
|
||||||
required: true
|
|
||||||
type: 'boolean'
|
|
||||||
default: true
|
|
||||||
create_nightly_release:
|
|
||||||
description: 'Auto apply the nightly release tag, input version is ignored.'
|
|
||||||
required: false
|
|
||||||
type: 'boolean'
|
|
||||||
default: false
|
|
||||||
create_preview_release:
|
|
||||||
description: 'Auto apply the preview release tag, input version is ignored.'
|
|
||||||
required: false
|
|
||||||
type: 'boolean'
|
|
||||||
default: false
|
|
||||||
force_skip_tests:
|
|
||||||
description: 'Select to skip the "Run Tests" step in testing. Prod releases should run tests'
|
|
||||||
required: false
|
|
||||||
type: 'boolean'
|
|
||||||
default: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
runs-on: 'ubuntu-latest'
|
|
||||||
environment:
|
|
||||||
name: 'production-release'
|
|
||||||
url: '${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
if: |-
|
|
||||||
${{ github.repository == 'google-gemini/gemini-cli' }}
|
|
||||||
permissions:
|
|
||||||
contents: 'write'
|
|
||||||
packages: 'write'
|
|
||||||
id-token: 'write'
|
|
||||||
issues: 'write' # For creating issues on failure
|
|
||||||
outputs:
|
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 'Checkout'
|
|
||||||
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
|
|
||||||
with:
|
|
||||||
ref: '${{ github.event.inputs.ref || github.sha }}'
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: 'Set booleans for simplified logic'
|
|
||||||
env:
|
|
||||||
CREATE_NIGHTLY_RELEASE: '${{ github.event.inputs.create_nightly_release }}'
|
|
||||||
CREATE_PREVIEW_RELEASE: '${{ github.event.inputs.create_preview_release }}'
|
|
||||||
EVENT_NAME: '${{ github.event_name }}'
|
|
||||||
CRON: '${{ github.event.schedule }}'
|
|
||||||
DRY_RUN_INPUT: '${{ github.event.inputs.dry_run }}'
|
|
||||||
id: 'vars'
|
|
||||||
run: |-
|
|
||||||
is_nightly="false"
|
|
||||||
if [[ "${CRON}" == "0 0 * * *" || "${CREATE_NIGHTLY_RELEASE}" == "true" ]]; then
|
|
||||||
is_nightly="true"
|
|
||||||
fi
|
|
||||||
echo "is_nightly=${is_nightly}" >> "${GITHUB_OUTPUT}"
|
|
||||||
|
|
||||||
is_preview="false"
|
|
||||||
if [[ "${CRON}" == "59 23 * * 2" || "${CREATE_PREVIEW_RELEASE}" == "true" ]]; then
|
|
||||||
is_preview="true"
|
|
||||||
fi
|
|
||||||
echo "is_preview=${is_preview}" >> "${GITHUB_OUTPUT}"
|
|
||||||
|
|
||||||
is_dry_run="false"
|
|
||||||
if [[ "${DRY_RUN_INPUT}" == "true" ]]; then
|
|
||||||
is_dry_run="true"
|
|
||||||
fi
|
|
||||||
echo "is_dry_run=${is_dry_run}" >> "${GITHUB_OUTPUT}"
|
|
||||||
|
|
||||||
- name: 'Setup Node.js'
|
|
||||||
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- name: 'Install Dependencies'
|
|
||||||
run: |-
|
|
||||||
npm ci
|
|
||||||
|
|
||||||
- name: 'Get the version'
|
|
||||||
id: 'version'
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
|
||||||
IS_NIGHTLY: '${{ steps.vars.outputs.is_nightly }}'
|
|
||||||
IS_PREVIEW: '${{ steps.vars.outputs.is_preview }}'
|
|
||||||
MANUAL_VERSION: '${{ inputs.version }}'
|
|
||||||
run: |-
|
|
||||||
VERSION_JSON="$(node scripts/get-release-version.js)"
|
|
||||||
echo "RELEASE_TAG=$(echo "${VERSION_JSON}" | jq -r .releaseTag)" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "RELEASE_VERSION=$(echo "${VERSION_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "NPM_TAG=$(echo "${VERSION_JSON}" | jq -r .npmTag)" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "PREVIOUS_TAG=$(echo "${VERSION_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}"
|
|
||||||
|
|
||||||
- name: 'Run Tests'
|
|
||||||
if: |-
|
|
||||||
${{ github.event.inputs.force_skip_tests != 'true' }}
|
|
||||||
env:
|
|
||||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
|
||||||
run: |-
|
|
||||||
npm run preflight
|
|
||||||
npm run test:integration:sandbox:none
|
|
||||||
npm run test:integration:sandbox:docker
|
|
||||||
|
|
||||||
- name: 'Configure Git User'
|
|
||||||
run: |-
|
|
||||||
git config user.name "gemini-cli-robot"
|
|
||||||
git config user.email "gemini-cli-robot@google.com"
|
|
||||||
|
|
||||||
- name: 'Create and switch to a release branch'
|
|
||||||
id: 'release_branch'
|
|
||||||
env:
|
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
run: |-
|
|
||||||
BRANCH_NAME="release/${RELEASE_TAG}"
|
|
||||||
git switch -c "${BRANCH_NAME}"
|
|
||||||
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
|
|
||||||
|
|
||||||
- name: 'Update package versions'
|
|
||||||
env:
|
|
||||||
RELEASE_VERSION: '${{ steps.version.outputs.RELEASE_VERSION }}'
|
|
||||||
run: |-
|
|
||||||
npm run release:version "${RELEASE_VERSION}"
|
|
||||||
|
|
||||||
- name: 'Commit and Conditionally Push package versions'
|
|
||||||
env:
|
|
||||||
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
|
||||||
IS_DRY_RUN: '${{ steps.vars.outputs.is_dry_run }}'
|
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
run: |-
|
|
||||||
git add package.json package-lock.json packages/*/package.json
|
|
||||||
git commit -m "chore(release): ${RELEASE_TAG}"
|
|
||||||
if [[ "${IS_DRY_RUN}" == "false" ]]; then
|
|
||||||
echo "Pushing release branch to remote..."
|
|
||||||
git push --set-upstream origin "${BRANCH_NAME}" --follow-tags
|
|
||||||
else
|
|
||||||
echo "Dry run enabled. Skipping push."
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 'Build and Prepare Packages'
|
|
||||||
run: |-
|
|
||||||
npm run build:packages
|
|
||||||
npm run prepare:package
|
|
||||||
|
|
||||||
- name: 'Configure npm for publishing'
|
|
||||||
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
registry-url: 'https://wombat-dressing-room.appspot.com'
|
|
||||||
scope: '@google'
|
|
||||||
|
|
||||||
- name: 'Publish @google/gemini-cli-core'
|
|
||||||
env:
|
|
||||||
IS_DRY_RUN: '${{ steps.vars.outputs.is_dry_run }}'
|
|
||||||
NODE_AUTH_TOKEN: '${{ secrets.WOMBAT_TOKEN_CORE }}'
|
|
||||||
NPM_TAG: '${{ steps.version.outputs.NPM_TAG }}'
|
|
||||||
run: |-
|
|
||||||
npm publish \
|
|
||||||
--dry-run="${IS_DRY_RUN}" \
|
|
||||||
--workspace="@google/gemini-cli-core" \
|
|
||||||
--tag="${NPM_TAG}"
|
|
||||||
|
|
||||||
- name: 'Install latest core package'
|
|
||||||
if: |-
|
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' }}
|
|
||||||
env:
|
|
||||||
RELEASE_VERSION: '${{ steps.version.outputs.RELEASE_VERSION }}'
|
|
||||||
run: |-
|
|
||||||
npm install "@google/gemini-cli-core@${RELEASE_VERSION}" \
|
|
||||||
--workspace="@google/gemini-cli" \
|
|
||||||
--save-exact
|
|
||||||
|
|
||||||
- name: 'Publish @google/gemini-cli'
|
|
||||||
env:
|
|
||||||
IS_DRY_RUN: '${{ steps.vars.outputs.is_dry_run }}'
|
|
||||||
NODE_AUTH_TOKEN: '${{ secrets.WOMBAT_TOKEN_CLI }}'
|
|
||||||
NPM_TAG: '${{ steps.version.outputs.NPM_TAG }}'
|
|
||||||
run: |-
|
|
||||||
npm publish \
|
|
||||||
--dry-run="${IS_DRY_RUN}" \
|
|
||||||
--workspace="@google/gemini-cli" \
|
|
||||||
--tag="${NPM_TAG}"
|
|
||||||
|
|
||||||
- name: 'Create GitHub Release and Tag'
|
|
||||||
if: |-
|
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' }}
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
|
||||||
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
PREVIOUS_TAG: '${{ steps.version.outputs.PREVIOUS_TAG }}'
|
|
||||||
run: |-
|
|
||||||
gh release create "${RELEASE_TAG}" \
|
|
||||||
bundle/gemini.js \
|
|
||||||
--target "$RELEASE_BRANCH" \
|
|
||||||
--title "Release ${RELEASE_TAG}" \
|
|
||||||
--notes-start-tag "$PREVIOUS_TAG" \
|
|
||||||
--generate-notes
|
|
||||||
|
|
||||||
- name: 'Create Issue on Failure'
|
|
||||||
if: |-
|
|
||||||
${{ failure() }}
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }} || "N/A"'
|
|
||||||
DETAILS_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
|
||||||
run: |-
|
|
||||||
gh issue create \
|
|
||||||
--title "Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')" \
|
|
||||||
--body "The release workflow failed. See the full run for details: ${DETAILS_URL}" \
|
|
||||||
--label "kind/bug,release-failure,priority/p0"
|
|
||||||
@@ -86,3 +86,4 @@ ignore:
|
|||||||
- 'thirdparty/'
|
- 'thirdparty/'
|
||||||
- 'third_party/'
|
- 'third_party/'
|
||||||
- 'vendor/'
|
- 'vendor/'
|
||||||
|
- 'node_modules/'
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export default tseslint.config(
|
|||||||
'bundle/**',
|
'bundle/**',
|
||||||
'package/bundle/**',
|
'package/bundle/**',
|
||||||
'.integration-tests/**',
|
'.integration-tests/**',
|
||||||
|
'dist/**',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
eslint.configs.recommended,
|
eslint.configs.recommended,
|
||||||
|
|||||||
264
package-lock.json
generated
264
package-lock.json
generated
@@ -1,16 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "@google/gemini-cli",
|
"name": "@google/gemini-cli",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@google/gemini-cli",
|
"name": "@google/gemini-cli",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@lvce-editor/ripgrep": "^2.4.0",
|
||||||
"simple-git": "^3.28.0"
|
"simple-git": "^3.28.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
"msw": "^2.10.4",
|
"msw": "^2.10.4",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"react-devtools-core": "^4.28.5",
|
"react-devtools-core": "^4.28.5",
|
||||||
|
"semver": "^7.7.2",
|
||||||
"tsx": "^4.20.3",
|
"tsx": "^4.20.3",
|
||||||
"typescript-eslint": "^8.30.1",
|
"typescript-eslint": "^8.30.1",
|
||||||
"vitest": "^3.2.4",
|
"vitest": "^3.2.4",
|
||||||
@@ -1840,6 +1842,35 @@
|
|||||||
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
|
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@lvce-editor/ripgrep": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lvce-editor/ripgrep/-/ripgrep-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-Y+Cq0otcsBtuVVVtGmgjjnw51m+RzhffIbyF9AOVKXkXXu7NaD5kawIEtrQX9nOOEZa95a6swU9lgkYZIznFKg==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@lvce-editor/verror": "^1.7.0",
|
||||||
|
"execa": "^9.6.0",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
|
"fs-extra": "^11.3.1",
|
||||||
|
"got": "^14.4.8",
|
||||||
|
"path-exists": "^5.0.0",
|
||||||
|
"tempy": "^3.1.0",
|
||||||
|
"xdg-basedir": "^5.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lvce-editor/ripgrep/node_modules/path-exists": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@lvce-editor/verror": {
|
"node_modules/@lvce-editor/verror": {
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lvce-editor/verror/-/verror-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@lvce-editor/verror/-/verror-1.7.0.tgz",
|
||||||
@@ -4355,19 +4386,6 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
|
|
||||||
"version": "7.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "8.35.0",
|
"version": "8.35.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.0.tgz",
|
||||||
@@ -4911,19 +4929,6 @@
|
|||||||
"node": "20 || >=22"
|
"node": "20 || >=22"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vscode/vsce/node_modules/semver": {
|
|
||||||
"version": "7.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@vscode/vsce/node_modules/yallist": {
|
"node_modules/@vscode/vsce/node_modules/yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
@@ -6470,6 +6475,33 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crypto-random-string": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"type-fest": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/crypto-random-string/node_modules/type-fest": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
|
||||||
|
"license": "(MIT OR CC0-1.0)",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/css-select": {
|
"node_modules/css-select": {
|
||||||
"version": "5.2.2",
|
"version": "5.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
|
||||||
@@ -7532,6 +7564,16 @@
|
|||||||
"ms": "^2.1.1"
|
"ms": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-import/node_modules/semver": {
|
||||||
|
"version": "6.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-plugin-license-header": {
|
"node_modules/eslint-plugin-license-header": {
|
||||||
"version": "0.8.0",
|
"version": "0.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-license-header/-/eslint-plugin-license-header-0.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-license-header/-/eslint-plugin-license-header-0.8.0.tgz",
|
||||||
@@ -7606,6 +7648,16 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-react/node_modules/semver": {
|
||||||
|
"version": "6.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-scope": {
|
"node_modules/eslint-scope": {
|
||||||
"version": "8.4.0",
|
"version": "8.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
|
||||||
@@ -8805,9 +8857,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/got": {
|
"node_modules/got": {
|
||||||
"version": "14.4.7",
|
"version": "14.4.8",
|
||||||
"resolved": "https://registry.npmjs.org/got/-/got-14.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/got/-/got-14.4.8.tgz",
|
||||||
"integrity": "sha512-DI8zV1231tqiGzOiOzQWDhsBmncFW7oQDH6Zgy6pDPrqJuVZMtoSgPLLsBZQj8Jg4JFfwoOsDA8NGtLQLnIx2g==",
|
"integrity": "sha512-vxwU4HuR0BIl+zcT1LYrgBjM+IJjNElOjCzs0aPgHorQyr/V6H6Y73Sn3r3FOlUffvWD+Q5jtRuGWaXkU8Jbhg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sindresorhus/is": "^7.0.1",
|
"@sindresorhus/is": "^7.0.1",
|
||||||
@@ -10415,19 +10467,6 @@
|
|||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jsonwebtoken/node_modules/semver": {
|
|
||||||
"version": "7.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/jsx-ast-utils": {
|
"node_modules/jsx-ast-utils": {
|
||||||
"version": "3.3.5",
|
"version": "3.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
|
||||||
@@ -10785,19 +10824,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/make-dir/node_modules/semver": {
|
|
||||||
"version": "7.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/markdown-it": {
|
"node_modules/markdown-it": {
|
||||||
"version": "14.1.0",
|
"version": "14.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||||
@@ -11217,20 +11243,6 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-abi/node_modules/semver": {
|
|
||||||
"version": "7.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"optional": true,
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-addon-api": {
|
"node_modules/node-addon-api": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
|
||||||
@@ -11320,18 +11332,6 @@
|
|||||||
"node": "^16.14.0 || >=18.0.0"
|
"node": "^16.14.0 || >=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/normalize-package-data/node_modules/semver": {
|
|
||||||
"version": "7.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/normalize-url": {
|
"node_modules/normalize-url": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.2.tgz",
|
||||||
@@ -11816,18 +11816,6 @@
|
|||||||
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
||||||
"license": "BlueOak-1.0.0"
|
"license": "BlueOak-1.0.0"
|
||||||
},
|
},
|
||||||
"node_modules/package-json/node_modules/semver": {
|
|
||||||
"version": "7.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/parent-module": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -13173,13 +13161,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "7.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/send": {
|
"node_modules/send": {
|
||||||
@@ -14321,6 +14311,45 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/temp-dir": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tempy": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-stream": "^3.0.0",
|
||||||
|
"temp-dir": "^3.0.0",
|
||||||
|
"type-fest": "^2.12.2",
|
||||||
|
"unique-string": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tempy/node_modules/is-stream": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/terminal-link": {
|
"node_modules/terminal-link": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-4.0.0.tgz",
|
||||||
@@ -14956,6 +14985,21 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/unique-string": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"crypto-random-string": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/universalify": {
|
"node_modules/universalify": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||||
@@ -15063,18 +15107,6 @@
|
|||||||
"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
|
"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/update-notifier/node_modules/semver": {
|
|
||||||
"version": "7.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/update-notifier/node_modules/string-width": {
|
"node_modules/update-notifier/node_modules/string-width": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
|
||||||
@@ -16021,7 +16053,7 @@
|
|||||||
},
|
},
|
||||||
"packages/a2a-server": {
|
"packages/a2a-server": {
|
||||||
"name": "@google/gemini-cli-a2a-server",
|
"name": "@google/gemini-cli-a2a-server",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@a2a-js/sdk": "^0.3.2",
|
"@a2a-js/sdk": "^0.3.2",
|
||||||
"@google-cloud/storage": "^7.16.0",
|
"@google-cloud/storage": "^7.16.0",
|
||||||
@@ -16292,7 +16324,7 @@
|
|||||||
},
|
},
|
||||||
"packages/cli": {
|
"packages/cli": {
|
||||||
"name": "@google/gemini-cli",
|
"name": "@google/gemini-cli",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google/gemini-cli-core": "file:../core",
|
"@google/gemini-cli-core": "file:../core",
|
||||||
"@google/genai": "1.16.0",
|
"@google/genai": "1.16.0",
|
||||||
@@ -16483,7 +16515,7 @@
|
|||||||
},
|
},
|
||||||
"packages/core": {
|
"packages/core": {
|
||||||
"name": "@google/gemini-cli-core",
|
"name": "@google/gemini-cli-core",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google/genai": "1.16.0",
|
"@google/genai": "1.16.0",
|
||||||
"@joshua.litt/get-ripgrep": "^0.0.2",
|
"@joshua.litt/get-ripgrep": "^0.0.2",
|
||||||
@@ -16624,7 +16656,7 @@
|
|||||||
},
|
},
|
||||||
"packages/test-utils": {
|
"packages/test-utils": {
|
||||||
"name": "@google/gemini-cli-test-utils",
|
"name": "@google/gemini-cli-test-utils",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
@@ -16635,7 +16667,7 @@
|
|||||||
},
|
},
|
||||||
"packages/vscode-ide-companion": {
|
"packages/vscode-ide-companion": {
|
||||||
"name": "gemini-cli-vscode-ide-companion",
|
"name": "gemini-cli-vscode-ide-companion",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"license": "LICENSE",
|
"license": "LICENSE",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.15.1",
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@google/gemini-cli",
|
"name": "@google/gemini-cli",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
},
|
},
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"url": "git+https://github.com/google-gemini/gemini-cli.git"
|
"url": "git+https://github.com/google-gemini/gemini-cli.git"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.4.0"
|
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.6.0-nightly"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node scripts/start.js",
|
"start": "node scripts/start.js",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@google/gemini-cli-a2a-server",
|
"name": "@google/gemini-cli-a2a-server",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Gemini CLI A2A Server",
|
"description": "Gemini CLI A2A Server",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@google/gemini-cli",
|
"name": "@google/gemini-cli",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"description": "Gemini CLI",
|
"description": "Gemini CLI",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.4.0"
|
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.6.0-nightly"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google/gemini-cli-core": "file:../core",
|
"@google/gemini-cli-core": "file:../core",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@google/gemini-cli-core",
|
"name": "@google/gemini-cli-core",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"description": "Gemini CLI Core",
|
"description": "Gemini CLI Core",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@google/gemini-cli-test-utils",
|
"name": "@google/gemini-cli-test-utils",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "gemini-cli-vscode-ide-companion",
|
"name": "gemini-cli-vscode-ide-companion",
|
||||||
"displayName": "Gemini CLI Companion",
|
"displayName": "Gemini CLI Companion",
|
||||||
"description": "Enable Gemini CLI with direct access to your IDE workspace.",
|
"description": "Enable Gemini CLI with direct access to your IDE workspace.",
|
||||||
"version": "0.4.0",
|
"version": "0.6.0-nightly",
|
||||||
"publisher": "google",
|
"publisher": "google",
|
||||||
"icon": "assets/icon.png",
|
"icon": "assets/icon.png",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @license
|
* @license
|
||||||
* Copyright 2025 Google LLC
|
* Copyright 2025 Google LLC
|
||||||
@@ -5,129 +7,82 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { execSync } from 'node:child_process';
|
import { execSync } from 'node:child_process';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import { readFileSync } from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
function getLatestStableTag() {
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
// Fetches all tags, then filters for the latest stable (non-prerelease) tag.
|
const __dirname = path.dirname(__filename);
|
||||||
const tags = execSync('git tag --list "v*.*.*" --sort=-v:refname')
|
|
||||||
.toString()
|
function getArgs() {
|
||||||
.split('\n');
|
const args = {};
|
||||||
const latestStableTag = tags.find((tag) =>
|
process.argv.slice(2).forEach((arg) => {
|
||||||
tag.match(/^v[0-9]+\.[0-9]+\.[0-9]+$/),
|
if (arg.startsWith('--')) {
|
||||||
);
|
const [key, value] = arg.substring(2).split('=');
|
||||||
if (!latestStableTag) {
|
args[key] = value === undefined ? true : value;
|
||||||
throw new Error('Could not find a stable tag.');
|
|
||||||
}
|
}
|
||||||
return latestStableTag;
|
});
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getShortSha() {
|
function getLatestTag(pattern) {
|
||||||
return execSync('git rev-parse --short HEAD').toString().trim();
|
const command = `gh release list --limit 100 --json tagName | jq -r '[.[] | select(.tagName | ${pattern})] | .[0].tagName'`;
|
||||||
}
|
|
||||||
|
|
||||||
function getNextVersionString(stableVersion, minorIncrement) {
|
|
||||||
const [major, minor] = stableVersion.substring(1).split('.');
|
|
||||||
const nextMinorVersion = parseInt(minor, 10) + minorIncrement;
|
|
||||||
return `${major}.${nextMinorVersion}.0`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getNightlyTagName(stableVersion) {
|
|
||||||
const version = getNextVersionString(stableVersion, 2);
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
const year = now.getUTCFullYear().toString();
|
|
||||||
const month = (now.getUTCMonth() + 1).toString().padStart(2, '0');
|
|
||||||
const day = now.getUTCDate().toString().padStart(2, '0');
|
|
||||||
const date = `${year}${month}${day}`;
|
|
||||||
|
|
||||||
const sha = getShortSha();
|
|
||||||
return `v${version}-nightly.${date}.${sha}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPreviewTagName(stableVersion) {
|
|
||||||
const version = getNextVersionString(stableVersion, 1);
|
|
||||||
return `v${version}-preview`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPreviousReleaseTag(isNightly) {
|
|
||||||
if (isNightly) {
|
|
||||||
console.error('Finding latest nightly release...');
|
|
||||||
return execSync(
|
|
||||||
`gh release list --limit 100 --json tagName | jq -r '[.[] | select(.tagName | contains("nightly"))] | .[0].tagName'`,
|
|
||||||
)
|
|
||||||
.toString()
|
|
||||||
.trim();
|
|
||||||
} else {
|
|
||||||
console.error('Finding latest STABLE release (excluding pre-releases)...');
|
|
||||||
return execSync(
|
|
||||||
`gh release list --limit 100 --json tagName | jq -r '[.[] | select(.tagName | (contains("nightly") or contains("preview")) | not)] | .[0].tagName'`,
|
|
||||||
)
|
|
||||||
.toString()
|
|
||||||
.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getReleaseVersion() {
|
|
||||||
const isNightly = process.env.IS_NIGHTLY === 'true';
|
|
||||||
const isPreview = process.env.IS_PREVIEW === 'true';
|
|
||||||
const manualVersion = process.env.MANUAL_VERSION;
|
|
||||||
|
|
||||||
let releaseTag;
|
|
||||||
|
|
||||||
if (isNightly) {
|
|
||||||
console.error('Calculating next nightly version...');
|
|
||||||
const stableVersion = getLatestStableTag();
|
|
||||||
releaseTag = getNightlyTagName(stableVersion);
|
|
||||||
} else if (isPreview) {
|
|
||||||
console.error('Calculating next preview version...');
|
|
||||||
const stableVersion = getLatestStableTag();
|
|
||||||
releaseTag = getPreviewTagName(stableVersion);
|
|
||||||
} else if (manualVersion) {
|
|
||||||
console.error(`Using manual version: ${manualVersion}`);
|
|
||||||
releaseTag = manualVersion;
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
'Error: No version specified and this is not a nightly or preview release.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!releaseTag) {
|
|
||||||
throw new Error('Error: Version could not be determined.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!releaseTag.startsWith('v')) {
|
|
||||||
console.error("Version is missing 'v' prefix. Prepending it.");
|
|
||||||
releaseTag = `v${releaseTag}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (releaseTag.includes('+')) {
|
|
||||||
throw new Error(
|
|
||||||
'Error: Versions with build metadata (+) are not supported for releases. Please use a pre-release version (e.g., v1.2.3-alpha.4) instead.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!releaseTag.match(/^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$/)) {
|
|
||||||
throw new Error(
|
|
||||||
'Error: Version must be in the format vX.Y.Z or vX.Y.Z-prerelease',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const releaseVersion = releaseTag.substring(1);
|
|
||||||
let npmTag = 'latest';
|
|
||||||
if (releaseVersion.includes('-')) {
|
|
||||||
npmTag = releaseVersion.split('-')[1].split('.')[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
const previousReleaseTag = getPreviousReleaseTag(isNightly);
|
|
||||||
|
|
||||||
return { releaseTag, releaseVersion, npmTag, previousReleaseTag };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.argv[1] === new URL(import.meta.url).pathname) {
|
|
||||||
try {
|
try {
|
||||||
const versions = getReleaseVersion();
|
return execSync(command).toString().trim();
|
||||||
console.log(JSON.stringify(versions));
|
} catch {
|
||||||
} catch (error) {
|
// Suppress error output for cleaner test failures
|
||||||
console.error(error.message);
|
return '';
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getVersion(options = {}) {
|
||||||
|
const args = getArgs();
|
||||||
|
const type = options.type || args.type || 'nightly';
|
||||||
|
|
||||||
|
let releaseVersion;
|
||||||
|
let npmTag;
|
||||||
|
let previousReleaseTag;
|
||||||
|
|
||||||
|
if (type === 'nightly') {
|
||||||
|
const packageJson = JSON.parse(
|
||||||
|
readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'),
|
||||||
|
);
|
||||||
|
const [major, minor] = packageJson.version.split('.');
|
||||||
|
const nextMinor = parseInt(minor) + 1;
|
||||||
|
const date = new Date().toISOString().slice(0, 10).replace(/-/g, '');
|
||||||
|
const gitShortHash = execSync('git rev-parse --short HEAD')
|
||||||
|
.toString()
|
||||||
|
.trim();
|
||||||
|
releaseVersion = `${major}.${nextMinor}.0-nightly.${date}.${gitShortHash}`;
|
||||||
|
npmTag = 'nightly';
|
||||||
|
previousReleaseTag = getLatestTag('contains("nightly")');
|
||||||
|
} else if (type === 'stable') {
|
||||||
|
const latestPreviewTag = getLatestTag('contains("preview")');
|
||||||
|
releaseVersion = latestPreviewTag
|
||||||
|
.replace(/-preview.*/, '')
|
||||||
|
.replace(/^v/, '');
|
||||||
|
npmTag = 'latest';
|
||||||
|
previousReleaseTag = getLatestTag(
|
||||||
|
'(contains("nightly") or contains("preview")) | not',
|
||||||
|
);
|
||||||
|
} else if (type === 'preview') {
|
||||||
|
const latestNightlyTag = getLatestTag('contains("nightly")');
|
||||||
|
releaseVersion =
|
||||||
|
latestNightlyTag.replace(/-nightly.*/, '').replace(/^v/, '') + '-preview';
|
||||||
|
npmTag = 'preview';
|
||||||
|
previousReleaseTag = getLatestTag('contains("preview")');
|
||||||
|
}
|
||||||
|
|
||||||
|
const releaseTag = `v${releaseVersion}`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
releaseTag,
|
||||||
|
releaseVersion,
|
||||||
|
npmTag,
|
||||||
|
previousReleaseTag,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||||
|
console.log(JSON.stringify(getVersion(), null, 2));
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,151 +4,82 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||||
import { getReleaseVersion } from '../get-release-version';
|
import { getVersion } from '../get-release-version.js';
|
||||||
|
import { execSync } from 'node:child_process';
|
||||||
|
|
||||||
// Mock child_process so we can spy on execSync
|
vi.mock('node:child_process');
|
||||||
vi.mock('child_process', () => ({
|
vi.mock('node:fs');
|
||||||
execSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('getReleaseVersion', async () => {
|
vi.mock('../get-release-version.js', async () => {
|
||||||
// Dynamically import execSync after mocking
|
const actual = await vi.importActual('../get-release-version.js');
|
||||||
const { execSync } = await import('node:child_process');
|
return {
|
||||||
const originalEnv = { ...process.env };
|
...actual,
|
||||||
|
getVersion: (options) => {
|
||||||
|
if (options.type === 'nightly') {
|
||||||
|
return {
|
||||||
|
releaseTag: 'v0.6.0-nightly.20250911.a1b2c3d',
|
||||||
|
releaseVersion: '0.6.0-nightly.20250911.a1b2c3d',
|
||||||
|
npmTag: 'nightly',
|
||||||
|
previousReleaseTag: 'v0.5.0-nightly.20250910.abcdef',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return actual.getVersion(options);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getReleaseVersion', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.resetAllMocks();
|
vi.resetAllMocks();
|
||||||
process.env = { ...originalEnv };
|
|
||||||
// Mock date to be consistent
|
// Mock date to be consistent
|
||||||
vi.setSystemTime(new Date('2025-08-20T00:00:00.000Z'));
|
vi.setSystemTime(new Date('2025-09-11T00:00:00.000Z'));
|
||||||
// Provide a default mock for execSync to avoid toString() on undefined
|
|
||||||
vi.mocked(execSync).mockReturnValue('');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
describe('Nightly Workflow Logic', () => {
|
||||||
process.env = originalEnv;
|
it('should calculate the next nightly version based on package.json', async () => {
|
||||||
vi.useRealTimers();
|
const { getVersion } = await import('../get-release-version.js');
|
||||||
|
const result = getVersion({ type: 'nightly' });
|
||||||
|
|
||||||
|
expect(result.releaseVersion).toBe('0.6.0-nightly.20250911.a1b2c3d');
|
||||||
|
expect(result.npmTag).toBe('nightly');
|
||||||
|
expect(result.previousReleaseTag).toBe('v0.5.0-nightly.20250910.abcdef');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a nightly version and get previous tag', () => {
|
describe('Promote Workflow Logic', () => {
|
||||||
process.env.IS_NIGHTLY = 'true';
|
it('should calculate stable version from the latest preview tag', () => {
|
||||||
|
const latestPreview = 'v0.5.0-preview';
|
||||||
|
const latestStable = 'v0.4.0';
|
||||||
|
|
||||||
vi.mocked(execSync).mockImplementation((command) => {
|
vi.mocked(execSync).mockImplementation((command) => {
|
||||||
if (command.includes('git tag')) {
|
if (command.includes('not')) return latestStable;
|
||||||
return 'v0.1.0\nv0.0.1';
|
if (command.includes('contains("preview")')) return latestPreview;
|
||||||
}
|
|
||||||
if (command.includes('git rev-parse')) {
|
|
||||||
return 'abcdef';
|
|
||||||
}
|
|
||||||
if (command.includes('gh release list')) {
|
|
||||||
return 'v0.3.0-nightly.20250819.abcdef';
|
|
||||||
}
|
|
||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = getReleaseVersion();
|
const result = getVersion({ type: 'stable' });
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result.releaseVersion).toBe('0.5.0');
|
||||||
releaseTag: 'v0.3.0-nightly.20250820.abcdef',
|
expect(result.npmTag).toBe('latest');
|
||||||
releaseVersion: '0.3.0-nightly.20250820.abcdef',
|
expect(result.previousReleaseTag).toBe(latestStable);
|
||||||
npmTag: 'nightly',
|
|
||||||
previousReleaseTag: 'v0.3.0-nightly.20250819.abcdef',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a preview version and get previous tag', () => {
|
it('should calculate preview version from the latest nightly tag', () => {
|
||||||
process.env.IS_PREVIEW = 'true';
|
const latestNightly = 'v0.6.0-nightly.20250910.abcdef';
|
||||||
|
const latestPreview = 'v0.5.0-preview';
|
||||||
|
|
||||||
vi.mocked(execSync).mockImplementation((command) => {
|
vi.mocked(execSync).mockImplementation((command) => {
|
||||||
if (command.includes('git tag')) {
|
if (command.includes('nightly')) return latestNightly;
|
||||||
return 'v0.1.0\nv0.0.1';
|
if (command.includes('preview')) return latestPreview;
|
||||||
}
|
|
||||||
if (command.includes('gh release list')) {
|
|
||||||
return 'v0.1.0'; // Previous stable release
|
|
||||||
}
|
|
||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = getReleaseVersion();
|
const result = getVersion({ type: 'preview' });
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result.releaseVersion).toBe('0.6.0-preview');
|
||||||
releaseTag: 'v0.2.0-preview',
|
expect(result.npmTag).toBe('preview');
|
||||||
releaseVersion: '0.2.0-preview',
|
expect(result.previousReleaseTag).toBe(latestPreview);
|
||||||
npmTag: 'preview',
|
|
||||||
previousReleaseTag: 'v0.1.0',
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the manual version and get previous tag', () => {
|
|
||||||
process.env.MANUAL_VERSION = 'v0.1.1';
|
|
||||||
|
|
||||||
vi.mocked(execSync).mockImplementation((command) => {
|
|
||||||
if (command.includes('gh release list')) {
|
|
||||||
return 'v0.1.0'; // Previous stable release
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = getReleaseVersion();
|
|
||||||
|
|
||||||
expect(result).toEqual({
|
|
||||||
releaseTag: 'v0.1.1',
|
|
||||||
releaseVersion: '0.1.1',
|
|
||||||
npmTag: 'latest',
|
|
||||||
previousReleaseTag: 'v0.1.0',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should prepend v to manual version if missing', () => {
|
|
||||||
process.env.MANUAL_VERSION = '1.2.3';
|
|
||||||
const { releaseTag } = getReleaseVersion();
|
|
||||||
expect(releaseTag).toBe('v1.2.3');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle pre-release versions correctly', () => {
|
|
||||||
process.env.MANUAL_VERSION = 'v1.2.3-beta.1';
|
|
||||||
const { releaseTag, releaseVersion, npmTag } = getReleaseVersion();
|
|
||||||
expect(releaseTag).toBe('v1.2.3-beta.1');
|
|
||||||
expect(releaseVersion).toBe('1.2.3-beta.1');
|
|
||||||
expect(npmTag).toBe('beta');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error for invalid version format', () => {
|
|
||||||
process.env.MANUAL_VERSION = '1.2';
|
|
||||||
expect(() => getReleaseVersion()).toThrow(
|
|
||||||
'Error: Version must be in the format vX.Y.Z or vX.Y.Z-prerelease',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error if no version is provided for non-nightly/preview release', () => {
|
|
||||||
expect(() => getReleaseVersion()).toThrow(
|
|
||||||
'Error: No version specified and this is not a nightly or preview release.',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error for versions with build metadata', () => {
|
|
||||||
process.env.MANUAL_VERSION = 'v1.2.3+build456';
|
|
||||||
expect(() => getReleaseVersion()).toThrow(
|
|
||||||
'Error: Versions with build metadata (+) are not supported for releases.',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly calculate the next version from a patch release', () => {
|
|
||||||
process.env.IS_PREVIEW = 'true';
|
|
||||||
|
|
||||||
vi.mocked(execSync).mockImplementation((command) => {
|
|
||||||
if (command.includes('git tag')) {
|
|
||||||
return 'v1.1.3\nv1.1.2\nv1.1.1\nv1.1.0\nv1.0.0';
|
|
||||||
}
|
|
||||||
if (command.includes('gh release list')) {
|
|
||||||
return 'v1.1.3';
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = getReleaseVersion();
|
|
||||||
|
|
||||||
expect(result.releaseTag).toBe('v1.2.0-preview');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user