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
This commit is contained in:
saravanakumardb1 2026-02-12 19:54:29 -08:00
parent 85e0689021
commit ae2e757fb2
5 changed files with 514 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 |

92
scripts/backup-main.sh Executable file
View File

@ -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}"