mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 22:21:22 -07:00
fix(release): Improve Patch Release Workflow Comments: Clearer Approval Guidance (#21894)
This commit is contained in:
@@ -120,6 +120,9 @@ jobs:
|
||||
if (recentRuns.length > 0) {
|
||||
core.setOutput('dispatched_run_urls', recentRuns.map(r => r.html_url).join(','));
|
||||
core.setOutput('dispatched_run_ids', recentRuns.map(r => r.id).join(','));
|
||||
|
||||
const markdownLinks = recentRuns.map(r => `- [View dispatched workflow run](${r.html_url})`).join('\n');
|
||||
core.setOutput('dispatched_run_links', markdownLinks);
|
||||
}
|
||||
|
||||
- name: 'Comment on Failure'
|
||||
@@ -138,16 +141,19 @@ jobs:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
issue-number: '${{ github.event.issue.number }}'
|
||||
body: |
|
||||
✅ **Patch workflow(s) dispatched successfully!**
|
||||
🚀 **[Step 1/4] Patch workflow(s) waiting for approval!**
|
||||
|
||||
**📋 Details:**
|
||||
- **Channels**: `${{ steps.dispatch_patch.outputs.dispatched_channels }}`
|
||||
- **Commit**: `${{ steps.pr_status.outputs.MERGE_COMMIT_SHA }}`
|
||||
- **Workflows Created**: ${{ steps.dispatch_patch.outputs.dispatched_run_count }}
|
||||
|
||||
**⏳ Status:** The patch creation workflow has been triggered and is waiting for deployment approval. Please visit the specific workflow links below and approve the runs.
|
||||
|
||||
**🔗 Track Progress:**
|
||||
- [View patch workflows](https://github.com/${{ github.repository }}/actions/workflows/release-patch-1-create-pr.yml)
|
||||
- [This workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
${{ steps.dispatch_patch.outputs.dispatched_run_links }}
|
||||
- [View patch workflow history](https://github.com/${{ github.repository }}/actions/workflows/release-patch-1-create-pr.yml)
|
||||
- [This trigger workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
|
||||
- name: 'Final Status Comment - Dispatch Success (No URL)'
|
||||
if: "always() && startsWith(github.event.comment.body, '/patch') && steps.dispatch_patch.outcome == 'success' && !steps.dispatch_patch.outputs.dispatched_run_urls"
|
||||
@@ -156,16 +162,18 @@ jobs:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
issue-number: '${{ github.event.issue.number }}'
|
||||
body: |
|
||||
✅ **Patch workflow(s) dispatched successfully!**
|
||||
🚀 **[Step 1/4] Patch workflow(s) waiting for approval!**
|
||||
|
||||
**📋 Details:**
|
||||
- **Channels**: `${{ steps.dispatch_patch.outputs.dispatched_channels }}`
|
||||
- **Commit**: `${{ steps.pr_status.outputs.MERGE_COMMIT_SHA }}`
|
||||
- **Workflows Created**: ${{ steps.dispatch_patch.outputs.dispatched_run_count }}
|
||||
|
||||
**⏳ Status:** The patch creation workflow has been triggered and is waiting for deployment approval. Please visit the workflow history link below and approve the runs.
|
||||
|
||||
**🔗 Track Progress:**
|
||||
- [View patch workflows](https://github.com/${{ github.repository }}/actions/workflows/release-patch-1-create-pr.yml)
|
||||
- [This workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
- [View patch workflow history](https://github.com/${{ github.repository }}/actions/workflows/release-patch-1-create-pr.yml)
|
||||
- [This trigger workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
|
||||
- name: 'Final Status Comment - Failure'
|
||||
if: "always() && startsWith(github.event.comment.body, '/patch') && (steps.dispatch_patch.outcome == 'failure' || steps.dispatch_patch.outcome == 'cancelled')"
|
||||
@@ -174,7 +182,7 @@ jobs:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
issue-number: '${{ github.event.issue.number }}'
|
||||
body: |
|
||||
❌ **Patch workflow dispatch failed!**
|
||||
❌ **[Step 1/4] Patch workflow dispatch failed!**
|
||||
|
||||
There was an error dispatching the patch creation workflow.
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ async function main() {
|
||||
let commentBody;
|
||||
|
||||
if (success) {
|
||||
commentBody = `✅ **Patch Release Complete!**
|
||||
commentBody = `✅ **[Step 4/4] Patch Release Complete!**
|
||||
|
||||
**📦 Release Details:**
|
||||
- **Version**: [\`${releaseVersion}\`](https://github.com/${repo.owner}/${repo.repo}/releases/tag/${releaseTag})
|
||||
@@ -144,9 +144,10 @@ async function main() {
|
||||
|
||||
**🔗 Links:**
|
||||
- [GitHub Release](https://github.com/${repo.owner}/${repo.repo}/releases/tag/${releaseTag})
|
||||
- [Workflow Run](https://github.com/${repo.owner}/${repo.repo}/actions/runs/${runId})`;
|
||||
- [This release workflow run](https://github.com/${repo.owner}/${repo.repo}/actions/runs/${runId})
|
||||
- [Workflow History](https://github.com/${repo.owner}/${repo.repo}/actions/workflows/release-patch-3-release.yml)`;
|
||||
} else if (raceConditionFailure) {
|
||||
commentBody = `⚠️ **Patch Release Cancelled - Concurrent Release Detected**
|
||||
commentBody = `⚠️ **[Step 4/4] Patch Release Cancelled - Concurrent Release Detected**
|
||||
|
||||
**🚦 What Happened:**
|
||||
Another patch release completed while this one was in progress, causing a version conflict.
|
||||
@@ -163,7 +164,7 @@ Another patch release completed while this one was in progress, causing a versio
|
||||
- **Next patch should be**: \`${currentReleaseVersion}\`
|
||||
- **New release tag**: \`${currentReleaseTag || 'unknown'}\``
|
||||
: `
|
||||
- **Status**: Version information updated since this release started`
|
||||
- **Status**: Version information updated since this release was triggered`
|
||||
}
|
||||
|
||||
**🔄 Next Steps:**
|
||||
@@ -175,9 +176,10 @@ Another patch release completed while this one was in progress, causing a versio
|
||||
Multiple patch releases can't run simultaneously. When they do, the second one is automatically cancelled to maintain version consistency.
|
||||
|
||||
**🔗 Details:**
|
||||
- [View cancelled workflow run](https://github.com/${repo.owner}/${repo.repo}/actions/runs/${runId})`;
|
||||
- [This release workflow run](https://github.com/${repo.owner}/${repo.repo}/actions/runs/${runId})
|
||||
- [Workflow History](https://github.com/${repo.owner}/${repo.repo}/actions/workflows/release-patch-3-release.yml)`;
|
||||
} else {
|
||||
commentBody = `❌ **Patch Release Failed!**
|
||||
commentBody = `❌ **[Step 4/4] Patch Release Failed!**
|
||||
|
||||
**📋 Details:**
|
||||
- **Version**: \`${releaseVersion || 'Unknown'}\`
|
||||
@@ -190,8 +192,9 @@ Multiple patch releases can't run simultaneously. When they do, the second one i
|
||||
3. You may need to retry the patch once the issue is resolved
|
||||
|
||||
**🔗 Troubleshooting:**
|
||||
- [View workflow run](https://github.com/${repo.owner}/${repo.repo}/actions/runs/${runId})
|
||||
- [View workflow logs](https://github.com/${repo.owner}/${repo.repo}/actions/runs/${runId})`;
|
||||
- [This release workflow run](https://github.com/${repo.owner}/${repo.repo}/actions/runs/${runId})
|
||||
- [View workflow logs](https://github.com/${repo.owner}/${repo.repo}/actions/runs/${runId})
|
||||
- [Workflow History](https://github.com/${repo.owner}/${repo.repo}/actions/workflows/release-patch-3-release.yml)`;
|
||||
}
|
||||
|
||||
if (testMode) {
|
||||
|
||||
@@ -145,7 +145,7 @@ async function main() {
|
||||
manualCommands = manualCommandsMatch[1].trim();
|
||||
}
|
||||
|
||||
commentBody = `🔒 **GitHub App Permission Issue**
|
||||
commentBody = `🔒 **[Step 2/4] GitHub App Permission Issue**
|
||||
|
||||
The patch creation failed due to insufficient GitHub App permissions for creating workflow files.
|
||||
|
||||
@@ -169,7 +169,7 @@ After running these commands, you can re-run the patch workflow.`
|
||||
const prMatch = logContent.match(/Found existing PR #(\d+): (.*)/);
|
||||
if (prMatch) {
|
||||
const [, prNumber, prUrl] = prMatch;
|
||||
commentBody = `ℹ️ **Patch PR already exists!**
|
||||
commentBody = `ℹ️ **[Step 2/4] Patch PR already exists!**
|
||||
|
||||
A patch PR for this change already exists: [#${prNumber}](${prUrl}).
|
||||
|
||||
@@ -185,7 +185,7 @@ A patch PR for this change already exists: [#${prNumber}](${prUrl}).
|
||||
const branchMatch = logContent.match(/Hotfix branch (.*) already exists/);
|
||||
if (branchMatch) {
|
||||
const [, branch] = branchMatch;
|
||||
commentBody = `ℹ️ **Patch branch exists but no PR found!**
|
||||
commentBody = `ℹ️ **[Step 2/4] Patch branch exists but no PR found!**
|
||||
|
||||
A patch branch [\`${branch}\`](https://github.com/${repository}/tree/${branch}) exists but has no open PR.
|
||||
|
||||
@@ -213,7 +213,7 @@ A patch branch [\`${branch}\`](https://github.com/${repository}/tree/${branch})
|
||||
logContent.includes('Cherry-pick has conflicts') ||
|
||||
logContent.includes('[CONFLICTS]');
|
||||
|
||||
commentBody = `🚀 **Patch PR Created!**
|
||||
commentBody = `🚀 **[Step 2/4] Patch PR Created!**
|
||||
|
||||
**📋 Patch Details:**
|
||||
- **Environment**: \`${environment}\`
|
||||
@@ -228,7 +228,8 @@ ${hasConflicts ? '3' : '2'}. Once merged, the patch release will automatically t
|
||||
${hasConflicts ? '4' : '3'}. You'll receive updates here when the release completes
|
||||
|
||||
**🔗 Track Progress:**
|
||||
- [View hotfix PR #${mockPrNumber}](${mockPrUrl})`;
|
||||
- [View hotfix PR #${mockPrNumber}](${mockPrUrl})
|
||||
- [This patch creation workflow run](https://github.com/${repository}/actions/runs/${runId})`;
|
||||
} else if (hasGitHubCli) {
|
||||
// Find the actual PR for the new branch using gh CLI
|
||||
try {
|
||||
@@ -269,7 +270,7 @@ ${hasConflicts ? '4' : '3'}. You'll receive updates here when the release comple
|
||||
logContent.includes('Cherry-pick has conflicts') ||
|
||||
pr.title.includes('[CONFLICTS]');
|
||||
|
||||
commentBody = `🚀 **Patch PR Created!**
|
||||
commentBody = `🚀 **[Step 2/4] Patch PR Created!**
|
||||
|
||||
**📋 Patch Details:**
|
||||
- **Environment**: \`${environment}\`
|
||||
@@ -284,10 +285,11 @@ ${hasConflicts ? '3' : '2'}. Once merged, the patch release will automatically t
|
||||
${hasConflicts ? '4' : '3'}. You'll receive updates here when the release completes
|
||||
|
||||
**🔗 Track Progress:**
|
||||
- [View hotfix PR #${pr.number}](${pr.url})`;
|
||||
- [View hotfix PR #${pr.number}](${pr.url})
|
||||
- [This patch creation workflow run](https://github.com/${repository}/actions/runs/${runId})`;
|
||||
} else {
|
||||
// Fallback if PR not found yet
|
||||
commentBody = `🚀 **Patch PR Created!**
|
||||
commentBody = `🚀 **[Step 2/4] Patch PR Created!**
|
||||
|
||||
The patch release PR for this change has been created on branch [\`${branch}\`](https://github.com/${repository}/tree/${branch}).
|
||||
|
||||
@@ -296,23 +298,25 @@ The patch release PR for this change has been created on branch [\`${branch}\`](
|
||||
2. Once merged, the patch release will automatically trigger
|
||||
|
||||
**🔗 Links:**
|
||||
- [View all patch PRs](https://github.com/${repository}/pulls?q=is%3Apr+is%3Aopen+label%3Apatch)`;
|
||||
- [View all patch PRs](https://github.com/${repository}/pulls?q=is%3Apr+is%3Aopen+label%3Apatch)
|
||||
- [This patch creation workflow run](https://github.com/${repository}/actions/runs/${runId})`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Error finding PR for branch:', error.message);
|
||||
// Fallback
|
||||
commentBody = `🚀 **Patch PR Created!**
|
||||
commentBody = `🚀 **[Step 2/4] Patch PR Created!**
|
||||
|
||||
The patch release PR for this change has been created.
|
||||
|
||||
**🔗 Links:**
|
||||
- [View all patch PRs](https://github.com/${repository}/pulls?q=is%3Apr+is%3Aopen+label%3Apatch)`;
|
||||
- [View all patch PRs](https://github.com/${repository}/pulls?q=is%3Apr+is%3Aopen+label%3Apatch)
|
||||
- [This patch creation workflow run](https://github.com/${repository}/actions/runs/${runId})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Failure
|
||||
commentBody = `❌ **Patch creation failed!**
|
||||
commentBody = `❌ **[Step 2/4] Patch creation failed!**
|
||||
|
||||
There was an error creating the patch release.
|
||||
|
||||
@@ -326,7 +330,7 @@ There was an error creating the patch release.
|
||||
}
|
||||
|
||||
if (!commentBody) {
|
||||
commentBody = `❌ **Patch creation failed!**
|
||||
commentBody = `❌ **[Step 2/4] Patch creation failed!**
|
||||
|
||||
No output was generated during patch creation.
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ async function main() {
|
||||
const isDryRun = argv.dryRun || body.includes('[DRY RUN]');
|
||||
const forceSkipTests =
|
||||
argv.forceSkipTests || process.env.FORCE_SKIP_TESTS === 'true';
|
||||
const runId = process.env.GITHUB_RUN_ID || '0';
|
||||
|
||||
if (!headRef) {
|
||||
throw new Error(
|
||||
@@ -264,7 +265,7 @@ async function main() {
|
||||
console.log(`Commenting on original PR ${originalPr}...`);
|
||||
const npmTag = channel === 'stable' ? 'latest' : 'preview';
|
||||
|
||||
const commentBody = `🚀 **Patch Release Started!**
|
||||
const commentBody = `🚀 **[Step 3/4] Patch Release ${environment === 'prod' ? 'Waiting for Approval' : 'Triggered'}!**
|
||||
|
||||
**📋 Release Details:**
|
||||
- **Environment**: \`${environment}\`
|
||||
@@ -273,10 +274,11 @@ async function main() {
|
||||
- **Hotfix PR**: Merged ✅
|
||||
- **Release Branch**: [\`${releaseRef}\`](https://github.com/${context.repo.owner}/${context.repo.repo}/tree/${releaseRef})
|
||||
|
||||
**⏳ Status:** The patch release is now running. You'll receive another update when it completes.
|
||||
**⏳ Status:** The patch release has been triggered${environment === 'prod' ? ' and is waiting for deployment approval. Please visit the specific workflow run link below and approve the deployment' : ''}. You'll receive another update when it completes.
|
||||
|
||||
**🔗 Track Progress:**
|
||||
- [View release workflow](https://github.com/${context.repo.owner}/${context.repo.repo}/actions)`;
|
||||
- [View release workflow history](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/workflows/${workflowId})
|
||||
- [This trigger workflow run](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId})`;
|
||||
|
||||
if (!testMode) {
|
||||
let tempDir;
|
||||
|
||||
@@ -57,7 +57,7 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('🚀 **Patch PR Created!**');
|
||||
expect(result.stdout).toContain('🚀 **[Step 2/4] Patch PR Created!**');
|
||||
expect(result.stdout).toContain('Environment**: `prod`');
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('🚀 **Patch PR Created!**');
|
||||
expect(result.stdout).toContain('🚀 **[Step 2/4] Patch PR Created!**');
|
||||
expect(result.stdout).toContain('Environment**: `dev`');
|
||||
});
|
||||
|
||||
@@ -90,7 +90,7 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('🚀 **Patch PR Created!**');
|
||||
expect(result.stdout).toContain('🚀 **[Step 2/4] Patch PR Created!**');
|
||||
expect(result.stdout).toContain('Environment**: `prod`');
|
||||
});
|
||||
});
|
||||
@@ -106,7 +106,7 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('🚀 **Patch PR Created!**');
|
||||
expect(result.stdout).toContain('🚀 **[Step 2/4] Patch PR Created!**');
|
||||
expect(result.stdout).toContain('Channel**: `preview`');
|
||||
expect(result.stdout).toContain('Commit**: `abc1234`');
|
||||
});
|
||||
@@ -118,7 +118,9 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('❌ **Patch creation failed!**');
|
||||
expect(result.stdout).toContain(
|
||||
'❌ **[Step 2/4] Patch creation failed!**',
|
||||
);
|
||||
expect(result.stdout).toContain(
|
||||
'There was an error creating the patch release',
|
||||
);
|
||||
@@ -136,7 +138,7 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('🚀 **Patch PR Created!**');
|
||||
expect(result.stdout).toContain('🚀 **[Step 2/4] Patch PR Created!**');
|
||||
expect(result.stdout).toContain('Channel**: `stable`');
|
||||
expect(result.stdout).toContain('Commit**: `abc1234`');
|
||||
expect(result.stdout).not.toContain('⚠️ Status');
|
||||
@@ -152,7 +154,7 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('🚀 **Patch PR Created!**');
|
||||
expect(result.stdout).toContain('🚀 **[Step 2/4] Patch PR Created!**');
|
||||
expect(result.stdout).toContain(
|
||||
'⚠️ Status**: Cherry-pick conflicts detected',
|
||||
);
|
||||
@@ -174,7 +176,9 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('ℹ️ **Patch PR already exists!**');
|
||||
expect(result.stdout).toContain(
|
||||
'ℹ️ **[Step 2/4] Patch PR already exists!**',
|
||||
);
|
||||
expect(result.stdout).toContain(
|
||||
'A patch PR for this change already exists: [#8700](https://github.com/google-gemini/gemini-cli/pull/8700)',
|
||||
);
|
||||
@@ -194,7 +198,7 @@ describe('patch-create-comment', () => {
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain(
|
||||
'ℹ️ **Patch branch exists but no PR found!**',
|
||||
'ℹ️ **[Step 2/4] Patch branch exists but no PR found!**',
|
||||
);
|
||||
expect(result.stdout).toContain(
|
||||
'Delete the branch: `git branch -D hotfix/v0.5.0-preview.2/preview/cherry-pick-jkl3456`',
|
||||
@@ -213,7 +217,9 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('❌ **Patch creation failed!**');
|
||||
expect(result.stdout).toContain(
|
||||
'❌ **[Step 2/4] Patch creation failed!**',
|
||||
);
|
||||
expect(result.stdout).toContain(
|
||||
'There was an error creating the patch release',
|
||||
);
|
||||
@@ -231,7 +237,9 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('❌ **Patch creation failed!**');
|
||||
expect(result.stdout).toContain(
|
||||
'❌ **[Step 2/4] Patch creation failed!**',
|
||||
);
|
||||
expect(result.stdout).toContain(
|
||||
'There was an error creating the patch release',
|
||||
);
|
||||
@@ -292,7 +300,9 @@ describe('patch-create-comment', () => {
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('❌ **Patch creation failed!**');
|
||||
expect(result.stdout).toContain(
|
||||
'❌ **[Step 2/4] Patch creation failed!**',
|
||||
);
|
||||
expect(result.stdout).toContain(
|
||||
'There was an error creating the patch release',
|
||||
);
|
||||
@@ -316,7 +326,9 @@ git push origin hotfix/v0.4.1/stable/cherry-pick-abc1234
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('🔒 **GitHub App Permission Issue**');
|
||||
expect(result.stdout).toContain(
|
||||
'🔒 **[Step 2/4] GitHub App Permission Issue**',
|
||||
);
|
||||
expect(result.stdout).toContain(
|
||||
'Please run these commands manually to create the release branch:',
|
||||
);
|
||||
@@ -339,7 +351,7 @@ git push origin hotfix/v0.4.1/stable/cherry-pick-abc1234
|
||||
expect(result.stdout).toContain(
|
||||
'🧪 TEST MODE - No API calls will be made',
|
||||
);
|
||||
expect(result.stdout).toContain('🚀 **Patch PR Created!**');
|
||||
expect(result.stdout).toContain('🚀 **[Step 2/4] Patch PR Created!**');
|
||||
});
|
||||
|
||||
it('should generate mock content in test mode for failure', () => {
|
||||
@@ -348,7 +360,9 @@ git push origin hotfix/v0.4.1/stable/cherry-pick-abc1234
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stdout).toContain('❌ **Patch creation failed!**');
|
||||
expect(result.stdout).toContain(
|
||||
'❌ **[Step 2/4] Patch creation failed!**',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user