#!/usr/bin/env bash # # sync-upstream.sh — look at what upstream Feather has done since our pin, and # optionally fold it in. # # FTStore is a HARD FORK. This script is not part of any routine: it runs when # someone asks for a sync, not on a schedule and not "because we're behind". # .upstream-sync.json is a pin recording where we last synced, so this has a # sensible place to diff from — it is not a promise to stay current. # # Workflow: # 1. Fetch upstream and report what has landed since the pin. # 2. Optionally merge upstream/main (pass --merge). # 3. Re-apply the FTStore rebrand (scripts/apply-rebrand.sh). # 4. Remind you to update .upstream-sync.json once the merge is committed. # # Run with no args for a read-only report — that is the normal use. `--merge` # takes upstream wholesale; because the trees have diverged on purpose, # cherry-picking the commits you actually want is usually the better move. # # Monorepo note: upstream's tree is rooted at the repo root, ours lives in ios/. # A merge therefore lands Feather's files *next to* ios/, and apply-rebrand.sh # relocates them in its first step — so always let the script run before judging # what the merge did. web/ is ours alone and upstream never touches it. # set -euo pipefail cd "$(git rev-parse --show-toplevel)" SYNC_FILE=".upstream-sync.json" REMOTE="upstream" BRANCH="main" DO_MERGE=0 [ "${1:-}" = "--merge" ] && DO_MERGE=1 bold() { printf '\033[1m%s\033[0m\n' "$*"; } # Ensure the upstream remote exists. if ! git remote get-url "$REMOTE" >/dev/null 2>&1; then bold "Adding '$REMOTE' remote -> claration/Feather" git remote add "$REMOTE" https://github.com/claration/Feather.git fi bold "Fetching $REMOTE …" git fetch "$REMOTE" --tags LAST="$(jq -r '.lastMerged.commit' "$SYNC_FILE")" HEAD_UP="$(git rev-parse "$REMOTE/$BRANCH")" COUNT="$(git rev-list --count "${LAST}..${REMOTE}/${BRANCH}")" echo bold "Last merged upstream commit: $LAST (version $(jq -r '.lastMerged.upstreamVersion' "$SYNC_FILE"), synced $(jq -r '.lastMerged.syncedAt' "$SYNC_FILE"))" bold "Upstream $REMOTE/$BRANCH HEAD: $HEAD_UP" bold "$COUNT upstream commit(s) since the pin. FTStore is a hard fork -- not a defect." echo if [ "$COUNT" -eq 0 ]; then echo "Nothing new upstream since the pin." exit 0 fi bold "New upstream commits:" git log --oneline --no-decorate "${LAST}..${REMOTE}/${BRANCH}" echo if [ "$DO_MERGE" -eq 0 ]; then echo "Read-only report. To fold something in, prefer cherry-picking the commits you" echo "actually want. For a wholesale catch-up: scripts/sync-upstream.sh --merge" exit 0 fi bold "Merging $REMOTE/$BRANCH …" if ! git merge --no-edit "$REMOTE/$BRANCH"; then echo bold "Merge conflicts detected. Resolve them, then:" echo " - keep FTStore branding in app-repo.json / README.md / project.pbxproj" echo " - keep OURS in .gitmodules (upstream says Zsign, we say ios/Zsign)" echo " - keep OURS in .gitignore and .github/workflows/ (monorepo layout)" echo " - run: bash scripts/apply-rebrand.sh # relocates root files into ios/" echo " - commit, then update $SYNC_FILE (commit=$HEAD_UP) and re-run validation" exit 1 fi bold "Re-applying FTStore rebrand …" bash scripts/apply-rebrand.sh echo bold "Merge + rebrand complete. Next:" echo " 1. Review: git status && git diff" echo " 2. Update $SYNC_FILE:" echo " lastMerged.commit = $HEAD_UP" echo " lastMerged.upstreamVersion = " echo " lastMerged.syncedAt = $(date +%F)" echo " 3. Commit the merge + rebrand + sync-file bump."