add release note chnage log generation
Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
This commit is contained in:
parent
5189d8b14c
commit
9c6b83501f
135
release.py
135
release.py
@ -1,22 +1,48 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from argparse import ArgumentParser, Namespace
|
from argparse import ArgumentParser, Namespace
|
||||||
from datetime import datetime
|
from collections import OrderedDict
|
||||||
from os import path
|
|
||||||
from configparser import RawConfigParser
|
from configparser import RawConfigParser
|
||||||
|
from datetime import datetime
|
||||||
|
from json import dumps
|
||||||
|
from os import path
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
from jinja2 import Environment, BaseLoader
|
||||||
|
from requests import patch
|
||||||
|
|
||||||
GIT_COMMANDS = {
|
GIT_COMMANDS = {
|
||||||
"get_tag": ["git describe --tags --abbrev=0"],
|
"get_tag": ["git describe --tags --abbrev=0"],
|
||||||
"create_new_branch": ["git checkout -b {new_version} master"],
|
"commit_version_change": [
|
||||||
"commit_version_change": ["git commit -m 'Bumping up version from {current_version} to {new_version}'"],
|
"git add . && git commit -m 'Bumping up version from {current_version} to {new_version}'"],
|
||||||
"push_new_branch": ["git push origin {new_version}"],
|
|
||||||
"create_new_tag": ["git tag -a {new_version} -m 'Bumping up version from {current_version} to {new_version}'"],
|
"create_new_tag": ["git tag -a {new_version} -m 'Bumping up version from {current_version} to {new_version}'"],
|
||||||
"push_tag": ["git push origin {new_version}"],
|
"push_tag": ["git push origin {new_version}"],
|
||||||
"get_change_log": ['git log --no-merges --pretty=format:"%h: %cn: %s" {current_version}..']
|
"get_change_log": ['git log --no-merges --pretty=format:"%h::: %cn::: %s" {current_version}..']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELASE_NOTE_TEMPLATE = """
|
||||||
|
# {{ release_name }} - {% now 'utc', '%Y-%m-%d' %}
|
||||||
|
|
||||||
|
To see the exhaustive list of pull requests included in this release see:
|
||||||
|
https://github.com/huge-success/sanic/milestone/{{milestone}}?closed=1
|
||||||
|
|
||||||
|
# Changelog
|
||||||
|
{% for row in changelogs %}
|
||||||
|
* {{ row -}}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
{% for author in authors %}
|
||||||
|
* {{ author -}}
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
JINJA_RELASE_NOTE_TEMPLATE = Environment(
|
||||||
|
loader=BaseLoader, extensions=['jinja2_time.TimeExtension']).from_string(RELASE_NOTE_TEMPLATE)
|
||||||
|
|
||||||
|
RELEASE_NOTE_UPDATE_URL = \
|
||||||
|
"https://api.github.com/repos/huge-success/sanic/releases/tags/{new_version}?access_token={token}"
|
||||||
|
|
||||||
|
|
||||||
def _run_shell_command(command: list):
|
def _run_shell_command(command: list):
|
||||||
try:
|
try:
|
||||||
@ -24,8 +50,10 @@ def _run_shell_command(command: list):
|
|||||||
shell=True)
|
shell=True)
|
||||||
output, error = process.communicate()
|
output, error = process.communicate()
|
||||||
return_code = process.returncode
|
return_code = process.returncode
|
||||||
return output, error, return_code
|
return output.decode("utf-8"), error, return_code
|
||||||
except:
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
return None, None, -1
|
return None, None, -1
|
||||||
|
|
||||||
|
|
||||||
@ -73,35 +101,69 @@ def _get_current_tag(git_command_name="get_tag"):
|
|||||||
|
|
||||||
|
|
||||||
def _update_release_version_for_sanic(current_version, new_version, config_file):
|
def _update_release_version_for_sanic(current_version, new_version, config_file):
|
||||||
old_version_line = '__version__ = "{current_version}"'.format(current_version=current_version)
|
|
||||||
new_version_line = '__version__ = "{new_version}"'.format(new_version=new_version)
|
|
||||||
|
|
||||||
with open("sanic/__init__.py") as init_file:
|
|
||||||
data = init_file.read()
|
|
||||||
|
|
||||||
new_data = data.replace(old_version_line, new_version_line)
|
|
||||||
with open("sanic/__init__.py", "w") as init_file:
|
|
||||||
init_file.write(new_data)
|
|
||||||
|
|
||||||
config_parser = RawConfigParser()
|
config_parser = RawConfigParser()
|
||||||
with open(config_file) as cfg:
|
with open(config_file) as cfg:
|
||||||
config_parser.read_file(cfg)
|
config_parser.read_file(cfg)
|
||||||
config_parser.set("version", "current_version", new_version)
|
config_parser.set("version", "current_version", new_version)
|
||||||
|
|
||||||
|
version_file = config_parser.get("version", "file")
|
||||||
|
current_version_line = config_parser.get("version", "current_version_pattern").format(
|
||||||
|
current_version=current_version)
|
||||||
|
new_version_line = config_parser.get("version", "new_version_pattern").format(new_version=new_version)
|
||||||
|
|
||||||
|
with open(version_file) as init_file:
|
||||||
|
data = init_file.read()
|
||||||
|
|
||||||
|
new_data = data.replace(current_version_line, new_version_line)
|
||||||
|
with open(version_file, "w") as init_file:
|
||||||
|
init_file.write(new_data)
|
||||||
|
|
||||||
with open(config_file, "w") as config:
|
with open(config_file, "w") as config:
|
||||||
config_parser.write(config)
|
config_parser.write(config)
|
||||||
|
|
||||||
command = GIT_COMMANDS.get("commit_version_change")
|
command = GIT_COMMANDS.get("commit_version_change")
|
||||||
command[0] = command[0].format(new_version=new_version, current_version=current_version)
|
command[0] = command[0].format(new_version=new_version, current_version=current_version)
|
||||||
_, _, ret = _run_shell_command(command)
|
_, err, ret = _run_shell_command(command)
|
||||||
if int(ret) != 0:
|
if int(ret) != 0:
|
||||||
print("Failed to Commit Version upgrade changes to Sanic")
|
print("Failed to Commit Version upgrade changes to Sanic: {}".format(err.decode("utf-8")))
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def _tag_release(new_version, current_version):
|
def _generate_change_log(current_version: str = None):
|
||||||
global GIT_COMMANDS
|
global GIT_COMMANDS
|
||||||
for command_name in ["push_new_branch", "create_new_tag", "push_tag"]:
|
command = GIT_COMMANDS.get("get_change_log")
|
||||||
|
command[0] = command[0].format(current_version=current_version)
|
||||||
|
output, error, ret = _run_shell_command(command=command)
|
||||||
|
if not len(str(output)):
|
||||||
|
print("Unable to Fetch Change log details to update the Release Note")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
commit_details = OrderedDict()
|
||||||
|
commit_details["authors"] = dict()
|
||||||
|
commit_details["commits"] = list()
|
||||||
|
|
||||||
|
for line in str(output).split("\n"):
|
||||||
|
commit, author, description = line.split(":::")
|
||||||
|
if 'GitHub' not in author:
|
||||||
|
commit_details["authors"][author] = 1
|
||||||
|
commit_details["commits"].append(" - ".join([commit, description]))
|
||||||
|
|
||||||
|
return commit_details
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_markdown_document(milestone, release_name, current_version, release_version):
|
||||||
|
global JINJA_RELASE_NOTE_TEMPLATE
|
||||||
|
release_name = release_name or release_version
|
||||||
|
change_log = _generate_change_log(current_version=current_version)
|
||||||
|
return JINJA_RELASE_NOTE_TEMPLATE.render(
|
||||||
|
release_name=release_name, milestone=milestone, changelogs=change_log["commits"],
|
||||||
|
authors=change_log["authors"].keys())
|
||||||
|
|
||||||
|
|
||||||
|
def _tag_release(new_version, current_version, milestone, release_name, token):
|
||||||
|
global GIT_COMMANDS
|
||||||
|
global RELEASE_NOTE_UPDATE_URL
|
||||||
|
for command_name in ["create_new_tag", "push_tag"]:
|
||||||
command = GIT_COMMANDS.get(command_name)
|
command = GIT_COMMANDS.get(command_name)
|
||||||
command[0] = command[0].format(new_version=new_version, current_version=current_version)
|
command[0] = command[0].format(new_version=new_version, current_version=current_version)
|
||||||
out, error, ret = _run_shell_command(command=command)
|
out, error, ret = _run_shell_command(command=command)
|
||||||
@ -109,16 +171,33 @@ def _tag_release(new_version, current_version):
|
|||||||
print("Failed to execute the command: {}".format(command[0]))
|
print("Failed to execute the command: {}".format(command[0]))
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
change_log = _generate_markdown_document(milestone, release_name, current_version, new_version)
|
||||||
|
|
||||||
|
body = {
|
||||||
|
"name": release_name or new_version,
|
||||||
|
"body": change_log
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"content-type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
response = patch(RELEASE_NOTE_UPDATE_URL.format(new_version=new_version, token=token),
|
||||||
|
data=dumps(body), headers=headers)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
|
||||||
def release(args: Namespace):
|
def release(args: Namespace):
|
||||||
current_tag = _get_current_tag()
|
current_tag = _get_current_tag()
|
||||||
current_version = _fetch_current_version(args.config)
|
current_version = _fetch_current_version(args.config)
|
||||||
if current_tag and current_version not in current_tag:
|
if current_tag and current_version not in current_tag:
|
||||||
print("Tag mismatch between what's in git and what was provided by --current-version")
|
print("Tag mismatch between what's in git and what was provided by --current-version. "
|
||||||
|
"Existing: {}, Give: {}".format(current_tag, current_version))
|
||||||
exit(1)
|
exit(1)
|
||||||
new_version = _get_new_version(args.config, current_version, args.micro_release)
|
new_version = args.release_version or _get_new_version(args.config, current_version, args.micro_release)
|
||||||
_update_release_version_for_sanic(current_version=current_version, new_version=new_version, config_file=args.config)
|
_update_release_version_for_sanic(current_version=current_version, new_version=new_version, config_file=args.config)
|
||||||
_tag_release(current_version=current_version, new_version=new_version)
|
_tag_release(current_version=current_version, new_version=new_version,
|
||||||
|
milestone=args.milestone, release_name=args.release_name, token=args.token)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@ -129,7 +208,13 @@ if __name__ == '__main__':
|
|||||||
cli.add_argument("--current-version", "-cv", help="Current Version to default in case if you don't want to "
|
cli.add_argument("--current-version", "-cv", help="Current Version to default in case if you don't want to "
|
||||||
"use the version configuration files",
|
"use the version configuration files",
|
||||||
default=None, required=False)
|
default=None, required=False)
|
||||||
cli.add_argument("--config", "-c", help="Configuration file used for release", default="./setup.cfg", required=False)
|
cli.add_argument("--config", "-c", help="Configuration file used for release", default="./setup.cfg",
|
||||||
|
required=False)
|
||||||
|
cli.add_argument("--token", "-t", help="Git access token with necessary access to Huge Sanic Org",
|
||||||
|
required=True)
|
||||||
|
cli.add_argument("--milestone", "-ms", help="Git Release milestone information to include in relase note",
|
||||||
|
required=True)
|
||||||
|
cli.add_argument("--release-name", "-n", help="Release Name to use if any", required=False)
|
||||||
cli.add_argument("--micro-release", "-m", help="Micro Release with patches only",
|
cli.add_argument("--micro-release", "-m", help="Micro Release with patches only",
|
||||||
default=False, action='store_true', required=False)
|
default=False, action='store_true', required=False)
|
||||||
args = cli.parse_args()
|
args = cli.parse_args()
|
||||||
|
@ -14,4 +14,7 @@ multi_line_output = 3
|
|||||||
not_skip = __init__.py
|
not_skip = __init__.py
|
||||||
|
|
||||||
[version]
|
[version]
|
||||||
current_version = 0.8.3
|
current_version = 18.12.0
|
||||||
|
file = sanic/__init__.py
|
||||||
|
current_version_pattern = __version__ = "{current_version}"
|
||||||
|
new_version_pattern = __version__ = "{new_version}"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user