Skip to content

Instantly share code, notes, and snippets.

@kerim
Last active November 30, 2025 17:10
Show Gist options
  • Select an option

  • Save kerim/5557a4e0aeecd657c24e8b5bcbc86d4b to your computer and use it in GitHub Desktop.

Select an option

Save kerim/5557a4e0aeecd657c24e8b5bcbc86d4b to your computer and use it in GitHub Desktop.
Updater for Logseq DB builds - runs in fish terminal (for MacOS), skips x.10.x builds
#!/usr/bin/env fish
# Logseq Build Updater Script
# Checks for and downloads the latest logseq-darwin-arm64 build from GitHub Actions
# Version: 1.1.0
set -l REPO "logseq/logseq"
set -l WORKFLOW "build-desktop-release.yml"
set -l APP_PATH "/Applications/Logseq.app"
set -l STATE_FILE "$HOME/.logseq_last_run"
set -l DOWNLOAD_DIR "$HOME/Downloads/logseq-builds"
# Colors for output
set -l GREEN (printf '\033[0;32m')
set -l YELLOW (printf '\033[1;33m')
set -l RED (printf '\033[0;31m')
set -l NC (printf '\033[0m') # No Color
function log_info
printf "%s[INFO]%s %s\n" $GREEN $NC "$argv"
end
function log_warn
printf "%s[WARN]%s %s\n" $YELLOW $NC "$argv"
end
function log_error
printf "%s[ERROR]%s %s\n" $RED $NC "$argv"
end
# Check if gh CLI is available
if not type -q gh
log_error "gh CLI is not installed. Please install it with: brew install gh"
exit 1
end
# Check if gh is authenticated
if not gh auth status >/dev/null 2>&1
log_warn "gh CLI is not authenticated. Running gh auth login..."
gh auth login
end
# Get current Logseq version info
if test -d $APP_PATH
set -l current_version (defaults read $APP_PATH/Contents/Info.plist CFBundleShortVersionString)
set -l current_build (defaults read $APP_PATH/Contents/Info.plist CFBundleVersion)
log_info "Current Logseq version: $current_version (build $current_build)"
else
log_warn "Logseq not found at $APP_PATH"
end
# Get the last checked commit SHA
set -l last_sha ""
if test -f $STATE_FILE
set last_sha (cat $STATE_FILE)
log_info "Last installed commit SHA: $last_sha"
end
# Get the latest successful workflow run
log_info "Fetching latest successful build from GitHub Actions..."
set -l latest_run_json (gh api "repos/$REPO/actions/workflows/$WORKFLOW/runs?per_page=1&status=success&branch=master" 2>/dev/null)
if test $status -ne 0
log_error "Failed to fetch workflow runs from GitHub"
exit 1
end
# Parse the latest run information
set -l latest_run_number (echo $latest_run_json | python3 -c "import sys, json; print(json.load(sys.stdin)['workflow_runs'][0]['run_number'])")
set -l latest_run_id (echo $latest_run_json | python3 -c "import sys, json; print(json.load(sys.stdin)['workflow_runs'][0]['id'])")
set -l latest_run_sha (echo $latest_run_json | python3 -c "import sys, json; print(json.load(sys.stdin)['workflow_runs'][0]['head_sha'][:7])")
set -l latest_run_date (echo $latest_run_json | python3 -c "import sys, json; print(json.load(sys.stdin)['workflow_runs'][0]['created_at'])")
log_info "Latest workflow run: #$latest_run_number (ID: $latest_run_id, SHA: $latest_run_sha)"
log_info "Build date: $latest_run_date"
# Compare commit SHAs
if test "$latest_run_sha" = "$last_sha"
log_info "Already on latest build (SHA: $latest_run_sha)"
exit 0
end
if test -n "$last_sha"
log_info "New build available! SHA: $latest_run_sha (previous: $last_sha)"
else
log_info "New build available! SHA: $latest_run_sha"
end
# Ask user if they want to download
echo ""
read -l -P "Download and install the new build? [y/N] " confirm
if test "$confirm" != "y" -a "$confirm" != "Y"
log_info "Download cancelled"
exit 0
end
# Create download directory
mkdir -p $DOWNLOAD_DIR
# Get artifacts for this run
log_info "Fetching artifact information..."
set -l artifacts_json (gh api "repos/$REPO/actions/runs/$latest_run_id/artifacts" 2>/dev/null)
if test $status -ne 0
log_error "Failed to fetch artifacts"
exit 1
end
# Find the darwin-arm64 artifact
set -l artifact_name "logseq-darwin-arm64-builds"
set -l artifact_id (echo $artifacts_json | python3 -c "import sys, json; artifacts = json.load(sys.stdin)['artifacts']; darwin_artifact = next((a for a in artifacts if a['name'] == '$artifact_name'), None); print(darwin_artifact['id'] if darwin_artifact else '')")
if test -z "$artifact_id"
log_error "Could not find $artifact_name artifact"
exit 1
end
log_info "Found artifact: $artifact_name (ID: $artifact_id)"
# Download the artifact
set -l artifact_zip "$DOWNLOAD_DIR/logseq-run-$latest_run_number.zip"
set -l download_url "https://api.github.com/repos/$REPO/actions/artifacts/$artifact_id/zip"
# Get GitHub token for authentication
set -l gh_token (gh auth token)
if test -z "$gh_token"
log_error "Failed to get GitHub authentication token"
exit 1
end
log_info "Downloading artifact to $artifact_zip..."
log_info "Download will resume automatically if interrupted"
# Use curl with progress bar and resume capability
curl -L -C - \
--progress-bar \
-H "Authorization: Bearer $gh_token" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-o "$artifact_zip" \
"$download_url"
if test $status -ne 0
log_error "Failed to download artifact"
log_warn "Download may have been interrupted. Run the script again to resume."
exit 1
end
# Extract the artifact
log_info "Extracting artifact..."
cd $DOWNLOAD_DIR
unzip -q -o $artifact_zip -d "logseq-run-$latest_run_number"
if test $status -ne 0
log_error "Failed to extract artifact"
exit 1
end
# Find the .dmg file
set -l dmg_file (find "$DOWNLOAD_DIR/logseq-run-$latest_run_number" -name "*.dmg" -type f | head -1)
if test -z "$dmg_file"
log_error "No .dmg file found in extracted artifact"
exit 1
end
log_info "Found DMG: "(basename $dmg_file)
# Ask if user wants to install now
echo ""
read -l -P "Install now? (This will replace the current Logseq.app) [y/N] " install_confirm
if test "$install_confirm" = "y" -o "$install_confirm" = "Y"
log_info "Mounting DMG..."
set -l mount_point (hdiutil attach "$dmg_file" | grep Volumes | sed 's/.*\/Volumes/\/Volumes/')
if test -z "$mount_point"
log_error "Failed to mount DMG"
exit 1
end
log_info "Removing old Logseq.app..."
rm -rf $APP_PATH
log_info "Copying new Logseq.app..."
cp -R "$mount_point/Logseq.app" /Applications/
log_info "Unmounting DMG..."
hdiutil detach "$mount_point" -quiet
log_info "Installation complete!"
# Clean up downloaded files
log_info "Cleaning up downloaded files..."
# Move the extracted folder to trash
set -l extracted_folder "$DOWNLOAD_DIR/logseq-run-$latest_run_number"
osascript -e "tell application \"Finder\" to delete POSIX file \"$extracted_folder\"" >/dev/null 2>&1
# Move the zip file to trash
osascript -e "tell application \"Finder\" to delete POSIX file \"$artifact_zip\"" >/dev/null 2>&1
if test $status -eq 0
log_info "Downloaded files moved to trash"
else
log_warn "Could not move all files to trash (may need manual cleanup in $DOWNLOAD_DIR)"
end
# Update state file
echo $latest_run_sha > $STATE_FILE
log_info "Updated last installed SHA to $latest_run_sha"
else
log_info "DMG saved to: $dmg_file"
log_info "You can install it manually later"
echo ""
log_info "To install manually:"
log_info " 1. Open $dmg_file"
log_info " 2. Drag Logseq.app to /Applications"
log_info " 3. Run: echo $latest_run_sha > $STATE_FILE"
end
log_info "Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment