Last active
December 14, 2025 22:27
-
-
Save kolber/28c20d6f3fa2a2389982408e623a44cc to your computer and use it in GitHub Desktop.
Zora Monorepo Rebuild Script - Automated rebuild of monorepo from latest commits in all 3 repos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -euo pipefail | |
| # Automated Monorepo Rebuild Script | |
| # Rebuilds the monorepo from scratch using the latest commits from source repos | |
| # Phase 1: Backend + Frontend only (Protocol excluded) | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| PURPLE='\033[0;35m' | |
| CYAN='\033[0;36m' | |
| BOLD='\033[1m' | |
| NC='\033[0m' | |
| # Repository URLs (Phase 1: Backend + Frontend only) | |
| BACKEND_REPO="git@github.com:ourzora/zora-backend-v2.git" | |
| FRONTEND_REPO="git@github.com:ourzora/zora-co.git" | |
| # Working directory | |
| WORK_DIR="$(pwd)" | |
| REBUILD_DIR="$WORK_DIR/zora-monorepo-rebuild-$(date +%Y%m%d-%H%M%S)" | |
| # Backup old monorepo | |
| OLD_MONOREPO_BACKUP="$WORK_DIR/zora-monorepo-backup-$(date +%Y%m%d-%H%M%S)" | |
| echo -e "${PURPLE}" | |
| cat << 'EOF' | |
| ╔═══════════════════════════════════════════════════════════╗ | |
| ║ ║ | |
| ║ Automated Monorepo Rebuild from Latest Commits ║ | |
| ║ Phase 1: Backend + Frontend ║ | |
| ║ ║ | |
| ╚═══════════════════════════════════════════════════════════╝ | |
| EOF | |
| echo -e "${NC}\n" | |
| ############################################################################# | |
| # Dependency Checks | |
| ############################################################################# | |
| check_dependencies() { | |
| echo -e "${BLUE}Checking dependencies...${NC}\n" | |
| if ! command -v git &> /dev/null; then | |
| echo -e "${RED}✗ git not found${NC}" | |
| exit 1 | |
| fi | |
| if ! command -v git-filter-repo &> /dev/null; then | |
| echo -e "${RED}✗ git-filter-repo not found${NC}" | |
| echo "Install with: pip install git-filter-repo" | |
| echo "Or: brew install git-filter-repo" | |
| exit 1 | |
| fi | |
| echo -e "${GREEN}✓ All dependencies satisfied${NC}\n" | |
| } | |
| ############################################################################# | |
| # Clone and Update Repos | |
| ############################################################################# | |
| clone_and_update_repos() { | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}" | |
| echo -e "${BLUE} Step 1: Clone/Update Original Repos${NC}" | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}\n" | |
| # Backend | |
| if [ -d "zora-backend-v2-original" ]; then | |
| echo -e "${CYAN}Updating zora-backend-v2...${NC}" | |
| (cd zora-backend-v2-original && git fetch origin && git checkout main && git pull origin main) | |
| else | |
| echo -e "${CYAN}Cloning zora-backend-v2...${NC}" | |
| git clone "$BACKEND_REPO" zora-backend-v2-original | |
| fi | |
| BACKEND_COMMIT=$(cd zora-backend-v2-original && git rev-parse HEAD) | |
| echo -e "${GREEN}✓ Backend: $BACKEND_COMMIT${NC}\n" | |
| # Frontend | |
| if [ -d "zora-co-original" ]; then | |
| echo -e "${CYAN}Updating zora-co...${NC}" | |
| (cd zora-co-original && git fetch origin && git checkout main && git pull origin main) | |
| else | |
| echo -e "${CYAN}Cloning zora-co...${NC}" | |
| git clone "$FRONTEND_REPO" zora-co-original | |
| fi | |
| FRONTEND_COMMIT=$(cd zora-co-original && git rev-parse HEAD) | |
| echo -e "${GREEN}✓ Frontend: $FRONTEND_COMMIT${NC}\n" | |
| # Note: Protocol excluded from Phase 1 | |
| echo -e "${YELLOW}ℹ Protocol excluded from Phase 1 migration${NC}\n" | |
| } | |
| ############################################################################# | |
| # Rewrite Repos with git-filter-repo | |
| ############################################################################# | |
| rewrite_repos() { | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}" | |
| echo -e "${BLUE} Step 2: Rewrite Repos into Subdirectories${NC}" | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}\n" | |
| # Backend | |
| echo -e "${CYAN}Rewriting backend into backend/...${NC}" | |
| rm -rf zora-backend-v2-rewritten | |
| cp -R zora-backend-v2-original zora-backend-v2-rewritten | |
| (cd zora-backend-v2-rewritten && git-filter-repo --to-subdirectory-filter backend --force) | |
| echo -e "${GREEN}✓ Backend rewritten${NC}\n" | |
| # Frontend | |
| echo -e "${CYAN}Rewriting frontend into frontend/...${NC}" | |
| rm -rf zora-co-rewritten | |
| cp -R zora-co-original zora-co-rewritten | |
| (cd zora-co-rewritten && git-filter-repo --to-subdirectory-filter frontend --force) | |
| echo -e "${GREEN}✓ Frontend rewritten${NC}\n" | |
| # Note: Protocol excluded from Phase 1 | |
| } | |
| ############################################################################# | |
| # Create New Monorepo | |
| ############################################################################# | |
| create_monorepo() { | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}" | |
| echo -e "${BLUE} Step 3: Create Fresh Monorepo${NC}" | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}\n" | |
| # Create new empty repo | |
| echo -e "${CYAN}Creating new monorepo at: ${REBUILD_DIR}${NC}" | |
| mkdir -p "$REBUILD_DIR" | |
| cd "$REBUILD_DIR" | |
| git init --initial-branch=main | |
| git commit --allow-empty -m "Initial commit" | |
| # Add origin remote | |
| git remote add origin git@github.com:ourzora/zora-monorepo-poc.git | |
| # Add rewritten repos as remotes (Phase 1: Backend + Frontend only) | |
| git remote add backend "$WORK_DIR/zora-backend-v2-rewritten" | |
| git remote add frontend "$WORK_DIR/zora-co-rewritten" | |
| echo -e "${GREEN}✓ Monorepo initialized${NC}\n" | |
| # Fetch all histories | |
| echo -e "${CYAN}Fetching histories...${NC}" | |
| git fetch backend --quiet | |
| git fetch frontend --quiet | |
| echo -e "${GREEN}✓ Histories fetched${NC}\n" | |
| # Merge backend | |
| echo -e "${CYAN}Merging backend...${NC}" | |
| git merge backend/main --allow-unrelated-histories -m "merge: add backend from zora-backend-v2" | |
| echo -e "${GREEN}✓ Backend merged${NC}\n" | |
| # Merge frontend | |
| echo -e "${CYAN}Merging frontend...${NC}" | |
| git merge frontend/main --allow-unrelated-histories -m "merge: add frontend from zora-co" | |
| echo -e "${GREEN}✓ Frontend merged${NC}\n" | |
| # Note: Protocol excluded from Phase 1 | |
| TOTAL_COMMITS=$(git rev-list --count HEAD) | |
| echo -e "${GREEN}✓ Monorepo created with ${TOTAL_COMMITS} commits${NC}\n" | |
| } | |
| ############################################################################# | |
| # Copy Configuration and Scripts | |
| ############################################################################# | |
| setup_monorepo() { | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}" | |
| echo -e "${BLUE} Step 4: Configure Monorepo${NC}" | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}\n" | |
| # Copy from old monorepo if it exists | |
| if [ -d "$WORK_DIR/zora-monorepo" ]; then | |
| echo -e "${CYAN}Copying configuration from existing monorepo...${NC}" | |
| # Root config files | |
| cp "$WORK_DIR/zora-monorepo/pyproject.toml" . 2>/dev/null || echo "No pyproject.toml" | |
| cp "$WORK_DIR/zora-monorepo/package.json" . 2>/dev/null || echo "No package.json" | |
| cp "$WORK_DIR/zora-monorepo/.env.example" . 2>/dev/null || echo "No .env.example" | |
| cp "$WORK_DIR/zora-monorepo/.gitignore" . 2>/dev/null || echo "No .gitignore" | |
| cp "$WORK_DIR/zora-monorepo/docker-compose.yaml" . 2>/dev/null || echo "No docker-compose.yaml" | |
| # Scripts directory - copy from existing monorepo, then overlay from backup to ensure required scripts exist | |
| if [ -d "$WORK_DIR/zora-monorepo/scripts" ]; then | |
| echo -e "${CYAN}Copying scripts from existing monorepo...${NC}" | |
| cp -R "$WORK_DIR/zora-monorepo/scripts" . | |
| chmod +x scripts/*.sh 2>/dev/null || true | |
| fi | |
| # Ensure required scripts exist from backup (these are critical for rye run commands) | |
| BACKUP_DIR="$WORK_DIR/backups/scripts" | |
| if [ -d "$BACKUP_DIR" ]; then | |
| echo -e "${CYAN}Ensuring required scripts from backup...${NC}" | |
| mkdir -p scripts | |
| # Shell scripts | |
| for script in sync.sh rye-start-wrapper.sh start-all-services-coordinated.sh start-core-services.sh stop-all-services.sh start-mobile.sh monitor-services.sh; do | |
| if [ -f "$BACKUP_DIR/$script" ]; then | |
| cp "$BACKUP_DIR/$script" "scripts/$script" | |
| fi | |
| done | |
| chmod +x scripts/*.sh 2>/dev/null || true | |
| # Python scripts (for seeding, schema generation, etc.) | |
| for script in seed_test_user.py seed_zora_price.py populate_gorse.py clear_gorse.py generate_local_graphql_schema.py; do | |
| if [ -f "$BACKUP_DIR/$script" ]; then | |
| cp "$BACKUP_DIR/$script" "scripts/$script" | |
| fi | |
| done | |
| # Seeders directory | |
| if [ -d "$BACKUP_DIR/seeders" ]; then | |
| echo -e "${CYAN}Copying seeders from backup...${NC}" | |
| cp -R "$BACKUP_DIR/seeders" scripts/ | |
| fi | |
| fi | |
| # Ensure critical root config files come from backup (these have correct settings) | |
| echo -e "${CYAN}Ensuring root config files from backup...${NC}" | |
| if [ -f "$WORK_DIR/backups/pyproject.toml" ]; then | |
| cp "$WORK_DIR/backups/pyproject.toml" . | |
| fi | |
| if [ -f "$WORK_DIR/backups/package.json" ]; then | |
| cp "$WORK_DIR/backups/package.json" . | |
| fi | |
| if [ -f "$WORK_DIR/backups/.env.example" ]; then | |
| cp "$WORK_DIR/backups/.env.example" . | |
| fi | |
| if [ -f "$WORK_DIR/backups/docker-compose.yaml" ]; then | |
| cp "$WORK_DIR/backups/docker-compose.yaml" . | |
| fi | |
| if [ -f "$WORK_DIR/backups/.gitignore" ]; then | |
| cp "$WORK_DIR/backups/.gitignore" . | |
| fi | |
| # GitHub workflows | |
| if [ -d "$WORK_DIR/zora-monorepo/.github" ]; then | |
| echo -e "${CYAN}Copying GitHub workflows...${NC}" | |
| cp -R "$WORK_DIR/zora-monorepo/.github" . | |
| fi | |
| # Husky hooks | |
| if [ -d "$WORK_DIR/zora-monorepo/.husky" ]; then | |
| echo -e "${CYAN}Copying husky hooks...${NC}" | |
| cp -R "$WORK_DIR/zora-monorepo/.husky" . | |
| chmod +x .husky/* 2>/dev/null || true | |
| chmod +x .husky/_/* 2>/dev/null || true | |
| fi | |
| # Create logs directory | |
| mkdir -p logs | |
| # Documentation | |
| cp "$WORK_DIR/zora-monorepo/README.md" . 2>/dev/null || echo "No README.md" | |
| cp "$WORK_DIR/zora-monorepo/SETUP.md" . 2>/dev/null || echo "No SETUP.md" | |
| echo -e "${GREEN}✓ Configuration copied${NC}\n" | |
| fi | |
| # Patch frontend package.json to disable husky install (husky is at monorepo root) | |
| if [ -f "frontend/package.json" ]; then | |
| echo -e "${CYAN}Patching frontend/package.json to disable husky install...${NC}" | |
| sed -i '' 's/"prepare": "husky install"/"prepare": "true"/' frontend/package.json | |
| echo -e "${GREEN}✓ Frontend package.json patched${NC}\n" | |
| fi | |
| # Apply frontend patches from backup (GitHub Actions, etc.) | |
| FRONTEND_PATCHES_DIR="$WORK_DIR/backups/frontend-patches" | |
| if [ -d "$FRONTEND_PATCHES_DIR" ]; then | |
| echo -e "${CYAN}Applying frontend patches from backup...${NC}" | |
| # Copy GitHub Actions install action (monorepo-aware paths) | |
| if [ -f "$FRONTEND_PATCHES_DIR/.github/actions/install/action.yml" ]; then | |
| mkdir -p frontend/.github/actions/install | |
| cp "$FRONTEND_PATCHES_DIR/.github/actions/install/action.yml" frontend/.github/actions/install/action.yml | |
| echo -e "${GREEN} ✓ Install action patched${NC}" | |
| fi | |
| echo -e "${GREEN}✓ Frontend patches applied${NC}\n" | |
| fi | |
| # Commit configuration | |
| git add -A | |
| git commit -m "chore: add monorepo configuration and tooling" || echo "Nothing to commit" | |
| echo -e "${GREEN}✓ Monorepo configured${NC}\n" | |
| } | |
| ############################################################################# | |
| # Finalize | |
| ############################################################################# | |
| finalize() { | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}" | |
| echo -e "${BLUE} Step 5: Finalize${NC}" | |
| echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}\n" | |
| # Backup old monorepo | |
| if [ -d "$WORK_DIR/zora-monorepo" ]; then | |
| echo -e "${CYAN}Backing up old monorepo...${NC}" | |
| mv "$WORK_DIR/zora-monorepo" "$OLD_MONOREPO_BACKUP" | |
| echo -e "${GREEN}✓ Old monorepo backed up to: ${OLD_MONOREPO_BACKUP}${NC}\n" | |
| fi | |
| # Move new monorepo into place | |
| echo -e "${CYAN}Moving new monorepo into place...${NC}" | |
| mv "$REBUILD_DIR" "$WORK_DIR/zora-monorepo" | |
| cd "$WORK_DIR/zora-monorepo" | |
| echo -e "${GREEN}✓ New monorepo ready at: $WORK_DIR/zora-monorepo${NC}\n" | |
| # Show summary | |
| BACKEND_COMMITS=$(git log --oneline backend/ | wc -l | tr -d ' ') | |
| FRONTEND_COMMITS=$(git log --oneline frontend/ | wc -l | tr -d ' ') | |
| TOTAL_COMMITS=$(git rev-list --count HEAD) | |
| echo -e "${GREEN}═══════════════════════════════════════════════════════════${NC}" | |
| echo -e "${GREEN} Rebuild Complete! 🎉${NC}" | |
| echo -e "${GREEN} Phase 1: Backend + Frontend${NC}" | |
| echo -e "${GREEN}═══════════════════════════════════════════════════════════${NC}\n" | |
| echo -e "${BOLD}Commit Summary:${NC}" | |
| echo -e " Backend: ${CYAN}${BACKEND_COMMITS}${NC} commits" | |
| echo -e " Frontend: ${CYAN}${FRONTEND_COMMITS}${NC} commits" | |
| echo -e " ${BOLD}Total: ${CYAN}${TOTAL_COMMITS}${NC} commits${NC}\n" | |
| echo -e "${YELLOW}Note: Protocol excluded from Phase 1${NC}\n" | |
| echo -e "${BOLD}Old monorepo backed up to:${NC}" | |
| echo -e " ${YELLOW}${OLD_MONOREPO_BACKUP}${NC}\n" | |
| echo -e "${BOLD}Next steps:${NC}" | |
| echo -e " 1. cd zora-monorepo" | |
| echo -e " 2. rye run setup" | |
| echo -e " 3. rye run start" | |
| echo -e " 4. Test PR migration: ./scripts/migrate-pr.sh\n" | |
| echo -e "${YELLOW}Note: If you need to restore the old monorepo:${NC}" | |
| echo -e " rm -rf zora-monorepo" | |
| echo -e " mv ${OLD_MONOREPO_BACKUP} zora-monorepo\n" | |
| # Optional: Push to remote | |
| echo -e "${YELLOW}⚠️ The rebuilt monorepo has a new git history${NC}" | |
| read -p "Push to remote with --force? (Y/n): " push_confirm | |
| if [[ ! "$push_confirm" =~ ^[Nn]$ ]]; then | |
| echo -e "\n${CYAN}Pushing to origin/main...${NC}" | |
| if git push origin main --force; then | |
| echo -e "${GREEN}✓ Successfully pushed to remote${NC}\n" | |
| else | |
| echo -e "${RED}✗ Push failed${NC}" | |
| echo -e "${YELLOW}You can manually push later with: git push origin main --force${NC}\n" | |
| fi | |
| else | |
| echo -e "${YELLOW}Skipped push. You can push later with:${NC}" | |
| echo -e " cd zora-monorepo && git push origin main --force\n" | |
| fi | |
| } | |
| ############################################################################# | |
| # Main | |
| ############################################################################# | |
| main() { | |
| echo -e "${YELLOW}This script will (Phase 1: Backend + Frontend only):${NC}" | |
| echo -e " 1. Clone/update backend and frontend repos from GitHub" | |
| echo -e " 2. Rewrite each repo into subdirectories" | |
| echo -e " 3. Create fresh monorepo with latest commits" | |
| echo -e " 4. Copy configuration from existing monorepo" | |
| echo -e " 5. Backup old monorepo and replace with new one\n" | |
| echo -e "${YELLOW}Note: Protocol is excluded from Phase 1${NC}\n" | |
| echo -e "${YELLOW}Working directory: ${WORK_DIR}${NC}" | |
| echo -e "${YELLOW}Temp build location: ${REBUILD_DIR}${NC}" | |
| echo -e "${YELLOW}Final monorepo location: ${WORK_DIR}/zora-monorepo${NC}" | |
| if [ -d "$WORK_DIR/zora-monorepo" ]; then | |
| echo -e "${YELLOW}Old monorepo backup: ${OLD_MONOREPO_BACKUP}${NC}" | |
| fi | |
| echo "" | |
| read -p "Continue? (Y/n): " confirm | |
| if [[ "$confirm" =~ ^[Nn]$ ]]; then | |
| echo -e "${YELLOW}Rebuild cancelled${NC}" | |
| exit 0 | |
| fi | |
| echo "" | |
| check_dependencies | |
| clone_and_update_repos | |
| rewrite_repos | |
| create_monorepo | |
| setup_monorepo | |
| finalize | |
| } | |
| main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment