Skip to content

Repository Migration Guide: syrf-test → camaradesuk/syrf

Overview

This guide provides step-by-step instructions for migrating the SyRF monorepo from camaradesuk/syrf-test to camaradesuk/syrf while preserving all GitHub metadata (issues, discussions, PRs, settings) from the existing camaradesuk/syrf-web repository.

Migration Strategy

Key Insight: The original syrf-web repository contains valuable GitHub metadata (470+ issues, 47 PRs, discussions, ZenHub configuration). Rather than starting fresh, we:

  1. Backup the original syrf-web repository completely
  2. Force push the monorepo code to syrf-web (preserves GitHub metadata)
  3. Rename syrf-web to syrf (GitHub handles redirects)

Result: All history, metadata, and ZenHub configuration preserved in one repository.


Prerequisites

  • Admin access to camaradesuk GitHub organization
  • GitHub CLI (gh) installed and authenticated
  • Local clone of syrf-test repository at /home/chris/workspace/syrf
  • Clean working directory (no uncommitted changes)

Pre-Migration Actions

1. Review Open Pull Requests

Recent PRs requiring decision (as of 2025-11-13):

PR # Title Created Decision
#2126 implement comments in quantitative data export 2025-11-06 ☐ Merge / ☐ Keep / ☐ Close
#2114 implement disable membership feature 2025-11-03 ☐ Merge / ☐ Keep / ☐ Close
#2059 feat: Implement project member disable feature 2025-10-07 ☐ Merge / ☐ Keep / ☐ Close

Action:

# View PR details
gh pr view 2126 --repo camaradesuk/syrf-web
gh pr view 2114 --repo camaradesuk/syrf-web
gh pr view 2059 --repo camaradesuk/syrf-web

# Option 1: Merge before migration
gh pr merge 2126 --repo camaradesuk/syrf-web --squash

# Option 2: Close with explanation
gh pr close 2126 --repo camaradesuk/syrf-web --comment "Closing due to monorepo migration. Will recreate if needed."

44 older PRs (2021-2024):

# List all open PRs
gh pr list --repo camaradesuk/syrf-web --state open --limit 100

# Bulk close stale PRs (requires manual review)
# Create GitHub issue first to document closure reason

2. Verify Local Repository State

cd /home/chris/workspace/syrf

# Verify clean working directory
git status

# Should show: "nothing to commit, working tree clean"

# Verify all local branches are pushed
git branch -a

# Push any unpushed changes
git push --all origin

Migration Execution

Phase 1: Create Backup Repository (15 minutes)

Why: Safety net in case migration needs to be reversed.

Step 1: Create backup repository

# Create empty repository
gh repo create camaradesuk/syrf-web-legacy \
  --public \
  --description "Backup of syrf-web before monorepo migration (2025-11-13)" \
  --disable-wiki \
  --disable-issues

# Expected output: ✓ Created repository camaradesuk/syrf-web-legacy on GitHub

Step 2: Mirror syrf-web to backup

# Create temporary mirror clone
cd /tmp
git clone --mirror https://github.com/camaradesuk/syrf-web.git syrf-web-mirror
cd syrf-web-mirror

# Add backup as remote
git remote add backup https://github.com/camaradesuk/syrf-web-legacy.git

# Push everything (branches, tags, refs)
git push --mirror backup

# Expected: Pushing 93 branches, 670+ tags

Step 3: Verify backup

# Check backup repository
gh repo view camaradesuk/syrf-web-legacy

# Verify branch count
gh api repos/camaradesuk/syrf-web-legacy/branches --paginate | jq '. | length'
# Expected: 93

# Verify tag count
gh api repos/camaradesuk/syrf-web-legacy/tags --paginate | jq '. | length'
# Expected: 670+

# Cleanup
cd /tmp
rm -rf syrf-web-mirror

Success Criteria:

  • ✅ Backup repository created
  • ✅ All branches present in backup
  • ✅ All tags present in backup

Phase 2: Force Push Monorepo (15 minutes)

What happens: Replaces syrf-web code with monorepo code while preserving GitHub metadata.

Step 1: Add syrf-web as remote

cd /home/chris/workspace/syrf

# Add syrf-web as remote
git remote add syrf-web https://github.com/camaradesuk/syrf-web.git

# Fetch current state
git fetch syrf-web

# View remote branches
git branch -r | grep syrf-web

