Skip to content

Commit

Permalink
ci: update release scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigge committed Jul 19, 2022
1 parent 9a81a0e commit e1e0b31
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 30 deletions.
64 changes: 40 additions & 24 deletions sbin/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import sys

import utils
import config

#
# Stop immediately if version too old.
Expand All @@ -16,17 +17,10 @@
f"You need Python >= {_MINIMUM_PYTHON_VERSION}, but you are running {sys.version}"
)

GITHUB_COMPARE_URL = (
"https://github.com/AxisCommunications/practical-react-components/compare"
)
GITHUB_COMMIT_URL = (
"https://github.com/AxisCommunications/practical-react-components/commit"
)

GROUP_TITLES = {
"build": "👷 Build",
"chore": "🚧 Maintenance",
"ci": "🚦 Continous integration",
"ci": "🚦 Continuous integration",
"docs": "📝 Documentation",
"feat": "✨ Features",
"fix": "🐛 Bug fixes",
Expand All @@ -41,36 +35,45 @@
def changelog_part(commitish_to: str, commitish_from: str, version: str):
date = utils.cmd(["git", "log", "-1", "--format=%ci", commitish_to])

commit_range = (
f"{commitish_from}..HEAD"
if commitish_to == "HEAD"
else f"{commitish_from}..{commitish_to}~"
)
if commitish_from is None:
commit_range = commitish_to
elif commitish_to == "HEAD":
commit_range = f"{commitish_from}..HEAD"
else:
commit_range = f"{commitish_from}..{commitish_to}~"

commits = utils.cmd(
["git", "log", "--no-merges", "--date-order", "--format=%H%x09%s", commit_range]
[
"git",
"log",
"--no-merges",
"--date-order",
"--format=%H%n%h%n%B%x1f",
commit_range,
]
)

if commits == "":
return ""

messages = {}

for commit in commits.split("\n"):
sha, msg = commit.split(maxsplit=1)
shortsha = utils.cmd(["git", "log", "-1", "--format=%h", sha])
for commit in commits.split("\x1f"):
sha, shortsha, msg = commit.strip().split("\n", maxsplit=2)

try:
data = utils.conventional_commit_parse(msg)
issues = utils.closing_issues_commit_parse(msg)
messages.setdefault(data["type"], []).append(
{**data, "sha": sha, "shortsha": shortsha}
{**data, "issues": issues, "sha": sha, "shortsha": shortsha}
)
except:
# No conventional commit
pass

content = [
f"## [{version}]({GITHUB_COMPARE_URL}/{commitish_from}...{version}) ({date})"
f"## [{version}]({config.GITHUB_RELEASE_URL}/{version})",
f"{date}, [Compare changes]({config.GITHUB_COMPARE_URL}/{commitish_from}...{version})",
]

for group in GROUP_TITLES.keys():
Expand All @@ -81,10 +84,24 @@ def changelog_part(commitish_to: str, commitish_from: str, version: str):

for data in messages[group]:

prefix = (
f' - **{data["scope"]}**: ' if data["scope"] is not None else " - "
prefix = " - "

pull_request = utils.get_github_pull_request(data["sha"])
# pull_request[0] is id, pull_request[1] is url
if pull_request is not None:
prefix += f"[!{pull_request[0]}]({pull_request[1]}) - "

if data["scope"] is not None:
prefix += f'**{data["scope"]}**: '

postfix = (
f' ([`{data["shortsha"]}`]({config.GITHUB_COMMIT_URL}/{data["sha"]}))'
)
postfix = f' ([{data["shortsha"]}]({GITHUB_COMMIT_URL}/{data["sha"]}))'

commit_author = utils.get_github_author(data["sha"])
# commit_author[0] is username, commit_author[1] is url
if commit_author is not None:
postfix += f" ([**@{commit_author[0]}**]({commit_author[1]}))"

if data["breaking"]:
content.append(f'{prefix}**BREAKING** {data["description"]}{postfix}')
Expand All @@ -96,9 +113,7 @@ def changelog_part(commitish_to: str, commitish_from: str, version: str):

HEADER = """
# Changelog
All notable changes to this project will be documented in this file.
"""


Expand Down Expand Up @@ -162,6 +177,7 @@ def changelog_part(commitish_to: str, commitish_from: str, version: str):

if args.type == "full" and args.release is not None:
tags.insert(0, "HEAD")
tags.append(None)

content = [HEADER] if not args.skip_header else []

Expand Down
4 changes: 1 addition & 3 deletions sbin/commitlint.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3

import argparse
import sys
Expand All @@ -11,11 +11,9 @@
description="""
If no range is given, HEAD~..HEAD is used (so only the latest commit
will be checked).
Note that the a range fa56eb..HEAD does not include the fa56eb commit
(to start from e.g. fa56eb, you would write fa56eb~..HEAD to use the parent
as starting point).
Check if message conforms to a conventional commit message, see
https://www.conventionalcommits.org/en/v1.0.0/#specification
"""
Expand Down
7 changes: 7 additions & 0 deletions sbin/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
GITHUB_URL = "https://github.com"
GITHUB_API_URL = "https://api.github.com"
GITHUB_REPOSITORY = "AxisCommunications/practical-react-components"

GITHUB_COMPARE_URL = f"{GITHUB_URL}/{GITHUB_REPOSITORY}/compare"
GITHUB_COMMIT_URL = f"{GITHUB_URL}/{GITHUB_REPOSITORY}/commit"
GITHUB_RELEASE_URL = f"{GITHUB_URL}/{GITHUB_REPOSITORY}/releases/tag"
58 changes: 55 additions & 3 deletions sbin/utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import os
import urllib.request
import json
import re
import subprocess
import sys
import typing

import config

possible_types = [
"build",
"chore",
Expand All @@ -19,14 +24,16 @@

types = "|".join(possible_types)

re_conventional_commit_header = re.compile(fr"^({types})(?:\(([^\)]+)\))?(!?): (.*)$")
re_conventional_commit_header = re.compile(
rf"^({types})(?:\(([^\)]+)\))?(!?): (.*)(?:\n|$)"
)


def conventional_commit_parse(message: str):
match = re.fullmatch(re_conventional_commit_header, message)
match = re.match(re_conventional_commit_header, message)

if match is None:
raise Exception()
raise Exception("Not a conventional commit")

type, scope, breaking, header = match.groups()

Expand All @@ -38,6 +45,51 @@ def conventional_commit_parse(message: str):
}


re_closing_issues = re.compile(
r"^Closes: ([A-Z]+-[0-9]+)$", re.MULTILINE | re.IGNORECASE
)


def closing_issues_commit_parse(message: str):
return re.findall(re_closing_issues, message)


def get_github_api(url: str):
try:
token = os.environ["GITHUB_TOKEN"]
req = urllib.request.Request(
f"{config.GITHUB_API_URL}{url}",
headers={"Authorization": f"Bearer {token}"},
)
res = urllib.request.urlopen(req)
data = json.load(res)

return data
except KeyError as e:
print("GITHUB_TOKEN environment not set")
sys.exit(1)
except urllib.error.HTTPError as e:
return None


def get_github_pull_request(sha: str):
data = get_github_api(f"/repos/{config.GITHUB_REPOSITORY}/commits/{sha}/pulls")

if data is None or len(data) == 0:
return None

return (data[0]["number"], data[0]["html_url"])


def get_github_author(sha: str):
data = get_github_api(f"/repos/{config.GITHUB_REPOSITORY}/commits/{sha}")

if data is None or data["author"] is None:
return None

return (data["author"]["login"], data["author"]["html_url"])


def cmd(cmd: typing.List[str]) -> str:
"""Call shell command and return the result"""
try:
Expand Down

0 comments on commit e1e0b31

Please sign in to comment.