#!/usr/bin/env bash set -e ARTIFACT_PATH="$1" ARTIFACT_NAME="$2" # Serialize across parallel invocations from goreleaser to avoid slamming the # PDS with simultaneous uploads. `goat account login` happens once in the # release workflow before goreleaser runs, so this script just reuses the # existing session. exec 9>/tmp/atcr-publish-artifact.lock flock 9 retry() { local max=5 attempt=1 while true; do if "$@"; then return 0; fi [ $attempt -ge $max ] && { echo "giving up after $max attempts: $*" >&2; return 1; } local sleep_s=$((attempt * 3)) echo "attempt $attempt failed; retrying in ${sleep_s}s..." >&2 sleep $sleep_s attempt=$((attempt + 1)) done } TAG_HASH=$(git rev-parse "$TANGLED_REF_NAME") TAG_BYTES=$(printf "$(printf '%s' "$TAG_HASH" | sed 's/../\\x&/g')" | base64 | tr -d '=') BLOB_OUTPUT=$(retry goat blob upload "$ARTIFACT_PATH") echo "$BLOB_OUTPUT" # Deterministic rkey from (tag, artifact name) makes record create idempotent. # Needed because tangled's PDS returns HTTP 500 (not 409) on duplicate rkey, # so a retry after a mid-write 500 would otherwise create a duplicate record. RKEY=$(printf '%s|%s' "$TANGLED_REF_NAME" "$ARTIFACT_NAME" | sha256sum | cut -c1-24) RECORD_URI="at://${TANGLED_REPO_DID}/sh.tangled.repo.artifact/${RKEY}" CREATED_AT=$(date -Iseconds) cat > temp_artifact.json </dev/null 2>&1; then echo "record already exists at $RECORD_URI — treating as success" break fi [ $attempt -eq 5 ] && { echo "record create failed and record does not exist" >&2; exit 1; } sleep $((attempt * 3)) done rm temp_artifact.json sleep 2