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
}
class Artifact {
release_artifact_path
release_artifact_type
path_str
path()
type()
}
class Credentials {
<<AggregateRoot>>

View file

@ -2,7 +2,7 @@ import json
from typing import List
from pathlib import Path
from ..infrastructure import GitApi, ArtifactDeploymentApi, BuildFileRepository
from ..domain import Version, Release, ReleaseType
from ..domain import Version, Release, ReleaseType, Artifact
class ReleaseService:
@ -70,29 +70,20 @@ class ReleaseService:
)
)
artifacts_to_attach = []
for artifact_path in release.release_artifacts:
self.artifact_deployment_api.calculate_checksums(artifact_path)
# TODO: make api more explizit to have the path calculation & decision which shas to take clear
artifacts_to_attach += [{
"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",
}]
artifacts_sums = []
for artifact in release.release_artifacts:
sha256 = self.artifact_deployment_api.calculate_sha256(artifact.path())
sha512 = self.artifact_deployment_api.calculate_sha512(artifact.path())
artifacts_sums += [Artifact(sha256), Artifact(sha512)]
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(
release.forgejo_release_asset_api_endpoint(release_id),
artifact["path"],
artifact["type"],
artifact.path(),
artifact.type(),
release.release_artifact_token,
)

View file

@ -17,6 +17,7 @@ from .provider_hetzner import Hetzner
from .provider_aws import Aws
from .provs_k3s import K3s
from .release import Release
from .artifact import Artifact
from .credentials import Credentials, CredentialMapping, GopassType
from .version import Version
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 (
Version,
)
from .artifact import (
Artifact,
)
class Release(Validateable):
@ -17,7 +20,6 @@ class Release(Validateable):
self.release_primary_build_file = inp.get(
"release_primary_build_file", "./project.clj"
)
self.release_artifacts = inp.get("release_artifacts", [])
self.release_secondary_build_files = inp.get(
"release_secondary_build_files", []
)
@ -26,6 +28,9 @@ class Release(Validateable):
self.release_organisation = inp.get("release_organisation")
self.release_repository_name = inp.get("release_repository_name")
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):
self.release_type = release_type

View file

@ -32,12 +32,6 @@ class Version(Validateable):
self.snapshot_suffix = 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):
return self.snapshot_suffix is not None
@ -139,3 +133,9 @@ class Version(Validateable):
snapshot_suffix=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}"',
)
def calculate_checksums(self, artifact_path: str):
# self.execution_api.execute(f"find {artifact_path} -type f
# -exec sha256sum {{}}; | sort > {artifact_path} sha256sum.lst")
# relevant für provs
def calculate_sha256(self, path: Path):
sum = f"{path}.sha256"
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(
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
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_count += 1
pass
def calculate_checksums(self, build_path: str):
pass
def calculate_sha256(self, path: Path):
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,
BuildType,
MixinType,
Artifact,
)
@ -50,6 +51,7 @@ def test_devops_creation():
assert sut is not None
assert sut.specialized_builds[BuildType.C4K] is not None
def test_release_devops_creation():
sut = DevopsFactory().build_devops(
{
"stage": "test",
@ -67,6 +69,30 @@ def test_devops_creation():
assert sut 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():
sut = DevopsFactory()