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
@@ -58,6 +63,13 @@ def component_build_pipeline(component_name, dockerfile_path, is_pr: bool = True
58
63
This is general enough to create PR pipeline as well as push pipeline.
59
64
"""
60
65
name = component_name + ("-on-pull-request" if is_pr else "-on-push" )
66
+ files_changed_cel_expression = ""
67
+ if is_pr :
68
+ files_changed_cel_expression = ' || ' .join ((
69
+ compute_cel_expression (dockerfile_path ),
70
+ f'".tekton/{ component_name } -pull-request.yaml".pathChanged()' ,
71
+ f'"{ dockerfile_path } ".pathChanged()'
72
+ ))
61
73
return {
62
74
"apiVersion" : "tekton.dev/v1" ,
63
75
"kind" : "PipelineRun" ,
@@ -71,6 +83,7 @@ def component_build_pipeline(component_name, dockerfile_path, is_pr: bool = True
71
83
"pipelinesascode.tekton.dev/max-keep-runs" : "3" ,
72
84
"pipelinesascode.tekton.dev/on-cel-expression" : (
73
85
f'event == "{ "pull_request" if is_pr else "push" } " && target_branch == "main"'
86
+ + (' && ( ' + files_changed_cel_expression + ' )' if files_changed_cel_expression else "" )
74
87
+ ' && has(body.repository) && body.repository.full_name == "opendatahub-io/notebooks"'
75
88
),
76
89
},
@@ -761,5 +774,48 @@ def main():
761
774
file = yaml_file )
762
775
763
776
777
+ def compute_cel_expression (dockerfile : pathlib .Path ) -> str :
778
+ return cel_expression (root_dir = ROOT_DIR , files = scripts .sandbox .buildinputs (dockerfile ))
779
+
780
+
781
+ def cel_expression (root_dir : pathlib .Path , files : list [pathlib .Path ]) -> str :
782
+ """
783
+ Generate a CEL expression for file change detection.
784
+
785
+ Args:
786
+ root_dir (pathlib.Path): Docker build context.
787
+ files (list[pathlib.Path]): List of file paths to check for changes.
788
+
789
+ Returns:
790
+ str: A CEL expression that checks if any of the given files have changed.
791
+ """
792
+ expressions = []
793
+ for file in files :
794
+ relative_path = file .relative_to (root_dir ) if file .is_absolute () else file
795
+ if file .is_dir ():
796
+ expressions .append (f'"{ relative_path } /***".pathChanged()' )
797
+ else :
798
+ expressions .append (f'"{ relative_path } ".pathChanged()' )
799
+
800
+ return " || " .join (expressions )
801
+
802
+
764
803
if __name__ == "__main__" :
765
804
main ()
805
+
806
+
807
+ class Tests :
808
+
809
+ def test_compute_cel_expression (self , fs : pyfakefs .fake_filesystem .FakeFilesystem ):
810
+ fs .cwd = ROOT_DIR
811
+ ROOT_DIR .mkdir (parents = True )
812
+ pathlib .Path ("a/" ).mkdir ()
813
+ pathlib .Path ("b/" ).mkdir ()
814
+ pathlib .Path ("b/c.txt" ).write_text ("" )
815
+
816
+ assert cel_expression (
817
+ ROOT_DIR ,
818
+ files = [
819
+ pathlib .Path ("a" ),
820
+ pathlib .Path ("b" ) / "c.txt"
821
+ ]) == '"a/***".pathChanged() || "b/c.txt".pathChanged()'
0 commit comments