def _helm_chart_impl(ctx): """ :param ctx Package k8s manifests into a Helm chart with specified Chart.yaml Sets default registry and tag to stable values defined in tools.sh / .envrc The following variables will be set in _helpers.tpl: * {name}.name * {name}.fullname * {name}.chart The following values.yaml variables will be available: * awsRegion (optional, default is us-east-2) * stage (required, example: dev) * image.repository (optional, default is STABLE_OCI_REGISTRY/STABLE_OCI_REGISTRY_REPO/image_name) * image.tag (optional, default is STABLE_BUILD_TAG) * {portName}.ingressHost (required if any ports/services are marked as exposed, port name can for example be "http" or "grpc") * postgresHostPort (required if service is backend or databaseUrl is not set) * databaseUrl (optional, required if postgresHostPort is not set) internal: The general structure of a Helm chart should be as follows: * Chart.yaml * values.yaml * .helmignore * templates/ * _helpers.tpl * ctx.files.srcs If resfdeploy templates are used, the following values.yaml variables changes defaults: * image.repository (sourced from deployment.yaml) * image.tag (sourced from deployment.yaml) """ # The stamp files should be brought in to be able to apply default registry and tag stamp_files = [ctx.info_file, ctx.version_file] # Create new staging directory staging_dir = "chart" tmp_dirname = "" # Declare inputs to the final Helm script inputs = [] # Fail if srcs contains a file called Chart.yaml, values.yaml, _helpers.tpl or .helmignore for src in ctx.files.srcs: if src.basename in ["Chart.yaml", "values.yaml", "_helpers.tpl", ".helmignore"]: fail("{} is a reserved file name and should not exist in srcs".format(src.basename)) # Copy srcs into staging directory for src in ctx.files.srcs + ctx.files.chart_yaml + ctx.files.values_yaml + ctx.files._helpers_tpl + ctx.files._helmignore: cp_out = ctx.actions.declare_file(staging_dir + "/" + src.basename) if tmp_dirname == "": tmp_dirname = cp_out.dirname inputs.append(cp_out) ctx.actions.run_shell( outputs = [cp_out], inputs = [src], mnemonic = "HelmCopyToStaging", arguments = [src.path, cp_out.path], command = "cp -RL $1 $2", ) # Expand template for Helm script tarball_file = ctx.actions.declare_file(ctx.label.name + ".tgz") out_file = ctx.actions.declare_file(ctx.label.name + ".helm.bash") ctx.actions.expand_template( template = ctx.file._helm_script, output = out_file, substitutions = { "TMPL_helm_bin": ctx.file._helm_bin.path, "TMPL_yq_bin": ctx.file._yq_bin.path, "TMPL_name": ctx.attr.package_name, "TMPL_staging_dir": tmp_dirname, "TMPL_image_name": ctx.attr.package_name if not ctx.attr.image_name else ctx.attr.image_name, "TMPL_tarball_file_path": tarball_file.path, "TMPL_stamp_files": ";".join([x.path for x in stamp_files]), }, is_executable = True, ) # Run Helm script and generate a tarball ctx.actions.run( outputs = [tarball_file], inputs = inputs + stamp_files + [ctx.file._helm_bin, ctx.file._yq_bin], executable = out_file, mnemonic = "HelmChart", ) return [DefaultInfo( files = depset([tarball_file]), )] helm_chart = rule( implementation = _helm_chart_impl, attrs = { "package_name": attr.string( doc = "The name of the package", mandatory = True, ), "image_name": attr.string( doc = "The name of the OCI image, defaults to package_name. Ignored if resfdeploy is used and sourced from deployment.yaml", ), "chart_yaml": attr.label( doc = "Chart.yaml file path", default = ":Chart.yaml", mandatory = True, allow_single_file = True, ), "values_yaml": attr.label( doc = "values.yaml file path", default = ":values.yaml", mandatory = True, allow_single_file = True, ), "srcs": attr.label_list( doc = "List of templates/manifests to be included in chart", mandatory = True, allow_files = True, ), "_helm_bin": attr.label( doc = "Helm binary path", default = "//rules_resf/internal/helm:helm_tool", allow_single_file = True, cfg = "host", ), "_yq_bin": attr.label( doc = "yq binary path", default = "//rules_resf/internal/helm:yq_tool", allow_single_file = True, cfg = "host", ), "_helpers_tpl": attr.label( doc = "Helpers template path", default = "//rules_resf/internal/helm:_helpers.tpl", allow_single_file = True, ), "_helm_script": attr.label( doc = "Helm script path", default = "//rules_resf/internal/helm:helm.bash", allow_single_file = True, ), "_helmignore": attr.label( doc = "Helmignore file path", default = "//rules_resf/internal/helm:.helmignore", allow_single_file = True, ), }, )