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:
- Backup the original
syrf-webrepository completely - Force push the monorepo code to
syrf-web(preserves GitHub metadata) - Rename
syrf-webtosyrf(GitHub handles redirects)
Result: All history, metadata, and ZenHub configuration preserved in one repository.
Prerequisites¶
- Admin access to
camaradesukGitHub 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:
- ✅
mainbranch 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.tsnow needs to targetsrc/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:
- Navigate to: https://github.com/camaradesuk/syrf-web/settings
- Scroll to "Danger Zone" → "Change repository name"
- Enter new name:
syrf - Confirm rename
Alternatively via gh CLI:
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:
- 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>
- README.md - Repository structure
- CLAUDE.md - Project instructions
- 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:
- docs/architecture/gitops-architecture.md
# Before
chartRepo: https://github.com/camaradesuk/syrf-test
# After
chartRepo: https://github.com/camaradesuk/syrf
- .github/workflows/README.md
- docs/how-to/production-promotion-and-notifications.md
- docs/planning/migration/backlog.md - Update issue links to reference
syrfinstead ofsyrf-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:
- Navigate to: https://github.com/camaradesuk/syrf-test/settings
- Scroll to "Danger Zone" → "Archive this repository"
- 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¶
CRITICAL: Link GHCR Packages to New Repository (Required)¶
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):
- Navigate to package settings:
- Web: https://github.com/orgs/camaradesuk/packages/container/syrf-web/settings
- API: https://github.com/orgs/camaradesuk/packages/container/syrf-api/settings
- PM: https://github.com/orgs/camaradesuk/packages/container/syrf-pm/settings
- Quartz: https://github.com/orgs/camaradesuk/packages/container/syrf-quartz/settings
- Docs: https://github.com/orgs/camaradesuk/packages/container/syrf-docs/settings
-
User Guide: https://github.com/orgs/camaradesuk/packages/container/syrf-user-guide/settings
-
Scroll to "Manage Actions access" section
-
Click "Add Repository"
-
Select:
camaradesuk/syrf -
Set permission to: Write
-
Click "Add repository"
-
(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:
- Navigate to: https://github.com/camaradesuk/syrf-web/settings/branches
- Temporarily disable branch protection for
main - Retry force push
- Re-enable branch protection
Issue: "PR shows 'This branch has conflicts'"¶
Cause: PR targets old file paths (pre-monorepo structure)
Solution:
- Check out PR branch locally
- Rebase onto new
mainbranch - Resolve path conflicts (files moved to
src/services/web/) - 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:
- Refresh ZenHub workspace page (Ctrl+Shift+R)
- Clear ZenHub cache: Settings → Clear Cache
- Wait 5-10 minutes for propagation
- 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¶
- ADR-005: Repository Migration Strategy
- GitHub Docs: Renaming a repository
- GitHub Docs: About repository transfers
Change Log¶
| Date | Change | Author |
|---|---|---|
| 2025-11-13 | Initial creation | Claude Code |