From 708adecc169edb003575fe8f9bcbe538078928bd Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 16 Feb 2026 19:44:25 +0000 Subject: [PATCH] docs: Add repository mirroring guide and GitHub Actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Complete mirroring guide (GitHub ↔ Gitea) - GitHub Actions workflow to sync to Gitea - Mirror status check workflow - SSH and token authentication methods - Troubleshooting guide --- .github/workflows/mirror-check.yml | 35 +++ .github/workflows/sync-to-gitea.yml | 27 ++ MIRRORING-GUIDE.md | 467 ++++++++++++++++++++++++++++ 3 files changed, 529 insertions(+) create mode 100644 .github/workflows/mirror-check.yml create mode 100644 .github/workflows/sync-to-gitea.yml create mode 100644 MIRRORING-GUIDE.md diff --git a/.github/workflows/mirror-check.yml b/.github/workflows/mirror-check.yml new file mode 100644 index 0000000..75340d7 --- /dev/null +++ b/.github/workflows/mirror-check.yml @@ -0,0 +1,35 @@ +name: Mirror Status Check + +on: + schedule: + - cron: '0 */6 * * *' # Every 6 hours + workflow_dispatch: + +jobs: + check-sync: + runs-on: ubuntu-latest + steps: + - name: Check if repositories are in sync + run: | + # Get latest commit from GitHub + GITHUB_SHA=$(curl -s \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/terraphim/gitea-infrastructure/commits/main" | \ + jq -r '.sha') + + # Get latest commit from Gitea + GITEA_SHA=$(curl -s \ + -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ + "https://git.terraphim.cloud/api/v1/repos/terraphim/gitea-infrastructure/commits/main" | \ + jq -r '.sha') + + echo "GitHub: ${GITHUB_SHA:0:7}" + echo "Gitea: ${GITEA_SHA:0:7}" + + if [ "$GITHUB_SHA" == "$GITEA_SHA" ]; then + echo "✅ Repositories are in sync" + exit 0 + else + echo "⚠️ Repositories are OUT OF SYNC" + exit 1 + fi diff --git a/.github/workflows/sync-to-gitea.yml b/.github/workflows/sync-to-gitea.yml new file mode 100644 index 0000000..f4b08f4 --- /dev/null +++ b/.github/workflows/sync-to-gitea.yml @@ -0,0 +1,27 @@ +name: Sync to Gitea + +on: + push: + branches: [main, master] + workflow_dispatch: # Allow manual trigger + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Full history + + - name: Push to Gitea + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + git remote add gitea https://git.terraphim.cloud/terraphim/gitea-infrastructure.git + git config user.name "GitHub Actions" + git config user.email "actions@github.com" + + # Push to Gitea with token authentication + # If using HTTPS with token: https://token@url + git push https://oauth2:${GITEA_TOKEN}@git.terraphim.cloud/terraphim/gitea-infrastructure.git main diff --git a/MIRRORING-GUIDE.md b/MIRRORING-GUIDE.md new file mode 100644 index 0000000..9066ff1 --- /dev/null +++ b/MIRRORING-GUIDE.md @@ -0,0 +1,467 @@ +# Repository Mirroring: GitHub ↔ Gitea + +Complete guide for setting up mirroring between GitHub and self-hosted Gitea. + +## Overview + +**Mirroring** keeps two repositories in sync automatically. Choose your direction: + +| Direction | Use Case | +|-----------|----------| +| **GitHub → Gitea** | GitHub as primary, Gitea as backup/mirror | +| **Gitea → GitHub** | Gitea as primary, GitHub for visibility/CI | +| **Bidirectional** | Both accept commits (advanced) | + +--- + +## Method 1: Gitea as Mirror (GitHub → Gitea) + +Gitea periodically pulls from GitHub. Best for backup scenarios. + +### Step 1: Create Mirror in Gitea + +**Via Web Interface:** + +1. Go to https://git.terraphim.cloud +2. Click **"+"** → **"New Migration"** +3. Select **"GitHub"** +4. Enter URL: `https://github.com/terraphim/gitea-infrastructure` +5. **Authentication:** + - If private repo: Enter GitHub Personal Access Token + - If public: Leave empty +6. Check **"This repository will be a mirror"** +7. Click **"Migrate Repository"** + +**Via Gitea API:** + +```bash +# Get Gitea API token (Settings → Applications → Generate Token) +GITEA_TOKEN="your_gitea_api_token" + +# Create mirror +curl -X POST \ + "https://git.terraphim.cloud/api/v1/repos/migrate" \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{ + "clone_addr": "https://github.com/terraphim/gitea-infrastructure", + "repo_name": "gitea-infrastructure-mirror", + "repo_owner": "terraphim", + "mirror": true, + "auth_token": "your_github_token_if_private" + }' +``` + +### Step 2: Configure Mirror Settings + +1. Go to repository **Settings** → **Repository** +2. Scroll to **Mirror Settings** +3. Set **Synchronization Interval**: `8h` (or your preference) +4. Click **"Update Mirror"** + +### Step 3: Manual Sync (Optional) + +```bash +# Trigger immediate sync +curl -X POST \ + "https://git.terraphim.cloud/api/v1/repos/terraphim/gitea-infrastructure-mirror/mirror-sync" \ + -H "Authorization: token ${GITEA_TOKEN}" +``` + +--- + +## Method 2: GitHub as Mirror (Gitea → GitHub) + +Push from Gitea to GitHub. Best when Gitea is your primary. + +### Step 1: Add GitHub Remote to Local Repository + +```bash +cd /home/alex/infrastructure/gitea_config + +# Add GitHub as mirror remote +git remote add github https://github.com/terraphim/gitea-infrastructure.git + +# Or use SSH (recommended for automation) +git remote add github git@github.com:terraphim/gitea-infrastructure.git +``` + +### Step 2: Configure Push Mirroring in Gitea + +**Option A: Gitea Push Mirror (Native)** + +1. In Gitea, go to repository **Settings** → **Repository** +2. Scroll to **Mirror Settings** +3. Check **"Push Mirror"** +4. Set **Git Remote URL**: `https://github.com/terraphim/gitea-infrastructure.git` +5. Add authentication: + - **Username**: Your GitHub username + - **Password/Token**: GitHub Personal Access Token +6. Set **Interval**: `8h` +7. Click **"Add Push Mirror"** + +**Option B: Using Git Hooks (More Control)** + +Create a post-receive hook in Gitea: + +1. Go to repository **Settings** → **Git Hooks** +2. Find **post-receive** hook +3. Edit and add: + +```bash +#!/bin/bash +# Push to GitHub after receiving commits + +# Use deploy key or HTTPS with token +export GIT_SSH_COMMAND='ssh -i /path/to/deploy_key -o StrictHostKeyChecking=no' + +git push github main --mirror + +echo "Mirrored to GitHub" +``` + +### Step 3: Test Push Mirroring + +```bash +# Make a test commit +echo "# Test" >> README.md +git add README.md +git commit -m "test: Mirror sync" + +# Push to Gitea +git push origin main + +# Check GitHub (should appear within seconds) +``` + +--- + +## Method 3: Bidirectional Mirroring + +Both repositories accept commits. **Warning:** Can cause conflicts! + +### Architecture + +``` +Developer A → Gitea ←→ GitHub ← Developer B + ↑___________↓ + Bidirectional sync +``` + +### Setup + +1. **Set up both mirrors:** + - GitHub → Gitea (Method 1) + - Gitea → GitHub (Method 2) + +2. **Conflict Resolution Strategy:** + - Always use `git merge` instead of `git push --force` + - Set up webhook for immediate sync + - Have clear contribution guidelines + +3. **Webhook-based Immediate Sync:** + + **In Gitea:** + - Settings → Webhooks → Add Webhook → Gitea + - Target URL: Your sync service + - Events: Push + + **GitHub → Gitea sync service:** + ```python + # sync-service.py (simplified) + from flask import Flask, request + import subprocess + + app = Flask(__name__) + + @app.route('/github-webhook', methods=['POST']) + def github_hook(): + # Trigger Gitea pull + subprocess.run(['curl', '-X', 'POST', + 'https://git.terraphim.cloud/api/v1/repos/terraphim/repo/mirror-sync']) + return 'OK' + + @app.route('/gitea-webhook', methods=['POST']) + def gitea_hook(): + # Trigger GitHub push + subprocess.run(['git', 'push', 'github', 'main']) + return 'OK' + ``` + +--- + +## Method 4: Local Git Configuration (Simplest) + +Push to both remotes simultaneously from your local machine. + +### Setup + +```bash +cd /home/alex/infrastructure/gitea_config + +# Check current remotes +git remote -v +# origin: should be Gitea + +# Add GitHub as additional remote +git remote add github https://github.com/terraphim/gitea-infrastructure.git + +# Or use SSH: +git remote add github git@github.com:terraphim/gitea-infrastructure.git +``` + +### Push to Both + +```bash +# Push to Gitea (origin) +git push origin main + +# Push to GitHub +git push github main +``` + +### Automate with Git Alias + +Add to `~/.gitconfig`: + +```ini +[alias] + pushall = !git push origin $(git branch --show-current) && git push github $(git branch --show-current) + pa = pushall +``` + +Usage: +```bash +git pa # Pushes to both remotes +``` + +### Automate with Bash Function + +Add to `~/.bashrc` or `~/.zshrc`: + +```bash +git-push-all() { + local current_branch=$(git branch --show-current) + echo "Pushing to all remotes..." + git push origin "$current_branch" + git push github "$current_branch" + echo "✅ Pushed to Gitea and GitHub" +} + +alias gpa='git-push-all' +``` + +--- + +## Authentication Setup + +### GitHub Personal Access Token + +1. Go to GitHub → Settings → Developer settings → Personal access tokens +2. Generate new token (classic) +3. Scopes needed: + - `repo` (full control of private repositories) + - `workflow` (if using GitHub Actions) +4. Copy token + +### Use Token in Gitea + +When setting up push mirror: +- **Username**: Your GitHub username +- **Password**: Your Personal Access Token (not your password!) + +### SSH Key Setup (Recommended) + +**For automated pushes:** + +1. Generate deploy key: +```bash +ssh-keygen -t ed25519 -f ~/.ssh/gitea_github_deploy -C "gitea-mirror" +``` + +2. Add public key to GitHub: + - Repository Settings → Deploy Keys → Add deploy key + - Paste contents of `~/.ssh/gitea_github_deploy.pub` + - Allow write access + +3. Add private key to Gitea server: +```bash +# Copy to Gitea server +scp ~/.ssh/gitea_github_deploy bigbox:~/.ssh/ +ssh bigbox "chmod 600 ~/.ssh/gitea_github_deploy" +``` + +4. Configure SSH for GitHub in Gitea: +```bash +# Create SSH config +ssh bigbox "cat > ~/.ssh/config << 'EOF' +Host github-mirror + HostName github.com + User git + IdentityFile ~/.ssh/gitea_github_deploy + StrictHostKeyChecking no +EOF" +``` + +5. Update remote to use SSH: +```bash +ssh bigbox "cd ~/gitea-stack && git remote set-url github git@github-mirror:terraphim/gitea-infrastructure.git" +``` + +--- + +## Verification and Monitoring + +### Check Mirror Status + +**In Gitea:** +- Repository → Settings → Repository → Mirror Settings +- Shows last sync time and status + +**Via API:** +```bash +# Check mirror status +curl -s \ + "https://git.terraphim.cloud/api/v1/repos/terraphim/gitea-infrastructure-mirror" \ + -H "Authorization: token ${GITEA_TOKEN}" | \ + jq '.mirror_updated, .mirror_interval' +``` + +### Monitoring Script + +Create `check-mirror.sh`: + +```bash +#!/bin/bash +# Check if mirrors are in sync + +echo "Checking repository sync status..." + +# Get latest commit from GitHub +GITHUB_SHA=$(curl -s \ + "https://api.github.com/repos/terraphim/gitea-infrastructure/commits/main" | \ + jq -r '.sha') + +# Get latest commit from Gitea +GITEA_SHA=$(curl -s \ + "https://git.terraphim.cloud/api/v1/repos/terraphim/gitea-infrastructure/commits/main" | \ + jq -r '.sha') + +if [ "$GITHUB_SHA" == "$GITEA_SHA" ]; then + echo "✅ Repositories are in sync" + echo "Latest commit: ${GITHUB_SHA:0:7}" +else + echo "⚠️ Repositories are OUT OF SYNC" + echo "GitHub: ${GITHUB_SHA:0:7}" + echo "Gitea: ${GITEA_SHA:0:7}" +fi +``` + +--- + +## Troubleshooting + +### Mirror Not Syncing + +**Check Gitea logs:** +```bash +ssh bigbox "docker logs gitea | grep -i mirror" +``` + +**Test manually:** +```bash +ssh bigbox +cd ~/gitea-stack +git fetch github +git log HEAD..github/main # Check if behind +``` + +### Authentication Failures + +**GitHub token expired:** +- Generate new token in GitHub +- Update in Gitea mirror settings + +**SSH key issues:** +```bash +ssh bigbox "ssh -T github-mirror" +# Should show: Hi terraphim/gitea-infrastructure! You've successfully authenticated +``` + +### Conflict Resolution + +If repositories diverge: + +```bash +# On local machine +git fetch origin # Gitea +git fetch github # GitHub + +# Check differences +git log --left-right --graph --cherry-pick --oneline origin/main...github/main + +# Merge changes +git checkout main +git merge origin/main +git merge github/main + +# Push to both +git push origin main +git push github main +``` + +--- + +## Best Practices + +### 1. One-Way vs Two-Way +- **Use one-way** for most cases (clear primary/secondary) +- **Use two-way** only for specific workflows with clear contribution guidelines + +### 2. Sync Frequency +- **Backup mirrors**: 24h interval +- **Active development**: 1h interval or webhook-triggered +- **CI/CD**: Immediate webhook sync + +### 3. Notifications +Set up alerts for sync failures: +- Gitea webhook on sync failure +- GitHub Actions monitoring +- Email notifications + +### 4. Documentation +Document your mirroring strategy: +- Which repository is primary? +- Where should PRs be opened? +- How to handle conflicts? + +--- + +## Quick Reference + +| Task | Command | +|------|---------| +| Check remotes | `git remote -v` | +| Add GitHub remote | `git remote add github https://github.com/terraphim/gitea-infrastructure.git` | +| Push to all | `git push origin main && git push github main` | +| Force sync | `curl -X POST "https://git.terraphim.cloud/api/v1/repos/terraphim/repo/mirror-sync"` | +| Check status | `git log origin/main..github/main` | + +--- + +## Recommended Setup for Your Use Case + +**Primary: Gitea (self-hosted, private)** +**Mirror: GitHub (backup, CI/CD)** + +1. Use **Method 2 (Push Mirror)** from Gitea to GitHub +2. Set sync interval: 1 hour +3. Use SSH authentication with deploy key +4. Enable GitHub Actions for CI/CD on GitHub side +5. Keep Gitea as single source of truth for commits + +This gives you: +- ✅ Full control on Gitea +- ✅ GitHub as backup +- ✅ Can use GitHub Actions for CI/CD +- ✅ Simple one-way sync (less conflicts)