-
-
Notifications
You must be signed in to change notification settings - Fork 345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pull request merge script #3263
Conversation
There's a Also do you think it would be possible to change the script so that no local branch is required? I'm often working with a detached HEAD and don't have a local copy of the PR branch, only if I need to test something bigger or I'm planning to commit/propose any changes. |
ce2798e
to
be51b0d
Compare
Sure, no harm in doing so. I also took a closer look at the other files in
The problem I had with this was in translating the reference name we get from GitHub into a remote name that |
... we might be able to compare |
I got it working by changing a bunch of the --- bin/ckan-merge-pr.py 2021-01-16 22:17:11.754527492 +0100
+++ bin/ckan-merge-pr-changed.py 2021-01-16 22:18:27.323449811 +0100
@@ -32,26 +32,11 @@
if r.head.commit.hexsha != remote_master.commit.hexsha:
print(f'master branch is not up to date!')
sys.exit(ExitStatus.failure)
- # Make sure PR's branch exists
- local_branch = pr.head.ref
- branch = r.heads[local_branch]
+ pr_head_sha = pr.head.sha
# Fetch remote to make sure we aren't missing changes
- tracking = branch.tracking_branch()
- if not tracking:
- print(f'Upstream {pr.head.label} missing!')
- sys.exit(ExitStatus.failure)
- remote = r.remotes[tracking.remote_name]
- if remote.name != master_remote.name:
- print(f'Fetching {remote.name}...')
- remote.fetch()
- # Make sure branch is identical to its upstream
- if branch.commit.hexsha != pr.head.sha:
- print(f'Branch {local_branch} not up to date!')
- # Bail and let the user figure it out, no way we can safely cover all possibilities here
- sys.exit(ExitStatus.failure)
# Get reviewers from PR
reviewers = [rvw.user.login for rvw in pr.get_reviews() if rvw.state == 'APPROVED']
- if not reviewers:
+ if False and not reviewers:
print(f'PR #{pr_num} is not approved!')
sys.exit(ExitStatus.failure)
# Get title from PR
@@ -59,8 +44,8 @@
# Get author from PR
author = pr.user.login
# Merge the branch with no-commit and no-ff
- base = r.merge_base(branch, r.head)
- r.index.merge_tree(branch, base=base)
+ base = r.merge_base(pr_head_sha, r.head)
+ r.index.merge_tree(pr_head_sha, base=base)
# Update the working copy
r.index.checkout(force=True)
# Print line to add to CHANGELOG.md at top of file, user needs to move it to the right spot
@@ -77,7 +62,7 @@
r.index.add([changelog_path.as_posix()])
# Commit
r.index.commit(f'Merge #{pr_num} {pr_title}',
- parent_commits=(r.head.commit, branch.commit))
+ parent_commits=(r.head.commit, r.commit(pr_head_sha)))
# Don't push, let the user inspect and decide
sys.exit(ExitStatus.success) |
But your |
Yeah, just realized that I'm missing some fetching there.
Maybe we can still do some auto-fetch though... |
Yeah looks like we might be able to fetch the clone_url without even assigning it a remote name, that should get the sha where it needs to be... |
How about something like this? diff --git a/bin/ckan-merge-pr.py b/bin/ckan-merge-pr.py
index 56c55b8c..8be0f753 100755
--- a/bin/ckan-merge-pr.py
+++ b/bin/ckan-merge-pr.py
@@ -32,23 +32,6 @@ def merge_pr(repo_path: str, token: str, pr_num: int) -> None:
if r.head.commit.hexsha != remote_master.commit.hexsha:
print(f'master branch is not up to date!')
sys.exit(ExitStatus.failure)
- # Make sure PR's branch exists
- local_branch = pr.head.ref
- branch = r.heads[local_branch]
- # Fetch remote to make sure we aren't missing changes
- tracking = branch.tracking_branch()
- if not tracking:
- print(f'Upstream {pr.head.label} missing!')
- sys.exit(ExitStatus.failure)
- remote = r.remotes[tracking.remote_name]
- if remote.name != master_remote.name:
- print(f'Fetching {remote.name}...')
- remote.fetch()
- # Make sure branch is identical to its upstream
- if branch.commit.hexsha != pr.head.sha:
- print(f'Branch {local_branch} not up to date!')
- # Bail and let the user figure it out, no way we can safely cover all possibilities here
- sys.exit(ExitStatus.failure)
# Get reviewers from PR
reviewers = [rvw.user.login for rvw in pr.get_reviews() if rvw.state == 'APPROVED']
if not reviewers:
@@ -58,6 +41,13 @@ def merge_pr(repo_path: str, token: str, pr_num: int) -> None:
pr_title = pr.title
# Get author from PR
author = pr.user.login
+ # Make sure we have the commit
+ r.git.fetch(pr.head.repo.clone_url)
+ # Get the commit
+ branch = r.commit(pr.head.sha)
+ if not branch:
+ print(f'PR #{pr_num} commit {pr.head.sha} not found!')
+ sys.exit(ExitStatus.failure)
# Merge the branch with no-commit and no-ff
base = r.merge_base(branch, r.head)
r.index.merge_tree(branch, base=base) |
be51b0d
to
b1d99eb
Compare
Pushed those changes. I do agree that eliminating the local branch is a nice advantage. |
I was looking for a way to use GitHub's neat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One embarrassingly short SLS green run test later: Looks good, useful tooling. I'll give it a real-world try on this PR.
48da7d4
to
0d2bde3
Compare
Did force-push a quick fix for this:
and apparently a rebase on master. |
Looks like it worked flawlessly! |
For some reason it didn't remove the deleted file from the working tree after the commit. Not sure what caused this and if it's a a fault of the script or something I did to my clone or whatever. |
What does |
German again, but yeah, it's the list of unstaged "new" files in the working dir. |
Motivation
CKAN's process for merging pull requests has some very specific rules about how things should be formatted:
Doing it manually requires a lot of fiddly copying and pasting and editing to reorder things, add parentheses, etc. This may sometimes discourage team members from attempting this flow.
Changes
Now a new
bin/ckan-merge-pr.py
script is created to automate the steps from the wiki, using the pull request data from the GitHub API to generate the descriptive strings. The script assumes you're running it from your CKAN working folder. The one required paramer is the number of the PR to merge, and theGITHUB_TOKEN
environment variable can be set to avoid rate limiting errors:The script does not attempt to set up everything as it should be, since chaos sometimes reigns in developer working copies, and you don't want robots guessing and messing with that; rather it is assumed that the user will get the repo into a usable state before running. Validation performed:
If everything looks OK, the PR's branch will be merged into master, and an entry will be added to the changelog file. The script does not attempt to set the
[Core]
/[GUI]
/etc. tag or guess whether it's a feature or a bug fix, so the user's git-configured editor will be launched to edit the changelog and perform this remaining manual work of setting the tag and moving the entry to the correct section. After the user saves and exits the editor, the changelog will be staged and a merge commit will be created with the appropriate commit message. The script does not perform the final push, so the user can take a look at the commit history and make sure everything is OK.Also the other Python scripts in
bin
that have a shebang are now executable.