Skip to content

Commit 3e45d99

Browse files
authored
feat: add --output_json to s3_sync() (#105)
This flag is not meant to be set in a `BUILD.bazel` file, but when `bazel run`ning the target to write out a JSON file containing which files where uploaded where and had which sha256 sum. This makes in easy for CI jobs uploading artifacts to access that information without having to dig into the bazel output tree.
1 parent 70d8e38 commit 3e45d99

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

MODULE.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ bazel_dep(name = "aspect_rules_py", version = "0.7.3", dev_dependency = True)
2020
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
2121
bazel_dep(name = "container_structure_test", version = "1.16.0", dev_dependency = True)
2222

23+
bazel_lib_toolchains = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "toolchains")
24+
bazel_lib_toolchains.jq()
25+
bazel_lib_toolchains.coreutils()
26+
use_repo(bazel_lib_toolchains, "coreutils_toolchains", "jq_toolchains")
27+
28+
register_toolchains(
29+
"@jq_toolchains//:all",
30+
"@coreutils_toolchains//:all",
31+
)
32+
2333
aws = use_extension("//aws:extensions.bzl", "aws")
2434
aws.toolchain(aws_cli_version = "2.13.0")
2535
use_repo(aws, "aws", "aws_darwin", "aws_linux-aarch64", "aws_linux-x86_64", "aws_toolchains")

aws/private/s3_sync.bzl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ _ATTRS = {
3838
}
3939

4040
def _s3_sync_impl(ctx):
41+
coreutils = ctx.toolchains["@aspect_bazel_lib//lib:coreutils_toolchain_type"]
42+
jq = ctx.toolchains["@aspect_bazel_lib//lib:jq_toolchain_type"]
43+
4144
executable = ctx.actions.declare_file("{}/s3_sync.sh".format(ctx.label.name))
42-
runfiles = [executable] + ctx.files.srcs
45+
runfiles = [executable, coreutils.coreutils_info.bin, jq.jqinfo.bin] + ctx.files.srcs
4346
vars = []
4447
if int(bool(ctx.attr.bucket)) + int(bool(ctx.attr.bucket_file)) + int(bool(ctx.attr.destination_uri_file)) != 1:
4548
fail("Exactly one of 'bucket', 'bucket_file', or 'destination_uri_file' must be set")
@@ -61,6 +64,8 @@ def _s3_sync_impl(ctx):
6164
is_executable = True,
6265
substitutions = {
6366
"$aws": ctx.attr.aws[DefaultInfo].default_runfiles.files.to_list()[0].short_path,
67+
"$coreutils": coreutils.coreutils_info.bin.short_path,
68+
"$jq": jq.jqinfo.bin.short_path,
6469
"artifacts=()": "artifacts=({})".format(" ".join([s.short_path for s in ctx.files.srcs])),
6570
"# Collect Args": "\n".join(vars),
6671
},
@@ -76,4 +81,8 @@ s3_sync = rule(
7681
executable = True,
7782
attrs = _ATTRS,
7883
doc = _DOC,
84+
toolchains = [
85+
"@aspect_bazel_lib//lib:coreutils_toolchain_type",
86+
"@aspect_bazel_lib//lib:jq_toolchain_type",
87+
],
7988
)

aws/private/s3_sync.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Options:
7474
--bucket_file <file> The path to a file that contains the name of the S3 bucket.
7575
--[no]dry_run Toggles whether the utility will run in dry-run mode.
7676
Default: false
77+
--output_json <file> Collect SHA256 sums/S3 destination for every file and write as JSON to the specified file.
7778
7879
Arguments:
7980
<artifact> The path to a file or directory which will be copied to the S3 bucket.
@@ -91,6 +92,11 @@ s3_cp() {
9192
else
9293
warn "[DRY RUN] Would copy ${src} to ${dst}"
9394
fi
95+
96+
if [[ -n "${output_json_file}" ]]; then
97+
local sha256_sum=$("$coreutils" sha256sum "${src}" | cut -d' ' -f1)
98+
sha256_results+=('{"file":"'"${src}"'","sha256":"'"${sha256_sum}"'","s3_path":"'"${dst}"'"}')
99+
fi
94100
}
95101

96102
cp_artifact() {
@@ -107,10 +113,18 @@ cp_artifact() {
107113
fi
108114
}
109115

116+
output_json_results() {
117+
local output_file="${1}"
118+
printf '%s\n' "${sha256_results[@]}" | "$jq" -s . > "${output_file}"
119+
msg "JSON output written to ${output_file}"
120+
}
121+
110122
# Collect Args
111123

112124
dry_run=false
125+
output_json_file=""
113126
artifacts=()
127+
sha256_results=()
114128

115129
while (("$#")); do
116130
case "${1}" in
@@ -137,6 +151,10 @@ while (("$#")); do
137151
dry_run="false"
138152
shift 1
139153
;;
154+
"--output_json")
155+
output_json_file="${2}"
156+
shift 2
157+
;;
140158
"--role")
141159
role="${2}"
142160
shift 2
@@ -213,6 +231,10 @@ else
213231
done
214232
fi
215233

234+
if [[ -n "${output_json_file}" ]]; then
235+
output_json_results "${output_json_file}"
236+
fi
237+
216238
# shellcheck disable=SC2236
217239
if [[ ! -z "${role:-}" && "${dry_run}" == "false" ]]; then
218240
unset AWS_ACCESS_KEY_ID

examples/release_to_s3/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ expand_template(
1818
# bazel run //examples/release_to_s3 -- --dry_run
1919
# Use a different profile:
2020
# bazel run //examples/release_to_s3 -- --profile=prod
21+
# Output a metadata JSON file:
22+
# bazel run //examples/release_to_s3 -- --output_json $PWD/out.json
2123
s3_sync(
2224
name = "release_to_s3",
2325
srcs = ["my_file.txt"],

0 commit comments

Comments
 (0)