Skip to content
This repository was archived by the owner on Aug 25, 2024. It is now read-only.

Commit fbeedde

Browse files
author
John Andersen
committed
scripts: images containers manifest: Build json from dirs
Related: #1273 Signed-off-by: John Andersen <[email protected]>
1 parent 7f98408 commit fbeedde

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

scripts/images_containers_manifest.py

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# This file generates a manifest for building container images
2+
# Usage: JSON_INDENT=" " nodemon -e py,Dockerfile,HEAD --exec 'clear; python scripts/images_containers_manifest.py; test 1'
3+
import os
4+
import sys
5+
import json
6+
import pathlib
7+
import itertools
8+
import traceback
9+
import subprocess
10+
import urllib.request
11+
12+
try:
13+
os.environ.update({
14+
"ROOT_PATH": str(pathlib.Path(subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode().strip()).relative_to(os.getcwd())),
15+
"SCHEMA": "https://github.com/intel/dffml/raw/c82f7ddd29a00d24217c50370907c281c4b5b54d/schema/github/actions/build/images/containers/0.0.0.schema.json",
16+
"COMMIT": subprocess.check_output(["git", "log", "-n", "1", "--format=%H"]).decode().strip(),
17+
"OWNER_REPOSITORY": "/".join(subprocess.check_output(["git", "remote", "get-url", "origin"]).decode().strip().replace(".git", "").split("/")[-2:]),
18+
"BRANCH": subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode().strip(),
19+
"PREFIX": os.environ.get("PREFIX", json.dumps([
20+
".",
21+
"scripts",
22+
"dffml/skel/operations",
23+
])),
24+
"NO_DELTA_PREFIX": os.environ.get("NO_DELTA_PREFIX", json.dumps([
25+
".",
26+
"scripts",
27+
"dffml/skel/operations",
28+
])),
29+
})
30+
except:
31+
traceback.print_exc(file=sys.stderr)
32+
33+
def path_to_image_name(path, root_path):
34+
# Stem as image name
35+
if path.stem != "Dockerfile":
36+
return path.stem
37+
# Non-top level no stem as image name (filename is Dockerfile)
38+
hyphen_dir_path = str(path.parent.relative_to(root_path)).replace(os.sep, "-")
39+
if hyphen_dir_path != ".":
40+
return hyphen_dir_path
41+
# Top level dir Dockerfile use top level dirname
42+
return str(root_path.resolve().name)
43+
44+
# Pull request file change delta filter using GitHub API
45+
prefixes = json.loads(os.environ["PREFIX"])
46+
no_delta_prefixes = json.loads(os.environ["NO_DELTA_PREFIX"])
47+
owner, repository = os.environ["OWNER_REPOSITORY"].split("/", maxsplit=1)
48+
base = None
49+
env_vars = ["BASE", "BASE_REF"]
50+
for env_var in env_vars:
51+
if env_var in os.environ and os.environ[env_var].strip():
52+
# Set if present and not blank
53+
base = os.environ[env_var]
54+
55+
# Empty manifest (list of manifests for each build file) in case not triggered
56+
# from on file change (workflow changed or dispatched).
57+
manifest = []
58+
# Path to root of repo
59+
root_path = pathlib.Path(os.environ["ROOT_PATH"])
60+
# Grab commit from git
61+
commit = os.environ["COMMIT"]
62+
if base is None:
63+
print(f"::notice file={__file__},line=1,endLine=1,title=nobase::None of {env_vars!r} found in os.environ", file=sys.stderr)
64+
65+
else:
66+
compare_url = os.environ["COMPARE_URL"]
67+
compare_url = compare_url.replace("{base}", base)
68+
compare_url = compare_url.replace("{head}", os.environ["HEAD"])
69+
with urllib.request.urlopen(
70+
urllib.request.Request(
71+
compare_url,
72+
headers={
73+
"Authorization": "bearer " + os.environ["GH_ACCESS_TOKEN"],
74+
},
75+
)
76+
) as response:
77+
response_json = json.load(response)
78+
# Print for debug
79+
print(json.dumps(response_json, sort_keys=True, indent=4))
80+
# Build the most recent commit
81+
commit = response_json["commits"][-1]["sha"]
82+
manifest = list(itertools.chain(*(
83+
[
84+
[
85+
{
86+
"image_name": path_to_image_name(path, root_path),
87+
"dockerfile": str(path.relative_to(root_path)),
88+
"owner": owner,
89+
"repository": repository,
90+
"branch": os.environ["BRANCH"],
91+
"commit": commit,
92+
}
93+
for path in [
94+
(print(compare_file) or pathlib.Path(compare_file["filename"]))
95+
for compare_file in response_json["files"]
96+
if (
97+
any([
98+
compare_file["filename"].startswith(prefix_path)
99+
for prefix_path in json.loads(os.environ["PREFIX"])
100+
]) and compare_file["filename"].endswith("Dockerfile")
101+
)
102+
]
103+
]
104+
] + [
105+
[
106+
json.loads(path.read_text())
107+
for path in [
108+
(print(compare_file) or pathlib.Path(compare_file["filename"]))
109+
for compare_file in response_json["files"]
110+
if (
111+
any([
112+
compare_file["filename"].startswith(prefix_path)
113+
for prefix_path in json.loads(os.environ["PREFIX"])
114+
]) and compare_file["filename"].endswith("manifest.json")
115+
)
116+
]
117+
]
118+
]
119+
)))
120+
121+
# Build everything if we aren't sure why we got here
122+
if not manifest:
123+
manifest = list(itertools.chain(*(
124+
[
125+
[
126+
{
127+
"image_name": path_to_image_name(path, root_path),
128+
"dockerfile": str(path.relative_to(root_path)),
129+
"owner": owner,
130+
"repository": repository,
131+
"branch": os.environ["BRANCH"],
132+
"commit": commit,
133+
}
134+
for path in prefix_path.glob("*Dockerfile")
135+
]
136+
for prefix_path in map(pathlib.Path, prefixes)
137+
if any(
138+
str(prefix_path.relative_to(root_path)) in no_delta_prefix
139+
for no_delta_prefix in no_delta_prefixes
140+
)
141+
] + [
142+
[
143+
json.loads(path.read_text())
144+
for path in prefix_path.glob("*manifest.json")
145+
]
146+
for prefix_path in map(pathlib.Path, prefixes)
147+
if any(
148+
str(prefix_path.relative_to(root_path)) in no_delta_prefix
149+
for no_delta_prefix in no_delta_prefixes
150+
)
151+
]
152+
)))
153+
154+
# Add proxies or other runtime args/env vars
155+
for i in manifest:
156+
build_args = {}
157+
if "build_args" in i:
158+
build_args = dict(json.loads(i["build_args"]))
159+
for env_var in [
160+
"HTTP_PROXY",
161+
"HTTPS_PROXY",
162+
"NO_PROXY",
163+
]:
164+
if not env_var in os.environ:
165+
continue
166+
build_args[env_var] = os.environ[env_var]
167+
i["build_args"] = json.dumps(list(build_args.items()))
168+
169+
print(json.dumps({
170+
"@context": {
171+
"@vocab": os.environ["SCHEMA"],
172+
},
173+
"include": manifest,
174+
}, sort_keys=True, indent=os.environ.get("JSON_INDENT", None)))

0 commit comments

Comments
 (0)