11"""Helm rules"""
22
3- load ("//helm:providers.bzl" , "HelmPackageInfo" )
43load ("//helm/private:helm_utils.bzl" , "is_stamping_enabled" )
54load ("//helm/private:json_to_yaml.bzl" , "json_to_yaml" )
6-
7- OciPushRepositoryInfo = provider (
8- doc = "Repository and image information for a given oci_push or image_push target" ,
9- fields = {
10- "manifest_file" : "File (optional): The manifest JSON file for rules_img images" ,
11- "oci_layout" : "File (optional): The OCI layout directory for rules_oci images (contains index.json)" ,
12- "remote_tags_file" : "File (optional): The file containing remote tags (one per line) used for the push target" ,
13- "repository_file" : "File: The file containing the repository path for the push target" ,
14- },
15- )
16-
17- def _oci_push_repository_aspect_impl (target , ctx ):
18- # Handle rules_img image_push
19- if hasattr (ctx .rule .attr , "registry" ) and ctx .rule .attr .registry :
20- # rules_img uses registry + repository attributes
21- if hasattr (ctx .rule .attr , "repository" ) and ctx .rule .attr .repository :
22- # Combine registry and repository for full repository path
23- registry = ctx .rule .attr .registry
24- repo = ctx .rule .attr .repository
25-
26- # Remove protocol from registry if present
27- registry_clean = registry .replace ("https://" , "" ).replace ("http://" , "" )
28- full_repo = "{}/{}" .format (registry_clean , repo )
29-
30- output = ctx .actions .declare_file ("{}.rules_helm.repository.txt" .format (target .label .name ))
31- ctx .actions .write (
32- output = output ,
33- content = full_repo ,
34- )
35- else :
36- fail ("image_push target {} must have a `repository` attribute" .format (target .label ))
37-
38- # rules_img image_push has 'image' attribute pointing to image_manifest
39- if not hasattr (ctx .rule .attr , "image" ) or not ctx .rule .attr .image :
40- fail ("image_push target {} must have an `image` attribute" .format (target .label ))
41-
42- # Get the image file from the image attribute
43- image_file = None
44- if hasattr (ctx .rule .files , "image" ) and ctx .rule .files .image :
45- image_file = ctx .rule .files .image [0 ]
46- elif hasattr (ctx .rule .file , "image" ) and ctx .rule .file .image :
47- image_file = ctx .rule .file .image
48- else :
49- fail ("image_push target {} `image` attribute must provide files" .format (target .label ))
50-
51- # rules_img uses tags attribute (list of strings) instead of remote_tags file
52- remote_tags_file = None
53- if hasattr (ctx .rule .attr , "tags" ) and ctx .rule .attr .tags :
54- # Write tags to a file for consistency with rules_oci
55- tags_output = ctx .actions .declare_file ("{}.rules_helm.tags.txt" .format (target .label .name ))
56- ctx .actions .write (
57- output = tags_output ,
58- content = "\n " .join (ctx .rule .attr .tags ),
59- )
60- remote_tags_file = tags_output
61-
62- return [OciPushRepositoryInfo (
63- repository_file = output ,
64- manifest_file = image_file ,
65- oci_layout = None ,
66- remote_tags_file = remote_tags_file ,
67- )]
68-
69- # Handle rules_oci oci_push
70- if hasattr (ctx .rule .attr , "repository" ) and ctx .rule .attr .repository :
71- output = ctx .actions .declare_file ("{}.rules_helm.repository.txt" .format (target .label .name ))
72- ctx .actions .write (
73- output = output ,
74- content = ctx .rule .attr .repository ,
75- )
76- elif hasattr (ctx .rule .file , "repository_file" ) and ctx .rule .file .repository_file :
77- output = ctx .rule .file .repository_file
78- else :
79- fail ("oci_push/image_push target {} must have a `repository` attribute or a `repository_file` file" .format (
80- target .label ,
81- ))
82-
83- if not hasattr (ctx .rule .file , "image" ):
84- fail ("oci_push/image_push target {} must have an `image` attribute" .format (
85- target .label ,
86- ))
87-
88- remote_tags_file = None
89- if hasattr (ctx .rule .file , "remote_tags" ) and ctx .rule .file .remote_tags :
90- remote_tags_file = ctx .rule .file .remote_tags
91-
92- return [OciPushRepositoryInfo (
93- repository_file = output ,
94- oci_layout = ctx .rule .file .image ,
95- manifest_file = None ,
96- remote_tags_file = remote_tags_file ,
97- )]
98-
99- # This aspect exists because rules_oci and rules_img don't provide a provider
100- # that cleanly publishes this information but for the helm rules, it's
101- # absolutely necessary that an image's repository and digest are knowable.
102- # If rules_oci/rules_img decide to define their own provider for this (which they should)
103- # then this should be deleted in favor of that.
104- _oci_push_repository_aspect = aspect (
105- doc = "Provides the repository and image_root for a given oci_push or image_push target" ,
106- implementation = _oci_push_repository_aspect_impl ,
107- )
5+ load (":image_utils.bzl" , "ImagePushRepositoryInfo" , "image_push_repository_aspect" )
6+ load (":providers.bzl" , "HelmPackageInfo" )
1087
1098def _rlocationpath (file , workspace_name ):
1109 if file .short_path .startswith ("../" ):
@@ -206,31 +105,31 @@ def _helm_package_impl(ctx):
206105 image_inputs = []
207106 single_image_manifests = []
208107 for image in ctx .attr .images :
209- image_inputs .append (image [OciPushRepositoryInfo ].repository_file )
108+ image_inputs .append (image [ImagePushRepositoryInfo ].repository_file )
210109
211110 # Add the appropriate image file based on format
212- if image [OciPushRepositoryInfo ].oci_layout :
213- image_inputs .append (image [OciPushRepositoryInfo ].oci_layout )
214- elif image [OciPushRepositoryInfo ].manifest_file :
215- image_inputs .append (image [OciPushRepositoryInfo ].manifest_file )
111+ if image [ImagePushRepositoryInfo ].oci_layout :
112+ image_inputs .append (image [ImagePushRepositoryInfo ].oci_layout )
113+ elif image [ImagePushRepositoryInfo ].manifest_file :
114+ image_inputs .append (image [ImagePushRepositoryInfo ].manifest_file )
216115 single_image_manifest = ctx .actions .declare_file ("{}/{}" .format (
217116 ctx .label .name ,
218117 str (image .label ).strip ("@" ).replace ("/" , "_" ).replace (":" , "_" ) + ".image_manifest" ,
219118 ))
220119 push_info = image [DefaultInfo ]
221120
222121 remote_tags_path = None
223- if image [OciPushRepositoryInfo ].remote_tags_file :
224- remote_tags_path = image [OciPushRepositoryInfo ].remote_tags_file .path
225- image_inputs .append (image [OciPushRepositoryInfo ].remote_tags_file )
122+ if image [ImagePushRepositoryInfo ].remote_tags_file :
123+ remote_tags_path = image [ImagePushRepositoryInfo ].remote_tags_file .path
124+ image_inputs .append (image [ImagePushRepositoryInfo ].remote_tags_file )
226125
227126 # Set mutually exclusive fields based on image format
228127 oci_layout_dir = None
229128 manifest_file = None
230- if image [OciPushRepositoryInfo ].oci_layout :
231- oci_layout_dir = image [OciPushRepositoryInfo ].oci_layout .path
232- elif image [OciPushRepositoryInfo ].manifest_file :
233- manifest_file = image [OciPushRepositoryInfo ].manifest_file .path
129+ if image [ImagePushRepositoryInfo ].oci_layout :
130+ oci_layout_dir = image [ImagePushRepositoryInfo ].oci_layout .path
131+ elif image [ImagePushRepositoryInfo ].manifest_file :
132+ manifest_file = image [ImagePushRepositoryInfo ].manifest_file .path
234133 else :
235134 fail ("Unable to determine repository info for {}" .format (image .label ))
236135
@@ -239,7 +138,7 @@ def _helm_package_impl(ctx):
239138 content = json .encode_indent (
240139 struct (
241140 label = str (image .label ),
242- repository_path = image [OciPushRepositoryInfo ].repository_file .path ,
141+ repository_path = image [ImagePushRepositoryInfo ].repository_file .path ,
243142 oci_layout_dir = oci_layout_dir ,
244143 manifest_file = manifest_file ,
245144 remote_tags_path = remote_tags_path ,
@@ -332,7 +231,7 @@ helm_package = rule(
332231 [oci_push](https://github.com/bazel-contrib/rules_oci/blob/main/docs/push.md#oci_push_rule-remote_tags) or \
333232 [image_push](https://github.com/bazel-contrib/rules_img) \
334233 targets.""" ,
335- aspects = [_oci_push_repository_aspect ],
234+ aspects = [image_push_repository_aspect ],
336235 ),
337236 "schema" : attr .label (
338237 doc = "The `values.schema.json` file for the current package." ,
0 commit comments