2
0
mirror of https://github.com/frappe/bench.git synced 2025-01-10 09:02:10 +00:00

Merge pull request #450 from saurabh6790/release_from_staging

[fix] provision to handle release from staging branch
This commit is contained in:
Saurabh 2017-07-25 15:53:19 +05:30 committed by GitHub
commit abae508cb9
2 changed files with 57 additions and 49 deletions

View File

@ -119,15 +119,15 @@ def backup_all_sites():
@click.command('release') @click.command('release')
@click.argument('app') @click.argument('app')
@click.argument('bump-type', type=click.Choice(['major', 'minor', 'patch', 'stable', 'prerelease'])) @click.argument('bump-type', type=click.Choice(['major', 'minor', 'patch', 'stable', 'prerelease']))
@click.option('--develop', default='develop') @click.option('--from-branch', default='develop')
@click.option('--master', default='master') @click.option('--to-branch', default='master')
@click.option('--remote', default='upstream') @click.option('--remote', default='upstream')
@click.option('--owner', default='frappe') @click.option('--owner', default='frappe')
@click.option('--repo-name') @click.option('--repo-name')
def release(app, bump_type, develop, master, owner, repo_name, remote): def release(app, bump_type, from_branch, to_branch, owner, repo_name, remote):
"Release app (internal to the Frappe team)" "Release app (internal to the Frappe team)"
from bench.release import release from bench.release import release
release(bench_path='.', app=app, bump_type=bump_type, develop=develop, master=master, release(bench_path='.', app=app, bump_type=bump_type, from_branch=from_branch, to_branch=to_branch,
remote=remote, owner=owner, repo_name=repo_name) remote=remote, owner=owner, repo_name=repo_name)

View File

