Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

merge-main-into-prs.yml 3.7 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  1. # Ultralytics YOLO 🚀, AGPL-3.0 license
  2. # Automatically merges repository 'main' branch into all open PRs to keep them up-to-date
  3. # Action runs on updates to main branch so when one PR merges to main all others update
  4. name: Merge main into PRs
  5. on:
  6. workflow_dispatch:
  7. # push:
  8. # branches:
  9. # - ${{ github.event.repository.default_branch }}
  10. jobs:
  11. Merge:
  12. if: github.repository == 'ultralytics/ultralytics'
  13. runs-on: ubuntu-latest
  14. steps:
  15. - name: Checkout repository
  16. uses: actions/checkout@v4
  17. with:
  18. fetch-depth: 0
  19. - uses: actions/setup-python@v5
  20. with:
  21. python-version: "3.x"
  22. cache: "pip"
  23. - name: Install requirements
  24. run: |
  25. pip install pygithub
  26. - name: Merge default branch into PRs
  27. shell: python
  28. run: |
  29. from github import Github
  30. import os
  31. import time
  32. g = Github("${{ secrets.PERSONAL_ACCESS_TOKEN }}")
  33. repo = g.get_repo("${{ github.repository }}")
  34. # Fetch the default branch name
  35. default_branch_name = repo.default_branch
  36. default_branch = repo.get_branch(default_branch_name)
  37. # Initialize counters
  38. updated_branches = 0
  39. up_to_date_branches = 0
  40. errors = 0
  41. for pr in repo.get_pulls(state='open', sort='created'):
  42. try:
  43. # Label PRs as popular for positive reactions
  44. reactions = pr.as_issue().get_reactions()
  45. if sum([(1 if r.content not in {"-1", "confused"} else 0) for r in reactions]) > 5:
  46. pr.set_labels(*("popular",) + tuple(l.name for l in pr.get_labels()))
  47. # Get full names for repositories and branches
  48. base_repo_name = repo.full_name
  49. head_repo_name = pr.head.repo.full_name
  50. base_branch_name = pr.base.ref
  51. head_branch_name = pr.head.ref
  52. # Check if PR is behind the default branch
  53. comparison = repo.compare(default_branch.commit.sha, pr.head.sha)
  54. if comparison.behind_by > 0:
  55. 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).")
  56. # Attempt to update the branch
  57. try:
  58. success = pr.update_branch()
  59. assert success, "Branch update failed"
  60. print(f"✅ Successfully merged '{default_branch_name}' into PR #{pr.number} ({head_repo_name}:{head_branch_name} -> {base_repo_name}:{base_branch_name}).")
  61. updated_branches += 1
  62. time.sleep(10) # rate limit merges
  63. except Exception as update_error:
  64. print(f"❌ Could not update PR #{pr.number} ({head_repo_name}:{head_branch_name} -> {base_repo_name}:{base_branch_name}): {update_error}")
  65. errors += 1
  66. else:
  67. print(f"✅ PR #{pr.number} ({head_repo_name}:{head_branch_name} -> {base_repo_name}:{base_branch_name}) is already up to date with {default_branch_name}, no merge required.")
  68. up_to_date_branches += 1
  69. except Exception as e:
  70. print(f"❌ Could not process PR #{pr.number}: {e}")
  71. errors += 1
  72. # Print summary
  73. print("\n\nSummary:")
  74. print(f"Branches updated: {updated_branches}")
  75. print(f"Branches already up-to-date: {up_to_date_branches}")
  76. print(f"Total errors: {errors}")
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...