Created
November 18, 2021 15:46
-
-
Save thusser/49b31c7f9d9258702a6a0223220f3787 to your computer and use it in GitHub Desktop.
Python script to update version using Poetry, merge develop->main and create a new release/tag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import argparse | |
import re | |
import subprocess | |
import sys | |
from github import Github | |
import os | |
def main(): | |
# set up parser | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-v', '--version', type=str, help='Version to release.') | |
parser.add_argument('-t', '--token', type=str, help='GitHub access token.', | |
default=os.getenv('GITHUB_ACCESS_TOKEN', None)) | |
args = parser.parse_args() | |
# check github access token | |
if args.token is None: | |
print('No GitHub access token found.') | |
return 1 | |
# get repo name | |
repo_remote = shell('git config --get remote.origin.url') | |
if not repo_remote: | |
print("Not a git repository.") | |
sys.exit(1) | |
m = re.search(r'github\.com[:/](.*)\.git$', repo_remote) | |
if m is None: | |
print('Could not identify GitHub repository.') | |
return 1 | |
repo_name = m.group(1) | |
repo_owner = shell('git config --get user.name') | |
print(f'Repository: {repo_name}') | |
print(f'User: {repo_owner}') | |
# pyproject.toml? | |
if not os.path.exists('pyproject.toml'): | |
print('No pyproject.toml found.') | |
return 1 | |
# Poetry? | |
try: | |
shell('poetry') | |
except subprocess.CalledProcessError: | |
print('No poetry found.') | |
return 1 | |
# current version | |
version = get_current_version() | |
print(f'Current version: {version}') | |
# connect to GitHub | |
print() | |
print('Connecting to GitHub...') | |
gh = Github(args.token) | |
print('Fetching repository...') | |
repo = gh.get_repo(repo_name) | |
branches = repo.get_branches() | |
branch_names = [b.name for b in branches] | |
if 'develop' not in branch_names: | |
print('No develop branch found.') | |
return 1 | |
main_branch = 'main' | |
if main_branch not in branch_names: | |
main_branch = 'master' | |
if main_branch not in branch_names: | |
print('No main/master branch found.') | |
return 1 | |
# currently in develop? | |
cur_branch = shell('git rev-parse --abbrev-ref HEAD') | |
if cur_branch != 'develop': | |
print('Current branch is not develop.') | |
return 1 | |
# print plan | |
print() | |
print('Will perform the following tasks:') | |
if args.version is None: | |
print(f'1. Set new version using "poetry version patch"') | |
set_version = 'patch' | |
else: | |
print(f'1. Set new version using "poetry version {args.version}"') | |
set_version = args.version | |
print(f'2. Commit and pull change.') | |
print(f'3. Create PR develop -> {main_branch}') | |
print(f'4. Merge PR') | |
print(f'5. Create tag and release with new version') | |
# continue | |
if input('Continue [y/N]') not in 'yY': | |
return 0 | |
# set new version | |
print() | |
print('Setting new version...') | |
shell(f'poetry version {set_version}') | |
version = get_current_version() | |
print(f'New version: {version}') | |
# commit it | |
shell(f'git commit -m "v{version}" pyproject.toml') | |
shell(f'git push') | |
# shortcuts | |
title = f'v{version}' | |
body = f'version {version}' | |
# create PR | |
print('Creating PR...') | |
pr = repo.create_pull(title=title, body=body, head='develop', base=main_branch) | |
# merge PR | |
print('Merging PR...') | |
pr.merge(commit_title=title, commit_message=body) | |
# get last commit | |
print('Fetching last commit...') | |
commit = repo.get_commits()[0] | |
print(f'Commit is {commit.sha}.') | |
# tag & release | |
print('Create tag and release...') | |
repo.create_git_tag_and_release(tag=title, tag_message=body, release_name=title, release_message=body, | |
object=commit.sha, type='commit') | |
print('Done.') | |
def shell(cmd, check=True): | |
result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, check=check) | |
return result.stdout.decode('utf-8').strip() | |
def get_current_version(): | |
return shell('poetry version').split()[1].strip() | |
if __name__ == '__main__': | |
code = main() | |
sys.exit(code) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment