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" ,
@@ -120,7 +132,8 @@ def component_build_pipeline(component_name, dockerfile_path,
120
132
"pipelinesascode.tekton.dev/cancel-in-progress" : "true" if is_pr else "false" ,
121
133
"pipelinesascode.tekton.dev/max-keep-runs" : "3" ,
122
134
"pipelinesascode.tekton.dev/on-cel-expression" : (
123
- f'event == "{ "pull_request" if is_pr else "push" } " && target_branch == "main"'
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
},
@@ -799,10 +812,11 @@ def main():
799
812
print ("# yamllint disable-file" , file = yaml_file )
800
813
print ("# This file is autogenerated by ci/cached-builds/konflux_generate_component_build_pipelines.py" ,
801
814
file = yaml_file )
802
- print (yaml .dump (component_build_pipeline (component_name = task_name , dockerfile_path = dockerfile ,
815
+ print (
816
+ yaml .dump (component_build_pipeline (component_name = task_name , dockerfile_path = dockerfile ,
803
817
build_container_tasks = [build_container ()], is_pr = False )),
804
- end = "" ,
805
- file = yaml_file )
818
+ end = "" ,
819
+ file = yaml_file )
806
820
with open (ROOT_DIR / ".tekton" / (task_name + "-pull-request.yaml" ), "w" ) as yaml_file :
807
821
print ("# yamllint disable-file" , file = yaml_file )
808
822
print ("# This file is autogenerated by ci/cached-builds/konflux_generate_component_build_pipelines.py" ,
@@ -813,5 +827,48 @@ def main():
813
827
file = yaml_file )
814
828
815
829
830
+ def compute_cel_expression (dockerfile : pathlib .Path ) -> str :
831
+ return cel_expression (root_dir = ROOT_DIR , files = scripts .sandbox .buildinputs (dockerfile ))
832
+
833
+
834
+ def cel_expression (root_dir : pathlib .Path , files : list [pathlib .Path ]) -> str :
835
+ """
836
+ Generate a CEL expression for file change detection.
837
+
838
+ Args:
839
+ root_dir (pathlib.Path): Docker build context.
840
+ files (list[pathlib.Path]): List of file paths to check for changes.
841
+
842
+ Returns:
843
+ str: A CEL expression that checks if any of the given files have changed.
844
+ """
845
+ expressions = []
846
+ for file in files :
847
+ relative_path = file .relative_to (root_dir ) if file .is_absolute () else file
848
+ if file .is_dir ():
849
+ expressions .append (f'"{ relative_path } /***".pathChanged()' )
850
+ else :
851
+ expressions .append (f'"{ relative_path } ".pathChanged()' )
852
+
853
+ return " || " .join (expressions )
854
+
855
+
816
856
if __name__ == "__main__" :
817
857
main ()
858
+
859
+
860
+ class Tests :
861
+
862
+ def test_compute_cel_expression (self , fs : pyfakefs .fake_filesystem .FakeFilesystem ):
863
+ fs .cwd = ROOT_DIR
864
+ ROOT_DIR .mkdir (parents = True )
865
+ pathlib .Path ("a/" ).mkdir ()
866
+ pathlib .Path ("b/" ).mkdir ()
867
+ pathlib .Path ("b/c.txt" ).write_text ("" )
868
+
869
+ assert cel_expression (
870
+ ROOT_DIR ,
871
+ files = [
872
+ pathlib .Path ("a" ),
873
+ pathlib .Path ("b" ) / "c.txt"
874
+ ]) == '"a/***".pathChanged() || "b/c.txt".pathChanged()'
0 commit comments