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

Commit f2f092b

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

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

scripts/images_containers_manifest.py

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

0 commit comments

Comments
 (0)