Download scripts/tests/patch-create-comment.test.js from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 13.7 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/scripts/tests/patch-create-comment.test.js
- Command line
-
hf download hf://SaylorTwift/gemini-cli/scripts/tests/patch-create-comment.test.js
-
curl -L -o patch-create-comment.test.js https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/scripts/tests/patch-create-comment.test.js
13.7 kB
| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest'; | |
| import { execSync } from 'node:child_process'; | |
| import { join } from 'node:path'; | |
| /** | |
| * Helper function to run the patch-create-comment script with given parameters | |
| */ | |
| function runPatchCreateComment(args, env = {}) { | |
| const scriptPath = join( | |
| process.cwd(), | |
| 'scripts/releasing/patch-create-comment.js', | |
| ); | |
| const fullEnv = { | |
| ...process.env, | |
| LC_ALL: 'en_US.UTF-8', | |
| LANG: 'en_US.UTF-8', | |
| ...env, | |
| }; | |
| try { | |
| const result = execSync(`node ${scriptPath} ${args}`, { | |
| encoding: 'utf8', | |
| env: fullEnv, | |
| }); | |
| return { stdout: result, stderr: '', success: true }; | |
| } catch (error) { | |
| return { | |
| stdout: error.stdout || '', | |
| stderr: error.stderr || '', | |
| success: false, | |
| code: error.status, | |
| }; | |
| } | |
| } | |
| describe('patch-create-comment', () => { | |
| beforeEach(() => { | |
| vi.stubEnv(); | |
| // Always run in test mode to avoid GitHub API calls | |
| vi.stubEnv('TEST_MODE', 'true'); | |
| }); | |
| afterEach(() => { | |
| vi.clearAllMocks(); | |
| vi.unstubAllEnvs(); | |
| }); | |
| describe('Environment flag', () => { | |
| it('can be overridden with a flag', () => { | |
| vi.stubEnv('ENVIRONMENT', 'dev'); | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --environment prod --commit abc1234 --channel preview --repository google-gemini/gemini-cli --test', | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain('π **[Step 2/4] Patch PR Created!**'); | |
| expect(result.stdout).toContain('Environment**: `prod`'); | |
| }); | |
| it('reads from the ENVIRONMENT env variable', () => { | |
| vi.stubEnv('ENVIRONMENT', 'dev'); | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit abc1234 --channel preview --repository google-gemini/gemini-cli --test', | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain('π **[Step 2/4] Patch PR Created!**'); | |
| expect(result.stdout).toContain('Environment**: `dev`'); | |
| }); | |
| it('fails if the ENVIRONMENT is bogus', () => { | |
| vi.stubEnv('ENVIRONMENT', 'totally-bogus'); | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit abc1234 --channel preview --repository google-gemini/gemini-cli --test', | |
| ); | |
| expect(result.success).toBe(false); | |
| expect(result.stderr).toContain( | |
| 'Argument: environment, Given: "totally-bogus", Choices: "prod", "dev"', | |
| ); | |
| }); | |
| it('defaults to prod if not specified', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit abc1234 --channel preview --repository google-gemini/gemini-cli --test', | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain('π **[Step 2/4] Patch PR Created!**'); | |
| expect(result.stdout).toContain('Environment**: `prod`'); | |
| }); | |
| }); | |
| describe('Environment Variable vs File Reading', () => { | |
| it('should prefer LOG_CONTENT environment variable over file', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit abc1234 --channel preview --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: | |
| 'Creating hotfix branch hotfix/v0.5.3/preview/cherry-pick-abc1234 from release/v0.5.3', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain('π **[Step 2/4] Patch PR Created!**'); | |
| expect(result.stdout).toContain('Channel**: `preview`'); | |
| expect(result.stdout).toContain('Commit**: `abc1234`'); | |
| }); | |
| it('should use empty log content when LOG_CONTENT is not set', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 1 --commit abc1234 --channel stable --repository google-gemini/gemini-cli --test', | |
| {}, // No LOG_CONTENT env var | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain( | |
| 'β **[Step 2/4] Patch creation failed!**', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'There was an error creating the patch release', | |
| ); | |
| }); | |
| }); | |
| describe('Log Content Parsing - Success Scenarios', () => { | |
| it('should generate success comment for clean cherry-pick', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit abc1234 --channel stable --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: | |
| 'Creating hotfix branch hotfix/v0.4.1/stable/cherry-pick-abc1234 from release/v0.4.1\nβ Cherry-pick successful - no conflicts detected', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| 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'); | |
| }); | |
| it('should generate conflict comment for cherry-pick with conflicts', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit def5678 --channel preview --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: | |
| 'Creating hotfix branch hotfix/v0.5.0-preview.2/preview/cherry-pick-def5678 from release/v0.5.0-preview.2\nCherry-pick has conflicts in 2 file(s):\nCONFLICT (content): Merge conflict in package.json', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain('π **[Step 2/4] Patch PR Created!**'); | |
| expect(result.stdout).toContain( | |
| 'β οΈ Status**: Cherry-pick conflicts detected', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'β οΈ **Resolve conflicts** in the hotfix PR first', | |
| ); | |
| expect(result.stdout).toContain('Channel**: `preview`'); | |
| }); | |
| }); | |
| describe('Log Content Parsing - Existing PR Scenarios', () => { | |
| it('should detect existing PR and generate appropriate comment', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit ghi9012 --channel stable --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: | |
| 'Hotfix branch hotfix/v0.4.1/stable/cherry-pick-ghi9012 already has an open PR.\nFound existing PR #8700: https://github.com/google-gemini/gemini-cli/pull/8700', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| 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)', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'Review and approve the existing patch PR', | |
| ); | |
| }); | |
| it('should detect branch exists but no PR scenario', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit jkl3456 --channel preview --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: | |
| 'Hotfix branch hotfix/v0.5.0-preview.2/preview/cherry-pick-jkl3456 exists but has no open PR.\nHotfix branch hotfix/v0.5.0-preview.2/preview/cherry-pick-jkl3456 already exists.', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain( | |
| 'βΉοΈ **[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`', | |
| ); | |
| expect(result.stdout).toContain('Run the patch command again'); | |
| }); | |
| }); | |
| describe('Log Content Parsing - Failure Scenarios', () => { | |
| it('should generate failure comment when exit code is non-zero', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 1 --commit mno7890 --channel stable --repository google-gemini/gemini-cli --run-id 12345 --test', | |
| { | |
| LOG_CONTENT: 'Error: Failed to create patch', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain( | |
| 'β **[Step 2/4] Patch creation failed!**', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'There was an error creating the patch release', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'View workflow run](https://github.com/google-gemini/gemini-cli/actions/runs/12345)', | |
| ); | |
| }); | |
| it('should generate fallback failure comment when no output is generated', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 1 --commit pqr4567 --channel preview --repository google-gemini/gemini-cli --run-id 67890 --test', | |
| { | |
| LOG_CONTENT: '', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain( | |
| 'β **[Step 2/4] Patch creation failed!**', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'There was an error creating the patch release', | |
| ); | |
| }); | |
| }); | |
| describe('Channel and NPM Tag Detection', () => { | |
| it('should correctly map stable channel to latest npm tag', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit stu8901 --channel stable --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: | |
| 'Creating hotfix branch hotfix/v0.4.1/stable/cherry-pick-stu8901 from release/v0.4.1', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain('will publish to npm tag `latest`'); | |
| }); | |
| it('should correctly map preview channel to preview npm tag', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit vwx2345 --channel preview --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: | |
| 'Creating hotfix branch hotfix/v0.5.0-preview.2/preview/cherry-pick-vwx2345 from release/v0.5.0-preview.2', | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain('will publish to npm tag `preview`'); | |
| }); | |
| }); | |
| describe('No Original PR Scenario', () => { | |
| it('should skip comment when no original PR is specified', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 0 --exit-code 0 --commit yza6789 --channel stable --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: | |
| 'Creating hotfix branch hotfix/v0.4.1/stable/cherry-pick-yza6789 from release/v0.4.1', | |
| ORIGINAL_PR: '', // Override with empty PR | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain( | |
| 'No original PR specified, skipping comment', | |
| ); | |
| }); | |
| }); | |
| describe('Error Handling', () => { | |
| it('should handle empty LOG_CONTENT gracefully', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 1 --commit bcd0123 --channel stable --repository google-gemini/gemini-cli --test', | |
| { LOG_CONTENT: '' }, // Empty log content | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain( | |
| 'β **[Step 2/4] Patch creation failed!**', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'There was an error creating the patch release', | |
| ); | |
| }); | |
| }); | |
| describe('GitHub App Permission Scenarios', () => { | |
| it('should parse manual commands with clipboard emoji correctly', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 1 --commit abc1234 --channel stable --repository google-gemini/gemini-cli --test', | |
| { | |
| LOG_CONTENT: `β Failed to create release branch due to insufficient GitHub App permissions. | |
| π Please run these commands manually to create the branch: | |
| \`\`\`bash | |
| git checkout -b hotfix/v0.4.1/stable/cherry-pick-abc1234 v0.4.1 | |
| git push origin hotfix/v0.4.1/stable/cherry-pick-abc1234 | |
| \`\`\``, | |
| }, | |
| ); | |
| expect(result.success).toBe(true); | |
| 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:', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'git checkout -b hotfix/v0.4.1/stable/cherry-pick-abc1234 v0.4.1', | |
| ); | |
| expect(result.stdout).toContain( | |
| 'git push origin hotfix/v0.4.1/stable/cherry-pick-abc1234', | |
| ); | |
| }); | |
| }); | |
| describe('Test Mode Flag', () => { | |
| it('should generate mock content in test mode for success', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 0 --commit efg4567 --channel preview --repository google-gemini/gemini-cli --test', | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain( | |
| 'π§ͺ TEST MODE - No API calls will be made', | |
| ); | |
| expect(result.stdout).toContain('π **[Step 2/4] Patch PR Created!**'); | |
| }); | |
| it('should generate mock content in test mode for failure', () => { | |
| const result = runPatchCreateComment( | |
| '--original-pr 8655 --exit-code 1 --commit hij8901 --channel stable --repository google-gemini/gemini-cli --test', | |
| ); | |
| expect(result.success).toBe(true); | |
| expect(result.stdout).toContain( | |
| 'β **[Step 2/4] Patch creation failed!**', | |
| ); | |
| }); | |
| }); | |
| }); | |