2
2
3
3
import re
4
4
import pathlib
5
+
5
6
import yaml
6
7
7
8
import gen_gha_matrix_jobs
8
9
import gha_pr_changed_files
10
+ import scripts .sandbox
11
+
12
+ # test dependencies
13
+ import pyfakefs .fake_filesystem
9
14
10
15
ROOT_DIR = pathlib .Path (__file__ ).parent .parent .parent
11
16
21
26
22
27
Usage:
23
28
24
- $ poetry run ci/cached-builds/konflux_generate_component_build_pipelines.py
29
+ $ PYTHONPATH=. poetry run ci/cached-builds/konflux_generate_component_build_pipelines.py
25
30
"""
26
31
27
32
@@ -108,6 +113,13 @@ def component_build_pipeline(component_name, dockerfile_path,
108
113
This is general enough to create PR pipeline as well as push pipeline.
109
114
"""
110
115
name = component_name + ("-on-pull-request" if is_pr else "-on-push" )
116
+ files_changed_cel_expression = ""
117
+ if is_pr :
118
+ files_changed_cel_expression = ' || ' .join ((
119
+ compute_cel_expression (dockerfile_path ),
120
+ f'".tekton/{ component_name } -pull-request.yaml".pathChanged()' ,
121
+ f'"{ dockerfile_path } ".pathChanged()'
122
+ ))
111
123
return {
112
124
"apiVersion" : "tekton.dev/v1" ,
113
125
"kind" : "PipelineRun" ,
@@ -121,6 +133,7 @@ def component_build_pipeline(component_name, dockerfile_path,
121
133
"pipelinesascode.tekton.dev/max-keep-runs" : "3" ,
122
134
"pipelinesascode.tekton.dev/on-cel-expression" : (
123
135
f'event == "{ "pull_request" if is_pr else "push" } " && target_branch == "main"'
136
+ + (' && ( ' + files_changed_cel_expression + ' )' if files_changed_cel_expression else "" )
124
137
+ ' && has(body.repository) && body.repository.full_name == "opendatahub-io/notebooks"'
125
138
),
126
139
},
@@ -813,5 +826,48 @@ def main():
813
826
file = yaml_file )
814
827
815
828
829
+ def compute_cel_expression (dockerfile : pathlib .Path ) -> str :
830
+ return cel_expression (root_dir = ROOT_DIR , files = scripts .sandbox .buildinputs (dockerfile ))
831
+
832
+
833
+ def cel_expression (root_dir : pathlib .Path , files : list [pathlib .Path ]) -> str :
834
+ """
835
+ Generate a CEL expression for file change detection.
836
+
837
+ Args:
838
+ root_dir (pathlib.Path): Docker build context.
839
+ files (list[pathlib.Path]): List of file paths to check for changes.
840
+
841
+ Returns:
842
+ str: A CEL expression that checks if any of the given files have changed.
843
+ """
844
+ expressions = []
845
+ for file in files :
846
+ relative_path = file .relative_to (root_dir ) if file .is_absolute () else file
847
+ if file .is_dir ():
848
+ expressions .append (f'"{ relative_path } /***".pathChanged()' )
849
+ else :
850
+ expressions .append (f'"{ relative_path } ".pathChanged()' )
851
+
852
+ return " || " .join (expressions )
853
+
854
+
816
855
if __name__ == "__main__" :
817
856
main ()
857
+
858
+
859
+ class Tests :
860
+
861
+ def test_compute_cel_expression (self , fs : pyfakefs .fake_filesystem .FakeFilesystem ):
862
+ fs .cwd = ROOT_DIR
863
+ ROOT_DIR .mkdir (parents = True )
864
+ pathlib .Path ("a/" ).mkdir ()
865
+ pathlib .Path ("b/" ).mkdir ()
866
+ pathlib .Path ("b/c.txt" ).write_text ("" )
867
+
868
+ assert cel_expression (
869
+ ROOT_DIR ,
870
+ files = [
871
+ pathlib .Path ("a" ),
872
+ pathlib .Path ("b" ) / "c.txt"
873
+ ]) == '"a/***".pathChanged() || "b/c.txt".pathChanged()'
0 commit comments