diff --git a/.github/actions/publish-release/action.yml b/.github/actions/publish-release/action.yml index 1561db07f9..8ab2104016 100644 --- a/.github/actions/publish-release/action.yml +++ b/.github/actions/publish-release/action.yml @@ -36,6 +36,10 @@ inputs: description: 'The working directory to run the steps in.' required: false default: '.' + force-skip-tests: + description: 'Skip tests and validation' + required: false + default: false runs: using: 'composite' @@ -107,7 +111,7 @@ runs: npm publish \ --dry-run="${{ inputs.dry-run }}" \ --workspace="@google/gemini-cli-core" \ - --tag="${{ inputs.npm-tag }}" + --no-tag - name: '🔗 Install latest core package' working-directory: '${{ inputs.working-directory }}' @@ -127,7 +131,31 @@ runs: npm publish \ --dry-run="${{ inputs.dry-run }}" \ --workspace="@google/gemini-cli" \ - --tag="${{ inputs.npm-tag }}" + --no-tag + + - name: '🔬 Verify NPM release by version' + uses: './.github/actions/verify-release' + if: "${{ inputs.dry-run == 'false' && inputs.force-skip-tests == 'false' }}" + with: + npm-package: '@google/gemini-cli@${{ inputs.release-version }}' + expected-version: '${{ inputs.release-version }}' + ref: '${{ steps.release_branch.outputs.BRANCH_NAME }}' + + - name: '🏷️ Tag release' + uses: './.github/actions/tag-npm-release' + if: "${{ inputs.dry-run == 'false' }}" + with: + channel: '${{ inputs.npm-tag }}' + version: '${{ inputs.release-version }}' + dry-run: '${{ inputs.dry-run }}' + wombat-token-core: '${{ inputs.wombat-token-core }}' + wombat-token-cli: '${{ inputs.wombat-token-cli }}' + + - name: 'Install deps' + working-directory: '${{ inputs.working-directory }}' + shell: 'bash' + run: | + npm install - name: '🎁 Bundle' working-directory: '${{ inputs.working-directory }}' @@ -137,7 +165,7 @@ runs: - name: '🎉 Create GitHub Release' working-directory: '${{ inputs.working-directory }}' - if: "${{ inputs.dry-run == 'false' && inputs.skip-github-release == 'false' }}" + if: "${{ inputs.dry-run == 'false' && inputs.skip-github-release == 'false' && inputs.npm-tag != 'dev' }}" env: GITHUB_TOKEN: '${{ inputs.github-token }}' shell: 'bash' diff --git a/.github/actions/tag-npm-release/action.yml b/.github/actions/tag-npm-release/action.yml new file mode 100644 index 0000000000..cbc49d3d8d --- /dev/null +++ b/.github/actions/tag-npm-release/action.yml @@ -0,0 +1,53 @@ +name: 'Tag an NPM release' +description: 'Tags a specific npm version to a specific channel.' + +inputs: + channel: + description: 'NPM Channel tag' + required: true + version: + description: 'version' + required: true + dry-run: + description: 'Whether to run in dry-run mode.' + required: true + wombat-token-core: + description: 'The npm token for the wombat @google/gemini-cli-core' + required: true + wombat-token-cli: + description: 'The npm token for wombat @google/gemini-cli' + +runs: + using: 'composite' + steps: + - name: 'Setup Node.js' + uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' + with: + node-version-file: '.nvmrc' + registry-url: 'https://wombat-dressing-room.appspot.com' + scope: '@google' + + - name: 'Change tag for @google/gemini-cli-core' + if: |- + ${{ inputs.dry-run == 'false' }} + env: + NODE_AUTH_TOKEN: '${{ inputs.wombat-token-core }}' + shell: 'bash' + run: | + npm dist-tag add @google/gemini-cli-core@${{ inputs.version }} ${{ inputs.channel }} + + - name: 'Change tag for @google/gemini-cli' + if: |- + ${{ inputs.dry-run == 'false' }} + env: + NODE_AUTH_TOKEN: '${{ inputs.wombat-token-cli }}' + shell: 'bash' + run: | + npm dist-tag add @google/gemini-cli@${{ inputs.version }} ${{ inputs.channel }} + + - name: 'Log dry run' + if: |- + ${{ inputs.dry-run == 'true' }} + shell: 'bash' + run: | + echo "Dry run: Would have added tag '${{ inputs.channel }}' to version '${{ inputs.version }}' for @google/gemini-cli and @google/gemini-cli-core." diff --git a/.github/actions/verify-release/action.yml b/.github/actions/verify-release/action.yml new file mode 100644 index 0000000000..36f0eff6ce --- /dev/null +++ b/.github/actions/verify-release/action.yml @@ -0,0 +1,55 @@ +name: 'Verify an NPM release' +description: 'Fetches a package from NPM and does some basic smoke tests' + +inputs: + npm-package: + description: 'NPM Package' + required: true + default: '@google/gemini-cli@latest' + expected-version: + description: 'Expected version' + required: true + ref: + description: 'The branch, tag, or SHA to release from.' + required: false + type: 'string' + default: 'main' + +runs: + using: 'composite' + steps: + - name: '📝 Print Inputs' + shell: 'bash' + run: | + echo "${{ toJSON(inputs) }}" + - name: 'Checkout' + uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v4 + with: + ref: '${{ github.event.inputs.ref }}' + fetch-depth: 0 + + - name: 'Install from NPM' + uses: 'nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08' # ratchet:nick-fields/retry@v3 + with: + timeout_seconds: 900 + retry_wait_seconds: 30 + max_attempts: 10 + command: |- + npm install --prefer-online --no-cache -g ${{ inputs.npm-package }} + + # This provides a very basic smoke test for Gemini CLI + - name: 'Run Gemini CLI' + id: 'gemini_cli' + shell: 'bash' + run: |- + echo "gemini_version=$(gemini --version)" >> $GITHUB_OUTPUT + + # Force a failure if it doesn't match + - name: 'Fail workflow if version does not match' + if: '${{ steps.gemini_cli.outputs.gemini_version != inputs.expected-version }}' + shell: 'bash' + run: |- + echo '❌ Got ${{ steps.gemini_cli.outputs.gemini_version }} from ${{ inputs.npm-package }}' + echo '❌ Expected Version ${{ inputs.expected-version }}' + + exit 1 diff --git a/.github/workflows/release-change-tags.yml b/.github/workflows/release-change-tags.yml index 88d0f9912f..50c2fd6c02 100644 --- a/.github/workflows/release-change-tags.yml +++ b/.github/workflows/release-change-tags.yml @@ -46,24 +46,11 @@ jobs: registry-url: 'https://wombat-dressing-room.appspot.com' scope: '@google' - - name: 'Change tag for @google/gemini-cli-core' - if: |- - ${{ github.event.inputs.dry-run == 'false' }} - env: - NODE_AUTH_TOKEN: '${{ secrets.WOMBAT_TOKEN_CORE }}' - run: | - npm dist-tag add @google/gemini-cli-core@${{ github.event.inputs.version }} ${{ github.event.inputs.channel }} - - - name: 'Change tag for @google/gemini-cli' - if: |- - ${{ github.event.inputs.dry-run == 'false' }} - env: - NODE_AUTH_TOKEN: '${{ secrets.WOMBAT_TOKEN_CLI }}' - run: | - npm dist-tag add @google/gemini-cli@${{ github.event.inputs.version }} ${{ github.event.inputs.channel }} - - - name: 'Log dry run' - if: |- - ${{ github.event.inputs.dry-run == 'true' }} - run: | - echo "Dry run: Would have added tag '${{ github.event.inputs.channel }}' to version '${{ github.event.inputs.version }}' for @google/gemini-cli and @google/gemini-cli-core." + - name: 'Change tag' + uses: './.github/actions/tag-npm-release' + with: + channel: '${{ github.event.inputs.channel }}' + version: '${{ github.event.inputs.version }}' + dry-run: '${{ github.event.inputs.dry-run }}' + wombat-token-core: '${{ secrets.WOMBAT_TOKEN_CORE }}' + wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}' diff --git a/.github/workflows/release-manual.yml b/.github/workflows/release-manual.yml index 56e0f8c919..6056e562cb 100644 --- a/.github/workflows/release-manual.yml +++ b/.github/workflows/release-manual.yml @@ -39,7 +39,7 @@ on: jobs: release: - runs-on: 'ubuntu-latest' + runs-on: 'self-hosted' permissions: contents: 'write' packages: 'write' @@ -77,6 +77,7 @@ jobs: - name: 'Publish Release' uses: './.github/actions/publish-release' with: + force-skip-tests: '${{ github.event.inputs.force_skip_tests }}' release-version: '${{ steps.release_info.outputs.RELEASE_VERSION }}' release-tag: '${{ github.event.inputs.version }}' npm-tag: '${{ github.event.inputs.npm_channel }}' diff --git a/.github/workflows/verify-release.yml b/.github/workflows/verify-release.yml new file mode 100644 index 0000000000..0ebacd0d3f --- /dev/null +++ b/.github/workflows/verify-release.yml @@ -0,0 +1,31 @@ +name: 'Verify NPM release tag' + +on: + workflow_dispatch: + inputs: + version: + description: 'The expected Gemini binary version that should be released (e.g., 0.5.0-preview-2).' + required: true + type: 'string' + npm-package: + description: 'NPM package to verify' + required: true + type: 'string' + default: '@google/gemini-cli@latest' + ref: + description: 'The branch, tag, or SHA to release from.' + required: false + type: 'string' + default: 'main' + +jobs: + build: + runs-on: 'ubuntu-latest' + steps: + - uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' + - name: 'Verify release' + uses: './.github/actions/verify-release' + with: + npm-package: '${github.event.inputs.npm-package}' + expected-version: '${github.event.inputs.version}' + ref: '${github.event.inputs.ref}'