Commit caee2d13 authored by Noé Gaumont's avatar Noé Gaumont 🐙
Browse files

feat: allow some steps to fail during build and print summary

parent b1abb0ab3a7a
...@@ -5,7 +5,7 @@ import subprocess ...@@ -5,7 +5,7 @@ import subprocess
import sys import sys
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional, List from typing import Optional, List, Any
from itertools import product from itertools import product
...@@ -54,9 +54,36 @@ class CubicWebImage: ...@@ -54,9 +54,36 @@ class CubicWebImage:
return f"{REGISTRY}:{self.base_docker_image}-{self.cubicweb_major_version}" return f"{REGISTRY}:{self.base_docker_image}-{self.cubicweb_major_version}"
def conditionnal_append(
true_tab: List[Any], false_tab: List[Any], condition: bool, value: Any
):
if condition:
true_tab.append(value)
else:
false_tab.append(value)
def print_summary(action_type: str, succeed: List[Any], failed: List[Any]):
LOG.info(f"########### {action_type.upper()} SUMMARY #############")
LOG.info(f"Succeed {action_type.lower()}:")
for elem in succeed:
LOG.info(f" -✅ {elem}")
if failed:
LOG.warning(f"Failed {action_type.lower()}:")
for elem in failed:
LOG.warning(red(f" -❌ {elem}"))
else:
LOG.info(f"All {action_type.lower()} succeed. Good Job !")
def run(*args): def run(*args):
LOG.info("%s", " ".join(args)) LOG.info("%s", " ".join(args))
return subprocess.run(args, stdout=subprocess.PIPE) # Capture both stdout and stder
result = subprocess.run(args, capture_output=True)
if result.returncode != 0:
LOG.warning(result.stdout.decode())
LOG.warning(red(result.stderr.decode()))
return result
def check_call(*args): def check_call(*args):
...@@ -100,6 +127,8 @@ def get_major_tags(images: List[CubicWebImage]): ...@@ -100,6 +127,8 @@ def get_major_tags(images: List[CubicWebImage]):
def tag_aliases(images: List[CubicWebImage], last_debian_dist: str): def tag_aliases(images: List[CubicWebImage], last_debian_dist: str):
latest = get_major_tags(images) latest = get_major_tags(images)
tags = []
fail_tags = []
for major, img in latest.items(): for major, img in latest.items():
tag = f"{REGISTRY}:{major}" tag = f"{REGISTRY}:{major}"
for onbuild in [None, "onbuild"]: for onbuild in [None, "onbuild"]:
...@@ -108,18 +137,25 @@ def tag_aliases(images: List[CubicWebImage], last_debian_dist: str): ...@@ -108,18 +137,25 @@ def tag_aliases(images: List[CubicWebImage], last_debian_dist: str):
else: else:
tag = f"{REGISTRY}:{major}" tag = f"{REGISTRY}:{major}"
src = img.tag src = img.tag
check_call("docker", "tag", src, tag) res = run("docker", "tag", src, tag)
check_call("docker", "tag", src, img.major_tag) conditionnal_append(tags, fail_tags, res.returncode == 0, tag)
res = run("docker", "tag", src, img.major_tag)
conditionnal_append(tags, fail_tags, res.returncode == 0, img.major_tag)
check_call( res = run(
"docker", "docker",
"tag", "tag",
f"{REGISTRY}:{last_debian_dist}-buildpackage", f"{REGISTRY}:{last_debian_dist}-buildpackage",
f"{REGISTRY}:buildpackage", f"{REGISTRY}:buildpackage",
) )
conditionnal_append(
tags, fail_tags, res.returncode == 0, f"{REGISTRY}:buildpackage"
)
print_summary("tag", tags, fail_tags)
def build_image(image: CubicWebImage, onbuild: Optional[str], no_cache=False):
def build_image(image: CubicWebImage, onbuild: Optional[str], no_cache=False) -> bool:
args = {} args = {}
dockerfile = "Dockerfile" dockerfile = "Dockerfile"
if onbuild is not None: if onbuild is not None:
...@@ -152,7 +188,10 @@ def build_image(image: CubicWebImage, onbuild: Optional[str], no_cache=False): ...@@ -152,7 +188,10 @@ def build_image(image: CubicWebImage, onbuild: Optional[str], no_cache=False):
for key, value in args.items(): for key, value in args.items():
cmd += ["--build-arg", "{}={}".format(key, value)] cmd += ["--build-arg", "{}={}".format(key, value)]
cmd += ["."] cmd += ["."]
check_call(*cmd) result = run(*cmd)
if result.returncode != 0:
return False
return True
def green(text): def green(text):
...@@ -218,9 +257,12 @@ def build(debian_dists: List[str], images: List[CubicWebImage] = [], rebuild=Fal ...@@ -218,9 +257,12 @@ def build(debian_dists: List[str], images: List[CubicWebImage] = [], rebuild=Fal
# pull base images # pull base images
check_call("docker", "pull", f"debian:{dist}-slim") check_call("docker", "pull", f"debian:{dist}-slim")
build_buildpackage(dist) build_buildpackage(dist)
built_images = []
failed_images = []
for image in images: for image in images:
for image_type in (None, "onbuild"): for image_type in (None, "onbuild"):
build_image(image, image_type) built = build_image(image, image_type)
conditionnal_append(built_images, failed_images, built, image)
if rebuild and image_type is None: if rebuild and image_type is None:
tag = image.tag tag = image.tag
...@@ -247,11 +289,16 @@ def build(debian_dists: List[str], images: List[CubicWebImage] = [], rebuild=Fal ...@@ -247,11 +289,16 @@ def build(debian_dists: List[str], images: List[CubicWebImage] = [], rebuild=Fal
assert (out.returncode, out.stdout) == (0, b""), out assert (out.returncode, out.stdout) == (0, b""), out
LOG.info(green("%s debian packages are up-to-date"), tag) LOG.info(green("%s debian packages are up-to-date"), tag)
print_summary("build image", built_images, failed_images)
def push(images: List[CubicWebImage], last_debian_dist: str): def push(images: List[CubicWebImage], last_debian_dist: str):
latest = get_major_tags(images) latest = get_major_tags(images)
succeed_push = []
fail_push = []
for image in images: for image in images:
check_call("docker", "push", image.tag) res = run("docker", "push", image.tag)
conditionnal_append(succeed_push, fail_push, res.returncode == 0, image.tag)
for major, img in latest.items(): for major, img in latest.items():
tag = f"{REGISTRY}:{major}" tag = f"{REGISTRY}:{major}"
...@@ -261,15 +308,24 @@ def push(images: List[CubicWebImage], last_debian_dist: str): ...@@ -261,15 +308,24 @@ def push(images: List[CubicWebImage], last_debian_dist: str):
else: else:
tag = f"{REGISTRY}:{major}" tag = f"{REGISTRY}:{major}"
src = img.tag src = img.tag
check_call("docker", "push", major) res = run("docker", "push", major)
check_call("docker", "push", img.major_tag) conditionnal_append(succeed_push, fail_push, res.returncode == 0, major)
res = run("docker", "push", img.major_tag)
conditionnal_append(
succeed_push, fail_push, res.returncode == 0, image.major_tag
)
check_call( res = run(
"docker", "docker",
"push", "push",
f"{REGISTRY}:{last_debian_dist}-buildpackage", f"{REGISTRY}:{last_debian_dist}-buildpackage",
f"{REGISTRY}:buildpackage", f"{REGISTRY}:buildpackage",
) )
conditionnal_append(
succeed_push, fail_push, res.returncode == 0, f"{REGISTRY}:buildpackage"
)
print_summary("push image", succeed_push, fail_push)
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment