mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 22:21:22 -07:00
patch e2e vnext (#8767)
This commit is contained in:
68
.github/workflows/release-patch-1-create-pr.yml
vendored
68
.github/workflows/release-patch-1-create-pr.yml
vendored
@@ -65,25 +65,13 @@ jobs:
|
||||
permission-pull-requests: 'write'
|
||||
permission-contents: 'write'
|
||||
|
||||
- name: 'Create Patch for Stable'
|
||||
id: 'create_patch_stable'
|
||||
if: "github.event.inputs.channel == 'stable'"
|
||||
- name: 'Create Patch'
|
||||
id: 'create_patch'
|
||||
env:
|
||||
GH_TOKEN: '${{ steps.generate_token.outputs.token }}'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
node scripts/create-patch-pr.js --commit=${{ github.event.inputs.commit }} --channel=stable --dry-run=${{ github.event.inputs.dry_run }} > patch_output.log 2>&1
|
||||
echo "EXIT_CODE=$?" >> "$GITHUB_OUTPUT"
|
||||
cat patch_output.log
|
||||
|
||||
- name: 'Create Patch for Preview'
|
||||
id: 'create_patch_preview'
|
||||
if: "github.event.inputs.channel != 'stable'"
|
||||
env:
|
||||
GH_TOKEN: '${{ steps.generate_token.outputs.token }}'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
node scripts/create-patch-pr.js --commit=${{ github.event.inputs.commit }} --channel=${{ github.event.inputs.channel }} --dry-run=${{ github.event.inputs.dry_run }} > patch_output.log 2>&1
|
||||
node scripts/releasing/create-patch-pr.js --commit=${{ github.event.inputs.commit }} --channel=${{ github.event.inputs.channel }} --dry-run=${{ github.event.inputs.dry_run }} > patch_output.log 2>&1
|
||||
echo "EXIT_CODE=$?" >> "$GITHUB_OUTPUT"
|
||||
cat patch_output.log
|
||||
|
||||
@@ -91,46 +79,12 @@ jobs:
|
||||
if: '!inputs.dry_run && inputs.original_pr'
|
||||
env:
|
||||
GH_TOKEN: '${{ steps.generate_token.outputs.token }}'
|
||||
ORIGINAL_PR: '${{ github.event.inputs.original_pr }}'
|
||||
EXIT_CODE: '${{ steps.create_patch.outputs.EXIT_CODE }}'
|
||||
OUTPUT_LOG: 'patch_output.log'
|
||||
COMMIT: '${{ github.event.inputs.commit }}'
|
||||
CHANNEL: '${{ github.event.inputs.channel }}'
|
||||
REPOSITORY: '${{ github.repository }}'
|
||||
GITHUB_RUN_ID: '${{ github.run_id }}'
|
||||
run: |
|
||||
# Determine which step ran based on channel
|
||||
if [ "${{ github.event.inputs.channel }}" = "stable" ]; then
|
||||
EXIT_CODE="${{ steps.create_patch_stable.outputs.EXIT_CODE }}"
|
||||
else
|
||||
EXIT_CODE="${{ steps.create_patch_preview.outputs.EXIT_CODE }}"
|
||||
fi
|
||||
|
||||
# Check if patch output exists and contains branch info
|
||||
if [ -f patch_output.log ]; then
|
||||
if grep -q "already has an open PR" patch_output.log; then
|
||||
# Branch exists with existing PR
|
||||
PR_NUMBER=$(grep "Found existing PR" patch_output.log | sed 's/.*Found existing PR #\([0-9]*\).*/\1/')
|
||||
PR_URL=$(grep "Found existing PR" patch_output.log | sed 's/.*Found existing PR #[0-9]*: \(.*\)/\1/')
|
||||
gh pr comment ${{ github.event.inputs.original_pr }} --body "ℹ️ Patch PR already exists! A patch PR for this change already exists: [#$PR_NUMBER]($PR_URL). Please review and approve this existing patch PR. If it's incorrect, close it and run the patch command again."
|
||||
|
||||
elif grep -q "exists but has no open PR" patch_output.log; then
|
||||
# Branch exists but no PR
|
||||
BRANCH=$(grep "Hotfix branch" patch_output.log | grep "already exists" | sed 's/.*Hotfix branch \(.*\) already exists.*/\1/')
|
||||
gh pr comment ${{ github.event.inputs.original_pr }} --body "ℹ️ Patch branch exists but no PR found! A patch branch [\`$BRANCH\`](https://github.com/${{ github.repository }}/tree/$BRANCH) exists but has no open PR. This might indicate an incomplete patch process. Please delete the branch and run the patch command again."
|
||||
|
||||
elif [ "$EXIT_CODE" = "0" ]; then
|
||||
# Success - find the newly created PR
|
||||
BRANCH=$(grep "Creating hotfix branch" patch_output.log | sed 's/.*Creating hotfix branch \(.*\) from.*/\1/')
|
||||
|
||||
# Find the PR for the new branch
|
||||
PR_INFO=$(gh pr list --head "$BRANCH" --json number,url --jq '.[0] // empty')
|
||||
|
||||
if [ -n "$PR_INFO" ]; then
|
||||
PR_NUMBER=$(echo "$PR_INFO" | jq -r '.number')
|
||||
PR_URL=$(echo "$PR_INFO" | jq -r '.url')
|
||||
gh pr comment ${{ github.event.inputs.original_pr }} --body "🚀 Patch PR created! The patch release PR has been created: [#$PR_NUMBER]($PR_URL). Please review and approve this PR to complete the patch release."
|
||||
else
|
||||
# Fallback if we can't find the specific PR
|
||||
gh pr comment ${{ github.event.inputs.original_pr }} --body "🚀 Patch PR created! The patch release PR for this change has been created. Please review and approve it: [View all patch PRs](https://github.com/${{ github.repository }}/pulls?q=is%3Apr+is%3Aopen+label%3Apatch)"
|
||||
fi
|
||||
else
|
||||
# Other error
|
||||
gh pr comment ${{ github.event.inputs.original_pr }} --body "❌ Patch creation failed! There was an error creating the patch. Please check the workflow logs for details: [View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})"
|
||||
fi
|
||||
else
|
||||
gh pr comment ${{ github.event.inputs.original_pr }} --body "❌ Patch creation failed! No output was generated. Please check the workflow logs: [View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})"
|
||||
fi
|
||||
node scripts/releasing/patch-create-comment.js
|
||||
|
||||
62
.github/workflows/release-patch-2-trigger.yml
vendored
62
.github/workflows/release-patch-2-trigger.yml
vendored
@@ -10,6 +10,11 @@ on:
|
||||
description: 'The head ref of the merged hotfix PR to trigger the release for (e.g. hotfix/v1.2.3/cherry-pick-abc).'
|
||||
required: true
|
||||
type: 'string'
|
||||
workflow_ref:
|
||||
description: 'The ref to checkout the workflow code from.'
|
||||
required: false
|
||||
type: 'string'
|
||||
default: 'main'
|
||||
workflow_id:
|
||||
description: 'The workflow to trigger. Defaults to patch-release.yml'
|
||||
required: false
|
||||
@@ -28,41 +33,30 @@ jobs:
|
||||
permissions:
|
||||
actions: 'write'
|
||||
steps:
|
||||
- name: 'Trigger Patch Release'
|
||||
uses: 'actions/github-script@00f12e3e20659f42342b1c0226afda7f7c042325'
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'
|
||||
with:
|
||||
script: |
|
||||
let body = '';
|
||||
let headRef = '';
|
||||
ref: "${{ github.event.inputs.workflow_ref || 'main' }}"
|
||||
fetch-depth: 1
|
||||
|
||||
if (context.eventName === 'pull_request') {
|
||||
body = context.payload.pull_request.body;
|
||||
headRef = context.payload.pull_request.head.ref;
|
||||
} else { // workflow_dispatch
|
||||
body = ${{ github.event.inputs.dry_run }} ? '[DRY RUN]' : '';
|
||||
headRef = '${{ github.event.inputs.ref }}';
|
||||
}
|
||||
- name: 'Setup Node.js'
|
||||
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020'
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
|
||||
const isDryRun = body.includes('[DRY RUN]');
|
||||
- name: 'Install Dependencies'
|
||||
run: 'npm ci'
|
||||
|
||||
// Extract base version and channel from hotfix branch name
|
||||
// e.g., hotfix/v0.5.3/cherry-pick-abc -> v0.5.3
|
||||
const version = headRef.split('/')[1];
|
||||
const channel = version.includes('preview') ? 'preview' : 'stable';
|
||||
const releaseRef = `release/${version}`;
|
||||
|
||||
const workflow_id = context.eventName === 'pull_request'
|
||||
? 'release-patch-3-release.yml'
|
||||
: '${{ github.event.inputs.workflow_id }}';
|
||||
|
||||
github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: workflow_id,
|
||||
ref: 'main',
|
||||
inputs: {
|
||||
type: channel,
|
||||
dry_run: isDryRun.toString(),
|
||||
release_ref: releaseRef
|
||||
}
|
||||
})
|
||||
- name: 'Trigger Patch Release'
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
HEAD_REF: "${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.event.inputs.ref }}"
|
||||
PR_BODY: "${{ github.event_name == 'pull_request' && github.event.pull_request.body || '' }}"
|
||||
WORKFLOW_ID: '${{ github.event.inputs.workflow_id }}'
|
||||
GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'
|
||||
GITHUB_REPOSITORY_NAME: '${{ github.event.repository.name }}'
|
||||
GITHUB_EVENT_NAME: '${{ github.event_name }}'
|
||||
GITHUB_EVENT_PAYLOAD: '${{ toJSON(github.event) }}'
|
||||
run: |
|
||||
node scripts/releasing/patch-trigger.js
|
||||
|
||||
96
.github/workflows/release-patch-3-release.yml
vendored
96
.github/workflows/release-patch-3-release.yml
vendored
@@ -24,6 +24,10 @@ on:
|
||||
description: 'The branch, tag, or SHA to release from.'
|
||||
required: true
|
||||
type: 'string'
|
||||
original_pr:
|
||||
description: 'The original PR number to comment back on.'
|
||||
required: false
|
||||
type: 'string'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
@@ -82,6 +86,55 @@ jobs:
|
||||
echo "NPM_TAG=${NPM_TAG}" >> "${GITHUB_OUTPUT}"
|
||||
echo "PREVIOUS_TAG=${PREVIOUS_TAG}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: 'Verify Version Consistency'
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
CHANNEL: '${{ github.event.inputs.type }}'
|
||||
run: |
|
||||
echo "🔍 Verifying no concurrent patch releases have occurred..."
|
||||
|
||||
# Store original calculation for comparison
|
||||
ORIGINAL_RELEASE_VERSION="${{ steps.patch_version.outputs.RELEASE_VERSION }}"
|
||||
ORIGINAL_RELEASE_TAG="${{ steps.patch_version.outputs.RELEASE_TAG }}"
|
||||
ORIGINAL_PREVIOUS_TAG="${{ steps.patch_version.outputs.PREVIOUS_TAG }}"
|
||||
|
||||
echo "Original calculation:"
|
||||
echo " Release version: ${ORIGINAL_RELEASE_VERSION}"
|
||||
echo " Release tag: ${ORIGINAL_RELEASE_TAG}"
|
||||
echo " Previous tag: ${ORIGINAL_PREVIOUS_TAG}"
|
||||
|
||||
# Re-run the same version calculation script
|
||||
echo "Re-calculating version to check for changes..."
|
||||
CURRENT_PATCH_JSON=$(node scripts/get-release-version.js --type=patch --patch-from="${CHANNEL}")
|
||||
CURRENT_RELEASE_VERSION=$(echo "${CURRENT_PATCH_JSON}" | jq -r .releaseVersion)
|
||||
CURRENT_RELEASE_TAG=$(echo "${CURRENT_PATCH_JSON}" | jq -r .releaseTag)
|
||||
CURRENT_PREVIOUS_TAG=$(echo "${CURRENT_PATCH_JSON}" | jq -r .previousReleaseTag)
|
||||
|
||||
echo "Current calculation:"
|
||||
echo " Release version: ${CURRENT_RELEASE_VERSION}"
|
||||
echo " Release tag: ${CURRENT_RELEASE_TAG}"
|
||||
echo " Previous tag: ${CURRENT_PREVIOUS_TAG}"
|
||||
|
||||
# Compare calculations
|
||||
if [[ "${ORIGINAL_RELEASE_VERSION}" != "${CURRENT_RELEASE_VERSION}" ]] || \
|
||||
[[ "${ORIGINAL_RELEASE_TAG}" != "${CURRENT_RELEASE_TAG}" ]] || \
|
||||
[[ "${ORIGINAL_PREVIOUS_TAG}" != "${CURRENT_PREVIOUS_TAG}" ]]; then
|
||||
echo "❌ RACE CONDITION DETECTED: Version calculations have changed!"
|
||||
echo "This indicates another patch release completed while this one was in progress."
|
||||
echo ""
|
||||
echo "Originally planned: ${ORIGINAL_RELEASE_VERSION} (from ${ORIGINAL_PREVIOUS_TAG})"
|
||||
echo "Should now build: ${CURRENT_RELEASE_VERSION} (from ${CURRENT_PREVIOUS_TAG})"
|
||||
echo ""
|
||||
echo "# Setting outputs for failure comment"
|
||||
echo "CURRENT_RELEASE_VERSION=${CURRENT_RELEASE_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "CURRENT_RELEASE_TAG=${CURRENT_RELEASE_TAG}" >> "${GITHUB_ENV}"
|
||||
echo "CURRENT_PREVIOUS_TAG=${CURRENT_PREVIOUS_TAG}" >> "${GITHUB_ENV}"
|
||||
echo "The patch release must be restarted to use the correct version numbers."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Version calculations unchanged - proceeding with release"
|
||||
|
||||
- name: 'Print Calculated Version'
|
||||
run: |-
|
||||
echo "Patch Release Summary:"
|
||||
@@ -121,3 +174,46 @@ jobs:
|
||||
--title 'Patch Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
|
||||
--body 'The patch-release workflow failed. See the full run for details: ${DETAILS_URL}' \
|
||||
--label 'kind/bug,release-failure,priority/p0'
|
||||
|
||||
- name: 'Comment Success on Original PR'
|
||||
if: '${{ success() && github.event.inputs.original_pr }}'
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
ORIGINAL_PR: '${{ github.event.inputs.original_pr }}'
|
||||
SUCCESS: 'true'
|
||||
RELEASE_VERSION: '${{ steps.patch_version.outputs.RELEASE_VERSION }}'
|
||||
RELEASE_TAG: '${{ steps.patch_version.outputs.RELEASE_TAG }}'
|
||||
NPM_TAG: '${{ steps.patch_version.outputs.NPM_TAG }}'
|
||||
CHANNEL: '${{ github.event.inputs.type }}'
|
||||
DRY_RUN: '${{ github.event.inputs.dry_run }}'
|
||||
GITHUB_RUN_ID: '${{ github.run_id }}'
|
||||
GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'
|
||||
GITHUB_REPOSITORY_NAME: '${{ github.event.repository.name }}'
|
||||
run: |
|
||||
node scripts/releasing/patch-comment.js
|
||||
|
||||
- name: 'Comment Failure on Original PR'
|
||||
if: '${{ failure() && github.event.inputs.original_pr }}'
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
ORIGINAL_PR: '${{ github.event.inputs.original_pr }}'
|
||||
SUCCESS: 'false'
|
||||
RELEASE_VERSION: '${{ steps.patch_version.outputs.RELEASE_VERSION }}'
|
||||
RELEASE_TAG: '${{ steps.patch_version.outputs.RELEASE_TAG }}'
|
||||
NPM_TAG: '${{ steps.patch_version.outputs.NPM_TAG }}'
|
||||
CHANNEL: '${{ github.event.inputs.type }}'
|
||||
DRY_RUN: '${{ github.event.inputs.dry_run }}'
|
||||
GITHUB_RUN_ID: '${{ github.run_id }}'
|
||||
GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'
|
||||
GITHUB_REPOSITORY_NAME: '${{ github.event.repository.name }}'
|
||||
# Pass current version info for race condition failures
|
||||
CURRENT_RELEASE_VERSION: '${{ env.CURRENT_RELEASE_VERSION }}'
|
||||
CURRENT_RELEASE_TAG: '${{ env.CURRENT_RELEASE_TAG }}'
|
||||
CURRENT_PREVIOUS_TAG: '${{ env.CURRENT_PREVIOUS_TAG }}'
|
||||
run: |
|
||||
# Check if this was a version consistency failure
|
||||
if [[ -n "${CURRENT_RELEASE_VERSION}" ]]; then
|
||||
echo "Detected version race condition failure - posting specific comment with current version info"
|
||||
export RACE_CONDITION_FAILURE=true
|
||||
fi
|
||||
node scripts/releasing/patch-comment.js
|
||||
|
||||
32
.github/workflows/release-patch-from-comment.yml
vendored
32
.github/workflows/release-patch-from-comment.yml
vendored
@@ -53,9 +53,35 @@ jobs:
|
||||
- name: 'Dispatch if Merged'
|
||||
if: "steps.pr_status.outputs.STATE == 'MERGED'"
|
||||
uses: 'actions/github-script@00f12e3e20659f42342b1c0226afda7f7c042325'
|
||||
env:
|
||||
COMMENT_BODY: '${{ github.event.comment.body }}'
|
||||
with:
|
||||
script: |
|
||||
const args = ${{ fromJSON(steps.slash_command.outputs.command-arguments || '{}') }};
|
||||
// Parse the comment body directly to extract channel
|
||||
const commentBody = process.env.COMMENT_BODY;
|
||||
console.log('Comment body:', commentBody);
|
||||
|
||||
let channel = 'stable'; // default
|
||||
|
||||
// Parse different formats:
|
||||
// /patch channel=preview
|
||||
// /patch --channel preview
|
||||
// /patch preview
|
||||
if (commentBody.includes('channel=preview')) {
|
||||
channel = 'preview';
|
||||
} else if (commentBody.includes('--channel preview')) {
|
||||
channel = 'preview';
|
||||
} else if (commentBody.trim() === '/patch preview') {
|
||||
channel = 'preview';
|
||||
}
|
||||
|
||||
// Validate channel
|
||||
if (channel !== 'stable' && channel !== 'preview') {
|
||||
throw new Error(`Invalid channel: ${channel}. Must be 'stable' or 'preview'.`);
|
||||
}
|
||||
|
||||
console.log('Detected channel:', channel);
|
||||
|
||||
github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
@@ -63,8 +89,8 @@ jobs:
|
||||
ref: 'main',
|
||||
inputs: {
|
||||
commit: '${{ steps.pr_status.outputs.MERGE_COMMIT_SHA }}',
|
||||
channel: args.channel || 'stable',
|
||||
dry_run: args.dry_run || 'false',
|
||||
channel: channel,
|
||||
dry_run: 'false',
|
||||
original_pr: '${{ github.event.issue.number }}'
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user