Skip to content

Commit

Permalink
cli: add release-helm command
Browse files Browse the repository at this point in the history
* Closes reanahub#363.
  • Loading branch information
Diego Rodriguez committed Aug 6, 2020
1 parent 8bbd737 commit 867e9ab
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 3 deletions.
3 changes: 2 additions & 1 deletion reana/reana_dev/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,11 @@ def help():
client_commands_list
+ cluster_commands_list
+ docker_commands_list
+ git_commands_list
+ kind_commands_list
+ kubectl_commands_list
+ git_commands_list
+ python_commands_list
+ release_commands_list
+ run_commands_list
):
reana_dev.add_command(cmd)
4 changes: 2 additions & 2 deletions reana/reana_dev/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def docker_build(
if is_component_dockerised(component):
cmd = "docker build"
if tag == "auto":
component_tag = get_current_version(component, dirty=True)
component_tag = get_current_version(component)
for arg in build_arg:
cmd += " --build-arg {0}".format(arg)
if no_cache:
Expand Down Expand Up @@ -267,7 +267,7 @@ def docker_push(user, tag, component): # noqa: D301
component_tag = tag
if is_component_dockerised(component):
if tag == "auto":
component_tag = get_current_version(component, dirty=True)
component_tag = get_current_version(component)
cmd = "docker push {0}/{1}:{2}".format(user, component, component_tag)
run_command(cmd, component)
else:
Expand Down
36 changes: 36 additions & 0 deletions reana/reana_dev/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,42 @@
)


def is_last_commit_tagged(component):
"""Check whether last commit of a component is a tag or not.
:param component: standard component name
:type component: str
"""
try:
last_commit_is_tag_cmd = "git describe --tags --exact-match"
current_dir = os.getcwd()
os.chdir(get_srcdir(component))
subprocess.check_call(
last_commit_is_tag_cmd, shell=True, stderr=subprocess.DEVNULL
)
return True
except subprocess.CalledProcessError:
return False
finally:
os.chdir(current_dir)


def get_current_version(component):
"""Return the current version of a component.
:param component: standard component name
:type component: str
"""
cmd = "git describe --tags"
if is_last_commit_tagged(component):
tag = run_command(cmd, component, return_output=True)
return tag
else:
msg = f"Cannot find a version: the latest commit is not a tag, please create a tag."
display_message(msg, component)
sys.exit(1)


def get_all_branches(srcdir):
"""Return all local and remote Git branch names in the given directory.
Expand Down
187 changes: 187 additions & 0 deletions reana/reana_dev/release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# -*- coding: utf-8 -*-
#
# This file is part of REANA.
# Copyright (C) 2020 CERN.
#
# REANA is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.

"""`reana-dev`'s release commands."""

import sys

import click
import semver
from packaging.version import InvalidVersion, Version

from reana.reana_dev.git import is_last_commit_tagged
from reana.reana_dev.utils import is_component_dockerised, run_command
from reana.config import REPO_LIST_CLUSTER
from reana.reana_dev.python import is_component_python_package


def bump_semver2_version(current_version):
"""Bump a semver2 version string.
:param current_version: current version to be bumped
:type current_version: str
:return: String representation of the next version
:rtype: string
"""
if not semver.VersionInfo.isvalid(current_version):
# FIXME if this happens means that last tag is not semver compliant, ask for manual
# interaction, but what is the manual interaction?
click.echo(f"Current version {current_version} is not a valid semver2 version.")
next_version = semver.VersionInfo.parse(current_version).bump_prerelease()
return str(next_version)


def bump_pep440_version(current_version):
"""Bump a PEP440 version string.
:param current_version: current version to be bumped
:type current_version: str
:return: String representation of the next version
:rtype: string
"""
try:
version = Version(current_version)
return Version(
f"{version.major}.{version.minor}.{version.micro}{version.pre[0]}{version.pre[1]+1}"
)
except InvalidVersion:
# FIXME if this happens means that last tag is not semver compliant, ask for manual
# interaction, but what is the manual interaction?
click.echo(f"Current {current_version} is not a valid PEP440 version.")


