Skip to content

Commit

Permalink
build: automate release process
Browse files Browse the repository at this point in the history
  • Loading branch information
necusjz committed Dec 12, 2023
1 parent f81ab5a commit b886c80
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ jobs:
name: package
path: dist

- name: Generate release notes
run: |
python scripts/release_notes.py > ${{ github.workspace }}-RELEASE_NOTES.md
- name: Publish package to PyPI
run: |
twine upload -u '${{ secrets.PYPI_USERNAME }}' -p '${{ secrets.PYPI_PASSWORD }}' dist/*
Expand All @@ -113,6 +117,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
body_path: ${{ github.workspace }}-RELEASE_NOTES.md
prerelease: ${{ contains(env.TAG, 'rc') }}
files: |
dist/*
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "splatbot"
dynamic = ["version"]
description = "Automate plotting detailed posts in Splatoon wirelessly based on BlueZ, and optimize its efficiency by treating the process as a variant of Traveling Salesman Problem (TSP)."
description = "Automate plotting posts in Splatoon based on BlueZ, and optimize its efficiency via Traveling Salesman Problem (TSP)."
authors = [{name = "necusjz", email = "[email protected]"}]
requires-python = ">=3.8"
readme = "README.md"
Expand All @@ -33,7 +33,7 @@ repository = "https://github.com/necusjz/splatbot"
[project.optional-dependencies]
dev = [
"build>=1.0.3",
"pytest>=7.2.1",
"packaging>=23.1",
"twine>=1.11.0",
]

Expand All @@ -42,6 +42,7 @@ splatbot = "splatbot.cli:main"

[tool.setuptools.packages.find]
exclude = [
"scripts*",
"tests*",
"vagrant*",
]
Expand Down
37 changes: 37 additions & 0 deletions scripts/prepare_changelog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env python
from datetime import datetime
from pathlib import Path

from splatbot.version import VERSION


def main():
changelog = Path("CHANGELOG.md")

with changelog.open() as fp:
lines = fp.readlines()

insert_idx = -1
for i in range(len(lines)):
line = lines[i]
if line.startswith("## [Unreleased]"):
insert_idx = i + 1
elif line.startswith(f"## [{VERSION}]"):
print("CHANGELOG.md already up-to-date.")
return

elif line.startswith("## ["):
break

if insert_idx < 0:
raise RuntimeError("Couldn't find [Unreleased] section.")

lines.insert(insert_idx, "\n")
lines.insert(insert_idx + 1, f"## [{VERSION}] - {datetime.now().strftime('%Y-%m-%d')}\n")

with changelog.open("w") as fp:
fp.writelines(lines)


if __name__ == "__main__":
main()
18 changes: 18 additions & 0 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -e

TAG=$(python -c 'from my_package.version import VERSION; print("v" + VERSION)')

read -p "Creating new release for $TAG. Do you want to continue? [Y/n] " prompt

if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then
python scripts/prepare_changelog.py
git add -A
git commit -m "build: release $TAG" || true && git push
echo "Creating new git tag $TAG."
git tag "$TAG" -m "$TAG"
git push --tags
else
echo "Cancelled."
exit 1
fi
65 changes: 65 additions & 0 deletions scripts/release_notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python
import os
import packaging.version

TAG = os.environ["TAG"]


def get_changelog_notes():
is_current_section = False
section_notes = []

with open("CHANGELOG.md") as changelog:
for line in changelog:
if line.startswith("## "):
if line.startswith("## [Unreleased]"):
continue

if line.startswith(f"## [{TAG[1:]}]"):
is_current_section = True
continue

break

if is_current_section:
section_notes.append(line)

assert section_notes

return "## What's new\n\n" + "".join(section_notes).strip() + "\n"


def get_commit_history():
version = packaging.version.parse(TAG)

os.popen("git fetch --tags")
tags = os.popen("git tag -l --sort=-version:refname 'v*'").read().split("\n")

prev_tag = None
for tag in tags:
if not tag.strip(): # blank line
continue

curr_version = packaging.version.parse(tag)
if version.pre is None and curr_version.pre is not None: # ignore pre-release
continue

if curr_version < version:
prev_tag = tag
break

if prev_tag is not None:
commits = os.popen(f"git log {prev_tag}..{TAG} --oneline --first-parent").read()
else:
commits = os.popen("git log --oneline --first-parent").read()

return "## Commits\n\n" + commits


def main():
print(get_changelog_notes())
print(get_commit_history())


if __name__ == "__main__":
main()

0 comments on commit b886c80

Please sign in to comment.