Migration Support Playbook — middag-io
Step-by-step migration support for active Bitbucket repositories when migration is operationally useful. References: ADR-001, ADR-004, ADR-006.
This guide does not define MIDDAG's main strategy. The main strategy is operational structuring. Migration is only one support activity.
GitLab is not a GitHub migration source in this process because the GitLab estate was already migrated to Bitbucket years ago.
Prerequisites
- GitHub CLI (
gh) authenticated withmiddag-ioorg admin - Git SSH access to both Bitbucket (
middagtec) and GitHub (middag-io) - 1Password CLI (
op) for secret migration verification
1. Pre-Migration
1.1 Determine target name
Follow ADR-001 — Repository Naming Convention for the complete naming table and edge cases. Key: every repo gets a category prefix (wp-plugin-, docker-, moodle-, etc.).
1.2 Check Bitbucket repo state
# List active branches
git ls-remote --heads git@bitbucket.org:middagtec/{old-name}.git
# Check pipeline variables (manual — BB Settings → Repository Variables)
# Document all variables for secret mapping later1.3 Map secrets
See ADR-005 — 1Password + GitHub Integration for the complete Bitbucket → GitHub variables mapping table.
If repo-specific secrets exist, create 1Password vault + SA per G03 — 1Password Operations.
2. Mirror Clone
# 1. Create empty repo on GitHub
gh repo create middag-io/{new-name} --private --description "{desc}"
# 2. Mirror clone from Bitbucket (preserves all branches, tags, history)
git clone --mirror git@bitbucket.org:middagtec/{old-name}.git /tmp/{old-name}.git
# 3. Push mirror to GitHub
cd /tmp/{old-name}.git
git push --mirror git@github.com:middag-io/{new-name}.git
# 4. Clean up temp clone
rm -rf /tmp/{old-name}.gitVerify mirror
# Check all branches arrived
gh api repos/middag-io/{new-name}/branches --jq '.[].name'
# Check tags
gh api repos/middag-io/{new-name}/tags --jq '.[].name'3. Configure Repository
# Set default branch
gh repo edit middag-io/{new-name} --default-branch main
# Rename master → main if needed
gh api repos/middag-io/{new-name}/branches/master/rename -f new_name=main
# Add topics
gh repo edit middag-io/{new-name} --add-topic wordpress,plugin,middag
# Custom properties
gh api repos/middag-io/{new-name}/properties/values \
-X PATCH \
-f properties[][property_name]=platform -f properties[][value]=wordpress \
-f properties[][property_name]=component-type -f properties[][value]=plugin \
-f properties[][property_name]=deploy-target -f properties[][value]=production4. Add CI Workflows
Follow G04 — Repo Setup Checklist sections 4-5 and ADR-006 — Reusable Workflows for:
- CI workflow (
.github/workflows/ci.yml) - Release workflow (
.github/workflows/release.yml) - release-please config files (see ADR-003 — Release Strategy)
Remove Bitbucket pipeline
git rm bitbucket-pipelines.yml
git commit -m "ci: remove Bitbucket Pipelines (migrated to GitHub Actions)"5. Update Local Dev Environment
# Update remote URL
cd /path/to/local/repo
git remote set-url origin git@github.com:middag-io/{new-name}.git
git fetch --all --prune
# Verify
git remote -v6. Update Composer References
If repo uses privatesatis packages, update composer.json:
{
"repositories": [
{
"type": "composer",
"url": "https://privatesatis.middag.com.br"
}
]
}Update auth.json for local dev:
{
"http-basic": {
"privatesatis.middag.com.br": {
"username": "github-middag-io",
"password": "<token>"
}
}
}7. Test CI
# Push to develop — CI should trigger
git push origin develop
# Open PR to main
gh pr create --base main --head develop --title "ci: migrate to GitHub Actions"
# Watch CI
gh run watch
# After merge to main — verify release-please creates Release PR
gh pr list --repo middag-io/{new-name}8. Archive on Bitbucket
After confirming GitHub Actions green on main + develop:
- Go to Bitbucket →
middagtec/{old-name}→ Settings - Set repository to read-only (not delete — preserve history)
- Add description:
MIGRATED → github.com/middag-io/{new-name}
Post-Migration Checklist
- [ ] All branches and tags present on GitHub
- [ ] Default branch set to
main - [ ]
developbranch exists - [ ] Topics and custom properties set
- [ ] CI workflow green on
develop - [ ] CI workflow green on PR to
main - [ ] release-please config + manifest created
- [ ] Version annotations in main file
- [ ]
bitbucket-pipelines.ymlremoved - [ ] Local dev remotes updated
- [ ] Composer references updated (if applicable)
- [ ] Deploy pipeline functional (if applicable)
- [ ] Bitbucket repo set to read-only
Migration Status
| Wave | Status | Notes |
|---|---|---|
| 0 — Infra | COMPLETE | .github, CI workflows, org config |
| 1 — WP | COMPLETE | 6 repos migrated, BB pipelines removed, reusable workflows + release-please |
| 2 — Libs | Pending | Rename + topics/properties polish |
| 3 — Apps | Pending | |
| 4 — Moodle core | Pending | Complex CI (moodle-plugin-ci) |
| 5 — Moodle sites | Pending | Per-site migration |
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
fatal: remote error: access denied | SSH key not in Bitbucket | Add deploy key or use personal key |
| Missing branches after mirror | Protected branches on BB side | Check BB branch permissions |
CI fails: workflow not found | Wrong path to reusable workflow | middag-io/.github-private/.github/workflows/{name}.yml@workflows-v1 |
secrets: inherit error | Repo not under middag-io org | Transfer repo to org first |
master branch still default | Rename didn't propagate | gh repo edit --default-branch main |
| Push conflict on mirror | GitHub repo was created with README | Recreate repo without README or force push |