forked from slaclab/rogue
-
Notifications
You must be signed in to change notification settings - Fork 0
/
releaseNotes.py
executable file
·147 lines (117 loc) · 4.59 KB
/
releaseNotes.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
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python3
#-----------------------------------------------------------------------------
# Title : Release notes generation
# ----------------------------------------------------------------------------
# File : releaseNotes.py
# Created : 2018-03-12
# ----------------------------------------------------------------------------
# Description:
# Generate release notes for pull requests relative to a tag.
# Usage: releaseNotes.py tag (i.e. releaseNotes.py v2.5.0
#
# Must be run within an up to date git clone with the proper branch checked out.
# Currently github complains if you run this script too many times in a short
# period of time. I am still looking at ssh key support for PyGithub
#
# Release steps:
# - Merge pre-release into master
# > git fetch
# > git co master
# > git merge origin/master
# > git merge origin/pre-release
# > git push
# - Tag the release in master:
# > git tag -a vMAJOR.MINOR.0
# > git push --tags
# - Create release using tag on github.com, use this script to generate notes
# ----------------------------------------------------------------------------
# This file is part of the rogue software platform. It is subject to
# the license terms in the LICENSE.txt file found in the top-level directory
# of this distribution and at:
# https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
# No part of the rogue software platform, including this file, may be
# copied, modified, propagated, or distributed except according to the terms
# contained in the LICENSE.txt file.
# ----------------------------------------------------------------------------
import os,sys
import git # GitPython
from github import Github # PyGithub
import re
import argparse
import pyperclip
from getpass import getpass
parser = argparse.ArgumentParser('Release notes generator')
parser.add_argument('tag', type=str, help='reference tag or range. (i.e. v2.5.0 or v2.5.0..v2.6.0)')
parser.add_argument('--user', type=str, help='Username for github, password will be prompted')
parser.add_argument('--nosort', help='Disable sort by change counts', action="store_true")
parser.add_argument('--copy', help='Copy to clipboard', action="store_true")
args = parser.parse_args()
if '..' in args.tag:
tags = args.tag
else:
tags = F"{args.tag}..HEAD"
print(f"Using range: {tags}")
# Local git clone
g = git.Git('.')
g.fetch()
project = re.compile(r'slaclab/(?P<name>.*?).git').search(g.remote('get-url','origin')).group('name')
user = args.user
password = None
if user is not None:
password = getpass("Password for github: ")
# Git server
gh = Github(user,password)
repo = gh.get_repo(f'slaclab/{project}')
loginfo = g.log(tags,'--grep','Merge pull request')
records = []
entry = {}
#print("# Pull Requests")
# Parse the log entries
for line in loginfo.splitlines():
if line.startswith('Author:'):
entry['Author'] = line[7:].lstrip()
elif line.startswith('Date:'):
entry['Date'] = line[5:].lstrip()
elif 'Merge pull request' in line:
entry['PR'] = line.split()[3].lstrip()
entry['Branch'] = line.split()[5].lstrip()
# Get PR info from github
#print(f"{entry['Pull']}")
req = repo.get_pull(int(entry['PR'][1:]))
entry['Title'] = req.title
entry['body'] = req.body
entry['changes'] = req.additions + req.deletions
entry['Pull'] = entry['PR'] + f" ({req.additions} additions, {req.deletions} deletions, {req.changed_files} files changed)"
# Detect JIRA entry
if entry['Branch'].startswith('slaclab/ES'):
url = 'https://jira.slac.stanford.edu/issues/{}'.format(entry['Branch'].split('/')[1])
entry['Jira'] = url
else:
entry['Jira'] = None
records.append(entry)
entry = {}
if args.nosort is False:
records = sorted(records, key=lambda v : v['changes'], reverse=True)
# Generate text
md = '# Pull Requests\n'
for i, entry in enumerate(records):
md += f" 1. {entry['PR']} - {entry['Title']}\n"
md += '## Pull Request Details\n'
for entry in records:
md += f"### {entry['Title']}"
md += '\n|||\n|---:|:---|\n'
for i in ['Author','Date','Pull','Branch','Jira']:
if entry[i] is not None:
md += f'|**{i}:**|{entry[i]}|\n'
md += '\n**Notes:**\n'
for line in entry['body'].splitlines():
md += '> ' + line + '\n'
md += '\n-------\n'
md += '\n\n'
print(md)
if args.copy:
try:
pyperclip.copy(md)
print('Release notes copied to clipboard')
except:
print("Copy to clipboard failed!")