From ae2e757fb2207fee08c2d6c9ec3bd518e87b3fdf Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Thu, 12 Feb 2026 19:54:29 -0800 Subject: [PATCH] feat: add backup main branch workflow with smart duplicate detection - Create Backup Main Branch skill with comprehensive documentation - Add Windsurf workflow for easy access - Implement bash script with multi-repo support - Smart detection to avoid duplicate backups - Automatic cleanup of old backups (keeps 7 days) - Color-coded output for better visibility - Always returns to main branch after backup --- .windsurf/workflows/backup-main-branch.md | 32 ++ AI.dev/SKILLS/README.md | 4 + AI.dev/SKILLS/backup-main-branch.md | 384 ++++++++++++++++++++++ AI.dev/SKILLS/index.md | 2 + scripts/backup-main.sh | 92 ++++++ 5 files changed, 514 insertions(+) create mode 100644 .windsurf/workflows/backup-main-branch.md create mode 100644 AI.dev/SKILLS/backup-main-branch.md create mode 100755 scripts/backup-main.sh diff --git a/.windsurf/workflows/backup-main-branch.md b/.windsurf/workflows/backup-main-branch.md new file mode 100644 index 00000000..e0a51552 --- /dev/null +++ b/.windsurf/workflows/backup-main-branch.md @@ -0,0 +1,32 @@ +--- +description: Smart backup of main branches with duplicate detection +--- + +# Backup Main Branch + +Creates smart backups of main branches across all repositories. + +// turbo +Run `bash scripts/backup-main.sh` from any repository root + +## What it does: + +1. Checks each repository for changes +2. Skips backup if main hasn't changed since last backup +3. Creates timestamped backup branch +4. Cleans up old backups (keeps 7 days) +5. Returns to main branch + +## Repositories covered: + +- learning_ai_common_plat +- learning_voice_ai_agent +- learning_multimodal_memory_agents + +## Features: + +- ✅ Smart duplicate detection +- ✅ Automatic cleanup of old backups +- ✅ Multi-repo support +- ✅ Safe operations (always returns to main) +- ✅ Color-coded output for clarity diff --git a/AI.dev/SKILLS/README.md b/AI.dev/SKILLS/README.md index 087a41b8..c1c0fde5 100644 --- a/AI.dev/SKILLS/README.md +++ b/AI.dev/SKILLS/README.md @@ -71,7 +71,10 @@ Each skill follows a consistent format: | Fix a failing service | [Debug Service](./debug-service.md) | 🔧 Development Workflows | | Prepare for release | [Production Readiness](./production-readiness.md) | 🧪 Testing & Quality | | Start all services locally | [Local Development Setup](./local-development.md) | 🔧 Development Workflows | +| Backup main branch | [Backup Main Branch](./backup-main-branch.md) | 🔧 Development Workflows | | Release desktop app | [Desktop Release](./desktop-release.md) | 🚀 Release & Deployment | +| Release iOS app | [iOS Release](./ios-release.md) | 🚀 Release & Deployment | +| Generate store assets | [Generate Store Assets](./generate-store-assets.md) | 🚀 Release & Deployment | | Ensure mobile code quality | [Mobile Code Quality](./mobile-code-quality.md) | 📱 Mobile Development | | Update AI docs | [Update Agent Documentation](./update-agent-docs.md) | 📚 Documentation & Communication | | Write tests | [Test Strategies](./test-strategies.md) | 🧪 Testing & Quality | @@ -87,6 +90,7 @@ Each skill follows a consistent format: - [Production Readiness](./production-readiness.md) - Complete pre-release validation - [Local Development Setup](./local-development.md) - Run all services locally - [Docker Compose](./docker-compose.md) - Containerized full stack +- [Backup Main Branch](./backup-main-branch.md) - Smart backup with duplicate detection - [Mobile Code Quality](./mobile-code-quality.md) - Cross-platform mobile standards - [Desktop Release](./desktop-release.md) - Build and package desktop apps - [iOS Release](./ios-release.md) - TestFlight and App Store deployment diff --git a/AI.dev/SKILLS/backup-main-branch.md b/AI.dev/SKILLS/backup-main-branch.md new file mode 100644 index 00000000..6d91d5cb --- /dev/null +++ b/AI.dev/SKILLS/backup-main-branch.md @@ -0,0 +1,384 @@ +# Backup Main Branch Skill + +**Description**: Smart backup of main branches across repositories with duplicate detection. + +## When to Use + +- Before making major changes to main branch +- Before risky operations (rebases, large refactors) +- Regular safety backups +- When working with critical repositories + +## Prerequisites + +- Git access to repositories +- Write permissions to backup branch +- Clean working directory + +## Quick Start + +```bash +# From any repo root +/windsurf-workflow backup-main-branch +``` + +## Workflow Steps + +### 1. Check Current State + +```bash +# Ensure we're on main branch +CURRENT_BRANCH=$(git branch --show-current) +if [ "$CURRENT_BRANCH" != "main" ]; then + echo "Switching to main branch..." + git switch main +fi + +# Check if working directory is clean +if [ -n "$(git status --porcelain)" ]; then + echo "⚠️ Working directory not clean!" + echo "Please commit or stash changes before backup" + exit 1 +fi +``` + +### 2. Check if Backup Needed + +```bash +# Get timestamp of last backup branch commit +BACKUP_BRANCH="backup/main-$(date +%Y-%m-%d)" +LATEST_BACKUP=$(git branch -r --sort=-committerdate | grep "origin/backup/main-" | head -1 | cut -d'/' -f2) + +if [ -n "$LATEST_BACKUP" ]; then + # Compare main with latest backup + MAIN_COMMIT=$(git rev-parse origin/main) + BACKUP_COMMIT=$(git rev-parse origin/$LATEST_BACKUP) + + if [ "$MAIN_COMMIT" = "$BACKUP_COMMIT" ]; then + echo "✅ Main branch already backed up in $LATEST_BACKUP" + echo "No backup needed" + exit 0 + fi +fi +``` + +### 3. Create New Backup + +```bash +# Create backup branch name with timestamp +BACKUP_BRANCH="backup/main-$(date +%Y-%m-%d-%H%M%S)" + +# Create and push backup branch +echo "Creating backup branch: $BACKUP_BRANCH" +git checkout -b $BACKUP_BRANCH +git push -u origin $BACKUP_BRANCH + +# Switch back to main +git checkout main + +echo "✅ Backup created: $BACKUP_BRANCH" +``` + +### 4. Cleanup Old Backups (Optional) + +```bash +# Keep only last 7 days of backups +echo "Cleaning up old backups..." +git fetch origin +for branch in $(git branch -r --sort=-committerdate | grep "origin/backup/main-" | tail -n +8); do + BACKUP_NAME=$(echo $branch | cut -d'/' -f2) + echo "Deleting old backup: $BACKUP_NAME" + git push origin --delete $BACKUP_NAME +done +``` + +## Full Script + +Create `scripts/backup-main.sh`: + +```bash +#!/bin/bash +# Backup main branch with smart duplicate detection + +set -e # Exit on any error + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo -e "${GREEN}🔄 Starting main branch backup...${NC}" + +# Function to backup a single repository +backup_repo() { + local repo_path=$1 + local repo_name=$(basename "$repo_path") + + echo -e "\n${YELLOW}Processing repository: $repo_name${NC}" + + cd "$repo_path" + + # Ensure we're on main + CURRENT_BRANCH=$(git branch --show-current) + if [ "$CURRENT_BRANCH" != "main" ]; then + echo "Switching to main branch..." + git switch main + fi + + # Pull latest changes + echo "Pulling latest changes..." + git pull origin main + + # Check if working directory is clean + if [ -n "$(git status --porcelain)" ]; then + echo -e "${RED}⚠️ Working directory not clean in $repo_name!${NC}" + echo "Skipping backup for this repository" + cd .. + return 1 + fi + + # Check if backup is needed + LATEST_BACKUP=$(git branch -r --sort=-committerdate 2>/dev/null | grep "origin/backup/main-" | head -1 | cut -d'/' -f2 || true) + + if [ -n "$LATEST_BACKUP" ]; then + MAIN_COMMIT=$(git rev-parse origin/main) + BACKUP_COMMIT=$(git rev-parse origin/$LATEST_BACKUP 2>/dev/null || true) + + if [ "$MAIN_COMMIT" = "$BACKUP_COMMIT" ]; then + echo -e "${GREEN}✅ $repo_name: Already backed up in $LATEST_BACKUP${NC}" + cd .. + return 0 + fi + fi + + # Create new backup + BACKUP_BRANCH="backup/main-$(date +%Y-%m-%d-%H%M%S)" + + echo "Creating backup branch: $BACKUP_BRANCH" + git checkout -b $BACKUP_BRANCH + git push -u origin $BACKUP_BRANCH + git checkout main + + echo -e "${GREEN}✅ $repo_name: Backup created successfully${NC}" + + # Cleanup old backups (keep last 7) + for branch in $(git branch -r --sort=-committerdate 2>/dev/null | grep "origin/backup/main-" | tail -n +8); do + BACKUP_NAME=$(echo $branch | cut -d'/' -f2) + echo "Deleting old backup: $BACKUP_NAME" + git push origin --delete $BACKUP_NAME 2>/dev/null || true + done + + cd .. +} + +# Backup all repositories +REPOS=( + "/Users/sd9235/code/mygh/learning_ai_common_plat" + "/Users/sd9235/code/mygh/learning_voice_ai_agent" + "/Users/sd9235/code/mygh/learning_multimodal_memory_agents" +) + +# Check which repos exist +for repo in "${REPOS[@]}"; do + if [ -d "$repo" ]; then + backup_repo "$repo" + else + echo -e "${YELLOW}Repository not found: $repo${NC}" + fi +done + +echo -e "\n${GREEN}✨ Backup process completed!${NC}" +``` + +## Windsurf Workflow + +Create `.windsurf/workflows/backup-main-branch.md`: + +```markdown +--- +description: Smart backup of main branches with duplicate detection +--- + +# Backup Main Branch + +Creates smart backups of main branches across all repositories. + +// turbo +Run `bash scripts/backup-main.sh` from any repository root + +## What it does: + +1. Checks each repository for changes +2. Skips backup if main hasn't changed since last backup +3. Creates timestamped backup branch +4. Cleans up old backups (keeps 7 days) +5. Returns to main branch + +## Repositories covered: + +- learning_ai_common_plat +- learning_voice_ai_agent +- learning_multimodal_memory_agents +``` + +## Advanced Features + +### Backup with Tags + +```bash +# Create backup with descriptive tag +BACKUP_BRANCH="backup/main-$(date +%Y-%m-%d)-before-refactor" +``` + +### Include Additional Repositories + +```bash +# Add to REPOS array in script +REPOS=( + "/Users/sd9235/code/mygh/learning_ai_common_plat" + "/Users/sd9235/code/mygh/learning_voice_ai_agent" + "/Users/sd9235/code/mygh/learning_multimodal_memory_agents" + "/path/to/your/repo" # Add new repo here +) +``` + +### Custom Retention Policy + +```bash +# Keep backups for 30 days instead of 7 +for branch in $(git branch -r --sort=-committerdate | grep "origin/backup/main-" | tail -n +31); do + # Delete old backup +done +``` + +## Restoration + +### From Backup Branch + +```bash +# List available backups +git branch -r | grep "backup/main-" + +# Switch to specific backup +git checkout -b restore-from-backup origin/backup/main-2024-01-15-143022 + +# Merge changes to main if needed +git switch main +git merge restore-from-backup +``` + +### Create Hotfix from Backup + +```bash +# Create hotfix branch from backup +git checkout -b hotfix/critical-bug origin/backup/main-2024-01-15-143022 + +# Make fixes, then merge to main +git switch main +git merge hotfix/critical-bug +git push origin main +``` + +## Automation + +### Cron Job for Daily Backups + +```bash +# Add to crontab (crontab -e) +0 18 * * * cd /Users/sd9235/code/mygh/learning_ai_common_plat && bash scripts/backup-main.sh +``` + +### GitHub Actions + +```yaml +name: Daily Backup + +on: + schedule: + - cron: '0 18 * * *' # Daily at 6 PM + workflow_dispatch: + +jobs: + backup: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.PAT }} # Personal Access Token with push permissions + + - name: Configure Git + run: | + git config --global user.name "Backup Bot" + git config --global user.email "backup@example.com" + + - name: Run Backup Script + run: bash scripts/backup-main.sh +``` + +## Best Practices + +### When to Backup + +- Before major refactors +- Before risky operations (rebase, force push) +- Before releases +- On a regular schedule (daily/weekly) + +### Backup Naming + +- Use descriptive names for important backups +- Include date and time in all backups +- Consider adding purpose (e.g., "-before-v2.0") + +### Security + +- Use secure Personal Access Tokens +- Limit backup branch permissions +- Regularly review and clean old backups + +## Troubleshooting + +### Permission Denied + +```bash +# Ensure PAT has correct permissions +# Settings → Developer settings → Personal access tokens → repo (full control) +``` + +### Branch Already Exists + +```bash +# Delete local branch if exists +git branch -D backup/main-YYYY-MM-DD-HHMMSS + +# Or use different timestamp +BACKUP_BRANCH="backup/main-$(date +%Y-%m-%d-%H%M%S)-$(uuidgen | head -c 8)" +``` + +### Network Issues + +```bash +# Retry failed pushes +git push -u origin $BACKUP_BRANCH + +# Or use retry loop +for i in {1..3}; do + git push -u origin $BACKUP_BRANCH && break + sleep 5 +done +``` + +## Notes + +- **Smart detection** prevents unnecessary backups +- **Automatic cleanup** keeps repository tidy +- **Multi-repo support** backs up all related projects +- **Safe operations** always returns to main branch +- **No data loss** only creates branches, never deletes main + +## Related Skills + +- [Git Workflow](./git-workflow.md) - General Git operations +- [Production Readiness](./production-readiness.md) - Backup before releases +- [Debug Service](./debug-service.md) - Backup before major changes diff --git a/AI.dev/SKILLS/index.md b/AI.dev/SKILLS/index.md index d6452b8e..d1f8de54 100644 --- a/AI.dev/SKILLS/index.md +++ b/AI.dev/SKILLS/index.md @@ -11,6 +11,7 @@ - [Local Development Setup](./local-development.md) - Starting services locally - [Docker Compose](./docker-compose.md) - Full stack containerization - [Production Readiness](./production-readiness.md) - Pre-release validation +- [Backup Main Branch](./backup-main-branch.md) - Smart backup with duplicate detection ## 📱 Mobile Development @@ -51,6 +52,7 @@ | Fix a failing service | [Debug Service](./debug-service.md) | 🔧 Development Workflows | | Prepare for release | [Production Readiness](./production-readiness.md) | 🧪 Testing & Quality | | Start all services | [Local Development Setup](./local-development.md) | 🔧 Development Workflows | +| Backup main branch | [Backup Main Branch](./backup-main-branch.md) | 🔧 Development Workflows | | Release desktop app | [Desktop Release](./desktop-release.md) | 🚀 Release & Deployment | | Release iOS app | [iOS Release](./ios-release.md) | 🚀 Release & Deployment | | Generate store assets | [Generate Store Assets](./generate-store-assets.md) | 🚀 Release & Deployment | diff --git a/scripts/backup-main.sh b/scripts/backup-main.sh new file mode 100755 index 00000000..39057554 --- /dev/null +++ b/scripts/backup-main.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# Backup main branch with smart duplicate detection + +set -e # Exit on any error + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo -e "${GREEN}🔄 Starting main branch backup...${NC}" + +# Function to backup a single repository +backup_repo() { + local repo_path=$1 + local repo_name=$(basename "$repo_path") + + echo -e "\n${YELLOW}Processing repository: $repo_name${NC}" + + cd "$repo_path" + + # Ensure we're on main + CURRENT_BRANCH=$(git branch --show-current) + if [ "$CURRENT_BRANCH" != "main" ]; then + echo "Switching to main branch..." + git switch main + fi + + # Pull latest changes + echo "Pulling latest changes..." + git pull origin main + + # Check if working directory is clean + if [ -n "$(git status --porcelain)" ]; then + echo -e "${RED}⚠️ Working directory not clean in $repo_name!${NC}" + echo "Skipping backup for this repository" + cd .. + return 1 + fi + + # Check if backup is needed + LATEST_BACKUP=$(git branch -r --sort=-committerdate 2>/dev/null | grep "origin/backup/main-" | head -1 | cut -d'/' -f2 || true) + + if [ -n "$LATEST_BACKUP" ]; then + MAIN_COMMIT=$(git rev-parse origin/main) + BACKUP_COMMIT=$(git rev-parse origin/$LATEST_BACKUP 2>/dev/null || true) + + if [ "$MAIN_COMMIT" = "$BACKUP_COMMIT" ]; then + echo -e "${GREEN}✅ $repo_name: Already backed up in $LATEST_BACKUP${NC}" + cd .. + return 0 + fi + fi + + # Create new backup + BACKUP_BRANCH="backup/main-$(date +%Y-%m-%d-%H%M%S)" + + echo "Creating backup branch: $BACKUP_BRANCH" + git checkout -b $BACKUP_BRANCH + git push -u origin $BACKUP_BRANCH + git checkout main + + echo -e "${GREEN}✅ $repo_name: Backup created successfully${NC}" + + # Cleanup old backups (keep last 7) + for branch in $(git branch -r --sort=-committerdate 2>/dev/null | grep "origin/backup/main-" | tail -n +8); do + BACKUP_NAME=$(echo $branch | cut -d'/' -f2) + echo "Deleting old backup: $BACKUP_NAME" + git push origin --delete $BACKUP_NAME 2>/dev/null || true + done + + cd .. +} + +# Backup all repositories +REPOS=( + "/Users/sd9235/code/mygh/learning_ai_common_plat" + "/Users/sd9235/code/mygh/learning_voice_ai_agent" + "/Users/sd9235/code/mygh/learning_multimodal_memory_agents" +) + +# Check which repos exist +for repo in "${REPOS[@]}"; do + if [ -d "$repo" ]; then + backup_repo "$repo" + else + echo -e "${YELLOW}Repository not found: $repo${NC}" + fi +done + +echo -e "\n${GREEN}✨ Backup process completed!${NC}"