-
Notifications
You must be signed in to change notification settings - Fork 3
/
check_changelog.py
105 lines (82 loc) · 3.39 KB
/
check_changelog.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
import json
import os
import sys
from github import Github
from core import loads
event_name = os.environ['GITHUB_EVENT_NAME']
if event_name not in ('pull_request_target', 'pull_request'):
print(f'No-op for {event_name}')
sys.exit(0)
event_jsonfile = os.environ['GITHUB_EVENT_PATH']
with open(event_jsonfile, encoding='utf-8') as fin:
event = json.load(fin)
pr_labels = [e['name'] for e in event['pull_request']['labels']]
if 'skip-changelog-checks' in pr_labels:
print('Changelog checks manually disabled for this pull request.')
sys.exit(0) # Green but no-op
# Skip check if it is the backport bot
pr_author = event['pull_request']['user']['login']
if pr_author in ('meeseeksmachine', 'pre-commit-ci[bot]'):
print(f'Skipping changelog check for bot "{pr_author}"')
sys.exit(0)
forkrepo = event['pull_request']['head']['repo']['full_name']
pr_branch = os.environ['GITHUB_HEAD_REF']
g = Github(os.environ.get('GITHUB_TOKEN'))
clog_file = os.environ.get('CHANGELOG_FILENAME', 'CHANGES.rst')
repo = g.get_repo(forkrepo)
try:
contents = repo.get_contents(clog_file, ref=pr_branch)
except Exception:
print('This repository does not appear to have a change log! '
f'(Expecting a file named {clog_file})')
sys.exit(1)
# Parse changelog
changelog = loads(contents.decoded_content.decode('utf-8'))
# Find versions for the pull request we are looking at
pr_num = event['number']
versions = changelog.versions_for_issue(pr_num)
if len(versions) > 1:
print('Change log entry present in multiple version sections '
f'({", ".join(versions)}).')
sys.exit(1)
if len(versions) == 1:
version = versions[0]
if 'no-changelog-entry-needed' in pr_labels:
print(f'Changelog entry present in {version} but '
'**no-changelog-entry-needed** label set.')
sys.exit(1)
if 'Affects-dev' in pr_labels:
print(f'Changelog entry present in {version} but '
'**Affects-dev** label set.')
sys.exit(1)
base_repo = event['pull_request']['base']['repo']['full_name']
repo = g.get_repo(base_repo)
pr = repo.get_pull(pr_num)
check_milestone = os.environ.get('CHECK_MILESTONE', 'true').lower()
if check_milestone == 'true':
if not pr.milestone:
print(f'Cannot check for consistency of change log in {version} since '
'milestone is not set.')
sys.exit(1)
milestone = pr.milestone.title
if milestone.startswith('v'):
milestone = milestone[1:]
if version.startswith('v'):
version = version[1:]
if milestone != version:
print(f'Changelog entry section ({version}) '
f'inconsistent with milestone ({milestone}).')
sys.exit(1)
print(f'Changelog entry consistent with milestone ({milestone}).')
else: # No change log found
if 'Affects-dev' in pr_labels:
print('Changelog entry not present, as expected since the '
'**Affects-dev** label is present.')
elif 'no-changelog-entry-needed' in pr_labels:
print('Changelog entry not present, as expected since the '
'**no-changelog-entry-needed** label is present')
else:
print('Changelog entry not present, (or PR number missing) and '
'neither the **Affects-dev** nor the '
'**no-changelog-entry-needed** label is set.')
sys.exit(1)