@@ -389,31 +389,184 @@ jobs:
389389 pull_number: context.payload.issue.number
390390 });
391391
392+ // Debug information
393+ core.info(`PR #${pr.number}: ${pr.title}`);
394+ core.info(`- Base: ${pr.base.ref} (repo: ${pr.base.repo.full_name})`);
395+ core.info(`- Head: ${pr.head.ref} (repo: ${pr.head.repo.full_name})`);
396+ core.info(`- Same repo: ${pr.head.repo.full_name === pr.base.repo.full_name}`);
397+
398+ // Validate branch information
399+ if (!pr.head.ref || !pr.base.ref) {
400+ core.setFailed('Invalid PR branch information');
401+ return;
402+ }
403+
404+ // Check if it's from the same repository
405+ const isSameRepo = pr.head.repo.full_name === pr.base.repo.full_name;
406+
392407 core.setOutput('base_branch', pr.base.ref);
393408 core.setOutput('head_branch', pr.head.ref);
394409 core.setOutput('head_repo', pr.head.repo.full_name);
395410 core.setOutput('base_repo', pr.base.repo.full_name);
411+ core.setOutput('is_same_repo', isSameRepo.toString());
396412
397- core.info(`PR #${pr.number}: ${pr.title}`);
398- core.info(`- Base: ${pr.base.ref}`);
399- core.info(`- Head: ${pr.head.ref}`);
400- core.info(`- Same repo: ${pr.head.repo.full_name === pr.base.repo.full_name}`);
413+ - name : Validate branch exists
414+ if : steps.check_perms.outputs.has_permission == 'true'
415+ id : validate_branch
416+ uses : actions/github-script@v8
417+ with :
418+ script : |
419+ const headBranch = '${{ steps.pr_info.outputs.head_branch }}';
420+ const headRepo = '${{ steps.pr_info.outputs.head_repo }}';
421+ const isSameRepo = '${{ steps.pr_info.outputs.is_same_repo }}' === 'true';
422+
423+ core.info(`Validating branch: ${headBranch} from repo: ${headRepo}`);
424+
425+ try {
426+ // Check if branch exists
427+ const { data: branch } = await github.rest.repos.getBranch({
428+ owner: headRepo.split('/')[0],
429+ repo: headRepo.split('/')[1],
430+ branch: headBranch
431+ });
432+
433+ core.info(`✅ Branch exists: ${headBranch} (SHA: ${branch.commit.sha})`);
434+ core.setOutput('branch_exists', 'true');
435+
436+ } catch (error) {
437+ if (error.status === 404) {
438+ core.setOutput('branch_exists', 'false');
439+ core.error(`❌ Branch not found: ${headBranch}`);
440+
441+ // Provide helpful error message
442+ let errorMessage = `❌ Cannot update branch: Branch \`${headBranch}\` not found.`;
443+
444+ if (!isSameRepo) {
445+ errorMessage += '\n\nThis appears to be a PR from a fork. Update commands only work for branches in the same repository.';
446+ } else {
447+ errorMessage += '\n\nThis could mean:\n';
448+ errorMessage += '- The branch was deleted after merge\n';
449+ errorMessage += '- The branch name changed\n';
450+ errorMessage += '- There was a force push that changed the branch reference';
451+ }
452+
453+ await github.rest.issues.createComment({
454+ owner: context.repo.owner,
455+ repo: context.repo.repo,
456+ issue_number: context.payload.issue.number,
457+ body: errorMessage
458+ });
459+
460+ return;
461+ }
462+
463+ core.setFailed(`Error checking branch: ${error.message}`);
464+ }
465+
466+ - name : Check if update is needed
467+ if : steps.check_perms.outputs.has_permission == 'true' && steps.validate_branch.outputs.branch_exists == 'true'
468+ id : check_update
469+ uses : actions/github-script@v8
470+ with :
471+ script : |
472+ const baseBranch = '${{ steps.pr_info.outputs.base_branch }}';
473+ const headBranch = '${{ steps.pr_info.outputs.head_branch }}';
474+ const isSameRepo = '${{ steps.pr_info.outputs.is_same_repo }}' === 'true';
475+
476+ if (!isSameRepo) {
477+ core.info('PR is from fork - update not supported');
478+ core.setOutput('update_needed', 'false');
479+ core.setOutput('is_fork', 'true');
480+ return;
481+ }
482+
483+ try {
484+ // Get latest commit from base branch
485+ const { data: baseBranchData } = await github.rest.repos.getBranch({
486+ owner: context.repo.owner,
487+ repo: context.repo.repo,
488+ branch: baseBranch
489+ });
490+
491+ const baseSha = baseBranchData.commit.sha;
492+
493+ // Check if head branch is behind base
494+ const { data: comparison } = await github.rest.repos.compareCommits({
495+ owner: context.repo.owner,
496+ repo: context.repo.repo,
497+ base: baseSha,
498+ head: `${context.repo.owner}/${context.repo.repo}:${headBranch}`
499+ });
500+
501+ const isBehind = comparison.behind_by > 0;
502+ const aheadBy = comparison.ahead_by;
503+ const behindBy = comparison.behind_by;
504+
505+ core.info(`Branch comparison: ${behindBy} commits behind, ${aheadBy} commits ahead`);
506+
507+ if (!isBehind) {
508+ core.info('✅ Branch is already up to date');
509+ core.setOutput('update_needed', 'false');
510+ core.setOutput('already_up_to_date', 'true');
511+ } else {
512+ core.info(`Update needed: ${behindBy} commits behind`);
513+ core.setOutput('update_needed', 'true');
514+ core.setOutput('commits_behind', behindBy.toString());
515+ }
516+
517+ } catch (error) {
518+ core.setFailed(`Error checking if update is needed: ${error.message}`);
519+ }
520+
521+ - name : Handle already up-to-date
522+ if : steps.check_perms.outputs.has_permission == 'true' && steps.check_update.outputs.already_up_to_date == 'true'
523+ uses : actions/github-script@v8
524+ with :
525+ script : |
526+ await github.rest.issues.createComment({
527+ owner: context.repo.owner,
528+ repo: context.repo.repo,
529+ issue_number: context.payload.issue.number,
530+ body: '✅ Branch is already up to date with the latest changes!'
531+ });
532+
533+ - name : Handle fork PR
534+ if : steps.check_perms.outputs.has_permission == 'true' && steps.check_update.outputs.is_fork == 'true'
535+ uses : actions/github-script@v8
536+ with :
537+ script : |
538+ await github.rest.issues.createComment({
539+ owner: context.repo.owner,
540+ repo: context.repo.repo,
541+ issue_number: context.payload.issue.number,
542+ body: 'ℹ️ Update commands are not supported for PRs from forks.
543+
544+ To update your branch, please run these commands locally :
545+
546+ ` ` ` bash
547+ git fetch upstream main
548+ git merge upstream/main
549+ git push
550+ ` ` `
551+
552+ Or create a new PR from the same repository.'
553+ });
401554
402555 - name : Checkout PR branch
403- if : steps.check_perms.outputs.has_permission == 'true'
556+ if : steps.check_perms.outputs.has_permission == 'true' && steps.check_update.outputs.update_needed == 'true' && steps.validate_branch.outputs.branch_exists == 'true'
404557 uses : actions/checkout@v4
405558 with :
406- repository : ${{ steps.pr_info.outputs.head_repo }}
407559 ref : ${{ steps.pr_info.outputs.head_branch }}
408560 fetch-depth : 0
409561 token : ${{ secrets.GITHUB_TOKEN }}
410562
411563 - name : Update branch
412- if : steps.check_perms.outputs.has_permission == 'true'
564+ if : steps.check_perms.outputs.has_permission == 'true' && steps.check_update.outputs.update_needed == 'true' && steps.validate_branch.outputs.branch_exists == 'true'
413565 id : update
414566 run : |
415567 BASE_BRANCH="${{ steps.pr_info.outputs.base_branch }}"
416568 HEAD_BRANCH="${{ steps.pr_info.outputs.head_branch }}"
569+ COMMITS_BEHIND="${{ steps.check_update.outputs.commits_behind }}"
417570
418571 git config user.name "github-actions[bot]"
419572 git config user.email "github-actions[bot]@users.noreply.github.com"
@@ -424,7 +577,7 @@ jobs:
424577 echo "Merging origin/$BASE_BRANCH into $HEAD_BRANCH..."
425578 if git merge "origin/$BASE_BRANCH" -m "chore: Update branch with latest changes from $BASE_BRANCH"; then
426579 echo "merge_success=true" >> $GITHUB_OUTPUT
427- echo "✅ Branch updated successfully"
580+ echo "✅ Branch updated successfully ($COMMITS_BEHIND commits merged) "
428581 else
429582 echo "merge_success=false" >> $GITHUB_OUTPUT
430583 git merge --abort || true
@@ -446,12 +599,15 @@ jobs:
446599 script : |
447600 const user = context.payload.comment.user.login;
448601 const baseBranch = '${{ steps.pr_info.outputs.base_branch }}';
602+ const commitsBehind = '${{ steps.check_update.outputs.commits_behind }}';
449603
450604 await github.rest.issues.createComment({
451605 owner: context.repo.owner,
452606 repo: context.repo.repo,
453607 issue_number: context.payload.issue.number,
454- body: `✅ Branch updated successfully by @${user}!\n\nMerged latest changes from \`${baseBranch}\`.`
608+ body: `✅ Branch updated successfully by @${user}!
609+
610+ Merged ${commitsBehind} commit(s) from \`${baseBranch}\`.`
455611 });
456612
457613 // Add +1 reaction to original comment
@@ -473,7 +629,17 @@ jobs:
473629 owner: context.repo.owner,
474630 repo: context.repo.repo,
475631 issue_number: context.payload.issue.number,
476- body: `❌ Failed to update branch with latest changes from \`${baseBranch}\`.\n\nThis usually means there are merge conflicts that need to be resolved manually.\n\nPlease update your branch locally:\n\`\`\`bash\ngit fetch origin ${baseBranch}\ngit merge origin/${baseBranch}\n# Resolve conflicts\ngit push\n\`\`\``
632+ body: `❌ Failed to update branch with latest changes from \`${baseBranch}\`.
633+
634+ This usually means there are merge conflicts that need to be resolved manually.
635+
636+ Please update your branch locally :
637+ \`\`\`bash
638+ git fetch origin ${baseBranch}
639+ git merge origin/${baseBranch}
640+ # Resolve conflicts
641+ git push
642+ \`\`\``
477643 });
478644
479645 // Add -1 reaction to original comment
@@ -482,4 +648,4 @@ jobs:
482648 repo : context.repo.repo,
483649 comment_id : context.payload.comment.id,
484650 content : ' -1'
485- });
651+ });
0 commit comments