-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Limit PR checks to build only the modified images #558
Merged
openshift-merge-bot
merged 1 commit into
opendatahub-io:main
from
jiridanek:jd_try_dep_inside_nodes
Jun 26, 2024
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import json | ||
import logging | ||
import os | ||
import pathlib | ||
import re | ||
import subprocess | ||
import unittest | ||
import urllib.request | ||
|
||
PROJECT_ROOT = pathlib.Path(__file__).parent.parent.parent.resolve() | ||
|
||
|
||
def get_github_token() -> str: | ||
github_token = os.environ['GITHUB_TOKEN'] | ||
return github_token | ||
|
||
|
||
# https://docs.github.com/en/graphql/guides/forming-calls-with-graphql | ||
def compose_gh_api_request(pull_number: int, owner="opendatahub-io", repo="notebooks", per_page=100, | ||
cursor="") -> urllib.request.Request: | ||
github_token = get_github_token() | ||
|
||
return urllib.request.Request( | ||
url="https://api.github.com/graphql", | ||
method="POST", | ||
headers={ | ||
"Authorization": f"bearer {github_token}", | ||
}, | ||
# https://docs.github.com/en/graphql/guides/using-the-explorer | ||
data=json.dumps({"query": f""" | ||
{{ | ||
repository(owner:"{owner}", name:"{repo}") {{ | ||
pullRequest(number:{pull_number}) {{ | ||
files(first:{per_page}, after:"{cursor}") {{ | ||
edges {{ | ||
node {{ | ||
path | ||
}} | ||
cursor | ||
}} | ||
}} | ||
}} | ||
}} | ||
}} | ||
"""}).encode("utf-8"), | ||
) | ||
|
||
|
||
def list_changed_files(owner: str, repo: str, pr_number: int, per_page=100) -> list[str]: | ||
files = [] | ||
|
||
logging.debug("Getting list of changed files from GitHub API") | ||
|
||
CURSOR = "" | ||
while CURSOR is not None: | ||
request = compose_gh_api_request(pull_number=pr_number, owner=owner, repo=repo, per_page=per_page, | ||
cursor=CURSOR) | ||
response = urllib.request.urlopen(request) | ||
data = json.loads(response.read().decode("utf-8")) | ||
response.close() | ||
edges = data["data"]["repository"]["pullRequest"]["files"]["edges"] | ||
|
||
CURSOR = None | ||
for edge in edges: | ||
files.append(edge["node"]["path"]) | ||
CURSOR = edge["cursor"] | ||
|
||
logging.debug(f"Determined {len(files)} changed files: {files[:5]} (..., printing up to 5)") | ||
return files | ||
|
||
|
||
def analyze_build_directories(make_target) -> list[str]: | ||
directories = [] | ||
|
||
pattern = re.compile(r"#\*# Image build directory: <(?P<dir>[^>]+)> #\(MACHINE-PARSED LINE\)#\*#\.\.\.") | ||
try: | ||
logging.debug(f"Running make in --just-print mode for target {make_target}") | ||
for line in subprocess.check_output(["make", make_target, "--just-print"], encoding="utf-8", | ||
cwd=PROJECT_ROOT).splitlines(): | ||
if m := pattern.match(line): | ||
directories.append(m["dir"]) | ||
except subprocess.CalledProcessError as e: | ||
print(e.stderr, e.stdout) | ||
raise | ||
|
||
logging.debug(f"Target {make_target} depends on files in directories {directories}") | ||
return directories | ||
|
||
|
||
def should_build_target(changed_files: list[str], target_directories: list[str]) -> str: | ||
"""Returns truthy if there is at least one changed file necessitating a build. | ||
Falsy (empty) string is returned otherwise.""" | ||
for directory in target_directories: | ||
for changed_file in changed_files: | ||
if changed_file.startswith(directory): | ||
return changed_file | ||
return "" | ||
|
||
|
||
def filter_out_unchanged(targets: list[str], changed_files: list[str]) -> list[str]: | ||
changed = [] | ||
for target in targets: | ||
target_directories = analyze_build_directories(target) | ||
if reason := should_build_target(changed_files, target_directories): | ||
logging.info(f"✅ Will build {target} because file {reason} has been changed") | ||
changed.append(target) | ||
else: | ||
logging.info(f"❌ Won't build {target}") | ||
return changed | ||
|
||
|
||
class SelfTests(unittest.TestCase): | ||
def test_compose_gh_api_request__call_without_asserting(self): | ||
request = compose_gh_api_request(pull_number=556, per_page=100, cursor="") | ||
print(request.data) | ||
|
||
def test_list_changed_files__pagination_works(self): | ||
changed_files = list_changed_files(owner="opendatahub-io", repo="notebooks", pr_number=556, per_page=1) | ||
assert set(changed_files) == {'codeserver/ubi9-python-3.9/Dockerfile', | ||
'codeserver/ubi9-python-3.9/run-code-server.sh'} | ||
|
||
def test_analyze_build_directories(self): | ||
directories = analyze_build_directories("jupyter-intel-pytorch-ubi9-python-3.9") | ||
assert set(directories) == {"base/ubi9-python-3.9", | ||
"intel/base/gpu/ubi9-python-3.9", | ||
"jupyter/intel/pytorch/ubi9-python-3.9"} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see we don't interact with GitHub Packages in this repository, so maybe the
packages
permission is not necessary here. I know it was there before, but just pointing it out.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
packages: read
is necessary to use ghcr.io repository as a cache; it is running podman withThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking at the trial PR, it does not seem to be pulling from cache, not even the base images which should be completely unchanged! https://github.com/opendatahub-io/notebooks/actions/runs/9498328161/job/26176821937?pr=555
In the recent PR from Diamond it is using the cache just fine; not sure what busted the cache here https://github.com/opendatahub-io/notebooks/actions/runs/9490922279/job/26155372847?pr=557
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not pulling from cache because the
FROM registry.access.redhat.com/ubi9/python-39:latest
image has been updated in the meantime! that explains things, mystery solved, never mind meThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Thanks for the info :)