def docker_bump_package_version(component, current_version):
"""FIXME."""
_, new_pep440_version = python_bump_package_version(component, current_version)
new_semver2_version = translate_pep440_to_semver2(new_pep440_version)
docker_tag(component, new_semver2_version)
version_dict = {"pep440": new_semver2_version, "semver2": new_semver2_version}


def helm_bump_package_version(component, current_version):
"""FIXME."""

def _helm_update_chart_yaml():
pass

new_semver2_version = bump_semver2_version(last_tag_name)
helm_update_chart_yaml(new_semver2_version)
version_dict = {"pep440": _, "semver2": new_semver2_version}


def javascript_bump_package_version(component, current_version):
"""FIXME."""
raise NotImplementedError()


def python_bump_package_version(component, current_version):
"""FIXME."""
new_pep440_version = bump_pep440_version(current_version)
python_update_version_py(component, new_pep440_version)
return (_, new_pep440_version)


bump_version = {
"docker": docker_bump_package_version,
"helm": helm_bump_package_version,
"javascript": javascript_bump_package_version,
"python": python_bump_package_version,
}


def git_get_last_tag(component):
"""Retrieve last component tag."""
last_tag_name_cmd = "git describe --abbrev=0 --tags"
return run_command(component, last_tag_name_cmd, display=False, return_output=True)


def bump_component_version(component, release_commit=False):
"""Bump version for a Python package."""
last_tag = git_get_last_tag(component)
new_version_dict = bump_version[get_component_type(component)](component, last_tag)
if release_commit:
git_create_release_commit(component, new_version_dict)
return new_version_dict


def git_create_release_commit(component, version_dict):
"""Create release commit for a component."""
version = ""
if is_component_python_package(component):
version = version_dict["pep440"]
else:
version = version_dict["semver2"]
cmd = f"git commit -m 'release: {version}''"
run_command(cmd, component)


def git_create_release_pr(component):
"""Create a release PR for the given component."""
# there is only one commit and it is a release commit
# execute gh/hub to create PR (if we change to gh -> grep `hub`)
pass


@click.group()
def release_commands():
"""Release commands group."""


@click.option(
"--skip-ci",
is_flag=True,
help="Skip CI to test if the Docker releases work correctly.",
)
@click.option(
"--component",
"-c",
multiple=True,
default=["CLUSTER"],
help="Which components? [name|CLUSTER]",
)
@click.option(
"--version", "-v", help="REANA version to release, e.g. 0.7.0a1",
)
@release_commands.command(name="release-helm")
@click.pass_context
def release_helm(ctx, skip_ci, component, version): # noqa: D30

cluster_docker_components_to_release = []
for component in REPO_LIST_CLUSTER:
if is_component_dockerised(component) and not is_last_commit_tagged(component):
cluster_docker_components_to_release.append(component)

should_reana_be_released = not is_last_commit_tagged("reana")

if not (should_reana_be_released or cluster_docker_components_to_release):
click.echo("Nothing to be released")
sys.exit(0)

if not skip_ci:
click.echo("reana-dev run-ci --mode=latest")

if cluster_docker_components_to_release:
for component in cluster_docker_components_to_release:
_, semver2_version = bump_component_version(component, release_commit=True)
# git_create_release_commit(component, version) Comming from another PR

click.echo(
f"reana-dev docker-push {' -c '.join(cluster_docker_components_to_release)} --tag {semver2_version}"
) # FIXME execute the command
helm_update_values()

version = bump_component_version("reana")
git_create_release_commit("reana", version)

for component in ["reana"] + cluster_docker_components_to_release:
git_create_release_pr(component)


release_commands_list = list(release_commands.commands.values())
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"click>=7",
"colorama>=0.3.9",
"PyYAML>=5.1",
"semver>=2.10.2",
]


Expand Down

0 comments on commit 867e9ab

Please sign in to comment.