introduce artifact class

This commit is contained in:
Michael Jerger 2023-08-14 20:39:59 +02:00
parent d555b34eef
commit 2e24e79a4c
10 changed files with 143 additions and 39 deletions

View file

@ -94,8 +94,9 @@ classDiagram
release_artifact_token release_artifact_token
} }
class Artifact { class Artifact {
release_artifact_path path_str
release_artifact_type path()
type()
} }
class Credentials { class Credentials {
<<AggregateRoot>> <<AggregateRoot>>

View file

@ -2,7 +2,7 @@ import json
from typing import List from typing import List
from pathlib import Path from pathlib import Path
from ..infrastructure import GitApi, ArtifactDeploymentApi, BuildFileRepository from ..infrastructure import GitApi, ArtifactDeploymentApi, BuildFileRepository
from ..domain import Version, Release, ReleaseType from ..domain import Version, Release, ReleaseType, Artifact
class ReleaseService: class ReleaseService:
@ -70,29 +70,20 @@ class ReleaseService:
) )
) )
artifacts_to_attach = [] artifacts_sums = []
for artifact_path in release.release_artifacts: for artifact in release.release_artifacts:
self.artifact_deployment_api.calculate_checksums(artifact_path) sha256 = self.artifact_deployment_api.calculate_sha256(artifact.path())
# TODO: make api more explizit to have the path calculation & decision which shas to take clear sha512 = self.artifact_deployment_api.calculate_sha512(artifact.path())
artifacts_to_attach += [{ artifacts_sums += [Artifact(sha256), Artifact(sha512)]
"path": artifact_path,
# TODO: it will not always be a jar file -> move type to release input-side.
"type": "application/x-java-archive",
},
{
"path": f"{artifact_path}.sha256",
"type": "text/plain",
},
{
"path": f"{artifact_path}.sha512",
"type": "text/plain",
}]
for artifact in artifacts_to_attach: artifacts = release.release_artifacts + artifacts_sums
print(artifacts)
for artifact in artifacts:
print(str)
self.artifact_deployment_api.add_asset_to_release( self.artifact_deployment_api.add_asset_to_release(
release.forgejo_release_asset_api_endpoint(release_id), release.forgejo_release_asset_api_endpoint(release_id),
artifact["path"], artifact.path(),
artifact["type"], artifact.type(),
release.release_artifact_token, release.release_artifact_token,
) )

View file

@ -17,6 +17,7 @@ from .provider_hetzner import Hetzner
from .provider_aws import Aws from .provider_aws import Aws
from .provs_k3s import K3s from .provs_k3s import K3s
from .release import Release from .release import Release
from .artifact import Artifact
from .credentials import Credentials, CredentialMapping, GopassType from .credentials import Credentials, CredentialMapping, GopassType
from .version import Version from .version import Version
from .build_file import BuildFileType, BuildFile from .build_file import BuildFileType, BuildFile

View file

@ -0,0 +1,43 @@
from enum import Enum
from pathlib import Path
from .common import (
Validateable,
)
class ArtifactType(Enum):
TEXT = 0
JAR = 1
class Artifact(Validateable):
def __init__(self, path: str):
self.path_str = path
def path(self) -> Path:
return Path(self.path_str)
def type(self) -> str:
suffix = self.path().suffix
match suffix:
case ".jar":
return "application/x-java-archive"
case _:
return "text/plain"
def validate(self):
result = []
result += self.__validate_is_not_empty__("path_str")
try:
Path(self.path_str)
except Exception as e:
result += [f"path was not a valid: {e}"]
return result
def __str__(self):
return str(self.path())
def __eq__(self, other):
return other and self.__str__() == other.__str__()
def __hash__(self) -> int:
return self.__str__().__hash__()

View file

@ -7,6 +7,9 @@ from .common import (
from .version import ( from .version import (
Version, Version,
) )
from .artifact import (
Artifact,
)
class Release(Validateable): class Release(Validateable):
@ -17,7 +20,6 @@ class Release(Validateable):
self.release_primary_build_file = inp.get( self.release_primary_build_file = inp.get(
"release_primary_build_file", "./project.clj" "release_primary_build_file", "./project.clj"
) )
self.release_artifacts = inp.get("release_artifacts", [])
self.release_secondary_build_files = inp.get( self.release_secondary_build_files = inp.get(
"release_secondary_build_files", [] "release_secondary_build_files", []
) )
@ -26,6 +28,9 @@ class Release(Validateable):
self.release_organisation = inp.get("release_organisation") self.release_organisation = inp.get("release_organisation")
self.release_repository_name = inp.get("release_repository_name") self.release_repository_name = inp.get("release_repository_name")
self.release_artifact_token = inp.get("release_artifact_token") self.release_artifact_token = inp.get("release_artifact_token")
self.release_artifacts = []
for a in inp.get("release_artifacts", []):
self.release_artifacts.append(Artifact(a))
def update_release_type(self, release_type: ReleaseType): def update_release_type(self, release_type: ReleaseType):
self.release_type = release_type self.release_type = release_type

View file

@ -32,12 +32,6 @@ class Version(Validateable):
self.snapshot_suffix = snapshot_suffix self.snapshot_suffix = snapshot_suffix
self.default_snapshot_suffix = default_snapshot_suffix self.default_snapshot_suffix = default_snapshot_suffix
def __eq__(self, other):
return other and self.to_string() == other.to_string()
def __hash__(self) -> int:
return self.to_string().__hash__()
def is_snapshot(self): def is_snapshot(self):
return self.snapshot_suffix is not None return self.snapshot_suffix is not None
@ -139,3 +133,9 @@ class Version(Validateable):
snapshot_suffix=None, snapshot_suffix=None,
version_str=None, version_str=None,
) )
def __eq__(self, other):
return other and self.to_string() == other.to_string()
def __hash__(self) -> int:
return self.to_string().__hash__()

