minor fixes & initialize context for release
This commit is contained in:
parent
7f7878fe36
commit
639815388e
11 changed files with 138 additions and 96 deletions
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = []
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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}")
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue