mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-03-28 09:55:53 +00:00
- Add state tracking and resume capability to release process - Create release-state.sh for tracking 9 major release steps - Add --resume and --status flags to release.sh - Fix private key format handling for sign_update tool - Create clean key file (sparkle_ed_private_key) automatically - Handle missing custom Node.js builds gracefully - Add DerivedData app location fallback - Create comprehensive release-checklist.sh script - Update release documentation with critical learnings - Enhance Stats.store documentation with setup instructions - Add troubleshooting for 'Application not found' error - Document fallback options for direct GitHub URLs - Update all scripts to handle clean key file format These improvements make the release process more reliable and resilient to interruptions, with better error handling throughout.
211 lines
No EOL
5.3 KiB
Bash
211 lines
No EOL
5.3 KiB
Bash
#!/bin/bash
|
|
#
|
|
# Release State Management Functions
|
|
# Used by release.sh to track progress and enable resumption
|
|
#
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$SCRIPT_DIR/.."
|
|
STATE_FILE="$PROJECT_ROOT/.release-state.json"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Initialize state file
|
|
init_state() {
|
|
local release_type=$1
|
|
local release_version=$2
|
|
local build_number=$3
|
|
local tag_name=$4
|
|
|
|
cat > "$STATE_FILE" << EOF
|
|
{
|
|
"release_type": "$release_type",
|
|
"release_version": "$release_version",
|
|
"build_number": "$build_number",
|
|
"tag_name": "$tag_name",
|
|
"started_at": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
|
|
"current_step": 1,
|
|
"steps": {
|
|
"1": {"name": "preflight_check", "status": "pending"},
|
|
"2": {"name": "clean_build", "status": "pending"},
|
|
"3": {"name": "set_version", "status": "pending"},
|
|
"4": {"name": "build_app", "status": "pending"},
|
|
"5": {"name": "sign_notarize", "status": "pending"},
|
|
"6": {"name": "create_dmg_zip", "status": "pending"},
|
|
"7": {"name": "github_release", "status": "pending"},
|
|
"8": {"name": "update_appcast", "status": "pending"},
|
|
"9": {"name": "commit_push", "status": "pending"}
|
|
},
|
|
"artifacts": {
|
|
"app_path": "",
|
|
"dmg_path": "",
|
|
"zip_path": "",
|
|
"sparkle_signature": ""
|
|
}
|
|
}
|
|
EOF
|
|
echo -e "${BLUE}📋 Initialized release state tracking${NC}"
|
|
}
|
|
|
|
# Get current step
|
|
get_current_step() {
|
|
if [[ -f "$STATE_FILE" ]]; then
|
|
jq -r '.current_step' "$STATE_FILE"
|
|
else
|
|
echo "1"
|
|
fi
|
|
}
|
|
|
|
# Get step status
|
|
get_step_status() {
|
|
local step=$1
|
|
if [[ -f "$STATE_FILE" ]]; then
|
|
jq -r ".steps.\"$step\".status" "$STATE_FILE"
|
|
else
|
|
echo "pending"
|
|
fi
|
|
}
|
|
|
|
# Update step status
|
|
update_step() {
|
|
local step=$1
|
|
local status=$2 # pending, in_progress, completed, failed
|
|
|
|
if [[ ! -f "$STATE_FILE" ]]; then
|
|
echo -e "${RED}❌ Error: State file not found${NC}"
|
|
return 1
|
|
fi
|
|
|
|
# Update the step status
|
|
local tmp=$(mktemp)
|
|
jq ".steps.\"$step\".status = \"$status\"" "$STATE_FILE" > "$tmp" && mv "$tmp" "$STATE_FILE"
|
|
|
|
# If completed, update current step to next
|
|
if [[ "$status" == "completed" ]]; then
|
|
local next_step=$((step + 1))
|
|
jq ".current_step = $next_step" "$STATE_FILE" > "$tmp" && mv "$tmp" "$STATE_FILE"
|
|
fi
|
|
|
|
# Add timestamp
|
|
jq ".steps.\"$step\".${status}_at = \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"" "$STATE_FILE" > "$tmp" && mv "$tmp" "$STATE_FILE"
|
|
}
|
|
|
|
# Save artifact path
|
|
save_artifact() {
|
|
local key=$1
|
|
local value=$2
|
|
|
|
if [[ ! -f "$STATE_FILE" ]]; then
|
|
echo -e "${RED}❌ Error: State file not found${NC}"
|
|
return 1
|
|
fi
|
|
|
|
local tmp=$(mktemp)
|
|
jq ".artifacts.$key = \"$value\"" "$STATE_FILE" > "$tmp" && mv "$tmp" "$STATE_FILE"
|
|
}
|
|
|
|
# Get artifact path
|
|
get_artifact() {
|
|
local key=$1
|
|
if [[ -f "$STATE_FILE" ]]; then
|
|
jq -r ".artifacts.$key" "$STATE_FILE"
|
|
else
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
# Get release info
|
|
get_release_info() {
|
|
local key=$1
|
|
if [[ -f "$STATE_FILE" ]]; then
|
|
jq -r ".$key" "$STATE_FILE"
|
|
else
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
# Show progress
|
|
show_progress() {
|
|
if [[ ! -f "$STATE_FILE" ]]; then
|
|
echo -e "${YELLOW}⚠️ No release in progress${NC}"
|
|
return
|
|
fi
|
|
|
|
echo -e "${BLUE}📊 Release Progress${NC}"
|
|
echo "=================="
|
|
|
|
local release_version=$(get_release_info "release_version")
|
|
local release_type=$(get_release_info "release_type")
|
|
local started_at=$(get_release_info "started_at")
|
|
|
|
echo "Version: $release_version ($release_type)"
|
|
echo "Started: $started_at"
|
|
echo ""
|
|
echo "Steps:"
|
|
|
|
for i in {1..9}; do
|
|
local name=$(jq -r ".steps.\"$i\".name" "$STATE_FILE")
|
|
local status=$(jq -r ".steps.\"$i\".status" "$STATE_FILE")
|
|
local icon="⏳"
|
|
|
|
case $status in
|
|
completed) icon="✅" ;;
|
|
in_progress) icon="🔄" ;;
|
|
failed) icon="❌" ;;
|
|
pending) icon="⏳" ;;
|
|
esac
|
|
|
|
printf "%s Step %d: %-20s %s\n" "$icon" "$i" "$name" "$status"
|
|
done
|
|
|
|
echo ""
|
|
echo "Artifacts:"
|
|
local dmg_path=$(get_artifact "dmg_path")
|
|
local zip_path=$(get_artifact "zip_path")
|
|
if [[ -n "$dmg_path" ]]; then
|
|
echo " DMG: $dmg_path"
|
|
fi
|
|
if [[ -n "$zip_path" ]]; then
|
|
echo " ZIP: $zip_path"
|
|
fi
|
|
}
|
|
|
|
# Check if release can be resumed
|
|
can_resume() {
|
|
if [[ ! -f "$STATE_FILE" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
# Check if any step is in progress or if there are pending steps after completed ones
|
|
local current_step=$(get_current_step)
|
|
if [[ "$current_step" -le 9 ]]; then
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# Clean up state file
|
|
cleanup_state() {
|
|
if [[ -f "$STATE_FILE" ]]; then
|
|
rm -f "$STATE_FILE"
|
|
echo -e "${GREEN}✅ Cleaned up release state${NC}"
|
|
fi
|
|
}
|
|
|
|
# Export functions
|
|
export -f init_state
|
|
export -f get_current_step
|
|
export -f get_step_status
|
|
export -f update_step
|
|
export -f save_artifact
|
|
export -f get_artifact
|
|
export -f get_release_info
|
|
export -f show_progress
|
|
export -f can_resume
|
|
export -f cleanup_state |