diff --git a/.github/workflows/release-patch-1-create-pr.yml b/.github/workflows/release-patch-1-create-pr.yml index 10b6d0ebeb..43b6eef050 100644 --- a/.github/workflows/release-patch-1-create-pr.yml +++ b/.github/workflows/release-patch-1-create-pr.yml @@ -52,43 +52,33 @@ jobs: - name: 'Install Script Dependencies' run: 'npm install yargs' + - name: 'Generate GitHub App Token' + id: 'generate_token' + uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' + with: + app-id: '${{ secrets.APP_ID }}' + private-key: '${{ secrets.PRIVATE_KEY }}' + permission-pull-requests: 'write' + permission-contents: 'write' - name: 'Configure Git User' run: |- git config user.name "gemini-cli-robot" git config user.email "gemini-cli-robot@google.com" - - - name: 'Test 1: Create branch from HEAD and push' - run: |- - echo "Testing branch creation from HEAD..." - BRANCH_NAME="test-from-head-$(date +%s)" - git checkout -b "$BRANCH_NAME" - echo "# Test file" > test-file.txt - git add test-file.txt - git commit -m "test commit from HEAD" - git push origin "$BRANCH_NAME" || echo "HEAD push failed" - - - name: 'Test 2: Create branch from v0.5.3 tag and push' - run: |- - echo "Testing branch creation from v0.5.3 tag..." - git fetch --tags - BRANCH_NAME="test-from-v053-$(date +%s)" - git checkout -b "$BRANCH_NAME" v0.5.3 || echo "Failed to checkout from v0.5.3" - git push origin "$BRANCH_NAME" || echo "v0.5.3 tag push failed" + # Configure git to use GITHUB_TOKEN for remote operations (has actions:write for workflow files) + git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" - name: 'Create Patch' id: 'create_patch' env: GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' - GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + GH_TOKEN: '${{ steps.generate_token.outputs.token }}' continue-on-error: true run: | # Capture output and display it in logs using tee { node scripts/releasing/create-patch-pr.js --commit=${{ github.event.inputs.commit }} --channel=${{ github.event.inputs.channel }} --dry-run=${{ github.event.inputs.dry_run }} - EXIT_CODE=$? - echo "EXIT_CODE=$EXIT_CODE" >> "$GITHUB_OUTPUT" - exit $EXIT_CODE + echo "EXIT_CODE=$?" >> "$GITHUB_OUTPUT" } 2>&1 | tee >( echo "LOG_CONTENT<> "$GITHUB_ENV" cat >> "$GITHUB_ENV" @@ -96,7 +86,7 @@ jobs: ) - name: 'Comment on Original PR' - if: 'always() && github.event.inputs.original_pr' + if: 'always() && inputs.original_pr' env: GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}' ORIGINAL_PR: '${{ github.event.inputs.original_pr }}' diff --git a/scripts/releasing/create-patch-pr.js b/scripts/releasing/create-patch-pr.js index 35e42e7e96..e647c8e22c 100644 --- a/scripts/releasing/create-patch-pr.js +++ b/scripts/releasing/create-patch-pr.js @@ -29,44 +29,18 @@ async function main() { type: 'boolean', default: false, }) - .option('skip-pr-creation', { - description: 'Only create branches, skip PR creation.', - type: 'boolean', - default: false, - }) - .option('pr-only', { - description: 'Only create PR, skip branch creation.', - type: 'boolean', - default: false, - }) .help() .alias('help', 'h').argv; - const { commit, channel, dryRun, skipPrCreation, prOnly } = argv; - - // Validate mutually exclusive flags - if (skipPrCreation && prOnly) { - console.error( - 'Error: --skip-pr-creation and --pr-only are mutually exclusive.', - ); - process.exit(1); - } + const { commit, channel, dryRun } = argv; console.log(`Starting patch process for commit: ${commit}`); console.log(`Targeting channel: ${channel}`); if (dryRun) { console.log('Running in dry-run mode.'); } - if (skipPrCreation) { - console.log('Mode: Branch creation only (skipping PR creation)'); - } - if (prOnly) { - console.log('Mode: PR creation only (skipping branch creation)'); - } - if (!prOnly) { - run('git fetch --all --tags --prune', dryRun); - } + run('git fetch --all --tags --prune', dryRun); const latestTag = getLatestTag(channel); console.log(`Found latest tag for ${channel}: ${latestTag}`); @@ -74,22 +48,6 @@ async function main() { const releaseBranch = `release/${latestTag}`; const hotfixBranch = `hotfix/${latestTag}/${channel}/cherry-pick-${commit.substring(0, 7)}`; - // If PR-only mode, skip all branch creation logic - if (prOnly) { - console.log( - 'PR-only mode: Skipping branch creation, proceeding to PR creation...', - ); - // Jump to PR creation section - return await createPullRequest( - hotfixBranch, - releaseBranch, - commit, - channel, - dryRun, - false, - ); - } - // Create the release branch from the tag if it doesn't exist. if (!branchExists(releaseBranch)) { console.log( @@ -101,9 +59,8 @@ async function main() { } catch (error) { // Check if this is a GitHub App workflows permission error if ( - /refusing to allow a GitHub App.*workflows?['`]? permission/i.test( - error.message, - ) + error.message.match(/refusing to allow a GitHub App/i) && + error.message.match(/workflows?['`]? permission/i) ) { console.error( `❌ Failed to create release branch due to insufficient GitHub App permissions.`, @@ -223,43 +180,7 @@ async function main() { console.log(`Pushing hotfix branch ${hotfixBranch} to origin...`); run(`git push --set-upstream origin ${hotfixBranch}`, dryRun); - // If skip-pr-creation mode, stop here - if (skipPrCreation) { - console.log( - '✅ Branch creation completed! Skipping PR creation as requested.', - ); - if (hasConflicts) { - console.log( - '⚠️ Note: Conflicts were detected during cherry-pick - manual resolution required before PR creation!', - ); - } - return { - newBranch: hotfixBranch, - created: true, - hasConflicts, - skippedPR: true, - }; - } - - // Create the pull request - return await createPullRequest( - hotfixBranch, - releaseBranch, - commit, - channel, - dryRun, - hasConflicts, - ); -} - -async function createPullRequest( - hotfixBranch, - releaseBranch, - commit, - channel, - dryRun, - hasConflicts, -) { + // Create the pull request. console.log( `Creating pull request from ${hotfixBranch} to ${releaseBranch}...`, );