Skip to content

Commit b7ffe0e

Browse files
committed
fixup, add more logging and selftests
1 parent ea24927 commit b7ffe0e

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

ci/cached-builds/gen_gha_matrix_jobs.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import re
88
import string
99
import sys
10+
import unittest
1011
from typing import Iterable
1112

1213
import gha_pr_changed_files
@@ -120,11 +121,13 @@ def write_github_workflow_file(tree: dict[str, list[str]], path: pathlib.Path) -
120121
def flatten(list_of_lists):
121122
return list(itertools.chain.from_iterable(list_of_lists))
122123

124+
123125
def compute_leafs_in_dependency_tree(tree: dict[str, list[str]]) -> list[str]:
124126
key_set = set(tree.keys())
125127
value_set = set(flatten(tree.values()))
126128
return [key for key in key_set if key not in value_set]
127129

130+
128131
def print_github_actions_pr_matrix(tree: dict[str, list[str]], leafs: list[str]) -> list[str]:
129132
"""Outputs GitHub matrix definition Json
130133
"""
@@ -148,10 +151,14 @@ def main() -> None:
148151
logging.basicConfig(level=logging.DEBUG, stream=sys.stderr)
149152

150153
argparser = argparse.ArgumentParser()
151-
argparser.add_argument("--owner", type=str, required=False, help="GitHub repo owner/org (for the --skip-unchanged feature)")
152-
argparser.add_argument("--repo", type=str, required=False, help="GitHub repo name (for the --skip-unchanged feature)")
153-
argparser.add_argument("--pr-number", type=int, required=False, help="PR number under owner/repo (for the --skip-unchanged feature)")
154-
argparser.add_argument("--skip-unchanged", type=bool, required=False, default=False, action=argparse.BooleanOptionalAction)
154+
argparser.add_argument("--owner", type=str, required=False,
155+
help="GitHub repo owner/org (for the --skip-unchanged feature)")
156+
argparser.add_argument("--repo", type=str, required=False,
157+
help="GitHub repo name (for the --skip-unchanged feature)")
158+
argparser.add_argument("--pr-number", type=int, required=False,
159+
help="PR number under owner/repo (for the --skip-unchanged feature)")
160+
argparser.add_argument("--skip-unchanged", type=bool, required=False, default=False,
161+
action=argparse.BooleanOptionalAction)
155162
args = argparser.parse_args()
156163

157164
# https://www.gnu.org/software/make/manual/make.html#Reading-Makefiles
@@ -164,7 +171,8 @@ def main() -> None:
164171
leafs = compute_leafs_in_dependency_tree(tree)
165172
if args.skip_unchanged:
166173
logging.info(f"Skipping targets not modified in PR #{args.pr_number}")
167-
leafs = gha_pr_changed_files.filter_out_unchanged(args.owner, args.repo, args.pr_number, leafs)
174+
changed_files = gha_pr_changed_files.list_changed_files(args.owner, args.repo, args.pr_number)
175+
leafs = gha_pr_changed_files.filter_out_unchanged(leafs, changed_files)
168176
output = print_github_actions_pr_matrix(tree, leafs)
169177

170178
print("leafs", leafs)
@@ -176,3 +184,18 @@ def main() -> None:
176184

177185
if __name__ == '__main__':
178186
main()
187+
188+
189+
class SelfTests(unittest.TestCase):
190+
def test_select_changed_targets(self):
191+
with open(project_dir / "Makefile", "rt") as makefile:
192+
lines = read_makefile_lines(makefile)
193+
tree = extract_target_dependencies(lines)
194+
leafs = compute_leafs_in_dependency_tree(tree)
195+
196+
changed_files = ["jupyter/datascience/ubi9-python-3.9/Dockerfile"]
197+
198+
leafs = gha_pr_changed_files.filter_out_unchanged(leafs, changed_files)
199+
assert set(leafs) == {'cuda-jupyter-tensorflow-ubi9-python-3.9',
200+
'jupyter-trustyai-ubi9-python-3.9',
201+
'jupyter-pytorch-ubi9-python-3.9'}

ci/cached-builds/gha_pr_changed_files.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ def get_github_token() -> str:
1616

1717

