minor fixes & initialize context for release

This commit is contained in:
Michael Jerger 2023-05-18 18:23:51 +02:00
parent 7f7878fe36
commit 639815388e
11 changed files with 138 additions and 96 deletions

View file

@ -9,10 +9,10 @@ class ReleaseService:
self.build_file_repository = build_file_repository
@classmethod
def prod(cls):
def prod(cls, base_dir: str):
return cls(
GitApi(),
BuildFileRepository(),
BuildFileRepository(base_dir),
)
def prepare_release(self, release: Release):

View file

@ -2,7 +2,7 @@ from .common import Validateable, DnsRecord, Devops, BuildType, MixinType, Relea
from .devops_factory import DevopsFactory
from .image import Image
from .c4k import C4k
from .release import Release, EnvironmentKeys
from .release import Release
from .credentials import Credentials, CredentialMapping, GopassType
from .version import Version
from .build_file import BuildFileType, BuildFile

View file

@ -33,7 +33,7 @@ class DevopsFactory:
return devops
def merge(self, input: dict, context: dict, authorization: dict) -> dict:
return {} | input | context | authorization
return {} | context | authorization | input
def __parse_build_types__(self, build_types: List[str]) -> List[BuildType]:
result = []

View file

@ -4,19 +4,22 @@ from .common import Devops, MixinType, BuildType
from .credentials import Credentials, GopassType
from .devops_factory import DevopsFactory
from .version import Version
from .release import ReleaseType
from src.main.python.ddadevops.infrastructure import (
BuildFileRepository,
CredentialsApi,
EnvironmentApi,
GitApi
)
class InitService:
def __init__(self, devops_factory, build_file_repository, credentials_api, environment_api):
def __init__(self, devops_factory, build_file_repository, credentials_api, environment_api, git_api):
self.devops_factory = devops_factory
self.build_file_repository = build_file_repository
self.credentials_api = credentials_api
self.environment_api = environment_api
self.git_api = git_api
@classmethod
def prod(cls, base_dir: str):
@ -25,6 +28,7 @@ class InitService:
BuildFileRepository(base_dir),
CredentialsApi(),
EnvironmentApi(),
GitApi(),
)
def initialize(self, input: dict) -> Devops:
@ -47,9 +51,11 @@ class InitService:
},
]
credentials = Credentials(input, default_mappings)
authorization = self.resolve_passwords(credentials)
authorization = self.authorization(credentials)
merged = self.devops_factory.merge(input, {}, authorization)
context = self.context()
merged = self.devops_factory.merge(input, context, authorization)
if MixinType.RELEASE in mixin_types:
primary_build_file_id = merged.get(
@ -62,7 +68,23 @@ class InitService:
return self.devops_factory.build_devops(merged, version=version)
def resolve_passwords(self, credentials: Credentials) -> List[str]:
def context(self) -> dict:
result = {}
release_type = self.environment_api.get("RELEASE_TYPE")
if not release_type:
latest_commit = self.git_api.get_latest_commit()
if latest_commit in [ReleaseType.MAJOR.name, ReleaseType.MINOR.name,
ReleaseType.PATCH.name, ReleaseType.NONE.name]:
release_type = latest_commit
result["release_type"] = release_type
result["release_current_branch"] = self.git_api.get_current_branch()
return result
def authorization(self, credentials: Credentials) -> List[str]:
result = {}
for name in credentials.mappings.keys():
mapping = credentials.mappings[name]

View file

@ -11,19 +11,19 @@ from .version import (
)
class EnvironmentKeys(Enum):
DDADEVOPS_RELEASE_TYPE = 0
class Release(Validateable):
def __init__(self, input: dict, version: Version):
self.release_type = ReleaseType[input.get("release_type", "NONE")]
self.release_main_branch = input.get("release_main_branch", "main")
self.release_current_branch = input.get("release_current_branch")
self.release_primary_build_file = input.get("release_primary_build_file", "./project.clj")
self.release_secondary_build_files = input.get("release_secondary_build_files", [])
self.release_primary_build_file = input.get(
"release_primary_build_file", "./project.clj"
)
self.release_secondary_build_files = input.get(
"release_secondary_build_files", []
)
self.version = version
def validate(self):
result = []
result += self.__validate_is_not_empty__("release_type")
@ -34,12 +34,16 @@ class Release(Validateable):
try:
Path(self.release_primary_build_file)
except Exception as e:
result.append(f"release_primary_build_file must be a valid path but was {e}")
result.append(
f"release_primary_build_file must be a valid path but was {e}"
)
for path in self.release_secondary_build_files:
try:
Path(path)
except Exception as e:
result.append(f"release_secondary_build_file must be contain valid paths but was {e}")
result.append(
f"release_secondary_build_file must be contain valid paths but was {e}"
)
if self.version:
result += self.version.validate()
if (

View file

@ -3,7 +3,6 @@ from sys import stdout
from os import chmod, environ
from pkg_resources import resource_string
import yaml
import deprecation
from subprocess import check_output, Popen, PIPE, run
from ..domain import Devops, Image, C4k, Release, BuildFile
@ -135,52 +134,50 @@ class CredentialsApi:
return credential
class GitApi():
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}')
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}')
f"git tag -a {annotation} -m {message} HEAD~{count}"
)
def tag_annotated_second_last(self, annotation: str, message:str):
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')
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()
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}')
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}')
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}')
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}')
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}"')
return self.execution_api.execute(f'git commit -m "{commit_message}"')
def push(self):
return self.execution_api.execute('git push')
return self.execution_api.execute("git push")
def checkout(self, branch: str):
return self.execution_api.execute(f'git checkout {branch}')
return self.execution_api.execute(f"git checkout {branch}")

