diff --git a/.github/workflows/release-rollback.yml b/.github/workflows/release-rollback.yml index 1f7a80a2b3..735a2e4660 100644 --- a/.github/workflows/release-rollback.yml +++ b/.github/workflows/release-rollback.yml @@ -3,13 +3,17 @@ name: 'Release: Rollback change' on: workflow_dispatch: inputs: - version: - description: 'The package version to tag (e.g., 0.5.0-preview-2). This version must already exist on the npm registry.' + rollback_origin: + description: 'The package version to rollback FROM and delete (e.g., 0.5.0-preview-2)' required: true type: 'string' + rollback_destination: + description: 'The package version to rollback TO (e.g., 0.5.0-preview-2). This version must already exist on the npm registry.' + required: false + type: 'string' channel: - description: 'The npm dist-tag to apply (e.g., latest, preview, nightly).' - required: true + description: 'The npm dist-tag to apply to rollback_destination (e.g., latest, preview, nightly). REQUIRED IF rollback_destination is set.' + required: false type: 'choice' options: - 'latest' @@ -47,3 +51,114 @@ jobs: node-version-file: '.nvmrc' registry-url: 'https://wombat-dressing-room.appspot.com' scope: '@google' + + - name: 'Get Origin Version Tag' + id: 'origin_tag' + shell: 'bash' + run: | + TAG_VALUE="v${{ github.event.inputs.rollback_origin }}" + echo "ORIGIN_TAG=$TAG_VALUE" >> "$GITHUB_OUTPUT" + + - name: 'Get Origin Commit Hash' + id: 'origin_hash' + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + shell: 'bash' + run: | + echo "ORIGIN_HASH=$(git rev-parse ${{ steps.origin_tag.outputs.ORIGIN_TAG }})" >> "$GITHUB_OUTPUT" + + - name: 'Change tag' + if: "${{ github.event.inputs.rollback_destination != '' }}" + uses: './.github/actions/tag-npm-release' + with: + channel: '${{ github.event.inputs.channel }}' + version: '${{ github.event.inputs.rollback_destination }}' + dry-run: '${{ github.event.inputs.dry-run }}' + wombat-token-core: '${{ secrets.WOMBAT_TOKEN_CORE }}' + wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}' + + - name: 'Deprecate Cli Npm Package' + if: "${{ github.event.inputs.dry-run == 'false' }}" + env: + NODE_AUTH_TOKEN: '${{ secrets.WOMBAT_TOKEN_CLI }}' + shell: 'bash' + run: | + npm deprecate @google/gemini-cli@${{ github.event.inputs.rollback_origin }} "This version has been rolled back." + + - name: 'Deprecate Core Npm Package' + if: "${{ github.event.inputs.dry-run == 'false' }}" + env: + NODE_AUTH_TOKEN: '${{ secrets.WOMBAT_TOKEN_CORE }}' + shell: 'bash' + run: | + npm deprecate @google/gemini-core@${{ github.event.inputs.rollback_origin }} "This version has been rolled back." + + - name: 'Delete Github Release' + if: "${{ github.event.inputs.dry-run == 'false' }}" + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + shell: 'bash' + run: | + gh release delete '${{ steps.origin_tag.outputs.ORIGIN_TAG }}' --yes + + - name: 'Verify Origin Release Deletion' + if: "${{ github.event.inputs.dry-run == 'false' }}" + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + shell: 'bash' + run: | + TARGET_TAG="${{ steps.origin_tag.outputs.ORIGIN_TAG }}" + RELEASE_TAG=$(gh release view "$TARGET_TAG" --json tagName --jq .tagName) + if [ "$RELEASE_TAG" = "$TARGET_TAG" ]; then + echo '❌ Failed to delete release with tag ${{ steps.origin_tag.outputs.ORIGIN_TAG }}' + echo '❌ This means the release was not deleted, and the workflow should fail.' + exit 1 + fi + + - name: 'Add Rollback Tag' + id: 'rollback_tag' + if: "${{ github.event.inputs.dry-run == 'false' }}" + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + shell: 'bash' + run: | + ROLLBACK_TAG_NAME="${{ steps.origin_tag.outputs.ORIGIN_TAG }}-rollback" + echo "ROLLBACK_TAG=$ROLLBACK_TAG_NAME" >> "$GITHUB_OUTPUT" + git tag "$ROLLBACK_TAG_NAME" "${{ steps.origin_hash.outputs.ORIGIN_HASH }}" + git push origin --tags + + - name: 'Verify Rollback Tag Added' + if: "${{ github.event.inputs.dry-run == 'false' }}" + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + shell: 'bash' + run: | + TARGET_TAG="${{ steps.rollback_tag.outputs.ROLLBACK_TAG }}" + TARGET_HASH="${{ steps.origin_hash.outputs.ORIGIN_HASH }}" + ROLLBACK_COMMIT=$(git rev-parse -q --verify "$TARGET_TAG") + if [ "$ROLLBACK_COMMIT" != "$TARGET_HASH" ]; then + echo '❌ Failed to add tag $TARGET_TAG to commit $TARGET_HASH' + echo '❌ This means the tag was not added, and the workflow should fail.' + exit 1 + fi + + - name: 'Log Dry run' + if: "${{ github.event.inputs.dry-run == 'true' }}" + shell: 'bash' + run: | + echo " + Inputs: + - rollback_origin: '${{ github.event.inputs.rollback_origin }}' + - rollback_destination: '${{ github.event.inputs.rollback_destination }}' + - channel: '${{ github.event.inputs.channel }}' + - ref: '${{ github.event.inputs.ref }}' + + Outputs: + - ORIGIN_TAG: '${{ steps.origin_tag.outputs.ORIGIN_TAG }}' + - ORIGIN_HASH: '${{ steps.origin_hash.outputs.ORIGIN_HASH }}' + - ROLLBACK_TAG: '${{ steps.rollback_tag.outputs.ROLLBACK_TAG }}' + + Would have npm deprecate @google/gemini-cli@${{ github.event.inputs.rollback_origin }} and @google/gemini-core@${{ github.event.inputs.rollback_origin }} + Would have deleted the github release with tag ${{ steps.origin_tag.outputs.ORIGIN_TAG }} + Would have added tag ${{ steps.origin_tag.outputs.ORIGIN_TAG }}-rollback to ${{ steps.origin_hash.outputs.ORIGIN_HASH }} + "