-
Notifications
You must be signed in to change notification settings - Fork 0
/
replace_string_existing_branch.py
136 lines (114 loc) · 5.3 KB
/
replace_string_existing_branch.py
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python3
"""
Usage:
python -m replace_string_existing_branch.py
Requires:
GITHUB_AUTH token in local environment
Description:
Assumes you've run `replace_string_with_another`, thus repos already have
your working branch defined, and you don't want to open a new set of PRs.
Checks out existing branch (or re-creates if existing was already merged)
and performs another string swap with the new strings, and makes a new
commit.
Note:
`swap_strings` (in shell_helpers.py) has hardcoded shell commands that are
wonky due to OSX. If you're not on OSX you should examine and change them.
"""
## Steps
# 1. check if strings exist on default_branch
# 2. if so try to check out branch; if that fails, create a new branch.
# 3. script as defined??
import datetime
import logging
import subprocess
import sys
import time
from github_helpers import *
from shell_helpers import *
# Switch to DEBUG for additional debugging info
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
LOG = logging.getLogger(__name__)
def main(org, root_dir, old_string, new_string, exclude_private=False, interactive=False):
"""
Goes through all repos in an org, clones them (or switches to the default
branch and then pulls latest changes), searches for the specified string, if
found makes a new branch, switches the string with the new string, creates a
pull request.
* org (str): GitHub organization
* root_dir (str): path to directory to clone repos (on Mac, may look like
`/Users/<uname>/path/to/dir`
* old_string: what string we're looking to see if each repo has
* new_string: if old_string is found, what we should replace it with
* exclude_private (bool): if True, script skips private repos (default
False)
* interactive (bool): if True, pauses before committing files upstream and
awaits user confirmation
"""
gh_headers = get_github_headers()
branch_name = "tcril/fix-gh-org-url"
commit_msg = "fix: update path to .github workflows to read from openedx org"
pr_details = {
"title": "Fix github url strings in .github workflows",
"body": "## This PR was autogenerated\n\nThis pr replaces the old GitHub organization, github.com/edx, with the new GitHub organization, github.com/openedx, in .github/workflow files.\n\nLooking for people to provide review.\n\nRef: https://github.com/openedx/tcril-engineering/issues/42"
}
count_commits = 0
count_prs = 0
count_skipped = 0
ts = str(datetime.datetime.now())[:19]
filename = f"output/replace_existing_branch_{ts}.json"
with open(filename, "w") as f:
for repo_data in get_repos(gh_headers, org, exclude_private):
(rname, ssh_url, dbranch, _, count) = repo_data
LOG.info("\n\n******* CHECKING REPO: {} ({}) ************".format(rname, count))
if rname == "cs_comments_service":
LOG.info(" skipping (was test repo)")
continue
repo_path = get_repo_path(rname, root_dir)
# clone repo; if exists, checkout the default branch & pull latest
clone_repo(root_dir, repo_path, ssh_url, dbranch)
# Search for the string; fail fast if none exist
if not found(old_string, repo_path):
LOG.info("Did not find string {}".format(old_string))
count_skipped += 1
f.write(f"NO STRING: {rname}\n")
continue
# Checkout the already-existing branch_name
branch_created = False
if not checkout_branch(repo_path, branch_name):
# this branch was never created, or already merged, so
# create it for the new commit
new_branch(repo_path, branch_name)
branch_created = True
# Swap old string for new string
swap_strings(old_string, new_string, repo_path)
if interactive:
try:
interactive_commit(repo_path)
except RepoError:
# move on to next repo
continue
make_commit(repo_path, commit_msg)
if branch_created:
try:
LOG.info(f" Making a pull request")
pr_url = make_pr(gh_headers, org, rname, branch_name, dbranch, pr_details)
f.write(f"CREATED PR: {pr_url}\n")
count_prs += 1
except PrCreationError as pr_err:
LOG.info(pr_err.__str__())
# info you need to retry
f.write(f"FAILED TO MAKE PR: {org}, {rname}, {branch_name}, {dbranch}, {pr_details}\n")
else:
LOG.info(f" committed to existing branch")
f.write(f"CREATED COMMIT: {rname}\n")
count_commits += 1
time.sleep(5)
LOG.info(
f"Processed {count} repos; {count_prs} PRs successfully made and {count_commits} commits created on existing branches"
)
LOG.info(f"Skipped {count_skipped} repos as string didn't exist")
if __name__ == "__main__":
root_dir = "/Users/sarinacanelake/openedx/"
old_string = "uses: edx/.github"
new_string = "uses: openedx/.github"
main("openedx", root_dir, old_string, new_string, exclude_private=False, interactive=False)