View file

@ -7,7 +7,7 @@ from src.main.python.ddadevops.domain import MixinType
class ReleaseMixin(DevopsBuild):
def __init__(self, project: Project, input: dict):
super().__init__(project, input)
self.release_service = ReleaseService.prod()
self.release_service = ReleaseService.prod(project.basedir)
devops = self.devops_repo.get_devops(self.project)
if MixinType.RELEASE not in devops.mixins:
raise ValueError(f"ReleaseMixin requires MixinType.RELEASE")

View file

@ -74,3 +74,44 @@ class CredentialsApiMock:
def gopass_password_from_path(self, path):
return self.mappings.get(path, None)
class GitApiMock:
def get_latest_n_commits(self, n: int):
pass
def get_latest_commit(self):
pass
def tag_annotated(self, annotation: str, message: str, count: int):
pass
def tag_annotated_second_last(self, annotation: str, message: str):
pass
def get_latest_tag(self):
pass
def get_current_branch(self):
pass
def init(self, default_branch: str = "main"):
pass
def set_user_config(self, email: str, name: str):
pass
def add_file(self, file_path: Path):
pass
def add_remote(self, origin: str, url: str):
pass
def commit(self, commit_message: str):
pass
def push(self):
pass
def checkout(self, branch: str):
pass

View file

