From ef599a2dc1d216cd6cb431207c47b7519fd37cc8 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Wed, 18 May 2022 12:38:27 +0900 Subject: [PATCH 01/10] ARROW-16602: [Dev] Use GitHub API to merge pull request We use local "git merge" to merge a pull request in dev/merge_arrow_pr.py. If we use "git merge" to merge a pull request, GitHub's Web UI shows "Closed" mark not "Merged" mark in a pull request page. This sometimes confuses new contributors. "Why was my pull request closed without merging?" See https://github.com/apache/arrow/pull/12004#issuecomment-1031619771 for example. If we use GitHub API https://docs.github.com/en/rest/pulls/pulls#merge-a-pull-request to merge a pull request, GitHub's Web UI shows "Merged" mark not "Closed" mark. See https://github.com/apache/arrow/pull/13180 for example. I used GitHub API to merge the pull request. And we don't need to create a local branch on local repository to merge a pull request. But we must specify ARROW_GITHUB_API_TOKEN to run dev/merge_arrow_pr.py. --- dev/merge_arrow_pr.py | 160 ++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 99 deletions(-) diff --git a/dev/merge_arrow_pr.py b/dev/merge_arrow_pr.py index 012a2ac6e7e..5ad49a25543 100755 --- a/dev/merge_arrow_pr.py +++ b/dev/merge_arrow_pr.py @@ -71,14 +71,12 @@ print("**************** DEBUGGING ****************") -# Prefix added to temporary branches -BRANCH_PREFIX = "PR_TOOL" JIRA_API_BASE = "https://issues.apache.org/jira" def get_json(url, headers=None): - req = requests.get(url, headers=headers) - return req.json() + response = requests.get(url, headers=headers) + return response.json() def run_cmd(cmd): @@ -101,21 +99,6 @@ def run_cmd(cmd): return output -original_head = run_cmd("git rev-parse HEAD")[:8] - - -def clean_up(): - print("Restoring head pointer to %s" % original_head) - run_cmd("git checkout %s" % original_head) - - branches = run_cmd("git branch").replace(" ", "").split("\n") - - for branch in [x for x in branches - if x.startswith(BRANCH_PREFIX)]: - print("Deleting local branch %s" % branch) - run_cmd("git branch -D %s" % branch) - - _REGEX_CI_DIRECTIVE = re.compile(r'\[[^\]]*\]') @@ -260,15 +243,35 @@ def __init__(self, project_name): .format(project_name)) token = os.environ.get('ARROW_GITHUB_API_TOKEN', None) + headers = { + 'Accept': 'application/vnd.github.v3+json', + } if token: - self.headers = {'Authorization': 'token {0}'.format(token)} - else: - self.headers = None + headers['Authorization'] = 'token {0}'.format(token) + self.headers = headers def get_pr_data(self, number): return get_json("%s/pulls/%s" % (self.github_api, number), headers=self.headers) + def get_pr_commits(self, number): + return get_json("%s/pulls/%s/commits" % (self.github_api, number), + headers=self.headers) + + def merge_pr(self, number, commit_title, commit_message): + payload = { + 'commit_title': commit_title, + 'commit_message': commit_message, + 'merge_method': 'squash', + } + response = requests.put(f'{self.github_api}/pulls/{number}/merge', + headers=self.headers, + json=payload) + result = response.json() + if response.status_code != 200 and not 'merged' in result: + result['merged'] = False + return result + class CommandInput(object): """ @@ -276,7 +279,6 @@ class CommandInput(object): """ def fail(self, msg): - clean_up() raise Exception(msg) def prompt(self, prompt): @@ -300,6 +302,7 @@ class PullRequest(object): def __init__(self, cmd, github_api, git_remote, jira_con, number): self.cmd = cmd + self._github_api = github_api self.git_remote = git_remote self.con = jira_con self.number = number @@ -358,35 +361,20 @@ def merge(self): """ merge the requested PR and return the merge hash """ - pr_branch_name = "%s_MERGE_PR_%s" % (BRANCH_PREFIX, self.number) - target_branch_name = "%s_MERGE_PR_%s_%s" % (BRANCH_PREFIX, - self.number, - self.target_ref.upper()) - run_cmd("git fetch %s pull/%s/head:%s" % (self.git_remote, - self.number, - pr_branch_name)) - run_cmd("git fetch %s %s:%s" % (self.git_remote, self.target_ref, - target_branch_name)) - run_cmd("git checkout %s" % target_branch_name) - - had_conflicts = False - try: - run_cmd(['git', 'merge', pr_branch_name, '--ff', '--squash']) - except Exception as e: - msg = ("Error merging: %s\nWould you like to " - "manually fix-up this merge?" % e) - self.cmd.continue_maybe(msg) - msg = ("Okay, please fix any conflicts and 'git add' " - "conflicting files... Finished?") - self.cmd.continue_maybe(msg) - had_conflicts = True - - commit_authors = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name, - '--pretty=format:%an <%ae>']).split("\n") - commit_co_authors = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name, - '--pretty=%(trailers:key=Co-authored-by,' - 'valueonly)']).split("\n") - commit_co_authors = list(filter(None, commit_co_authors)) + pr_commits = self._github_api.get_pr_commits(self.number) + def format_commit_author(commit): + author = commit['commit']['author'] + name = author['name'] + email = author['email'] + return f'{name} <{email}>' + commit_authors = [format_commit_author(commit) for commit in pr_commits] + co_authored_by_re = re.compile(r'^Co-authored-by:\s*(.*)') + def extract_co_authors(commit): + message = commit['commit']['message'] + return co_authored_by_re.findall(message) + commit_co_authors = [] + for commit in pr_commits: + commit_co_authors.extend(extract_co_authors(commit)) all_commit_authors = commit_authors + commit_co_authors distinct_authors = sorted(set(all_commit_authors), key=lambda x: commit_authors.count(x), @@ -402,11 +390,10 @@ def merge(self): # If there is only one author, do not prompt for a lead author primary_author = distinct_authors[0] - merge_message_flags = [] - - merge_message_flags += ["-m", self.title] + commit_title = f'{self.title} (#{self.number})' + commit_message_chunks = [] if self.body is not None: - merge_message_flags += ["-m", self.body] + commit_message_chunks.append(self.body) committer_name = run_cmd("git config --get user.name").strip() committer_email = run_cmd("git config --get user.email").strip() @@ -419,51 +406,28 @@ def merge(self): for a in distinct_authors]) authors += "\n" + "Signed-off-by: %s <%s>" % (committer_name, committer_email) + commit_message_chunks.append(authors) - if had_conflicts: - committer_name = run_cmd("git config --get user.name").strip() - committer_email = run_cmd("git config --get user.email").strip() - message = ("This patch had conflicts when merged, " - "resolved by\nCommitter: %s <%s>" % - (committer_name, committer_email)) - merge_message_flags += ["-m", message] - - # The string "Closes #%s" string is required for GitHub to correctly - # close the PR - merge_message_flags += [ - "-m", - "Closes #%s from %s" - % (self.number, self.description)] - merge_message_flags += ["-m", authors] + commit_message = "\n\n".join(commit_message_chunks) if DEBUG: - print("\n".join(merge_message_flags)) - - run_cmd(['git', 'commit', - '--no-verify', # do not run commit hooks - '--author="%s"' % primary_author] + - merge_message_flags) - - self.cmd.continue_maybe("Merge complete (local ref %s). Push to %s?" - % (target_branch_name, self.git_remote)) + print(commit_title) + print() + print(commit_message) - try: - push_cmd = ('git push %s %s:%s' % (self.git_remote, - target_branch_name, - self.target_ref)) - if DEBUG: - print(push_cmd) - else: - run_cmd(push_cmd) - except Exception as e: - clean_up() - self.cmd.fail("Exception while pushing: %s" % e) + if DEBUG: + merge_hash = None + else: + result = self._github_api.merge_pr(self.number, + commit_title, + commit_message) + if not result['merged']: + message = result['message'] + self.cmd.fail(f'Failed to merge pull request: {message}') + merge_hash = result['sha'] - merge_hash = run_cmd("git rev-parse %s" % target_branch_name)[:8] - clean_up() print("Pull request #%s merged!" % self.number) print("Merge hash: %s" % merge_hash) - return merge_hash def get_primary_author(cmd, distinct_authors): @@ -587,19 +551,17 @@ def cli(): pr = PullRequest(cmd, github_api, PR_REMOTE_NAME, jira_con, pr_num) if pr.is_merged: - print("Pull request %s has already been merged") + print("Pull request %s has already been merged" % pr_num) sys.exit(0) if not pr.is_mergeable: - msg = ("Pull request %s is not mergeable in its current form.\n" - % pr_num + "Continue? (experts only!)") - cmd.continue_maybe(msg) + print("Pull request %s is not mergeable in its current form" % pr_num) + sys.exit(1) pr.show() cmd.continue_maybe("Proceed with merging pull request #%s?" % pr_num) - # merged hash not used pr.merge() if pr.jira_issue is None: From 6b33f4bebb48219db4a4987d627f45d50a270844 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Wed, 18 May 2022 13:50:01 +0900 Subject: [PATCH 02/10] Fix lint problems --- dev/merge_arrow_pr.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/dev/merge_arrow_pr.py b/dev/merge_arrow_pr.py index 5ad49a25543..f7faf286282 100755 --- a/dev/merge_arrow_pr.py +++ b/dev/merge_arrow_pr.py @@ -268,7 +268,7 @@ def merge_pr(self, number, commit_title, commit_message): headers=self.headers, json=payload) result = response.json() - if response.status_code != 200 and not 'merged' in result: + if response.status_code != 200 and 'merged' not in result: result['merged'] = False return result @@ -361,20 +361,23 @@ def merge(self): """ merge the requested PR and return the merge hash """ - pr_commits = self._github_api.get_pr_commits(self.number) + commits = self._github_api.get_pr_commits(self.number) + def format_commit_author(commit): author = commit['commit']['author'] name = author['name'] email = author['email'] return f'{name} <{email}>' - commit_authors = [format_commit_author(commit) for commit in pr_commits] + commit_authors = [format_commit_author(commit) for commit in commits] co_authored_by_re = re.compile(r'^Co-authored-by:\s*(.*)') + def extract_co_authors(commit): message = commit['commit']['message'] return co_authored_by_re.findall(message) commit_co_authors = [] - for commit in pr_commits: + for commit in commits: commit_co_authors.extend(extract_co_authors(commit)) + all_commit_authors = commit_authors + commit_co_authors distinct_authors = sorted(set(all_commit_authors), key=lambda x: commit_authors.count(x), @@ -384,11 +387,12 @@ def extract_co_authors(commit): print("Author {}: {}".format(i + 1, author)) if len(distinct_authors) > 1: - primary_author, distinct_authors = get_primary_author( + primary_author, distinct_other_authors = get_primary_author( self.cmd, distinct_authors) else: # If there is only one author, do not prompt for a lead author - primary_author = distinct_authors[0] + primary_author = distinct_authors.pop() + distinct_other_authors = [] commit_title = f'{self.title} (#{self.number})' commit_message_chunks = [] @@ -398,12 +402,12 @@ def extract_co_authors(commit): committer_name = run_cmd("git config --get user.name").strip() committer_email = run_cmd("git config --get user.email").strip() - authors = ("Authored-by:" if len(distinct_authors) == 1 + authors = ("Authored-by:" if len(distinct_other_authors) == 0 else "Lead-authored-by:") - authors += " %s" % (distinct_authors.pop(0)) + authors += " %s" % primary_author if len(distinct_authors) > 0: authors += "\n" + "\n".join(["Co-authored-by: %s" % a - for a in distinct_authors]) + for a in distinct_other_authors]) authors += "\n" + "Signed-off-by: %s <%s>" % (committer_name, committer_email) commit_message_chunks.append(authors) @@ -447,10 +451,9 @@ def get_primary_author(cmd, distinct_authors): # When primary author is specified manually, de-dup it from # author list and put it at the head of author list. - distinct_authors = [x for x in distinct_authors - if x != primary_author] - distinct_authors = [primary_author] + distinct_authors - return primary_author, distinct_authors + distinct_other_authors = [x for x in distinct_authors + if x != primary_author] + return primary_author, distinct_other_authors def prompt_for_fix_version(cmd, jira_issue): From b1e60ba94349e05eb6e14c28a0a657fb22d33370 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Wed, 18 May 2022 14:22:36 +0900 Subject: [PATCH 03/10] Update expected --- dev/test_merge_arrow_pr.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) mode change 100644 => 100755 dev/test_merge_arrow_pr.py diff --git a/dev/test_merge_arrow_pr.py b/dev/test_merge_arrow_pr.py old mode 100644 new mode 100755 index 8fe18835082..9098cf0cc5c --- a/dev/test_merge_arrow_pr.py +++ b/dev/test_merge_arrow_pr.py @@ -208,25 +208,25 @@ def test_multiple_authors_bad_input(): a0 = 'Jimbob Crawfish ' a1 = 'Jarvis McCratchett ' a2 = 'Hank Miller ' - distinct_authors = [a0, a1] + distinct_other_authors = [a1] cmd = FakeCLI(responses=['']) - primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author( - cmd, distinct_authors) + primary_author, new_distinct_other_authors = \ + merge_arrow_pr.get_primary_author(cmd, distinct_authors) assert primary_author == a0 - assert new_distinct_authors == [a0, a1] + assert new_distinct_other_authors == [a1] cmd = FakeCLI(responses=['oops', a1]) - primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author( - cmd, distinct_authors) + primary_author, new_distinct_other_authors = \ + merge_arrow_pr.get_primary_author(cmd, distinct_authors) assert primary_author == a1 - assert new_distinct_authors == [a1, a0] + assert new_distinct_other_authors == [a0] cmd = FakeCLI(responses=[a2]) - primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author( - cmd, distinct_authors) + primary_author, new_other_distinct_authors = \ + merge_arrow_pr.get_primary_author(cmd, distinct_authors) assert primary_author == a2 - assert new_distinct_authors == [a2, a0, a1] + assert new_distinct_other_authors == [a0, a1] def test_jira_already_resolved(): From 5a3a87f97bf718bc49b030e19e60edec513ad234 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Wed, 18 May 2022 15:01:09 +0900 Subject: [PATCH 04/10] Fix variables --- dev/test_merge_arrow_pr.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dev/test_merge_arrow_pr.py b/dev/test_merge_arrow_pr.py index 9098cf0cc5c..407f687163e 100755 --- a/dev/test_merge_arrow_pr.py +++ b/dev/test_merge_arrow_pr.py @@ -208,25 +208,25 @@ def test_multiple_authors_bad_input(): a0 = 'Jimbob Crawfish ' a1 = 'Jarvis McCratchett ' a2 = 'Hank Miller ' - distinct_other_authors = [a1] + distinct_authors = [a0, a1] cmd = FakeCLI(responses=['']) - primary_author, new_distinct_other_authors = \ + primary_author, distinct_other_authors = \ merge_arrow_pr.get_primary_author(cmd, distinct_authors) assert primary_author == a0 - assert new_distinct_other_authors == [a1] + assert distinct_other_authors == [a1] cmd = FakeCLI(responses=['oops', a1]) - primary_author, new_distinct_other_authors = \ + primary_author, distinct_other_authors = \ merge_arrow_pr.get_primary_author(cmd, distinct_authors) assert primary_author == a1 - assert new_distinct_other_authors == [a0] + assert distinct_other_authors == [a0] cmd = FakeCLI(responses=[a2]) - primary_author, new_other_distinct_authors = \ + primary_author, other_distinct_authors = \ merge_arrow_pr.get_primary_author(cmd, distinct_authors) assert primary_author == a2 - assert new_distinct_other_authors == [a0, a1] + assert distinct_other_authors == [a0, a1] def test_jira_already_resolved(): From d53f305a805a44448545d0630f92602bf1792c99 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Wed, 18 May 2022 15:53:17 +0900 Subject: [PATCH 05/10] Fix tests --- dev/merge_arrow_pr.py | 2 +- dev/test_merge_arrow_pr.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/merge_arrow_pr.py b/dev/merge_arrow_pr.py index f7faf286282..a3baed8507e 100755 --- a/dev/merge_arrow_pr.py +++ b/dev/merge_arrow_pr.py @@ -443,7 +443,7 @@ def get_primary_author(cmd, distinct_authors): "\"name \" [%s]: " % distinct_authors[0]) if primary_author == "": - return distinct_authors[0], distinct_authors + return distinct_authors[0], distinct_authors[1:] if author_pat.match(primary_author): break diff --git a/dev/test_merge_arrow_pr.py b/dev/test_merge_arrow_pr.py index 407f687163e..54521528288 100755 --- a/dev/test_merge_arrow_pr.py +++ b/dev/test_merge_arrow_pr.py @@ -223,7 +223,7 @@ def test_multiple_authors_bad_input(): assert distinct_other_authors == [a0] cmd = FakeCLI(responses=[a2]) - primary_author, other_distinct_authors = \ + primary_author, distinct_other_authors = \ merge_arrow_pr.get_primary_author(cmd, distinct_authors) assert primary_author == a2 assert distinct_other_authors == [a0, a1] From 4d052381fa80480a174f2a81d5390173bac3a76d Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Sun, 22 May 2022 06:28:36 +0900 Subject: [PATCH 06/10] Update document and add support for conf and prompt --- dev/README.md | 6 +++--- dev/merge.conf.sample | 4 ++++ dev/merge_arrow_pr.py | 17 ++++++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/dev/README.md b/dev/README.md index d861944e1e9..f2689ced68f 100644 --- a/dev/README.md +++ b/dev/README.md @@ -53,9 +53,9 @@ After installed, it runs the merge script. have to install Python dependencies yourself and then run `dev/merge_arrow_pr.py` directly) -The merge script uses the GitHub REST API; if you encounter rate limit issues, -you may set a `ARROW_GITHUB_API_TOKEN` environment variable to use a Personal -Access Token. +The merge script uses the GitHub REST API. You must set a +`ARROW_GITHUB_API_TOKEN` environment variable to use a Personal Access +Token. You need only `public_repo` scope for the Personal Access Token. You can specify the username and the password of your JIRA account in `APACHE_JIRA_USERNAME` and `APACHE_JIRA_PASSWORD` environment variables. diff --git a/dev/merge.conf.sample b/dev/merge.conf.sample index c71b211614d..6ac332eb612 100644 --- a/dev/merge.conf.sample +++ b/dev/merge.conf.sample @@ -23,3 +23,7 @@ # token credentials. Ensure that the file is properly protected. username=johnsmith password=123456 + +[github] +# GitHub's personal access token. "public_repo" scope is only needed. +api_token=ghp_ABC diff --git a/dev/merge_arrow_pr.py b/dev/merge_arrow_pr.py index a3baed8507e..217c770769b 100755 --- a/dev/merge_arrow_pr.py +++ b/dev/merge_arrow_pr.py @@ -33,8 +33,7 @@ # Configuration environment variables: # - APACHE_JIRA_USERNAME: your Apache JIRA ID # - APACHE_JIRA_PASSWORD: your Apache JIRA password -# - ARROW_GITHUB_API_TOKEN: a GitHub API token to use for API requests (to -# avoid rate limiting) +# - ARROW_GITHUB_API_TOKEN: a GitHub API token to use for API requests # - PR_REMOTE_NAME: the name of the remote to the Apache git repo (set to # 'apache' by default) # - DEBUG: use for testing to avoid pushing to apache (0 by default) @@ -242,12 +241,20 @@ def __init__(self, project_name): self.github_api = ("https://api.github.com/repos/apache/{0}" .format(project_name)) - token = os.environ.get('ARROW_GITHUB_API_TOKEN', None) + token = None + config = load_configuration() + if "github" in config.sections(): + token = config["github"]["api_token"] + if not token: + token = os.environ.get('ARROW_GITHUB_API_TOKEN') + if not token: + token = cmd.prompt('Env ARROW_GITHUB_API_TOKEN not set, ' + 'please enter your GitHub API token ' + '(GitHub personal access token):') headers = { 'Accept': 'application/vnd.github.v3+json', + 'Authorization': 'token {0}'.format(token), } - if token: - headers['Authorization'] = 'token {0}'.format(token) self.headers = headers def get_pr_data(self, number): From d7984d855fd2f1368c695ea038ac207d78297973 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Sun, 22 May 2022 22:16:08 +0900 Subject: [PATCH 07/10] Pass cmd --- dev/merge_arrow_pr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/merge_arrow_pr.py b/dev/merge_arrow_pr.py index 217c770769b..b09ecf1b894 100755 --- a/dev/merge_arrow_pr.py +++ b/dev/merge_arrow_pr.py @@ -237,7 +237,7 @@ def format_jira_output(jira_id, status, summary, assignee, components): class GitHubAPI(object): - def __init__(self, project_name): + def __init__(self, project_name, cmd): self.github_api = ("https://api.github.com/repos/apache/{0}" .format(project_name)) @@ -555,7 +555,7 @@ def cli(): os.chdir(ARROW_HOME) - github_api = GitHubAPI(PROJECT_NAME) + github_api = GitHubAPI(PROJECT_NAME, cmd) jira_con = connect_jira(cmd) pr = PullRequest(cmd, github_api, PR_REMOTE_NAME, jira_con, pr_num) From 286d7bb3069e5dd067ce5f68ce1bfa5252ec82bd Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Thu, 26 May 2022 13:30:10 +0900 Subject: [PATCH 08/10] Show URL on error --- dev/merge_arrow_pr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/merge_arrow_pr.py b/dev/merge_arrow_pr.py index b09ecf1b894..117bdda5625 100755 --- a/dev/merge_arrow_pr.py +++ b/dev/merge_arrow_pr.py @@ -266,17 +266,17 @@ def get_pr_commits(self, number): headers=self.headers) def merge_pr(self, number, commit_title, commit_message): + url = f'{self.github_api}/pulls/{number}/merge' payload = { 'commit_title': commit_title, 'commit_message': commit_message, 'merge_method': 'squash', } - response = requests.put(f'{self.github_api}/pulls/{number}/merge', - headers=self.headers, - json=payload) + response = requests.put(url, headers=self.headers, json=payload) result = response.json() if response.status_code != 200 and 'merged' not in result: result['merged'] = False + result['message'] += f': {url}' return result From 397494f2609f28a3b7965a4b3743a088fe372e8e Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Fri, 27 May 2022 14:47:24 +0900 Subject: [PATCH 09/10] Need workflow scope --- dev/README.md | 2 +- dev/merge.conf.sample | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/README.md b/dev/README.md index f2689ced68f..267bf008ac8 100644 --- a/dev/README.md +++ b/dev/README.md @@ -55,7 +55,7 @@ directly) The merge script uses the GitHub REST API. You must set a `ARROW_GITHUB_API_TOKEN` environment variable to use a Personal Access -Token. You need only `public_repo` scope for the Personal Access Token. +Token. You need to add `workflow` scope to the Personal Access Token. You can specify the username and the password of your JIRA account in `APACHE_JIRA_USERNAME` and `APACHE_JIRA_PASSWORD` environment variables. diff --git a/dev/merge.conf.sample b/dev/merge.conf.sample index 6ac332eb612..9c0aa414855 100644 --- a/dev/merge.conf.sample +++ b/dev/merge.conf.sample @@ -25,5 +25,5 @@ username=johnsmith password=123456 [github] -# GitHub's personal access token. "public_repo" scope is only needed. +# GitHub's personal access token. "workflow" scope is needed. api_token=ghp_ABC From 5ca3b616b6c0412c71ef99c5491845791cf16a63 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Fri, 27 May 2022 14:58:25 +0900 Subject: [PATCH 10/10] Use --group=trailer:signed-off-by instead of -c --- dev/release/post-04-website.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/release/post-04-website.sh b/dev/release/post-04-website.sh index d8a9df42493..0f41a97e664 100755 --- a/dev/release/post-04-website.sh +++ b/dev/release/post-04-website.sh @@ -67,7 +67,7 @@ rough_n_development_months=$(( git_tag=apache-arrow-${version} git_range=apache-arrow-${previous_version}..${git_tag} -committers_command_line="git shortlog -csn ${git_range}" +committers_command_line="git shortlog -sn --group=trailer:signed-off-by ${git_range}" contributors_command_line="git shortlog -sn ${git_range}" committers=$(${committers_command_line})