Skip to content

Commit

Permalink
CI: Add scripts and workflow for automated version bumping and releases
Browse files Browse the repository at this point in the history
  • Loading branch information
singjc committed Jan 31, 2024
1 parent 5b4f226 commit 698c481
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Create a new patch release

on: [workflow_dispatch]

jobs:
resources:
name: Update __init__.py patch version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- name: Update version
run: ./scripts/update_version.py --file-path ../../massdash/__init__.py
- name: Commit version update
uses: test-room-7/action-update-file@v1
with:
file-path: ../../massdash/__init__.py
commit-msg: Bump patch version
github-token: ${{ secrets.GITHUB_TOKEN }}

# github:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v3
# - name: Create new patch release
# run: .github/scripts/release.py
# env:
# GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
48 changes: 48 additions & 0 deletions .github/workflows/scripts/release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
import json
import subprocess


def get_last_version() -> str:
"""Return the version number of the last release."""
json_string = (
subprocess.run(
["gh", "release", "view", "--json", "tagName"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
.stdout.decode("utf8")
.strip()
)

return json.loads(json_string)["tagName"]


def bump_patch_number(version_number: str) -> str:
"""Return a copy of `version_number` with the patch number incremented."""
major, minor, patch = version_number.split(".")
return f"{major}.{minor}.{int(patch) + 1}"


def create_new_patch_release():
"""Create a new patch release on GitHub."""
try:
last_version_number = get_last_version()
except subprocess.CalledProcessError as err:
if err.stderr.decode("utf8").startswith("HTTP 404:"):
# The project doesn't have any releases yet.
new_version_number = "0.0.1"
else:
raise
else:
new_version_number = bump_patch_number(last_version_number)

subprocess.run(
["gh", "release", "create", "--generate-notes", new_version_number],
check=True,
)


if __name__ == "__main__":
create_new_patch_release()
53 changes: 53 additions & 0 deletions .github/workflows/scripts/update_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
import re
import argparse

def update_version(init_file_path, version_type='patch'):
print(f"Updating {version_type} version in {init_file_path}...")
with open(init_file_path, 'r') as file:
init_content = file.read()

# Use a regular expression to find and extract the current version
version_match = re.search(r"__version__ = \"(.*?)\"", init_content)
if version_match:
current_version = version_match.group(1)
print(f"Current version: {current_version}")

# Increment the version based on the specified version type
version_parts = list(map(int, current_version.split('.')))
if version_type == 'major':
version_parts[0] += 1
version_parts[1] = 0 # Reset minor version to 0
version_parts[2] = 0 # Reset patch version to 0
elif version_type == 'minor':
version_parts[1] += 1
version_parts[2] = 0 # Reset patch version to 0
elif version_type == 'patch':
version_parts[2] += 1
else:
print("Invalid version type. Please use 'major', 'minor', or 'patch'.")
return

new_version = '.'.join(map(str, version_parts))
print(f"New version: {new_version}")

# Replace the version in the content
updated_content = re.sub(r"(__version__ = \")(.*?)(\")", rf"\g<1>{new_version}\g<3>", init_content)

print(f"Updating {init_file_path}:\n{updated_content}...")
# Write the updated content back to the file
with open(init_file_path, 'w') as file:
file.write(updated_content)

print("Version updated successfully.")
else:
print("Could not find the version in the init file.")

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Update the version in the __init__.py file.")
parser.add_argument("--file-path", default='__init__.py', help="Path to the __init__.py file")
parser.add_argument("--version-type", choices=['major', 'minor', 'patch'], default='patch',
help="Type of version update (default: patch)")

args = parser.parse_args()
update_version(args.file_path, args.version_type)

0 comments on commit 698c481

Please sign in to comment.