/ upload.sh
upload.sh
1 #!/usr/bin/env bash 2 set -euo pipefail 3 4 ROOT="target/dx/web/release/web/public" 5 BASE_URL="http://ceratina.local/api/filesystem/sd" 6 7 c_reset=$'\033[0m' 8 c_dim=$'\033[2m' 9 c_bold=$'\033[1m' 10 c_cyan=$'\033[36m' 11 c_green=$'\033[32m' 12 c_yellow=$'\033[33m' 13 c_red=$'\033[31m' 14 c_magenta=$'\033[35m' 15 16 printf "\n ${c_bold}${c_cyan}ceratina deploy${c_reset}\n" 17 printf " ${c_dim}──────────────────────────────────────${c_reset}\n" 18 19 # printf " ${c_dim}Flashing firmware ...${c_reset}\n" 20 # pio run -t upload || { 21 # echo "${c_red}error:${c_reset} firmware flash failed" >&2 22 # exit 1 23 # } 24 # printf " ${c_green}flashed${c_reset}\n" 25 26 [ -d "$ROOT" ] || { 27 echo "${c_red}error:${c_reset} missing dir $ROOT" >&2 28 exit 1 29 } 30 31 # ── Prune stale assets ──────────────────────────────── 32 # index.html references only the current build's hashed files. 33 # Previous builds leave orphaned assets that waste upload bandwidth. 34 if [ -f "$ROOT/index.html" ]; then 35 stale=0 36 for f in "$ROOT"/assets/*; do 37 [ -f "$f" ] || continue 38 base=$(basename "$f") 39 # Skip .gz companions — they'll be removed with their source 40 [[ "$base" == *.gz ]] && continue 41 # Keep files referenced by index.html 42 if grep -qF "$base" "$ROOT/index.html"; then 43 continue 44 fi 45 # Keep files referenced by the main JS bundle 46 main_js=$(grep -o 'assets/web-[^"]*\.js' "$ROOT/index.html" | head -1) 47 if [ -n "$main_js" ] && [ -f "$ROOT/$main_js" ] && grep -qF "$base" "$ROOT/$main_js"; then 48 continue 49 fi 50 rm -f "$f" "${f}.gz" 51 ((stale += 1)) 52 done 53 if ((stale > 0)); then 54 printf " ${c_yellow}pruned${c_reset} %d stale assets\n" "$stale" 55 fi 56 fi 57 58 HOST="ceratina.local" 59 printf " ${c_dim}Waiting for ${HOST} ...${c_reset}" 60 until ping -c1 -W1 "$HOST" &>/dev/null; do 61 printf "${c_dim}.${c_reset}" 62 sleep 1 63 done 64 printf " ${c_green}online${c_reset}\n" 65 66 human_size() { 67 local bytes=$1 68 if ((bytes >= 1048576)); then 69 printf "%.1f MB" "$(echo "scale=1; $bytes / 1048576" | bc)" 70 elif ((bytes >= 1024)); then 71 printf "%.1f KB" "$(echo "scale=1; $bytes / 1024" | bc)" 72 else 73 printf "%d B" "$bytes" 74 fi 75 } 76 77 echo 78 79 printf "${c_dim} Compressing ...${c_reset}" 80 compressed=0 81 find "$ROOT" -type f \( -name "*.wasm" -o -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.svg" \) | while read f; do 82 gzip -kf "$f" 83 done 84 printf " ${c_green}done${c_reset}\n" 85 86 mapfile -d '' files < <(find "$ROOT" -type f -print0 | sort -z) 87 total=${#files[@]} 88 89 upload_count=0 90 skip_count=0 91 total_bytes=0 92 for f in "${files[@]}"; do 93 if [[ "$f" != *.gz ]] && [[ -f "${f}.gz" ]]; then 94 ((skip_count += 1)) 95 else 96 ((upload_count += 1)) 97 total_bytes=$((total_bytes + $(stat -f%z "$f" 2>/dev/null || stat -c%s "$f" 2>/dev/null))) 98 fi 99 done 100 101 printf " ${c_dim}target${c_reset} %s\n" "$BASE_URL" 102 printf " ${c_dim}upload${c_reset} ${c_bold}%d${c_reset} files ${c_dim}(%s)${c_reset}\n" "$upload_count" "$(human_size $total_bytes)" 103 printf " ${c_dim}skip${c_reset} %d files ${c_dim}(uncompressed originals)${c_reset}\n" "$skip_count" 104 printf "${c_dim} ──────────────────────────────────────${c_reset}\n" 105 echo 106 107 start_ts=$(date +%s) 108 uploaded=0 109 uploaded_bytes=0 110 111 for f in "${files[@]}"; do 112 rel="${f#"$ROOT"/}" 113 114 if [[ "$f" != *.gz ]] && [[ -f "${f}.gz" ]]; then 115 continue 116 fi 117 118 ((uploaded += 1)) 119 fsize=$(stat -f%z "$f" 2>/dev/null || stat -c%s "$f" 2>/dev/null) 120 uploaded_bytes=$((uploaded_bytes + fsize)) 121 122 ext="${rel##*.}" 123 case "$ext" in 124 gz) icon="$c_magenta" ;; 125 wasm) icon="$c_yellow" ;; 126 js) icon="$c_yellow" ;; 127 css) icon="$c_cyan" ;; 128 html) icon="$c_green" ;; 129 svg | png) icon="$c_magenta" ;; 130 bin) icon="$c_red" ;; 131 *) icon="$c_dim" ;; 132 esac 133 134 printf " ${c_dim}[%d/%d]${c_reset} ${icon}%s${c_reset} ${c_dim}(%s)${c_reset}\n" \ 135 "$uploaded" "$upload_count" "$rel" "$(human_size $fsize)" 136 137 if ! curl -X PUT --fail --progress-bar \ 138 -o /dev/null \ 139 -F "file=@${f}" \ 140 "${BASE_URL}/${rel}"; then 141 printf " ${c_red}FAIL${c_reset} %s\n\n" "$rel" 142 continue 143 fi 144 145 printf " ${c_green} ok${c_reset}\n" 146 done 147 148 elapsed=$(($(date +%s) - start_ts)) 149 echo 150 printf "${c_dim} ──────────────────────────────────────${c_reset}\n" 151 printf " ${c_bold}${c_green}done${c_reset} %d files ${c_dim}%s in %ss${c_reset}\n" "$uploaded" "$(human_size $uploaded_bytes)" "$elapsed" 152 echo