From f75f790b7cbb00e4843e66ff652444ec08b6ac12 Mon Sep 17 00:00:00 2001 From: Jesse Hines Date: Tue, 20 May 2025 11:06:33 -0400 Subject: [PATCH 1/4] Support pushing to specific tag --- skylib/k8s.bzl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/skylib/k8s.bzl b/skylib/k8s.bzl index b73201db..0ae67081 100644 --- a/skylib/k8s.bzl +++ b/skylib/k8s.bzl @@ -65,11 +65,13 @@ show = rule( executable = True, ) -def _image_pushes(name_suffix, images, image_registry, image_repository, image_digest_tag, tags = []): +def _image_pushes(name_suffix, images, image_registry, image_repository, image_digest_tag, remote_tags = None, tags = []): image_pushes = [] def process_image(image_label, image_alias = None): rule_name_parts = [image_label, image_registry, image_repository] + if remote_tags: + rule_name_parts = rule_name_parts + remote_tags rule_name_parts = [p for p in rule_name_parts if p] rule_name = "_".join(rule_name_parts) rule_name = rule_name.replace("/", "_").replace(":", "_").replace("@", "_").replace(".", "_") @@ -82,6 +84,8 @@ def _image_pushes(name_suffix, images, image_registry, image_repository, image_d registry = image_registry, repository = image_repository, tags = tags, + tag = bool(remote_tags), + remote_tags = remote_tags, visibility = ["//visibility:public"], ) if not image_alias: @@ -135,6 +139,7 @@ def k8s_deploy( image_digest_tag = False, image_registry = "docker.io", # registry to push container to. jenkins will need an access configured for gitops to work. Ignored for mynamespace. image_repository = None, # repository (registry path) to push container to. Generated from the image bazel path if empty. + remote_tags = None, # tags to push to the registry objects = [], gitops = True, # make sure to use gitops = False to work with individual namespace. This option will be turned False if namespace is '{BUILD_USER}' gitops_path = "cloud", @@ -142,7 +147,7 @@ def k8s_deploy( release_branch_prefix = "main", start_tag = "{{", end_tag = "}}", - tags = [], # tags to add to all generated rules. + tags = [], # bazel tags to add to all generated rules. visibility = None): """ k8s_deploy """ @@ -174,6 +179,7 @@ def k8s_deploy( image_registry = image_registry + "/mynamespace", image_repository = image_repository, image_digest_tag = image_digest_tag, + remote_tags = remote_tags, tags = tags, ) kustomize( @@ -251,6 +257,7 @@ def k8s_deploy( image_registry = image_registry, image_repository = image_repository, image_digest_tag = image_digest_tag, + remote_tags = remote_tags, tags = tags, ) kustomize( From 0267ea430a0e26c3c3da0e3157591764ee61b463 Mon Sep 17 00:00:00 2001 From: Jesse Hines Date: Fri, 20 Jun 2025 15:39:43 -0400 Subject: [PATCH 2/4] Remove redundant argument --- gitops/testing/BUILD.bazel | 1 - push_oci/push_oci.bzl | 3 +-- skylib/k8s.bzl | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/gitops/testing/BUILD.bazel b/gitops/testing/BUILD.bazel index bcd16729..d50434a2 100644 --- a/gitops/testing/BUILD.bazel +++ b/gitops/testing/BUILD.bazel @@ -90,7 +90,6 @@ push_oci( image = "//skylib/kustomize/tests:image", registry = "gcr.io", repository = "repo/imagethere", - tag = "thetag", ) k8s_deploy( diff --git a/push_oci/push_oci.bzl b/push_oci/push_oci.bzl index b54fa7bc..74bc8ef3 100644 --- a/push_oci/push_oci.bzl +++ b/push_oci/push_oci.bzl @@ -105,11 +105,10 @@ def push_oci( repository, registry = None, image_digest_tag = False, # buildifier: disable=unused-variable either remove parameter or implement - tag = None, remote_tags = None, # file with tags to push tags = [], # bazel tags to add to the push_oci_rule visibility = None): - if tag: + if remote_tags: tags_label = "_{}_write_tags".format(name) write_file( name = tags_label, diff --git a/skylib/k8s.bzl b/skylib/k8s.bzl index 0ae67081..73f1da81 100644 --- a/skylib/k8s.bzl +++ b/skylib/k8s.bzl @@ -84,7 +84,6 @@ def _image_pushes(name_suffix, images, image_registry, image_repository, image_d registry = image_registry, repository = image_repository, tags = tags, - tag = bool(remote_tags), remote_tags = remote_tags, visibility = ["//visibility:public"], ) From 9fba2de3f45de6577c8198eb21e8485483ed2d77 Mon Sep 17 00:00:00 2001 From: Jesse Hines Date: Fri, 20 Jun 2025 16:42:45 -0400 Subject: [PATCH 3/4] Implement image_digest_tag --- push_oci/push_oci.bzl | 49 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/push_oci/push_oci.bzl b/push_oci/push_oci.bzl index 74bc8ef3..1ec7aa8b 100644 --- a/push_oci/push_oci.bzl +++ b/push_oci/push_oci.bzl @@ -1,9 +1,6 @@ """ Implementation of the `k8s_push` rule based on rules_oci """ - -load("@bazel_skylib//rules:write_file.bzl", "write_file") - # TODO: remove this once rules_oci is updated # buildifier: disable=bzl-visibility load("@rules_oci//oci/private:push.bzl", "oci_push_lib") @@ -99,6 +96,44 @@ push_oci_rule = rule( # provides = [GitopsPushInfo, DefaultInfo], ) + +def _write_tag_file_impl(ctx): + jq_bin = ctx.toolchains["@aspect_bazel_lib//lib:jq_toolchain_type"].jqinfo.bin + remote_tags = "\n".join(ctx.attr.remote_tags) + command = "" + if ctx.attr.remote_tags: + command += 'echo "${3}" > ${4}\n' + if ctx.attr.image_digest_tag: + command += "${1} --raw-output '.manifests[].digest' ${2}/index.json | cut -d ':' -f 2 | cut -c 1-7 >> ${4}\n" + + ctx.actions.run_shell( + inputs = [ctx.file.image], + outputs = [ctx.outputs.out], + arguments = [jq_bin.path, ctx.file.image.path, remote_tags, ctx.outputs.out.path], + command = command, + progress_message = "Extracting digest from %s" % ctx.file.image.short_path, + tools = [jq_bin], + ) + + files = depset(direct = [ctx.outputs.out]) + return [DefaultInfo(files = files)] + +write_tag_file_rule = rule( + implementation = _write_tag_file_impl, + attrs = { + "image": attr.label( + allow_single_file = True, + mandatory = True, + ), + "remote_tags": attr.string_list(), + "image_digest_tag": attr.bool(default = False), + "out": attr.output(mandatory = True), + "_jq": oci_push_lib.attrs['_jq'], + }, + toolchains = ["@aspect_bazel_lib//lib:jq_toolchain_type"] + oci_push_lib.toolchains, +) + + def push_oci( name, image, @@ -108,12 +143,14 @@ def push_oci( remote_tags = None, # file with tags to push tags = [], # bazel tags to add to the push_oci_rule visibility = None): - if remote_tags: + if remote_tags or image_digest_tag: tags_label = "_{}_write_tags".format(name) - write_file( + write_tag_file_rule( name = tags_label, + image = image, + remote_tags = remote_tags, + image_digest_tag = image_digest_tag, out = "_{}.tags.txt".format(name), - content = remote_tags, ) remote_tags = tags_label From 38ae5fa54d49e97317dfd49169360f2ef934d20d Mon Sep 17 00:00:00 2001 From: Jesse Hines Date: Fri, 20 Jun 2025 16:59:26 -0400 Subject: [PATCH 4/4] Update docs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d6dfcbf8..5ba5b9ce 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ When you run `bazel run ///helloworld:mynamespace.apply`, it applies this file i | ***deps_aliases*** | `{}` | A dict of labels of file dependencies. File dependency contents are available for template expansion in manifests as `{{imports.