Step 2: Force push all branches

# Push all local branches to syrf-web
git push syrf-web --all --force

# Expected output:
# + 0368a2f...531b2cba main -> main (forced update)
# * [new branch]      backup-before-web-remerge -> backup-before-web-remerge
# * [new branch]      migration -> migration

Step 3: Push all tags

# Push all tags (no conflicts with syrf-web tags)
git push syrf-web --tags --force

# Expected output:
# * [new tag]         api-v8.20.1 -> api-v8.20.1
# * [new tag]         api-v9.0.0 -> api-v9.0.0
# * [new tag]         pm-v10.44.1 -> pm-v10.44.1
# * [new tag]         web-v4.1.5 -> web-v4.1.5
# * [new tag]         web-v5.0.0 -> web-v5.0.0
# ... (and many more)

Step 4: Verify push

# Verify main branch updated
gh api repos/camaradesuk/syrf-web/branches/main | jq '.commit.sha[0:7]'
# Expected: 531b2cb (latest monorepo commit)

# Verify tags present
git ls-remote --tags syrf-web | grep "api-v\|pm-v\|web-v\|quartz-v\|docs-v"

# Verify original syrf-web branches still exist
gh api repos/camaradesuk/syrf-web/branches --paginate | jq '.[].name' | grep -E "feat/|fix/"
# Expected: All 93 original branches still present

Success Criteria:

  • main branch shows monorepo code
  • ✅ Monorepo branches added (backup-before-web-remerge, migration)
  • ✅ All monorepo tags present (api-v*, pm-v*, web-v*, etc.)
  • ✅ Original syrf-web branches preserved
  • ✅ Original syrf-web tags preserved (v3., v4., etc.)

What about open PRs?

  • PRs remain open but may need rebasing (file paths changed due to git mv)
  • Example: PR changing /src/app/component.ts now needs to target src/services/web/src/app/component.ts
  • Review PRs case-by-case after migration

Phase 3: Rename Repository (5 minutes)

Rename syrf-web to syrf via GitHub UI:

  1. Navigate to: https://github.com/camaradesuk/syrf-web/settings
  2. Scroll to "Danger Zone" → "Change repository name"
  3. Enter new name: syrf
  4. Confirm rename

Alternatively via gh CLI:

gh api -X PATCH /repos/camaradesuk/syrf-web -f name='syrf'

GitHub automatic redirects:

  • Old URL: https://github.com/camaradesuk/syrf-web
  • New URL: https://github.com/camaradesuk/syrf
  • Old URLs automatically redirect to new URLs ✅

Verify rename:

# Test old URL redirects
curl -I https://github.com/camaradesuk/syrf-web 2>&1 | grep -i location
# Expected: Location: https://github.com/camaradesuk/syrf

# Verify new repository accessible
gh repo view camaradesuk/syrf

Success Criteria:

  • ✅ Repository renamed to syrf
  • ✅ Old URL redirects to new URL
  • ✅ ZenHub workspace shows new name (same workspace, new label)

Phase 4: Update Local Clone Remote URLs (10 minutes)

Update your local clone:

cd /home/chris/workspace/syrf

# Remove temporary remote
git remote remove syrf-web

# Update origin to new repository name
git remote set-url origin https://github.com/camaradesuk/syrf.git

# Verify update
git remote -v
# Expected:
# origin  https://github.com/camaradesuk/syrf.git (fetch)
# origin  https://github.com/camaradesuk/syrf.git (push)

# Test fetch
git fetch origin
# Expected: Success (no errors)

Update cluster-gitops references:

cd /home/chris/workspace/cluster-gitops

# Find all references to syrf-test
grep -r "syrf-test" environments/

# Update service values files (e.g., environments/staging/services/api.yaml)
# Change: chartRepo: https://github.com/camaradesuk/syrf-test
# To:     chartRepo: https://github.com/camaradesuk/syrf

# Commit changes
git add environments/
git commit -m "chore: update chart repo references after monorepo migration"
git push origin main

Team communication:

Send notification to team:

Subject: Action Required - Update Local Git Remote URLs

The SyRF monorepo has been migrated to https://github.com/camaradesuk/syrf

ACTION REQUIRED: Update your local clone's remote URL:

  cd /path/to/your/syrf/clone
  git remote set-url origin https://github.com/camaradesuk/syrf.git
  git fetch origin

The old URL (syrf-web) will continue to work via GitHub redirects,
but updating ensures you're using the canonical URL.

Questions? See docs/how-to/repository-migration-guide.md

Phase 5: Update Documentation References (60 minutes)

High Priority Files:

  1. Directory.Build.props - NuGet package metadata
<!-- Before -->
<PackageProjectUrl>https://github.com/camaradesuk/syrf-test</PackageProjectUrl>
<RepositoryUrl>https://github.com/camaradesuk/syrf-test</RepositoryUrl>

<!-- After -->
<PackageProjectUrl>https://github.com/camaradesuk/syrf</PackageProjectUrl>
<RepositoryUrl>https://github.com/camaradesuk/syrf</RepositoryUrl>
  1. README.md - Repository structure
<!-- Before -->
syrf-monorepo/

<!-- After -->
syrf/
  1. CLAUDE.md - Project instructions
<!-- Update all references from "syrf-monorepo" to "syrf" -->
  1. Service READMEs (src/services/*/README.md)
# Find and update clone URLs
# Before: git clone https://github.com/camaradesuk/syrf-test.git
# After:  git clone https://github.com/camaradesuk/syrf.git

Medium Priority Files:

  1. docs/architecture/gitops-architecture.md
# Before
chartRepo: https://github.com/camaradesuk/syrf-test

# After
chartRepo: https://github.com/camaradesuk/syrf
  1. .github/workflows/README.md
  2. docs/how-to/production-promotion-and-notifications.md
  3. docs/planning/migration/backlog.md - Update issue links to reference syrf instead of syrf-web

Batch find and replace:

cd /home/chris/workspace/syrf

# Find all files with "syrf-monorepo"
grep -r "syrf-monorepo" --include="*.md" --include="*.yml" --include="*.yaml" --include="*.props" .

# Find all files with "syrf-test"
grep -r "syrf-test" --include="*.md" --include="*.yml" --include="*.yaml" --include="*.props" .

# Update references (use Claude Code Edit tool for precision)

Phase 6: Validate & Cleanup (30 minutes)

Validation Checklist:

# 1. ZenHub workspace
# Visit: https://app.zenhub.com/workspaces/syrf
# Expected: Workspace shows "camaradesuk/syrf" (not syrf-web)

# 2. CI/CD runs successfully
cd /home/chris/workspace/syrf
git commit --allow-empty -m "test: verify CI/CD after migration"
git push origin main
# Expected: GitHub Actions runs successfully

# 3. All branches accessible
gh api repos/camaradesuk/syrf/branches --paginate | jq '.[].name' | wc -l
# Expected: 96 branches (3 from syrf-test + 93 from syrf-web)

# 4. All tags accessible
git ls-remote --tags origin | wc -l
# Expected: 700+ tags (monorepo tags + original syrf-web tags)

# 5. Issues and PRs functional
gh issue list --repo camaradesuk/syrf --limit 5
gh pr list --repo camaradesuk/syrf --limit 5
# Expected: All accessible, no errors

# 6. Old URLs redirect
curl -I https://github.com/camaradesuk/syrf-web 2>&1 | grep -i location
# Expected: Redirects to https://github.com/camaradesuk/syrf

Archive syrf-test:

  1. Navigate to: https://github.com/camaradesuk/syrf-test/settings
  2. Scroll to "Danger Zone" → "Archive this repository"
  3. Confirm archive

Add archive notice:

# Update README.md in syrf-test (before archiving)
git clone https://github.com/camaradesuk/syrf-test.git
cd syrf-test

# Add notice to top of README.md
cat > README.md << 'EOF'
# ARCHIVED - SyRF Monorepo (Test)

**This repository has been archived (2025-11-13).**

The SyRF monorepo has been successfully migrated to:
👉 **https://github.com/camaradesuk/syrf**

This test repository was used for monorepo development and is preserved for historical reference only.

---

EOF

git add README.md
git commit -m "docs: add archive notice after successful migration"
git push origin main

Safety Period: Keep syrf-test archived (not deleted) for 2 weeks to ensure no issues arise.


Post-Migration Actions

Issue: After repository rename, existing GHCR packages are still associated with the old repository name. The GITHUB_TOKEN from the new repository won't have write permissions, causing 403 Forbidden errors in CI/CD workflows.

Symptoms:

ERROR: failed to push ghcr.io/camaradesuk/syrf-web:5.1.0:
unexpected status from HEAD request: 403 Forbidden

Solution: Link each package to the new syrf repository with Write access.

For each package (syrf-api, syrf-pm, syrf-quartz, syrf-web, syrf-docs, syrf-user-guide):

  1. Navigate to package settings:
  2. Web: https://github.com/orgs/camaradesuk/packages/container/syrf-web/settings
  3. API: https://github.com/orgs/camaradesuk/packages/container/syrf-api/settings
  4. PM: https://github.com/orgs/camaradesuk/packages/container/syrf-pm/settings
  5. Quartz: https://github.com/orgs/camaradesuk/packages/container/syrf-quartz/settings
  6. Docs: https://github.com/orgs/camaradesuk/packages/container/syrf-docs/settings
  7. User Guide: https://github.com/orgs/camaradesuk/packages/container/syrf-user-guide/settings

  8. Scroll to "Manage Actions access" section

  9. Click "Add Repository"

  10. Select: camaradesuk/syrf

  11. Set permission to: Write

  12. Click "Add repository"

  13. (Optional) Remove old repository associations (e.g., syrf-test)

Verification:

# Re-run a failed workflow to verify fix
gh run rerun <run-id> --repo camaradesuk/syrf

# Watch for successful Docker push
gh run watch <run-id> --repo camaradesuk/syrf

Expected Result: CI/CD workflows can now push Docker images to GHCR without 403 errors.


Update External References

GitHub Actions:

  • No changes needed (workflows are in the repo)

ArgoCD Applications:

  • No changes needed (ArgoCD references cluster-gitops, not source repo)

External Documentation:

  • Update any external docs referencing old repo URLs

Rollback Procedure

If critical issues arise during migration:

Option 1: Rename back to syrf-web

# Undo the rename (preserves all metadata)
gh api -X PATCH /repos/camaradesuk/syrf -f name='syrf-web'

Option 2: Restore from backup

# Force push backup to syrf-web (restores original state)
cd /tmp
git clone --mirror https://github.com/camaradesuk/syrf-web-legacy.git syrf-web-backup
cd syrf-web-backup
git remote set-url origin https://github.com/camaradesuk/syrf-web.git
git push --mirror origin --force

Option 3: Continue using syrf-test

# syrf-test remains archived, can be unarchived if needed
# Unarchive via GitHub UI: Settings → Danger Zone → Unarchive

Troubleshooting

Issue: "Failed to push some refs"

Cause: Protected branch rules preventing force push

Solution:

  1. Navigate to: https://github.com/camaradesuk/syrf-web/settings/branches
  2. Temporarily disable branch protection for main
  3. Retry force push
  4. Re-enable branch protection

Issue: "PR shows 'This branch has conflicts'"

Cause: PR targets old file paths (pre-monorepo structure)

Solution:

  1. Check out PR branch locally
  2. Rebase onto new main branch
  3. Resolve path conflicts (files moved to src/services/web/)
  4. Force push updated branch

Example:

gh pr checkout 2126
git rebase origin/main
# Resolve conflicts (files moved from root to src/services/web/)
git rebase --continue
git push --force

Issue: "ZenHub workspace shows old repository name"

Cause: ZenHub cache not updated yet

Solution:

  1. Refresh ZenHub workspace page (Ctrl+Shift+R)
  2. Clear ZenHub cache: Settings → Clear Cache
  3. Wait 5-10 minutes for propagation
  4. ZenHub workspace ID remains the same, only display name changes

Success Metrics

After migration, verify:

  • ✅ Repository accessible at https://github.com/camaradesuk/syrf
  • ✅ Old URLs redirect automatically
  • ✅ All branches present (96 total)
  • ✅ All tags present (700+)
  • ✅ All issues accessible (470+)
  • ✅ All PRs accessible (47 open)
  • ✅ ZenHub workspace functional
  • ✅ CI/CD runs successfully
  • ✅ Documentation updated (28 files)
  • ✅ Team notified to update local clones

Timeline

Phase Duration Status
Pre-migration review 30 min
Create backup 15 min
Force push monorepo 15 min
Rename repository 5 min
Update remote URLs 10 min
Update documentation 60 min
Validate & cleanup 30 min
Total ~3 hours

References


Change Log

Date Change Author
2025-11-13 Initial creation Claude Code