forked from Netflix/dispatch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub_utils.py
More file actions
executable file
·147 lines (113 loc) · 3.99 KB
/
github_utils.py
File metadata and controls
executable file
·147 lines (113 loc) · 3.99 KB
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
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python
"""
Utility Python script to automate GitHub-related actions.
Instructions on how to install gh can be found here: https://github.com/cli/cli#installation
"""
import click
import json
import subprocess
from time import sleep
from typing import NoReturn
@click.group()
def cli():
pass
def run_command(command: str) -> str:
"""Utility function to run commands."""
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
output, _ = process.communicate()
return output.decode("utf-8")
@cli.command()
@click.option(
"--label",
"-l",
required=True,
type=str,
help="Label used for filtering pull requests.",
)
def bulk_merge(label: str) -> NoReturn:
"""Utility function to assist with bulk merging pull requests."""
gh_pr_list_command = f"gh pr list -s open -l {label} --json title,number"
gh_pr_bulk_merge_command = "gh pr merge -s -d --admin"
click.echo(f"Fetching open PRs with {label} label...")
pull_requests = json.loads(run_command(gh_pr_list_command))
if not pull_requests:
click.echo(f"No open PRs with {label} label found.")
return
for pull_request in pull_requests:
number = pull_request["number"]
title = pull_request["title"]
click.echo(f"Merging PR #{number} {title}...")
run_command(f"{gh_pr_bulk_merge_command} {number}")
sleep(
5
) # NOTE: Needed to avoid error "Base branch was modified. Review and try the merge again"
click.echo(f"Open PRs with {label} label merged.")
def is_excluded_label(label: str, exclude_labels: list) -> bool:
"""Checks if label is in the excluded labels list."""
return label["name"] in exclude_labels
def is_excluded_author(pull_request: dict, exclude_bot_authors: bool) -> bool:
"""Checks if author is a bot."""
return exclude_bot_authors and pull_request["author"]["is_bot"]
def update_section(
pull_request: dict, sections: dict, label_name: str, dispatch_pr_url: str
) -> NoReturn:
"""Updates release notes section."""
title = pull_request["title"]
number = pull_request["number"]
author = pull_request["author"]["login"]
sections[label_name] += f"\n* {title} ([#{number}]({dispatch_pr_url}{number})) by @{author}"
@cli.command()
@click.option(
"--pull-request-number",
"-n",
required=True,
type=int,
help="Pull request number from where to generate draft release notes.",
)
def release_notes(pull_request_number: int) -> NoReturn:
"""Utility function to assist with generating release notes."""
dispatch_pr_url = "https://github.com/Netflix/dispatch/pull/"
exclude_bot_authors = True
exclude_labels = ["skip-changelog", "UI/UX", "javascript"]
gh_pr_list_merged_command = 'gh pr list -s merged --json "title,author,number,labels" -L 250'
sections = {
"bug": "",
"dependencies": "",
"documentation": "",
"enhancement": "",
"feature": "",
"techdebt": "",
"tests": "",
}
click.echo(f"Fetching list of merged PRs since #{pull_request_number}...")
pull_requests = json.loads(run_command(gh_pr_list_merged_command))
if not pull_requests:
click.echo(f"No PRs merged since #{pull_request_number}.")
for pull_request in pull_requests:
number = pull_request["number"]
if number < pull_request_number:
break
if is_excluded_author(pull_request, exclude_bot_authors):
continue
for label in pull_request["labels"]:
if is_excluded_label(label, exclude_labels):
continue
update_section(pull_request, sections, label["name"], dispatch_pr_url)
print(
f"""
Features:
{sections["feature"]}
Enhancements:
{sections["enhancement"]}
Bug Fixes:
{sections["bug"]}
Tech Debt:
{sections["techdebt"]}
Tests:
{sections["tests"]}
Documentation:
{sections["documentation"]}
"""
)
if __name__ == "__main__":
cli()