@ -10,6 +10,7 @@ from .helper import (
BuildFileRepositoryMock,
EnvironmentApiMock,
CredentialsApiMock,
GitApiMock,
devops_config,
)
@ -23,6 +24,7 @@ def test_should_load_build_file():
"server/meissa/grafana-cloud": "gopass-gfc-password",
}),
EnvironmentApiMock({}),
GitApiMock(),
)
assert (
Version.from_str("1.1.5-SNAPSHOT")
@ -41,8 +43,12 @@ def test_should_resolve_passwords():
}
),
EnvironmentApiMock({"C4K_GRAFANA_CLOUD_USER": "env-gfc-user"}),
GitApiMock(),
)
devops = sut.initialize(devops_config({}))
config = devops_config({})
del config["c4k_grafana_cloud_user"]
del config["c4k_grafana_cloud_password"]
devops = sut.initialize(config)
c4k = devops.specialized_builds[BuildType.C4K]
assert {
"mon-auth": {

View file

@ -5,7 +5,7 @@ from src.main.python.ddadevops.c4k_build import C4kBuild, add_c4k_mixin_config
from .domain.helper import devops_config
def test_c4k_mixin(tmp_path):
def test_c4k_build(tmp_path):
str_tmp_path = str(tmp_path)
project = Project(str_tmp_path, name="name")

View file

@ -1,83 +1,55 @@
import pytest as pt
import os
from pathlib import Path
from pybuilder.core import Project
from src.main.python.ddadevops.release_mixin import ReleaseMixin
from src.main.python.ddadevops.domain import Devops, Release
from .resource_helper import ResourceHelper
from .domain.test_helper import devops_config
MAIN_BRANCH = "main"
STAGE = "test"
PROJECT_ROOT_PATH = "."
MODULE = "test"
BUILD_DIR_NAME = "build_dir"
def change_test_dir(tmp_path: Path, monkeypatch: pt.MonkeyPatch):
monkeypatch.chdir(tmp_path)
def initialize_with_object(project, CONFIG_FILE):
project.build_depends_on("ddadevops>=3.1.2")
build = ReleaseMixin(
project,
devops_config(
{
"name": "release_test",
"stage": "test",
"module": MODULE,
"project_root_path": PROJECT_ROOT_PATH,
"build_types": [],
"mixin_types": ["RELEASE"],
"build_dir_name": BUILD_DIR_NAME,
"release_main_branch": MAIN_BRANCH,
"release_config_file": CONFIG_FILE,
}
),
)
return build
from .domain.helper import devops_config
from .resource_helper import copy_resource
def test_release_mixin(tmp_path):
tmp_path_str = str(tmp_path)
str_tmp_path = str(tmp_path)
copy_resource(Path('package.json'), tmp_path)
project = Project(str_tmp_path, name="name")
project = Project(tmp_path_str, name="name")
sut = ReleaseMixin(
project,
devops_config(
{
"project_root_path": tmp_path_str,
"build_types": [],
"project_root_path": str_tmp_path,
"mixin_types": ["RELEASE"],
"build_types": [],
"module": "release-test",
}
),
)
assert sut is not None
sut.initialize_build_dir()
assert sut.build_path() == f"{str_tmp_path}/target/name/release-test"
def test_release_mixin_git(tmp_path: Path, monkeypatch: pt.MonkeyPatch):
# init
th = ResourceHelper()
th.copy_files(th.TEST_FILE_PATH, tmp_path)
th.TEST_FILE_PATH = tmp_path / th.TEST_FILE_NAME
# def test_release_mixin_git(tmp_path: Path, monkeypatch: pt.MonkeyPatch):
# # init
# th = ResourceHelper()
# th.copy_files(th.TEST_FILE_PATH, tmp_path)
# th.TEST_FILE_PATH = tmp_path / th.TEST_FILE_NAME
change_test_dir(tmp_path, monkeypatch)
project = Project(tmp_path)
# change_test_dir(tmp_path, monkeypatch)
# project = Project(tmp_path)
git_api = GitApi()
git_api.init()
git_api.set_user_config("ex.ample@mail.com", "Ex Ample")
git_api.add_file(th.TEST_FILE_NAME)
git_api.commit("MAJOR release")
# git_api = GitApi()
# git_api.init()
# git_api.set_user_config("ex.ample@mail.com", "Ex Ample")
# git_api.add_file(th.TEST_FILE_NAME)
# git_api.commit("MAJOR release")
build = initialize_with_object(project, th.TEST_FILE_PATH)
build.prepare_release()
release_version = build.release_repo.version_repository.get_version()
# build = initialize_with_object(project, th.TEST_FILE_PATH)
# build.prepare_release()
# release_version = build.release_repo.version_repository.get_version()
# test
assert "124.0.1-SNAPSHOT" in release_version.get_version_string()
# # test
# assert "124.0.1-SNAPSHOT" in release_version.get_version_string()
# def test_release_mixin_environment(tmp_path: Path, monkeypatch: pt.MonkeyPatch):