Azure DevOps → GitHub
Move Azure Repos and supported pull-request metadata into GitHub while separately planning Boards, Pipelines, Artifacts, permissions, identities, policies, service connections, and changes made after the final snapshot.
Should you make this move?
Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.
Azure DevOps
- Repos, boards, pipelines, artifacts, and enterprise controls are tightly integrated
- Repository-centered workflows keep code, review, and automation close together
- The interface and administration model can feel heavy outside Microsoft-centric organizations
- Advanced governance and automation can become configuration-heavy
GitHub
- The largest developer ecosystem combines collaboration, automation, and public discovery
- Repository-centered workflows keep code, review, and automation close together
- Enterprise planning and governance can require several overlapping GitHub products
- Advanced governance and automation can become configuration-heavy
GitHub: The largest developer ecosystem combines collaboration, automation, and public discovery. This removes a major source-side concern: The interface and administration model can feel heavy outside Microsoft-centric organizations.
What you lose: Repos, boards, pipelines, artifacts, and enterprise controls are tightly integrated. What you inherit: Enterprise planning and governance can require several overlapping GitHub products.
Jump to a section
Know the shape of the move.
This timeline assumes
- Editorial planning scale: up to 100 repositories, 500 GB of Git data, and 250 users.
- GitHub Enterprise Importer is used only for Azure DevOps Cloud; Azure DevOps Server must first move to Cloud or use a source-and-history-only path.
- Choose and record one route per repository before the pilot: Cloud with GitHub Enterprise Importer, or Server through a preliminary Cloud migration/source-and-history-only path.
- A representative repository set is migrated into an isolated destination organization first.
- The source remains read-only until developers and automation pass one complete release cycle.
- The migration team records evidence for every blocking verification check.
What survives the move.
“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.
| Item | Outcome | Impact | What happens | Mitigation |
|---|---|---|---|---|
| Azure DevOps Cloud repositories and supported pull-request metadata | partial | critical | GitHub Enterprise Importer supports Azure DevOps Cloud repository data, but not Azure DevOps Server directly. | Use GitHub Enterprise Importer only for Cloud and pilot repositories with large or unusual pull-request histories. |
| Azure DevOps Server repositories | manual | critical | GitHub Enterprise Importer does not import Azure DevOps Server directly. | Move the repository to Azure DevOps Cloud first or use a separately verified source-and-history-only path with metadata archived. |
| Repository permissions | lost | critical | GitHub explicitly does not migrate Azure DevOps repository permissions. | Create organizations, teams, IdP groups, and rulesets before production access. |
| Azure Boards, Pipelines, Artifacts, and service connections | manual | critical | These services are separate from the repository migration and may be retained, integrated, or migrated independently. | Give each service an approved keep, integrate, rebuild, archive, or retire decision. |
| Post-snapshot changes | lost | critical | The Cloud GEI route has no delta migration, and the Server source-and-history path must not be assumed to update metadata incrementally. | Halt writes during the selected production route and record every exceptional change in a manual ledger. |
| Scoped Git branches, tags, and commit history | clean | critical | Approved user branches and tags can move through the selected Cloud importer or Server source-and-history path; provider-owned refs are classified separately. | Compare the approved ref scope, commit graphs, default branches, submodules, signatures, and shallow state. |
| Pull requests through the Cloud GEI path | partial | critical | GitHub Enterprise Importer migrates supported Azure DevOps Cloud pull-request metadata; a Server source-and-history-only path does not provide the same guarantee. | Pilot Cloud pull requests; archive Server metadata unless it first moves to Cloud. |
| Azure Boards work items | manual | high | Repository migration does not turn Azure Boards work items into GitHub Issues; work-item links attached to migrated pull requests are a narrower supported item. | Keep Boards integrated or run a separately scoped work-item migration. |
| Users and contribution attribution | partial | critical | Email and username differences can create placeholders or migration identities. | Freeze an identity map and reclaim or annotate unmapped activity. |
| Git size and ref limits | partial | critical | GitHub migration limits include a 2 GiB single commit, 255-byte ref names, 100 MiB files after migration, 400 MiB files during GEI, and a public-preview 40 GiB source-code archive limit; the 40 GiB figure is not a combined metadata allowance. | Scan every repository for limit violations and remediate before the production import. |
| Git LFS objects | manual | critical | LFS transfer is a separate critical binary path and must not be inferred from repository or commit counts. | Fetch and transfer LFS objects explicitly, then compare inventories, hashes, and representative downloads. |
| Branch policies by migration route | partial | critical | Supported Azure Repos branch policies can migrate through the Cloud GEI path, except user-scoped and cross-repository policies; a Server source-and-history path does not carry policy metadata. | Verify Cloud GEI policy logs and manually rebuild excluded policies; rebuild all required protections for Server source-only routes before write access. |
| CI/CD pipelines and secrets | manual | critical | GitHub Actions Importer can convert supported Azure Pipeline constructs, but secrets, service connections, self-hosted agents, environments, and pre-deployment approvals remain manual; pre/post-deployment gates, post-deployment approvals, and some resource triggers are unsupported. | Audit and dry-run every pipeline, manually rebuild required constructs, replace unsupported behavior, and rehearse every active build and release workflow. |
| Packages, containers, and releases | partial | high | Registries and release assets do not necessarily follow repository data. | Copy immutable artifacts and update package coordinates and credentials. |
Where each thing goes.
| Source | Destination | Method | Notes |
|---|---|---|---|
| Azure DevOps repository | GitHub repository | automatic | Preserve stable source URL and default branch. |
| Approved user branch and tag | Git branch and tag | automatic | Compare only the approved user-ref scope and classify provider-owned refs separately. |
| Azure DevOps Cloud pull request | GitHub pull request | transform | Supported through the Cloud GEI path; archive metadata on a Server source-only path. |
| Azure Boards work item | Retained Boards integration or separate migration | manual | Repository migration carries pull-request work-item links, not Boards items as GitHub Issues. |
| Azure DevOps user | GitHub user or migration attribution | manual | Freeze an identity map before migration. |
| Azure Repos branch policy | GitHub branch protection | transform | Cloud GEI migrates supported policies; user-scoped/cross-repository policies and every Server source-only policy require manual rebuilding. |
| Azure Pipeline | Retained Azure Pipeline integration or separately migrated GitHub Actions workflow | transform | Use Actions Importer only as a starting point; secrets, service connections, agents, environments, approvals, gates, and some triggers require manual replacement or are unsupported. |
| Git LFS object | GitHub LFS object | transform | Transfer separately from GEI and compare hashes. |
| Azure DevOps group, team, or repository permission | GitHub organization, team, and repository role | manual | Apply least privilege. |
Make the move recoverable.
Create the source-of-truth backup
Preserve Azure DevOps data, configuration, and operating evidence before any destination write.
- Inventory and export Azure DevOps repositories, metadata, users, permissions, pipelines, packages, releases, webhooks, and settings.
- Mirror every Git repository and fetch Git LFS objects.
- Record counts by repository, ref, pull request, issue, user, package, and integration.
- Hash archives and migration manifests.
Proof to capture: A signed manifest reconciles every scoped record class, runtime dependency, export file, count, and hash.
Repository and identity manifest
Preserve repository scope, Git refs, users, and metadata ownership.
- Inventory source values and exceptions.
- Define explicit destination mappings.
- Reject unmapped critical records.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
Workflow and integration conversion
Rebuild delivery and connected services safely.
- Normalize encoding, dates, identifiers, and blanks.
- Run a representative pilot.
- Reconcile accepted, rejected, and transformed rows.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
The things most likely to hurt.
These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.
A code-only move is mistaken for a metadata migration
Git refs exist while pull requests, issues, users, or settings are missing.
- Consequence
- Collaboration and control history disappears.
- Mitigation
- Choose and verify the required migration fidelity explicitly.
Stop if: Any required metadata class lacks a supported path.
Both platforms accept writes
Developers or bots push and update work in both systems.
- Consequence
- Repositories and release state diverge.
- Mitigation
- Freeze source writes and change remotes in one controlled window.
Stop if: Any unapproved source writer remains active.
Permissions or secrets are over-broad
Migrated users or automation receive more authority than intended.
- Consequence
- Code, packages, or production systems are exposed.
- Mitigation
- Apply least privilege before opening repositories.
Stop if: An unauthorized test identity can perform a protected action.
Do the work in this order.
- Days 1–3 · inventory
Inventory and decisions
6–12 hours active2–3 days elapsedOwner review waiting- Inventory Azure DevOps data, features, users, domains, and integrations.
- Approve scope, owners, mappings, and exclusions.
Depends on: Azure DevOps and GitHub administrator access
Stop / go checkpointExport?
Go when: Every critical item has an owner and disposition.
Stop when: Consent, billing, access, or system ownership is unclear.
- Days 3–5 · backup
Backup and reconcile
5–10 hours active1–3 days elapsedExport processing waiting- Create immutable exports and configuration evidence.
- Reconcile counts, totals, and hashes.
Depends on: Approved inventory
Stop / go checkpointTransform?
Go when: Source totals and export manifests agree.
Stop when: Any critical dataset or configuration is absent.
- Days 5–12 · pilot
Map and pilot
10–35 hours active3–8 days elapsedDestination processing and review waiting- Configure GitHub and transform representative data.
- Run a pilot containing normal records and every critical edge case.
Depends on: Verified backup
Stop / go checkpointScale?
Go when: Pilot mappings, behavior, access, and evidence pass.
Stop when: Any critical check fails or produces unexplained variance.
- Days 10–20 · cutover
Production import and switch
5–25 hours active1–5 days elapsedSelected Cloud GEI or Server source-history processing waiting- Freeze production writes in Azure DevOps.
- Run the approved Cloud GEI or Server source-history route, then switch repository remotes and integrations; neither route is treated as an automatic delta update.
Depends on: Passed pilot and approved rollback
Stop / go checkpointOpen production?
Go when: Counts reconcile and one destination system owns production.
Stop when: A source writer remains active or a blocking check fails.
- Days 12–40 · observe
Observe and close
3–18 hours active3–10 days elapsedOperating-cycle evidence waiting- Monitor one complete operating cycle.
- Sign the verification report and close rollback only after stability.
Depends on: Verified cutover
Stop / go checkpointClose rollback?
Go when: No trigger occurs during the agreed observation period.
Stop when: Data, access, delivery, routing, or business results regress.
Cut over with a way back.
Cutover
Make GitHub the only writable repository system after the selected Cloud or Server route completes under a write freeze.
- Freeze production writes and scheduled actions in Azure DevOps.
- For Cloud, run GitHub Enterprise Importer; for Server, run the approved preliminary Cloud or source-and-history path while writes remain frozen.
- Reconcile scoped refs and LFS for every route, plus pull requests, identities, work-item links, and branch policies only where the Cloud GEI path supports them.
- Switch repository remotes, CI, integrations, package consumers, and developer instructions.
- Run every blocking verification check and keep the source intact.
Proof to capture: GitHub owns production, totals reconcile, and every blocking check has durable evidence.
Rollback
Return production ownership to Azure DevOps without losing destination-era changes.
- Stop new writes and scheduled actions in GitHub.
- Restore Azure DevOps repository remotes, pipelines, integrations, and developer instructions.
- Record GitHub-era commits and metadata in a quarantine ledger; the selected migration path cannot reverse or safely delta-sync them.
- Review and apply safe destination-era changes to Azure DevOps.
- Run the same blocking checks against the restored source.
Proof to capture: Azure DevOps again owns production with current data and no duplicate destination action.
- Unexplained critical count or value variance
- Missing or exposed critical data
- Duplicate production action
- Failed access, routing, delivery, or integration check
- A critical feature has no safe destination replacement
Prove the migration worked.
Every blocking check must pass. Capture the evidence before cleanup begins.
| Pass | ID | Check | Method | Expected result | Evidence |
|---|---|---|---|---|---|
V-01Blocking | Repository and ref parity | Compare the approved user-ref scope, commits, default branches, submodules, and separately transferred LFS objects. | Every scoped Git object is accounted for and the source-code archive is within the applicable 40 GiB preview limit. | Git manifest. | |
V-02Blocking | Collaboration coverage | For Cloud GEI, compare supported pull requests and work-item links; for Server source-only routes, verify the approved metadata archive disposition. | Every required item is migrated or explicitly archived. | Metadata ledger. | |
V-03Blocking | Attribution mapping | Inspect active, inactive, bot, and external contributors. | Every required author has a destination or annotation. | Identity map. | |
V-04Blocking | Teams and repository rules | Test representative users and protected actions. | Least privilege and branch controls match policy. | Access report. | |
V-05Blocking | Build and release parity | Run representative workflows from identical commits. | Tests, artifacts, approvals, and deployments match. | Workflow evidence. | |
V-06Blocking | Packages, releases, and LFS | Compare counts, coordinates, sizes, and hashes. | Every required binary is present and retrievable. | Artifact manifest. | |
V-07Blocking | Connected services | Exercise each webhook, app, key, and notification. | One correct destination callback per event. | Integration log. | |
V-08Blocking | Single repository authority | Inspect developer remotes, bots, and source protections. | GitHub alone accepts approved writes. | Cutover checklist. |
Remove the scaffolding safely.
Safe after: One complete operating cycle, at least seven stable days, and owner sign-off on every blocking check.
- Create final Azure DevOps exports and archive verification evidence.
- Revoke temporary credentials, API keys, webhooks, and elevated roles.
- Remove obsolete Azure Repos webhooks, pipeline hooks, service connections, mirrors, and developer integrations.
- Keep the source intact through the approved retention window.
- Cancel paid plans only after billing, legal, and recovery review.
- Schedule the next GitHub backup, access, and migration-playbook review.
Verify against the primary material.
Platform behavior changes. Check these sources and the review dates above before executing a production migration.
- GitHub: understand Azure DevOps migrationsAccessed 2026-07-27
- GitHub: prepare an Azure DevOps migrationAccessed 2026-07-27
- GitHub: migrate Azure DevOps repositoriesAccessed 2026-07-27
- GitHub: migrate from Azure DevOps with GitHub Actions ImporterAccessed 2026-07-27