#!/usr/bin/env bash set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" script="$repo_root/scripts/docker-image/upload_works_drive.sh" doc="$repo_root/docs/works-drive-docker-image-archive.md" makefile="$repo_root/Makefile" fail() { echo "ERROR: $*" >&2 exit 1 } [[ -f "$script" ]] || fail "WORKS Drive Docker image upload script must exist." [[ -f "$doc" ]] || fail "WORKS Drive Docker image archive design document must exist." grep -Fq 'WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR:-docker-build-image' "$script" \ || fail "script must default WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR to docker-build-image." grep -Fq 'docker commit' "$script" \ || fail "script must support committing a local container before image export." grep -Fq 'docker save' "$script" \ || fail "script must use docker save for CLI-compatible image artifacts." grep -Fq 'zstd' "$script" \ || fail "script must compress Docker image archives with zstd." grep -Fq 'manifest.json' "$script" \ || fail "script must write a manifest.json next to the image archive." grep -Fq 'image.tar.zst.sha256' "$script" \ || fail "script must write a checksum file for the compressed image archive." grep -Fq 'docker-build-image/baron_sso/backend/v1.2606.ab12' "$doc" \ || fail "document must describe the expected WORKS Drive folder layout." grep -Fq 'debian:trixie-slim' "$doc" \ || fail "document must use debian:trixie-slim for smoke image examples." grep -Fq 'staging과 production은 같은 image_tag' "$doc" \ || fail "document must state that staging and production consume the same image tag." grep -Fq 'docker-image-upload-works:' "$makefile" \ || fail "Makefile must expose a docker-image-upload-works target." grep -Fq 'scripts/docker-image/upload_works_drive.sh' "$makefile" \ || fail "Makefile target must call the WORKS Drive image upload script." if grep -Eq 'docker (push|pull)' "$script"; then fail "WORKS Drive image archive script must not pretend to be a Docker Registry push/pull backend." fi tmp_dir="$(mktemp -d /tmp/baron-sso-works-image-test.XXXXXX)" trap 'rm -rf "$tmp_dir"' EXIT INT TERM fake_bin="$tmp_dir/bin" mkdir -p "$fake_bin" cat >"$fake_bin/docker" <<'EOF' #!/usr/bin/env bash set -euo pipefail printf 'docker %s\n' "$*" >>"${FAKE_DOCKER_LOG}" if [[ "$1" == "commit" ]]; then printf 'sha256:committed-image\n' exit 0 fi if [[ "$1" == "image" && "$2" == "inspect" ]]; then printf 'sha256:inspect-image-id\n' exit 0 fi if [[ "$1" == "save" ]]; then output="" image_ref="" shift while [[ "$#" -gt 0 ]]; do case "$1" in -o) output="$2" shift 2 ;; *) image_ref="$1" shift ;; esac done [[ -n "$output" ]] || exit 2 printf 'docker image archive for %s\n' "$image_ref" >"$output" exit 0 fi echo "unexpected docker command: $*" >&2 exit 2 EOF chmod +x "$fake_bin/docker" cat >"$fake_bin/zstd" <<'EOF' #!/usr/bin/env bash set -euo pipefail output="" input="" while [[ "$#" -gt 0 ]]; do case "$1" in -o) output="$2" shift 2 ;; -*) shift ;; *) input="$1" shift ;; esac done [[ -n "$output" && -n "$input" ]] || exit 2 cp "$input" "$output" EOF chmod +x "$fake_bin/zstd" fake_curl="$tmp_dir/fake-curl.sh" cat >"$fake_curl" <<'EOF' #!/usr/bin/env bash set -euo pipefail printf '%s\n' "$*" >>"${FAKE_CURL_LOG}" last_arg="${!#}" case "$last_arg" in https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/root-folder/children) printf '{"files":[]}' ;; https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/root-folder/createfolder) printf '{"fileId":"docker-build-image-id","fileName":"docker-build-image","fileType":"FOLDER"}' ;; https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/docker-build-image-id/children) printf '{"files":[]}' ;; https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/docker-build-image-id/createfolder) printf '{"fileId":"baron-sso-id","fileName":"baron_sso","fileType":"FOLDER"}' ;; https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/baron-sso-id/children) printf '{"files":[]}' ;; https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/baron-sso-id/createfolder) printf '{"fileId":"backend-id","fileName":"backend","fileType":"FOLDER"}' ;; https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/backend-id/children) printf '{"files":[]}' ;; https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/backend-id/createfolder) printf '{"fileId":"tag-id","fileName":"v1.2606.ab12","fileType":"FOLDER"}' ;; https://www.worksapis.com/v1.0/sharedrives/shared-drive-1/files/tag-id) printf '{"uploadUrl":"https://upload.example.test/docker-image"}' ;; https://upload.example.test/docker-image) printf '{"fileId":"uploaded-file-id"}' ;; *) echo "unexpected curl URL: $last_arg" >&2 exit 2 ;; esac EOF chmod +x "$fake_curl" docker_log="$tmp_dir/docker.log" curl_log="$tmp_dir/curl.log" archive_dir="$tmp_dir/archive" FAKE_DOCKER_LOG="$docker_log" \ FAKE_CURL_LOG="$curl_log" \ PATH="$fake_bin:$PATH" \ WORKS_DRIVE_ACCESS_TOKEN="test-access-token" \ WORKS_DRIVE_TARGET="sharedrive" \ WORKS_DRIVE_SHARED_DRIVE_ID="shared-drive-1" \ WORKS_DRIVE_PARENT_FILE_ID="root-folder" \ WORKS_DRIVE_CURL_BIN="$fake_curl" \ WORKS_DOCKER_IMAGE_ARCHIVE_DIR="$archive_dir" \ WORKS_DOCKER_COMMIT_CONTAINER="baron_backend" \ DOCKER_IMAGE_REF="registry.example/baron_sso/backend:v1.2606.ab12" \ "$script" >"$tmp_dir/upload.out" artifact_dir="$archive_dir/baron_sso/backend/v1.2606.ab12" [[ -f "$artifact_dir/image.tar.zst" ]] || fail "script must create image.tar.zst." [[ -f "$artifact_dir/image.tar.zst.sha256" ]] || fail "script must create image.tar.zst.sha256." [[ -f "$artifact_dir/manifest.json" ]] || fail "script must create manifest.json." jq -e \ '.schema_version == 1 and .format == "docker-save-zstd" and .image_ref == "registry.example/baron_sso/backend:v1.2606.ab12" and .repository == "baron_sso/backend" and .tag == "v1.2606.ab12" and .remote_path == "docker-build-image/baron_sso/backend/v1.2606.ab12" and .archive.file_name == "image.tar.zst" and (.archive.sha256 | type == "string")' \ "$artifact_dir/manifest.json" >/dev/null || fail "manifest must describe the image archive and remote path." grep -Fq "docker commit baron_backend registry.example/baron_sso/backend:v1.2606.ab12" "$docker_log" \ || fail "script must commit the requested container into the requested image ref." grep -Fq "docker save -o" "$docker_log" \ || fail "script must save the requested image." grep -Fq "sharedrives/shared-drive-1/files/root-folder/createfolder" "$curl_log" \ || fail "script must create the top-level docker-build-image folder when needed." grep -Fq "docker-build-image" "$curl_log" \ || fail "script must use WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR in folder creation." grep -Fq "baron_sso" "$curl_log" \ || fail "script must create repository namespace folder." grep -Fq "backend" "$curl_log" \ || fail "script must create image repository folder." grep -Fq "v1.2606.ab12" "$curl_log" \ || fail "script must create tag folder." grep -Fq "image.tar.zst" "$curl_log" \ || fail "script must upload the compressed image archive." grep -Fq "image.tar.zst.sha256" "$curl_log" \ || fail "script must upload the checksum file." grep -Fq "manifest.json" "$curl_log" \ || fail "script must upload the manifest file." report_file="$artifact_dir/works-upload.json" [[ -f "$report_file" ]] || fail "script must write works-upload.json." jq -e '.status == "uploaded" and (.files | length) == 3' "$report_file" >/dev/null \ || fail "upload report must include three uploaded artifact files." echo "OK: WORKS Drive Docker image archive upload flow commits, packages, and uploads image artifacts"