Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 38 additions & 23 deletions .github/workflows/merge-main-into-prs.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# Ultralytics YOLOv5 πŸš€, AGPL-3.0 license
# Ultralytics YOLO πŸš€, AGPL-3.0 license
# Automatically merges repository 'main' branch into all open PRs to keep them up-to-date
# Action runs on updates to main branch so when one PR merges to main all others update

name: Merge main into PRs

on:
workflow_dispatch:
push:
branches:
- main
- master
# push:
# branches:
# - ${{ github.event.repository.default_branch }}

jobs:
Merge:
Expand All @@ -22,35 +21,51 @@ jobs:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip" # caching pip dependencies
python-version: "3.x"
cache: "pip"
- name: Install requirements
run: |
pip install pygithub
- name: Merge main into PRs
- name: Merge default branch into PRs
shell: python
run: |
from github import Github
import os

# Authenticate with the GitHub Token
g = Github(os.getenv('GITHUB_TOKEN'))

# Get the repository dynamically
repo = g.get_repo(os.getenv('GITHUB_REPOSITORY'))

# List all open pull requests
open_pulls = repo.get_pulls(state='open', sort='created')

for pr in open_pulls:
# Compare PR head with main to see if it's behind
# Fetch the default branch name
default_branch_name = repo.default_branch
default_branch = repo.get_branch(default_branch_name)

for pr in repo.get_pulls(state='open', sort='created'):
try:
# Merge main into the PR branch
success = pr.update_branch()
assert success, "Branch update failed"
print(f"Merged 'master' into PR #{pr.number} ({pr.head.ref}) successfully.")
# Get full names for repositories and branches
base_repo_name = repo.full_name
head_repo_name = pr.head.repo.full_name
base_branch_name = pr.base.ref
head_branch_name = pr.head.ref

# Check if PR is behind the default branch
comparison = repo.compare(default_branch.commit.sha, pr.head.sha)

if comparison.behind_by > 0:
print(f"⚠️ PR #{pr.number} ({head_repo_name}:{head_branch_name} -> {base_repo_name}:{base_branch_name}) is behind {default_branch_name} by {comparison.behind_by} commit(s).")

# Attempt to update the branch
try:
success = pr.update_branch()
assert success, "Branch update failed"
print(f"βœ… Successfully merged '{default_branch_name}' into PR #{pr.number} ({head_repo_name}:{head_branch_name} -> {base_repo_name}:{base_branch_name}).")
except Exception as update_error:
print(f"❌ Could not update PR #{pr.number} ({head_repo_name}:{head_branch_name} -> {base_repo_name}:{base_branch_name}): {update_error}")
print(" This might be due to branch protection rules or insufficient permissions.")
else:
print(f"βœ… PR #{pr.number} ({head_repo_name}:{head_branch_name} -> {base_repo_name}:{base_branch_name}) is up to date with {default_branch_name}.")
except Exception as e:
print(f"Could not merge 'master' into PR #{pr.number} ({pr.head.ref}): {e}")
print(f"❌ Could not process PR #{pr.number}: {e}")

env:
GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}