From 7f7878fe3656c6e92b695d4d9847b4f0ae03a406 Mon Sep 17 00:00:00 2001 From: Michael Jerger Date: Thu, 18 May 2023 17:24:05 +0200 Subject: [PATCH] release_mixin now might work --- .../python/ddadevops/application/__init__.py | 2 +- .../application/release_mixin_services.py | 80 ++++++++++++------- src/main/python/ddadevops/domain/release.py | 7 +- .../ddadevops/infrastructure/__init__.py | 1 + .../infrastructure/infrastructure.py | 51 ++++++++++++ .../infrastructure/release_mixin/__init__.py | 2 +- .../release_mixin/infrastructure_api.py | 49 ------------ src/main/python/ddadevops/release_mixin.py | 36 +++------ src/test/python/test_release_mixin.py | 4 - 9 files changed, 123 insertions(+), 109 deletions(-) diff --git a/src/main/python/ddadevops/application/__init__.py b/src/main/python/ddadevops/application/__init__.py index 6159750..9f46f1a 100644 --- a/src/main/python/ddadevops/application/__init__.py +++ b/src/main/python/ddadevops/application/__init__.py @@ -1,2 +1,2 @@ from .image_build_service import ImageBuildService -from .release_mixin_services import TagAndPushReleaseService, PrepareReleaseService +from .release_mixin_services import ReleaseService diff --git a/src/main/python/ddadevops/application/release_mixin_services.py b/src/main/python/ddadevops/application/release_mixin_services.py index 22c904c..655c230 100644 --- a/src/main/python/ddadevops/application/release_mixin_services.py +++ b/src/main/python/ddadevops/application/release_mixin_services.py @@ -1,34 +1,60 @@ -from src.main.python.ddadevops.infrastructure.release_mixin import ReleaseContextRepository, VersionRepository, GitApi +from typing import Optional, List +from src.main.python.ddadevops.infrastructure import GitApi, BuildFileRepository from src.main.python.ddadevops.domain import Version, Release -class PrepareReleaseService(): - - def __init__(self): - self.git_api = GitApi() - - def __write_and_commit_version(self, release: Release, version_repository: VersionRepository, version: Version, commit_message: str): - release.is_valid() - - version_repository.write_file(version.get_version_string()) - self.git_api.add_file(version_repository.file) - self.git_api.commit(commit_message) - - def write_and_commit_release(self, release: Release, version_repository: VersionRepository): - self.__write_and_commit_version(release, version_repository, release.release_version(), commit_message=f'Release v{release.release_version().get_version_string()}') - - def write_and_commit_bump(self, release: Release, version_repository: VersionRepository): - self.__write_and_commit_version(release, version_repository, release.bump_version(), commit_message='Version bump') - -class TagAndPushReleaseService(): - - def __init__(self, git_api: GitApi): +class ReleaseService: + def __init__(self, git_api: GitApi, build_file_repository: BuildFileRepository): self.git_api = git_api + self.build_file_repository = build_file_repository - def tag_release(self, release_repo: ReleaseContextRepository): - annotation = 'v' + release_repo.get_release().version.get_version_string() - message = 'Release ' + annotation - self.git_api.tag_annotated_second_last(annotation, message) + @classmethod + def prod(cls): + return cls( + GitApi(), + BuildFileRepository(), + ) - def push_release(self): + def prepare_release(self, release: Release): + match release.release_type: + case ReleaseType.MAJOR: + version = release.version.create_major() + case ReleaseType.MINOR: + version = release.version.create_minor() + case ReleaseType.PATCH: + version = release.version.create_patch() + case ReleaseType.NONE: + return + message = f"release: {version.to_string()}" + self.__set_version_and_commit__(version, release.build_files(), message) + + def tag_bump_and_push_release(self, release: Release): + match release.release_type: + case ReleaseType.MAJOR: + release_version = release.version.create_major() + case ReleaseType.MINOR: + release_version = release.version.create_minor() + case ReleaseType.PATCH: + release_version = release.version.create_patch() + case ReleaseType.NONE: + return + bump_version = release_version.create_bump() + release_message = f"release: {release_version.to_string()}" + bump_message = f"bump version to: {bump_version.to_string()}" + self.git_api.tag_annotated(release_version.to_string(), release_message, 0) + self.__set_version_and_commit__( + bump_version, + release.build_files(), + bump_message, + ) self.git_api.push() + + def __set_version_and_commit__( + self, version: Version, build_file_ids: List[str], message: str + ): + for id in build_file_ids: + build_file = self.build_file_repository.get(id) + build_file.set_version(release_version) + self.build_file_repository.write(build_file) + self.git_api.add_file(build_file.file_path) + self.git_api.commit(message) diff --git a/src/main/python/ddadevops/domain/release.py b/src/main/python/ddadevops/domain/release.py index b5b126b..5c36fdc 100644 --- a/src/main/python/ddadevops/domain/release.py +++ b/src/main/python/ddadevops/domain/release.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Optional +from typing import Optional, List from pathlib import Path from .common import ( Validateable, @@ -49,3 +49,8 @@ class Release(Validateable): ): result.append(f"Releases are allowed only on {self.release_main_branch}") return result + + def build_files(self) -> List[str]: + result = [self.release_primary_build_file] + result += self.release_secondary_build_files + return result diff --git a/src/main/python/ddadevops/infrastructure/__init__.py b/src/main/python/ddadevops/infrastructure/__init__.py index ab663ee..a0e975e 100644 --- a/src/main/python/ddadevops/infrastructure/__init__.py +++ b/src/main/python/ddadevops/infrastructure/__init__.py @@ -5,5 +5,6 @@ from .infrastructure import ( ExecutionApi, EnvironmentApi, CredentialsApi, + GitApi, ) from .repository import DevopsRepository, BuildFileRepository diff --git a/src/main/python/ddadevops/infrastructure/infrastructure.py b/src/main/python/ddadevops/infrastructure/infrastructure.py index 888afc4..9146e3c 100644 --- a/src/main/python/ddadevops/infrastructure/infrastructure.py +++ b/src/main/python/ddadevops/infrastructure/infrastructure.py @@ -133,3 +133,54 @@ class CredentialsApi: ["gopass", "show", "--password", path] ) return credential + + +class GitApi(): + + def __init__(self): + self.execution_api = ExecutionApi() + + # pylint: disable=invalid-name + def get_latest_n_commits(self, n: int): + return self.execution_api.execute( + f'git log --oneline --format="%s %b" -n {n}') + + def get_latest_commit(self): + return self.get_latest_n_commits(1) + + def tag_annotated(self, annotation: str, message: str, count: int): + return self.execution_api.execute( + f'git tag -a {annotation} -m {message} HEAD~{count}') + + def tag_annotated_second_last(self, annotation: str, message:str): + return self.tag_annotated(annotation, message, 1) + + def get_latest_tag(self): + return self.execution_api.execute('git describe --tags --abbrev=0') + + def get_current_branch(self): + return ''.join(self.execution_api.execute('git branch --show-current')).rstrip() + + def init(self, default_branch: str = "main"): + self.execution_api.execute('git init') + self.execution_api.execute(f'git checkout -b {default_branch}') + + def set_user_config(self, email: str, name: str): + self.execution_api.execute(f'git config user.email {email}') + self.execution_api.execute(f'git config user.name {name}') + + def add_file(self, file_path: Path): + return self.execution_api.execute(f'git add {file_path}') + + def add_remote(self, origin: str, url: str): + return self.execution_api.execute(f'git remote add {origin} {url}') + + def commit(self, commit_message: str): + return self.execution_api.execute( + f'git commit -m "{commit_message}"') + + def push(self): + return self.execution_api.execute('git push') + + def checkout(self, branch: str): + return self.execution_api.execute(f'git checkout {branch}') diff --git a/src/main/python/ddadevops/infrastructure/release_mixin/__init__.py b/src/main/python/ddadevops/infrastructure/release_mixin/__init__.py index b3120ff..9d311aa 100644 --- a/src/main/python/ddadevops/infrastructure/release_mixin/__init__.py +++ b/src/main/python/ddadevops/infrastructure/release_mixin/__init__.py @@ -1,2 +1,2 @@ -from .infrastructure_api import FileHandler, GitApi, JsonFileHandler, GradleFileHandler, PythonFileHandler, ClojureFileHandler +from .infrastructure_api import FileHandler, JsonFileHandler, GradleFileHandler, PythonFileHandler, ClojureFileHandler from .repo import VersionRepository, ReleaseContextRepository, ReleaseTypeRepository diff --git a/src/main/python/ddadevops/infrastructure/release_mixin/infrastructure_api.py b/src/main/python/ddadevops/infrastructure/release_mixin/infrastructure_api.py index 9a6ea17..0babdc1 100644 --- a/src/main/python/ddadevops/infrastructure/release_mixin/infrastructure_api.py +++ b/src/main/python/ddadevops/infrastructure/release_mixin/infrastructure_api.py @@ -180,54 +180,5 @@ class ClojureFileHandler(FileHandler): clj_file.truncate() -class GitApi(): - - def __init__(self): - self.execution_api = ExecutionApi() - - # pylint: disable=invalid-name - def get_latest_n_commits(self, n: int): - return self.execution_api.execute( - f'git log --oneline --format="%s %b" -n {n}') - - def get_latest_commit(self): - return self.get_latest_n_commits(1) - - def tag_annotated(self, annotation: str, message: str, count: int): - return self.execution_api.execute( - f'git tag -a {annotation} -m {message} HEAD~{count}') - - def tag_annotated_second_last(self, annotation: str, message:str): - return self.tag_annotated(annotation, message, 1) - - def get_latest_tag(self): - return self.execution_api.execute('git describe --tags --abbrev=0') - - def get_current_branch(self): - return ''.join(self.execution_api.execute('git branch --show-current')).rstrip() - - def init(self, default_branch: str = "main"): - self.execution_api.execute('git init') - self.execution_api.execute(f'git checkout -b {default_branch}') - - def set_user_config(self, email: str, name: str): - self.execution_api.execute(f'git config user.email {email}') - self.execution_api.execute(f'git config user.name {name}') - - def add_file(self, file_path: Path): - return self.execution_api.execute(f'git add {file_path}') - - def add_remote(self, origin: str, url: str): - return self.execution_api.execute(f'git remote add {origin} {url}') - - def commit(self, commit_message: str): - return self.execution_api.execute( - f'git commit -m "{commit_message}"') - - def push(self): - return self.execution_api.execute('git push') - - def checkout(self, branch: str): - return self.execution_api.execute(f'git checkout {branch}') diff --git a/src/main/python/ddadevops/release_mixin.py b/src/main/python/ddadevops/release_mixin.py index 8b5a94d..8488f61 100644 --- a/src/main/python/ddadevops/release_mixin.py +++ b/src/main/python/ddadevops/release_mixin.py @@ -1,39 +1,23 @@ from pybuilder.core import Project from src.main.python.ddadevops.devops_build import DevopsBuild -from src.main.python.ddadevops.infrastructure.release_mixin import ReleaseContextRepository, ReleaseTypeRepository, VersionRepository, GitApi -from src.main.python.ddadevops.infrastructure import EnvironmentApi -from src.main.python.ddadevops.application import PrepareReleaseService, TagAndPushReleaseService -from src.main.python.ddadevops.domain import Release, EnvironmentKeys, MixinType +from src.main.python.ddadevops.application import ReleaseService +from src.main.python.ddadevops.domain import MixinType + class ReleaseMixin(DevopsBuild): def __init__(self, project: Project, input: dict): super().__init__(project, input) - devops = self.repo.get_devops(self.project) - git_api = GitApi() - self.tag_and_push_release_service = TagAndPushReleaseService(git_api) - environment_api = EnvironmentApi() + self.release_service = ReleaseService.prod() + devops = self.devops_repo.get_devops(self.project) if MixinType.RELEASE not in devops.mixins: raise ValueError(f"ReleaseMixin requires MixinType.RELEASE") - # TODO: move this to service - release = devops.mixins[MixinType.RELEASE] - env_key = EnvironmentKeys.DDADEVOPS_RELEASE_TYPE.name - environment_val_set = environment_api.get(env_key) != "" and environment_api.get(env_key) is not None - if environment_val_set: - release_type_repo = ReleaseTypeRepository.from_environment(environment_api) - else: - release_type_repo = ReleaseTypeRepository.from_git(git_api) - version_repo = VersionRepository(release.release_config_file) - self.release_repo = ReleaseContextRepository(version_repo, release_type_repo) - # Here the initialization can happen - self.prepare_release_service = PrepareReleaseService() - def prepare_release(self): devops = self.repo.get_devops(self.project) release = devops.mixins[MixinType.RELEASE] - self.prepare_release_service.write_and_commit_release(release, self.release_repo.version_repository) - self.prepare_release_service.write_and_commit_bump(release, self.release_repo.version_repository) + self.release_service.prepare_release(release) - def tag_and_push_release(self): - self.tag_and_push_release_service.tag_release(self.release_repo) - self.tag_and_push_release_service.push_release() + def tag_bump_and_push_release(self): + devops = self.repo.get_devops(self.project) + release = devops.mixins[MixinType.RELEASE] + self.release_service.tag_bump_and_push_release(release) diff --git a/src/test/python/test_release_mixin.py b/src/test/python/test_release_mixin.py index ed5c417..8a579a7 100644 --- a/src/test/python/test_release_mixin.py +++ b/src/test/python/test_release_mixin.py @@ -3,10 +3,6 @@ from pathlib import Path from pybuilder.core import Project from src.main.python.ddadevops.release_mixin import ReleaseMixin -from src.main.python.ddadevops.infrastructure.release_mixin import ( - GitApi, - EnvironmentApi, -) from src.main.python.ddadevops.domain import Devops, Release from .resource_helper import ResourceHelper