1818
# https://docs.github.com/en/graphql/guides/forming-calls-with-graphql
19-
def compose_gh_api_request(pull_number: int, owner="opendatahub-io", repo="notebooks", per_page=100, cursor="") -> urllib.request.Request:
19+
def compose_gh_api_request(pull_number: int, owner="opendatahub-io", repo="notebooks", per_page=100,
20+
cursor="") -> urllib.request.Request:
2021
github_token = get_github_token()
2122

2223
return urllib.request.Request(
@@ -52,7 +53,8 @@ def list_changed_files(owner: str, repo: str, pr_number: int, per_page=100) -> l
5253

5354
CURSOR = ""
5455
while CURSOR is not None:
55-
request = compose_gh_api_request(pull_number=pr_number, owner=owner, repo=repo, per_page=per_page, cursor=CURSOR)
56+
request = compose_gh_api_request(pull_number=pr_number, owner=owner, repo=repo, per_page=per_page,
57+
cursor=CURSOR)
5658
response = urllib.request.urlopen(request)
5759
data = json.loads(response.read().decode("utf-8"))
5860
response.close()
@@ -81,21 +83,30 @@ def analyze_build_directories(make_target) -> list[str]:
8183
print(e.stderr, e.stdout)
8284
raise
8385

84-
logging.debug(f"Running make in --just-print mode for target {make_target}")
86+
logging.debug(f"Target {make_target} depends on files in directories {directories}")
8587
return directories
8688

8789

88-
def should_build_target(changed_files: list[str], target_directories: list[str]) -> bool:
90+
def should_build_target(changed_files: list[str], target_directories: list[str]) -> str:
91+
"""Returns truthy if there is at least one changed file necessitating a build.
92+
Falsy (empty) string is returned otherwise."""
8993
for directory in target_directories:
90-
if any(changed_file.startswith(directory) for changed_file in changed_files):
91-
return True
92-
return False
94+
for changed_file in changed_files:
95+
if changed_file.startswith(directory):
96+
return changed_file
97+
return ""
9398

9499

95-
def filter_out_unchanged(owner: str, repo: str, pr_number: int, targets: list[str]) -> list[str]:
96-
changed_files = list_changed_files(owner, repo, pr_number)
97-
return [target for target in targets if
98-
should_build_target(changed_files, target_directories=analyze_build_directories(target))]
100+
def filter_out_unchanged(targets: list[str], changed_files: list[str]) -> list[str]:
101+
changed = []
102+
for target in targets:
103+
target_directories = analyze_build_directories(target)
104+
if reason := should_build_target(changed_files, target_directories):
105+
logging.info(f"✅ Will build {target} because file {reason} has been changed")
106+
changed.append(target)
107+
else:
108+
logging.info(f"❌ Won't build {target}")
109+
return changed
99110

100111

101112
class SelTestsTest(unittest.TestCase):
@@ -104,12 +115,12 @@ def test_compose_gh_api_request__call_without_asserting(self):
104115
print(request.data)
105116

106117
def test_list_changed_files__pagination_works(self):
107-
changed_files = list_changed_files(556, per_page=1)
108-
assert changed_files == ['codeserver/ubi9-python-3.9/Dockerfile',
109-
'codeserver/ubi9-python-3.9/run-code-server.sh']
118+
changed_files = list_changed_files(owner="opendatahub-io", repo="notebooks", pr_number=556, per_page=1)
119+
assert set(changed_files) == {'codeserver/ubi9-python-3.9/Dockerfile',
120+
'codeserver/ubi9-python-3.9/run-code-server.sh'}
110121

111122
def test_analyze_build_directories(self):
112123
directories = analyze_build_directories("jupyter-intel-pytorch-ubi9-python-3.9")
113-
assert directories == ["base/ubi9-python-3.9",
114-
"intel/base/gpu/ubi9-python-3.9",
115-
"jupyter/intel/pytorch/ubi9-python-3.9"]
124+
assert set(directories) == {"base/ubi9-python-3.9",
125+
"intel/base/gpu/ubi9-python-3.9",
126+
"jupyter/intel/pytorch/ubi9-python-3.9"}

0 commit comments

Comments
 (0)