View file

@ -247,13 +247,16 @@ class ArtifactDeploymentApi:
+ f'-F "attachment=@{attachment};type={attachment_type}"', + f'-F "attachment=@{attachment};type={attachment_type}"',
) )
def calculate_checksums(self, artifact_path: str): def calculate_sha256(self, path: Path):
# self.execution_api.execute(f"find {artifact_path} -type f sum = f"{path}.sha256"
# -exec sha256sum {{}}; | sort > {artifact_path} sha256sum.lst")
# relevant für provs
self.execution_api( self.execution_api(
f"sha256sum {artifact_path} > {artifact_path}.sha256", f"sha256sum {path} > {sum}",
) )
return sum
def calculate_sha512(self, path: Path):
sum = f"{path}.sha512"
self.execution_api( self.execution_api(
f"sha512sum {artifact_path} > {artifact_path}.sha512", f"sha512sum {path} > {sum}",
) )
return sum

View file

@ -168,10 +168,15 @@ class ArtifactDeploymentApiMock:
self.create_forgejo_release_count += 1 self.create_forgejo_release_count += 1
return self.release return self.release
def add_asset_to_release(self, api_endpoint: str, attachment: str, attachment_type: str, token: str): def add_asset_to_release(
self, api_endpoint: str, attachment: str, attachment_type: str, token: str
):
self.add_asset_to_release_api_endpoint = api_endpoint self.add_asset_to_release_api_endpoint = api_endpoint
self.add_asset_to_release_count += 1 self.add_asset_to_release_count += 1
pass pass
def calculate_checksums(self, build_path: str): def calculate_sha256(self, path: Path):
pass return f"{path}.sha256"
def calculate_sha512(self, path: Path):
return f"{path}.sha512"

View file

@ -0,0 +1,29 @@
import pytest
from pybuilder.core import Project
from pathlib import Path
from src.main.python.ddadevops.domain import (
Validateable,
DnsRecord,
Devops,
BuildType,
MixinType,
Artifact,
Image,
)
from .helper import build_devops, devops_config
def test_sould_validate_release():
sut = Artifact("x")
assert sut.is_valid()
sut = Artifact(None)
assert not sut.is_valid()
def test_should_calculate_type():
sut = Artifact("x.jar")
assert "application/x-java-archive" == sut.type()
sut = Artifact("x.jar.sha256")
assert "text/plain" == sut.type()

View file

@ -4,6 +4,7 @@ from src.main.python.ddadevops.domain import (
Version, Version,
BuildType, BuildType,
MixinType, MixinType,
Artifact,
) )
@ -50,6 +51,7 @@ def test_devops_creation():
assert sut is not None assert sut is not None
assert sut.specialized_builds[BuildType.C4K] is not None assert sut.specialized_builds[BuildType.C4K] is not None
def test_release_devops_creation():
sut = DevopsFactory().build_devops( sut = DevopsFactory().build_devops(
{ {
"stage": "test", "stage": "test",
@ -67,6 +69,30 @@ def test_devops_creation():
assert sut is not None assert sut is not None
assert sut.mixins[MixinType.RELEASE] is not None assert sut.mixins[MixinType.RELEASE] is not None
sut = DevopsFactory().build_devops(
{
"stage": "test",
"name": "mybuild",
"module": "test_image",
"project_root_path": "../../..",
"build_types": [],
"mixin_types": ["RELEASE"],
"release_main_branch": "main",
"release_current_branch": "my_feature",
"release_config_file": "project.clj",
"release_artifacts": ["x.jar"],
"release_artifact_token": "y",
"release_artifact_server_url": "https://repo.prod.meissa.de",
"release_organisation": "meissa",
"release_repository_name": "provs",
},
Version.from_str("1.0.0", "SNAPSHOT"),
)
release = sut.mixins[MixinType.RELEASE]
assert release is not None
assert Artifact("x.jar") == release.release_artifacts[0]
def test_on_merge_input_should_win(): def test_on_merge_input_should_win():
sut = DevopsFactory() sut = DevopsFactory()