@ -4,10 +4,8 @@ import os
import sys import sys
import semantic_version import semantic_version
import git import git
import json
import requests import requests
import getpass import getpass
import argparse
import re import re
from requests.auth import HTTPBasicAuth from requests.auth import HTTPBasicAuth
import requests.exceptions import requests.exceptions
@ -15,23 +13,32 @@ from time import sleep
from .config.common_site_config import get_config from .config.common_site_config import get_config
import click import click
branches_to_update = {
'develop': [],
'hotfix': ['develop']
}
github_username = None github_username = None
github_password = None github_password = None
def release(bench_path, app, bump_type, develop='develop', master='master', def release(bench_path, app, bump_type, from_branch='develop', to_branch='master',
remote='upstream', owner='frappe', repo_name=None): remote='upstream', owner='frappe', repo_name=None):
validate(bench_path)
bump(bench_path, app, bump_type, develop=develop, master=master, owner=owner,
repo_name=repo_name, remote=remote)
def validate(bench_path):
config = get_config(bench_path) config = get_config(bench_path)
if not config.get('release_bench'): if not config.get('release_bench'):
print('bench not configured to release') print('bench not configured to release')
sys.exit(1) sys.exit(1)
if config.get('branches_to_update'):
branches_to_update.update(config.get('branches_to_update'))
validate(bench_path, config)
bump(bench_path, app, bump_type, from_branch=from_branch, to_branch=to_branch, owner=owner,
repo_name=repo_name, remote=remote)
def validate(bench_path, config):
global github_username, github_password global github_username, github_password
github_username = config.get('github_username') github_username = config.get('github_username')
@ -46,12 +53,12 @@ def validate(bench_path):
r = requests.get('https://api.github.com/user', auth=HTTPBasicAuth(github_username, github_password)) r = requests.get('https://api.github.com/user', auth=HTTPBasicAuth(github_username, github_password))
r.raise_for_status() r.raise_for_status()
def bump(bench_path, app, bump_type, develop, master, remote, owner, repo_name=None): def bump(bench_path, app, bump_type, from_branch, to_branch, remote, owner, repo_name=None):
assert bump_type in ['minor', 'major', 'patch', 'stable', 'prerelease'] assert bump_type in ['minor', 'major', 'patch', 'stable', 'prerelease']
repo_path = os.path.join(bench_path, 'apps', app) repo_path = os.path.join(bench_path, 'apps', app)
update_branches_and_check_for_changelog(repo_path, develop, master, remote=remote) update_branches_and_check_for_changelog(repo_path, from_branch, to_branch, remote=remote)
message = get_release_message(repo_path, develop=develop, master=master, remote=remote) message = get_release_message(repo_path, from_branch=from_branch, to_branch=to_branch, remote=remote)
if not message: if not message:
print('No commits to release') print('No commits to release')
@ -63,21 +70,22 @@ def bump(bench_path, app, bump_type, develop, master, remote, owner, repo_name=N
click.confirm('Do you want to continue?', abort=True) click.confirm('Do you want to continue?', abort=True)
new_version = bump_repo(repo_path, bump_type, develop=develop, master=master) new_version = bump_repo(repo_path, bump_type, from_branch=from_branch, to_branch=to_branch)
commit_changes(repo_path, new_version) commit_changes(repo_path, new_version)
tag_name = create_release(repo_path, new_version, develop=develop, master=master) tag_name = create_release(repo_path, new_version, from_branch=from_branch, to_branch=to_branch)
push_release(repo_path, develop=develop, master=master, remote=remote) push_release(repo_path, from_branch=from_branch, to_branch=to_branch, remote=remote)
create_github_release(repo_path, tag_name, message, remote=remote, owner=owner, repo_name=repo_name) create_github_release(repo_path, tag_name, message, remote=remote, owner=owner, repo_name=repo_name)
print('Released {tag} for {repo_path}'.format(tag=tag_name, repo_path=repo_path)) print('Released {tag} for {repo_path}'.format(tag=tag_name, repo_path=repo_path))
def update_branches_and_check_for_changelog(repo_path, develop='develop', master='master', remote='upstream'): def update_branches_and_check_for_changelog(repo_path, from_branch='develop', to_branch='master', remote='upstream'):
update_branch(repo_path, master, remote=remote) update_branch(repo_path, to_branch, remote=remote)
update_branch(repo_path, develop, remote=remote) update_branch(repo_path, from_branch, remote=remote)
if develop != 'develop':
update_branch(repo_path, 'develop', remote=remote)
git.Repo(repo_path).git.checkout(develop) for branch in branches_to_update[from_branch]:
update_branch(repo_path, branch, remote=remote)
git.Repo(repo_path).git.checkout(from_branch)
check_for_unmerged_changelog(repo_path) check_for_unmerged_changelog(repo_path)
def update_branch(repo_path, branch, remote): def update_branch(repo_path, branch, remote):
@ -94,18 +102,18 @@ def check_for_unmerged_changelog(repo_path):
if os.path.exists(current) and [f for f in os.listdir(current) if f != "readme.md"]: if os.path.exists(current) and [f for f in os.listdir(current) if f != "readme.md"]:
raise Exception("Unmerged change log! in " + repo_path) raise Exception("Unmerged change log! in " + repo_path)
def get_release_message(repo_path, develop='develop', master='master', remote='upstream'): def get_release_message(repo_path, from_branch='develop', to_branch='master', remote='upstream'):
print('getting release message for', repo_path, 'comparing', master, '...', develop) print('getting release message for', repo_path, 'comparing', to_branch, '...', from_branch)
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
g = repo.git g = repo.git
log = g.log('{remote}/{master}..{remote}/{develop}'.format( log = g.log('{remote}/{to_branch}..{remote}/{from_branch}'.format(
remote=remote, master=master, develop=develop), '--format=format:%s', '--no-merges') remote=remote, to_branch=to_branch, from_branch=from_branch), '--format=format:%s', '--no-merges')
if log: if log:
return "* " + log.replace('\n', '\n* ') return "* " + log.replace('\n', '\n* ')
def bump_repo(repo_path, bump_type, develop='develop', master='master'): def bump_repo(repo_path, bump_type, from_branch='develop', to_branch='master'):
current_version = get_current_version(repo_path) current_version = get_current_version(repo_path)
new_version = get_bumped_version(current_version, bump_type) new_version = get_bumped_version(current_version, bump_type)
@ -199,32 +207,32 @@ def commit_changes(repo_path, new_version):
repo.index.add([os.path.join(app_name, '__init__.py')]) repo.index.add([os.path.join(app_name, '__init__.py')])
repo.index.commit('bumped to version {}'.format(new_version)) repo.index.commit('bumped to version {}'.format(new_version))
def create_release(repo_path, new_version, develop='develop', master='master'): def create_release(repo_path, new_version, from_branch='develop', to_branch='master'):
print('creating release for version', new_version) print('creating release for version', new_version)
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
g = repo.git g = repo.git
g.checkout(master) g.checkout(to_branch)
try: try:
g.merge(develop, '--no-ff') g.merge(from_branch, '--no-ff')
except git.exc.GitCommandError as e: except git.exc.GitCommandError as e:
handle_merge_error(e, source=develop, target=master) handle_merge_error(e, source=from_branch, target=to_branch)
tag_name = 'v' + new_version tag_name = 'v' + new_version
repo.create_tag(tag_name, message='Release {}'.format(new_version)) repo.create_tag(tag_name, message='Release {}'.format(new_version))
g.checkout(develop) g.checkout(from_branch)
try: try:
g.merge(master) g.merge(to_branch)
except git.exc.GitCommandError as e: except git.exc.GitCommandError as e:
handle_merge_error(e, source=master, target=develop) handle_merge_error(e, source=to_branch, target=from_branch)
if develop != 'develop': for branch in branches_to_update[from_branch]:
print('merging master into develop') print('merging master into', branch)
g.checkout('develop') g.checkout(branch)
try: try:
g.merge(master) g.merge(to_branch)
except git.exc.GitCommandError as e: except git.exc.GitCommandError as e:
handle_merge_error(e, source=master, target='develop') handle_merge_error(e, source=to_branch, target=branch)
return tag_name return tag_name
@ -236,18 +244,18 @@ def handle_merge_error(e, source, target):
print('-'*80) print('-'*80)
click.confirm('Have you manually resolved the error?', abort=True) click.confirm('Have you manually resolved the error?', abort=True)
def push_release(repo_path, develop='develop', master='master', remote='upstream'): def push_release(repo_path, from_branch='develop', to_branch='master', remote='upstream'):
print('pushing branches', master, develop, 'of', repo_path) print('pushing branches', to_branch, from_branch, 'of', repo_path)
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
g = repo.git g = repo.git
args = [ args = [
'{master}:{master}'.format(master=master), '{to_branch}:{to_branch}'.format(to_branch=to_branch),
'{develop}:{develop}'.format(develop=develop) '{from_branch}:{from_branch}'.format(from_branch=from_branch)
] ]
if develop != 'develop': for branch in branches_to_update[from_branch]:
print('pushing develop branch of', repo_path) print('pushing {0} branch of'.format(branch), repo_path)
args.append('develop:develop') args.append('{branch}:{branch}'.format(branch=branch))
args.append('--tags') args.append('--tags')