Files
zima-apps/scripts/build-appstore-zip.sh
T

161 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
push_mode=0
positional=()
while [[ $# -gt 0 ]]; do
case "$1" in
--push)
push_mode=1
shift
;;
-h|--help)
# handled below via usage
positional+=("$1")
shift
;;
*)
positional+=("$1")
shift
;;
esac
done
if [[ ${#positional[@]} -gt 2 ]]; then
echo "ERROR: too many arguments"
exit 2
fi
output_dir="${positional[0]:-$repo_root/dist}"
#zip_name="${positional[1]:-zima-appstore-$(date +%Y%m%d-%H%M%S).zip}"
zip_name="${positional[1]:-phirna-appstore.zip}"
usage() {
cat <<USAGE
Usage: $0 [output_dir] [zip_name]
$0 --push [output_dir] [zip_name]
Examples:
$0
$0 ./dist zima-apps-main.zip
$0 --push
USAGE
}
if [[ "${positional[0]:-}" == "-h" || "${positional[0]:-}" == "--help" ]]; then
usage
exit 0
fi
if ! command -v zip >/dev/null 2>&1; then
echo "ERROR: 'zip' command not found"
exit 1
fi
required_root_files=(
"category-list.json"
"recommend-list.json"
"featured-apps.json"
)
for file in "${required_root_files[@]}"; do
if [[ ! -f "$repo_root/$file" ]]; then
echo "ERROR: missing required file: $file"
exit 1
fi
done
if [[ ! -d "$repo_root/Apps" ]]; then
echo "ERROR: missing required directory: Apps"
exit 1
fi
is_git_repo=0
if git -C "$repo_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
is_git_repo=1
fi
tmp_dir="$(mktemp -d)"
staging_dir="$tmp_dir/appstore"
cleanup() {
rm -rf "$tmp_dir"
}
trap cleanup EXIT
mkdir -p "$staging_dir/Apps"
copy_file() {
local rel="$1"
mkdir -p "$staging_dir/$(dirname "$rel")"
cp "$repo_root/$rel" "$staging_dir/$rel"
}
if [[ "$is_git_repo" -eq 1 ]]; then
# Build from tracked files only so accidental local files are excluded.
while IFS= read -r rel; do
[[ -z "$rel" ]] && continue
case "$rel" in
Apps/*|category-list.json|recommend-list.json|featured-apps.json)
if [[ -f "$repo_root/$rel" ]]; then
copy_file "$rel"
fi
;;
esac
done < <(git -C "$repo_root" ls-files)
else
cp -R "$repo_root/Apps" "$staging_dir/"
for file in "${required_root_files[@]}"; do
copy_file "$file"
done
fi
# Export compatibility: source uses .yaml, AppStore tooling often expects .yml
while IFS= read -r compose_yaml; do
compose_yml="${compose_yaml%.yaml}.yml"
cp "$compose_yaml" "$compose_yml"
rm -f "$compose_yaml"
done < <(find "$staging_dir/Apps" -type f -name 'docker-compose.yaml' | sort)
if ! find "$staging_dir/Apps" -type f -name 'docker-compose.yml' | grep -q .; then
echo "ERROR: no docker-compose.yml files found in exported Apps"
exit 1
fi
mkdir -p "$output_dir"
zip_path="$(cd "$output_dir" && pwd)/$zip_name"
(
cd "$staging_dir"
zip -rq "$zip_path" . -x "*.DS_Store" "__MACOSX/*"
)
if command -v shasum >/dev/null 2>&1; then
checksum="$(shasum -a 256 "$zip_path" | awk '{print $1}')"
echo "ZIP created: $zip_path"
echo "SHA256: $checksum"
else
echo "ZIP created: $zip_path"
fi
if [[ "$push_mode" -eq 1 ]]; then
if [[ "$is_git_repo" -ne 1 ]]; then
echo "ERROR: --push requires a git repository"
exit 1
fi
echo "Push mode enabled: switching to main and publishing dist/"
git -C "$repo_root" checkout main
git -C "$repo_root" add dist/
if git -C "$repo_root" diff --cached --quiet; then
echo "No staged changes in dist/. Nothing to commit."
exit 0
fi
git -C "$repo_root" commit -m "Updated appstore"
git -C "$repo_root" push origin main
fi