Skip to content

Instantly share code, notes, and snippets.

@thusser
Created November 18, 2021 15:46
Show Gist options
  • Save thusser/49b31c7f9d9258702a6a0223220f3787 to your computer and use it in GitHub Desktop.
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
#!/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