From ba092eb7603a0b997a1da36165c7e9ccac6b6218 Mon Sep 17 00:00:00 2001 From: Tomas Valenta Date: Tue, 12 May 2026 22:56:34 -0700 Subject: [PATCH 1/2] add upload-release-to-gcs.sh for uploading release assets to GCS --- scripts/upload-release-to-gcs.sh | 112 +++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100755 scripts/upload-release-to-gcs.sh diff --git a/scripts/upload-release-to-gcs.sh b/scripts/upload-release-to-gcs.sh new file mode 100755 index 000000000..0c7c8d5f5 --- /dev/null +++ b/scripts/upload-release-to-gcs.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# Uploads firecracker-{amd64,arm64} assets from a fc-versions GitHub release +# to GCS at: +# ///firecracker +# //firecracker (legacy amd64 copy) +# +# Existing objects are never overwritten. +# +# Usage: +# ./scripts/upload-release-to-gcs.sh --tag --bucket [--dry-run] [--repo ] +# +# Options: +# --tag Release tag / version name (e.g. v1.14.1_af9c995). +# --bucket Target bucket (with optional path prefix), e.g. +# my-bucket +# my-bucket/firecrackers +# gs://my-bucket/firecrackers +# --repo GitHub repo (default: e2b-dev/fc-versions). +# --dry-run Print what would be uploaded without writing. +# -h, --help Show this help. + +set -euo pipefail + +REPO="e2b-dev/fc-versions" +TAG="" +BUCKET="" +DRY_RUN=false + +usage() { sed -n '2,/^$/p' "$0" | sed 's/^# \{0,1\}//'; exit "${1:-0}"; } + +while [[ $# -gt 0 ]]; do + case "$1" in + --tag) TAG="${2:?--tag needs a value}"; shift 2 ;; + --bucket) BUCKET="${2:?--bucket needs a value}"; shift 2 ;; + --repo) REPO="${2:?--repo needs a value}"; shift 2 ;; + --dry-run) DRY_RUN=true; shift ;; + -h|--help) usage 0 ;; + *) echo "Unknown argument: $1" >&2; usage 1 ;; + esac +done + +[[ -n "$TAG" ]] || { echo "ERROR: --tag is required" >&2; usage 1; } +[[ -n "$BUCKET" ]] || { echo "ERROR: --bucket is required" >&2; usage 1; } + +command -v gh >/dev/null || { echo "ERROR: gh CLI not found" >&2; exit 1; } +command -v gcloud >/dev/null || { echo "ERROR: gcloud CLI not found" >&2; exit 1; } + +BUCKET="${BUCKET#gs://}" +BUCKET="${BUCKET%/}" +BUCKET_URI="gs://${BUCKET}" + +if ! gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1; then + echo "ERROR: release '$TAG' not found in $REPO" >&2 + exit 1 +fi + +echo "Release: $TAG" +echo "Target: ${BUCKET_URI}" +$DRY_RUN && echo "Mode: dry-run" + +ASSETS=() +while IFS= read -r line || [[ -n "$line" ]]; do + [[ -n "$line" ]] && ASSETS+=("$line") +done < <(gh release view "$TAG" --repo "$REPO" --json assets \ + --jq '.assets[].name') + +if [[ "${#ASSETS[@]}" -eq 0 ]]; then + echo "ERROR: release $TAG has no assets" >&2 + exit 1 +fi + +TMP_DIR=$(mktemp -d) +trap 'rm -rf "$TMP_DIR"' EXIT + +uploaded=0 +skipped=0 +for asset in "${ASSETS[@]}"; do + if [[ "$asset" =~ ^firecracker-(amd64|arm64)$ ]]; then + arch="${BASH_REMATCH[1]}" + dst="${BUCKET_URI}/${TAG}/${arch}/firecracker" + elif [[ "$asset" == "firecracker" ]]; then + dst="${BUCKET_URI}/${TAG}/firecracker" + else + continue + fi + + if gcloud storage ls "$dst" >/dev/null 2>&1; then + echo " EXISTS $dst" + skipped=$((skipped + 1)) + continue + fi + + if $DRY_RUN; then + echo " WOULD $asset -> $dst" + uploaded=$((uploaded + 1)) + continue + fi + + echo " UPLOAD $asset -> $dst" + gh release download "$TAG" --repo "$REPO" \ + --pattern "$asset" --dir "$TMP_DIR" --clobber >/dev/null + gcloud storage cp "$TMP_DIR/$asset" "$dst" + rm -f "$TMP_DIR/$asset" + uploaded=$((uploaded + 1)) +done + +echo "" +if $DRY_RUN; then + echo "Dry run complete. Would upload: $uploaded, already in GCS: $skipped." +else + echo "Done. Uploaded: $uploaded, already in GCS: $skipped." +fi From 92e651f89b9bdfc614f7d5dd35cbf7715f4d846c Mon Sep 17 00:00:00 2001 From: Tomas Valenta Date: Tue, 12 May 2026 23:03:34 -0700 Subject: [PATCH 2/2] skip legacy flat-path firecracker asset, only upload arch-specific --- scripts/upload-release-to-gcs.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/upload-release-to-gcs.sh b/scripts/upload-release-to-gcs.sh index 0c7c8d5f5..cf7dd91ac 100755 --- a/scripts/upload-release-to-gcs.sh +++ b/scripts/upload-release-to-gcs.sh @@ -2,7 +2,6 @@ # Uploads firecracker-{amd64,arm64} assets from a fc-versions GitHub release # to GCS at: # ///firecracker -# //firecracker (legacy amd64 copy) # # Existing objects are never overwritten. # @@ -78,8 +77,6 @@ for asset in "${ASSETS[@]}"; do if [[ "$asset" =~ ^firecracker-(amd64|arm64)$ ]]; then arch="${BASH_REMATCH[1]}" dst="${BUCKET_URI}/${TAG}/${arch}/firecracker" - elif [[ "$asset" == "firecracker" ]]; then - dst="${BUCKET_URI}/${TAG}/firecracker" else continue fi