Skip to content

Commit 0d03f4e

Browse files
Release Process vNext (#8152)
Co-authored-by: gemini-cli-robot <[email protected]>
1 parent a31830a commit 0d03f4e

File tree

15 files changed

+647
-593
lines changed

15 files changed

+647
-593
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
name: 'Publish Release'
2+
description: 'Builds, prepares, and publishes the gemini-cli packages to npm and creates a GitHub release.'
3+
4+
inputs:
5+
release-version:
6+
description: 'The version to release (e.g., 0.1.11).'
7+
required: true
8+
npm-tag:
9+
description: 'The npm tag to publish with (e.g., latest, preview, nightly).'
10+
required: true
11+
wombat-token-core:
12+
description: 'The npm token for the @google/gemini-cli-core package.'
13+
required: true
14+
wombat-token-cli:
15+
description: 'The npm token for the @google/gemini-cli package.'
16+
required: true
17+
github-token:
18+
description: 'The GitHub token for creating the release.'
19+
required: true
20+
dry-run:
21+
description: 'Whether to run in dry-run mode.'
22+
required: true
23+
release-branch:
24+
description: 'The branch to target for the release.'
25+
required: true
26+
previous-tag:
27+
description: 'The previous tag to use for generating release notes.'
28+
required: true
29+
working-directory:
30+
description: 'The working directory to run the steps in.'
31+
required: false
32+
default: '.'
33+
34+
runs:
35+
using: 'composite'
36+
steps:
37+
- name: 'Build and Prepare Packages'
38+
working-directory: '${{ inputs.working-directory }}'
39+
run: |-
40+
npm run build:packages
41+
npm run prepare:package
42+
shell: 'bash'
43+
44+
- name: 'Configure npm for publishing'
45+
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
46+
with:
47+
node-version-file: '${{ inputs.working-directory }}/.nvmrc'
48+
registry-url: 'https://wombat-dressing-room.appspot.com'
49+
scope: '@google'
50+
51+
- name: 'Publish @google/gemini-cli-core'
52+
working-directory: '${{ inputs.working-directory }}'
53+
env:
54+
NODE_AUTH_TOKEN: '${{ inputs.wombat-token-core }}'
55+
run: |-
56+
npm publish \
57+
--dry-run="${{ inputs.dry-run }}" \
58+
--workspace="@google/gemini-cli-core" \
59+
--tag="${{ inputs.npm-tag }}"
60+
shell: 'bash'
61+
62+
- name: 'Install latest core package'
63+
working-directory: '${{ inputs.working-directory }}'
64+
if: '${{ inputs.dry-run == "false" }}'
65+
run: |-
66+
npm install "@google/gemini-cli-core@${{ inputs.release-version }}" \
67+
--workspace="@google/gemini-cli" \
68+
--save-exact
69+
shell: 'bash'
70+
71+
- name: 'Publish @google/gemini-cli'
72+
working-directory: '${{ inputs.working-directory }}'
73+
env:
74+
NODE_AUTH_TOKEN: '${{ inputs.wombat-token-cli }}'
75+
run: |-
76+
npm publish \
77+
--dry-run="${{ inputs.dry-run }}" \
78+
--workspace="@google/gemini-cli" \
79+
--tag="${{ inputs.npm-tag }}"
80+
shell: 'bash'
81+
82+
- name: 'Bundle'
83+
working-directory: '${{ inputs.working-directory }}'
84+
run: 'npm run bundle'
85+
shell: 'bash'
86+
87+
- name: 'Create GitHub Release'
88+
working-directory: '${{ inputs.working-directory }}'
89+
if: '${{ inputs.dry-run == "false" }}'
90+
env:
91+
GITHUB_TOKEN: '${{ inputs.github-token }}'
92+
run: |-
93+
gh release create "v${{ inputs.release-version }}" \
94+
bundle/gemini.js \
95+
--target "${{ inputs.release-branch }}" \
96+
--title "Release v${{ inputs.release-version }}" \
97+
--notes-start-tag "${{ inputs.previous-tag }}" \
98+
--generate-notes
99+
shell: 'bash'

.github/workflows/nightly-release.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: 'Nightly Release'
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
workflow_dispatch:
7+
inputs:
8+
dry_run:
9+
description: 'Run a dry-run of the release process; no branches, npm packages or GitHub releases will be created.'
10+
required: true
11+
type: 'boolean'
12+
default: true
13+
14+
jobs:
15+
release:
16+
runs-on: 'ubuntu-latest'
17+
steps:
18+
- name: 'Checkout'
19+
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
20+
with:
21+
fetch-depth: 0
22+
23+
- name: 'Setup Node.js'
24+
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
25+
with:
26+
node-version-file: '.nvmrc'
27+
cache: 'npm'
28+
29+
- name: 'Install Dependencies'
30+
run: 'npm ci'
31+
32+
- name: 'Get Nightly Version'
33+
id: 'nightly_version'
34+
env:
35+
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
36+
run: |
37+
VERSION_JSON=$(node scripts/get-release-version.js --type=nightly)
38+
echo "RELEASE_TAG=$(echo "${VERSION_JSON}" | jq -r .releaseTag)" >> "${GITHUB_OUTPUT}"
39+
echo "RELEASE_VERSION=$(echo "${VERSION_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
40+
echo "NPM_TAG=$(echo "${VERSION_JSON}" | jq -r .npmTag)" >> "${GITHUB_OUTPUT}"
41+
echo "PREVIOUS_TAG=$(echo "${VERSION_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}"
42+
43+
- name: 'Publish Release'
44+
uses: './.github/actions/publish-release'
45+
with:
46+
release-version: '${{ steps.nightly_version.outputs.RELEASE_VERSION }}'
47+
npm-tag: '${{ steps.nightly_version.outputs.NPM_TAG }}'
48+
wombat-token-core: '${{ secrets.WOMBAT_TOKEN_CORE }}'
49+
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
50+
github-token: '${{ secrets.GITHUB_TOKEN }}'
51+
dry-run: '${{ github.event.inputs.dry_run }}'
52+
release-branch: 'main'
53+
previous-tag: '${{ steps.nightly_version.outputs.PREVIOUS_TAG }}'

.github/workflows/promote-release.yml

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
name: 'Promote Release'
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
dry_run:
7+
description: 'Run a dry-run of the release process; no branches, npm packages or GitHub releases will be created.'
8+
required: true
9+
type: 'boolean'
10+
default: true
11+
12+
jobs:
13+
calculate-versions:
14+
name: 'Calculate Versions and Plan'
15+
runs-on: 'ubuntu-latest'
16+
outputs:
17+
STABLE_VERSION: '${{ steps.versions.outputs.STABLE_VERSION }}'
18+
STABLE_SHA: '${{ steps.versions.outputs.STABLE_SHA }}'
19+
PREVIOUS_STABLE_TAG: '${{ steps.versions.outputs.PREVIOUS_STABLE_TAG }}'
20+
PREVIEW_VERSION: '${{ steps.versions.outputs.PREVIEW_VERSION }}'
21+
PREVIEW_SHA: '${{ steps.versions.outputs.PREVIEW_SHA }}'
22+
PREVIOUS_PREVIEW_TAG: '${{ steps.versions.outputs.PREVIOUS_PREVIEW_TAG }}'
23+
NEXT_NIGHTLY_VERSION: '${{ steps.versions.outputs.NEXT_NIGHTLY_VERSION }}'
24+
25+
steps:
26+
- name: 'Checkout'
27+
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
28+
with:
29+
fetch-depth: 0
30+
31+
- name: 'Setup Node.js'
32+
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
33+
with:
34+
node-version-file: '.nvmrc'
35+
cache: 'npm'
36+
37+
- name: 'Install Dependencies'
38+
run: 'npm ci'
39+
40+
- name: 'Calculate Versions and SHAs'
41+
id: 'versions'
42+
env:
43+
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
44+
run: |
45+
set -e
46+
STABLE_JSON=$(node scripts/get-release-version.js --type=stable)
47+
PREVIEW_JSON=$(node scripts/get-release-version.js --type=preview)
48+
NIGHTLY_JSON=$(node scripts/get-release-version.js --type=nightly)
49+
echo "STABLE_VERSION=$(echo "${STABLE_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
50+
# shellcheck disable=SC1083
51+
echo "STABLE_SHA=$(git rev-parse "$(echo "${STABLE_JSON}" | jq -r .previousReleaseTag)"^{commit})" >> "${GITHUB_OUTPUT}"
52+
echo "PREVIOUS_STABLE_TAG=$(echo "${STABLE_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}"
53+
echo "PREVIEW_VERSION=$(echo "${PREVIEW_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
54+
# shellcheck disable=SC1083
55+
echo "PREVIEW_SHA=$(git rev-parse "$(echo "${PREVIEW_JSON}" | jq -r .previousReleaseTag)"^{commit})" >> "${GITHUB_OUTPUT}"
56+
echo "PREVIOUS_PREVIEW_TAG=$(echo "${PREVIEW_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}"
57+
echo "NEXT_NIGHTLY_VERSION=$(echo "${NIGHTLY_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
58+
59+
promote:
60+
name: 'Promote to ${{ matrix.channel }}'
61+
needs: 'calculate-versions'
62+
runs-on: 'ubuntu-latest'
63+
permissions:
64+
contents: 'write'
65+
packages: 'write'
66+
strategy:
67+
matrix:
68+
include:
69+
- channel: 'stable'
70+
version: '${{ needs.calculate-versions.outputs.STABLE_VERSION }}'
71+
sha: '${{ needs.calculate-versions.outputs.STABLE_SHA }}'
72+
npm-tag: 'latest'
73+
previous-tag: '${{ needs.calculate-versions.outputs.PREVIOUS_STABLE_TAG }}'
74+
- channel: 'preview'
75+
version: '${{ needs.calculate-versions.outputs.PREVIEW_VERSION }}'
76+
sha: '${{ needs.calculate-versions.outputs.PREVIEW_SHA }}'
77+
npm-tag: 'preview'
78+
previous-tag: '${{ needs.calculate-versions.outputs.PREVIOUS_PREVIEW_TAG }}'
79+
80+
steps:
81+
- name: 'Checkout main'
82+
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
83+
with:
84+
ref: 'main'
85+
86+
- name: 'Checkout correct SHA'
87+
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
88+
with:
89+
ref: '${{ matrix.sha }}'
90+
path: 'release'
91+
92+
- name: 'Setup Node.js'
93+
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
94+
with:
95+
node-version-file: '.nvmrc'
96+
cache: 'npm'
97+
98+
- name: 'Install Dependencies'
99+
working-directory: './release'
100+
run: 'npm ci'
101+
102+
- name: 'Configure Git User'
103+
working-directory: './release'
104+
run: |-
105+
git config user.name "gemini-cli-robot"
106+
git config user.email "[email protected]"
107+
108+
- name: 'Create and switch to a release branch'
109+
working-directory: './release'
110+
id: 'release_branch'
111+
run: |
112+
BRANCH_NAME="release/v${{ matrix.version }}"
113+
git switch -c "${BRANCH_NAME}"
114+
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
115+
116+
- name: 'Update package versions'
117+
working-directory: './release'
118+
run: 'npm run release:version "${{ matrix.version }}"'
119+
120+
- name: 'Commit and Conditionally Push package versions'
121+
working-directory: './release'
122+
env:
123+
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
124+
DRY_RUN: '${{ github.event.inputs.dry_run }}'
125+
RELEASE_TAG: 'v${{ matrix.version }}'
126+
run: |-
127+
git add package.json package-lock.json packages/*/package.json
128+
git commit -m "chore(release): ${RELEASE_TAG}"
129+
if [[ "${DRY_RUN}" == "false" ]]; then
130+
echo "Pushing release branch to remote..."
131+
git push --set-upstream origin "${BRANCH_NAME}" --follow-tags
132+
else
133+
echo "Dry run enabled. Skipping push."
134+
fi
135+
136+
- name: 'Publish Release'
137+
uses: './.github/actions/publish-release'
138+
with:
139+
release-version: '${{ matrix.version }}'
140+
npm-tag: '${{ matrix.npm-tag }}'
141+
wombat-token-core: '${{ secrets.WOMBAT_TOKEN_CORE }}'
142+
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
143+
github-token: '${{ secrets.GITHUB_TOKEN }}'
144+
dry-run: '${{ github.event.inputs.dry_run }}'
145+
release-branch: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
146+
previous-tag: '${{ matrix.previous-tag }}'
147+
working-directory: './release'
148+
149+
nightly-pr:
150+
name: 'Create Nightly PR'
151+
needs: 'calculate-versions'
152+
runs-on: 'ubuntu-latest'
153+
permissions:
154+
contents: 'write'
155+
pull-requests: 'write'
156+
steps:
157+
- name: 'Checkout main'
158+
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
159+
with:
160+
ref: 'main'
161+
162+
- name: 'Setup Node.js'
163+
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
164+
with:
165+
node-version-file: '.nvmrc'
166+
cache: 'npm'
167+
168+
- name: 'Install Dependencies'
169+
run: 'npm ci'
170+
171+
- name: 'Configure Git User'
172+
run: |-
173+
git config user.name "gemini-cli-robot"
174+
git config user.email "[email protected]"
175+
176+
- name: 'Create and switch to a new branch'
177+
id: 'release_branch'
178+
run: |
179+
BRANCH_NAME="chore/nightly-version-bump-${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"
180+
git switch -c "${BRANCH_NAME}"
181+
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
182+
183+
- name: 'Update package versions'
184+
run: 'npm run release:version "${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"'
185+
186+
- name: 'Commit and Push package versions'
187+
env:
188+
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
189+
DRY_RUN: '${{ github.event.inputs.dry_run }}'
190+
run: |-
191+
git add package.json package-lock.json packages/*/package.json
192+
git commit -m "chore(release): bump version to ${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"
193+
if [[ "${DRY_RUN}" == "false" ]]; then
194+
echo "Pushing release branch to remote..."
195+
git push --set-upstream origin "${BRANCH_NAME}"
196+
else
197+
echo "Dry run enabled. Skipping push."
198+
fi
199+
200+
- name: 'Create and Approve Pull Request'
201+
if: |-
202+
${{ github.event.inputs.dry_run == 'false' }}
203+
env:
204+
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
205+
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
206+
run: |
207+
gh pr create \
208+
--title "chore(release): bump version to ${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}" \
209+
--body "Automated version bump to prepare for the next nightly release." \
210+
--base "main" \
211+
--head "${BRANCH_NAME}" \
212+
--fill
213+
gh pr merge --auto --squash

0 commit comments

Comments
 (0)