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 Sep 2, 2020
1 parent 2909e92 commit ee3f23b
Showing 1 changed file with 104 additions and 14 deletions.
118 changes: 104 additions & 14 deletions reana/reana_dev/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,28 @@

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

import os
import re
import sys
from time import sleep

import click
import semver

from reana.reana_dev.docker import docker_push
from reana.config import REPO_LIST_CLUSTER
from reana.reana_dev.git import (
git_clean,
git_is_current_version_tagged,
is_last_commit_release_commit,
)
from reana.reana_dev.utils import (
bump_component_version,
display_message,
fetch_latest_pypi_version,
get_current_component_version_from_source_files,
get_current_tag,
get_srcdir,
is_component_dockerised,
parse_pep440_version,
run_command,
Expand Down Expand Up @@ -68,6 +73,26 @@ def is_component_releasable(component, exit_code=False, display=False):
return is_releasable


def get_component_version_as_semver2(component):
"""Get Docker release friendly component version (semver2)."""
docker_tag = ""
current_tag = get_current_tag(component)

if parse_pep440_version(current_tag):
docker_tag = translate_pep440_to_semver2(current_tag)
elif semver.VersionInfo.isvalid(current_tag):
docker_tag = current_tag
else:
display_message(
f"The component's latest tag ({current_tag}) is not a "
"valid version (nor PEP440 nor semver2 compliant).",
component,
)
sys.exit(1)

return docker_tag


@click.group()
def release_commands():
"""Release commands group."""
Expand Down Expand Up @@ -112,21 +137,8 @@ def release_docker(ctx, component, user, image_name): # noqa: D301
cannot_release_on_dockerhub.append(component_)
is_component_releasable(component_, exit_code=True, display=True)

current_tag = get_current_tag(component_)
full_image_name = f"{user}/{image_name or component_}"
docker_tag = ""

if parse_pep440_version(current_tag):
docker_tag = translate_pep440_to_semver2(current_tag)
elif semver.VersionInfo.isvalid(current_tag):
docker_tag = current_tag
else:
display_message(
f"The component's latest tag ({current_tag}) is not a "
"valid version (nor PEP440 nor semver2 compliant).",
component_,
)
sys.exit(1)
docker_tag = get_component_version_as_semver2(component_)

run_command(
f"docker tag {full_image_name}:latest {full_image_name}:{docker_tag}",
Expand Down Expand Up @@ -202,4 +214,82 @@ def release_pypi(ctx, component, timeout): # noqa: D301
click.secho(f"{component} successfully released on PyPI", fg="green")


@click.option(
"--version", "-v", help="REANA version to release, e.g. 0.7.0a1",
)
@click.option("--user", "-u", default="reanahub", help="DockerHub user name [reanahub]")
@release_commands.command(name="release-helm")
@click.pass_context
def release_helm(ctx, version, user): # noqa: D30
"""Release REANA as a Helm chart.
\b
:param components: The option ``component`` can be repeated. The value may
consist of:
* (1) standard component name such as
'reana-workflow-controller';
* (2) short component name such as 'r-w-controller';
* (3) special value '.' indicating component of the
current working directory;
* (4) special value 'CLUSTER' that will expand to
cover all REANA cluster components [default];
* (5) special value 'CLIENT' that will expand to
cover all REANA client components;
* (6) special value 'DEMO' that will expand
to include several runable REANA demo examples;
* (7) special value 'ALL' that will expand to include
all REANA repositories.
:type component: str
"""

def _update_values_yaml(new_docker_images):
"""Update all images in ``values.yaml``, skipping the ones up to date."""
update_images_cmds = [] # FIXME
values_yaml_relative_path = "helm/reana/values.yaml"
values_yaml_abs_path = os.path.join(
get_srcdir("reana"), values_yaml_relative_path
)
values_yaml = ""

with open(values_yaml_abs_path) as f:
values_yaml = f.read()
for docker_image in new_docker_images:
image_name, _ = docker_image.split(":")
if image_name in values_yaml:
values_yaml = re.sub(
f"{image_name}:.*", lambda _: docker_image, values_yaml, count=1
)

with open(values_yaml_abs_path, "w") as f:
f.write(values_yaml)

remaining_docker_releases = []
new_docker_images = []
for component in REPO_LIST_CLUSTER:
if not is_component_dockerised(component):
continue
if not git_is_current_version_tagged(component):
remaining_docker_releases.append(component)
else:
new_docker_images.append(
f"{user}/{component}:{get_component_version_as_semver2(component)}"
)

if remaining_docker_releases:
line_by_line_missing_releases = "\n".join(remaining_docker_releases)
click.secho(
"The following components are missing to be released:\n"
f"{line_by_line_missing_releases}",
fg="red",
)
sys.exit(1)

_update_values_yaml(new_docker_images)
version = bump_component_version(
"reana",
get_current_component_version_from_source_files("reana"),
next_version=version,
)


release_commands_list = list(release_commands.commands.values())

0 comments on commit ee3f23b

Please sign in to comment.