FJAN Logo

Azure Repos to GitHub: Keep Boards, Links and Your DoD

Publicatiedatum

Leestijd

10 minuten

Delen

Illustration of a planning board linked to code repositories crossing a bridge to a new platform
Profile photo of Funs Janssen

Geschreven door Funs Janssen

Software Consultant

Ik ben Funs Janssen. Ik ontwikkel software en schrijf over de beslissingen die daarbij komen kijken: architectuur, ontwikkelmethoden, AI-tools en de zakelijke impact van technische keuzes. Deze blog is een verzameling praktische aantekeningen van echte projecten: wat schaalbaar is, wat misgaat en wat in blogvriendelijke voorbeelden vaak over het hoofd wordt gezien.

Moving your code from Azure Repos to GitHub has never been easier. Enterprise Live Migrations syncs your repositories in the background, converts branch policies to rulesets and cuts over with typically less than 30 minutes of downtime. Then Monday morning arrives and your product owner asks why the Development section on her user story is empty, why a merged PR closed one bug but not the other two, and who exactly is checking the Definition of Done now that pull requests live somewhere else.

The repo migration is the easy part. Every guide I found stops at "your repositories are now on GitHub" and leaves the Boards side as an exercise for the reader.

This post is that exercise, done. You'll get what a migration actually moves, how to reconnect Azure Boards to the migrated repos, the AB# linking rules that bite in week one, and how to move your Definition of Done to the one place that survives the migration: the work item itself.

What a repo migration moves, and what it leaves in Azure DevOps

Enterprise Live Migrations in one paragraph

Microsoft put Enterprise Live Migrations into public preview at the end of August 2026. It works in three stages: validate that a repository is ready, synchronize it continuously while your team keeps working, then cut over with a final sync. It moves repositories, commit history, branches and tags, pull request metadata and comments, and converts branch policies to GitHub rulesets. One requirement matters a lot later in this post: it only targets GitHub Enterprise Cloud with data residency, meaning organizations on a ghe.com URL. Standard github.com enterprises are not supported yet. If you're on github.com, the older GitHub Enterprise Importer route still applies, and everything below about Boards works the same way.

What stays behind

The service explicitly does not migrate work items, pipeline definitions, releases, wikis, test artifacts or Azure Artifacts. That's not a gap to work around; it's the design. Azure DevOps stays your planning, build and test system. Only the code moves.

What quietly stops working

This is the part that doesn't show up in a migration report:

  • Azure Repos branch policies stop guarding your work items. If you relied on "Check for linked work items" or a required reviewer group, that enforcement now has to be rebuilt as GitHub rulesets, and GitHub has no native rule that says "this PR must link a Boards work item".
  • Existing Development links point at the old Azure Repos PRs. History is preserved on the Azure DevOps side, but new work only links once you set up the GitHub connection.
  • Boards auto-complete behavior changes. Completing an Azure Repos PR with "complete linked work items" is replaced by Fixes AB# keywords, which follow different rules.

Why "GitHub for code, Boards for planning" is a sane end state

Microsoft recommends exactly this

This isn't a halfway house. Microsoft's own guidance is to host code on GitHub to get the newest Copilot capabilities, while keeping Azure Boards, Azure Pipelines and Test Plans. Azure DevOps Basic access is also included with GitHub Enterprise licenses, so for most teams the hybrid doesn't add a second per-seat bill. Your process template, custom fields, queries, dashboards and Delivery Plans all stay where they are, and your product owners don't have to learn GitHub Projects.

When the hybrid is the wrong choice

If your team is small, your process is light and half the backlog already lives in GitHub Issues, running two systems adds overhead you don't need. I compared the two planning tools in Azure DevOps vs GitHub Projects. The hybrid earns its keep when Boards carries real process: custom states, compliance traceability, portfolio backlogs, or a Definition of Done that someone actually audits.

Reconnecting Azure Boards to the migrated repos

Use the Azure Boards app, not a personal connection

Connect through the Azure Boards app for GitHub rather than a connection tied to one person's OAuth token. The app authenticates as an app, survives that person leaving, and lets you manage repositories from both sides. You'll need a GitHub organization owner and a Project Collection Administrator (or project member) on the Azure DevOps side, and the GitHub org must allow third-party app access. If you already have an old OAuth connection, remove it first, because the two conflict.

Pick the right connection type for ghe.com

Because Enterprise Live Migrations lands your code on ghe.com, the default GitHub option in Azure Boards is the wrong one. When you create the connection, choose GitHub Enterprise Cloud with data residency and enter your https://<org>.ghe.com URL. That option has been available for both Boards and Pipelines since Sprint 260. Picking plain GitHub here is the most common reason the repository list comes back empty.

One repo, one Azure DevOps organization

A GitHub repository should be connected to one Azure DevOps organization only. Connect it to two and AB# mentions start linking to the wrong work item IDs, because AB#412 exists in both. If you run several Azure DevOps organizations, decide the owner of each repo before cutover, not after.

Pipelines: repoint now, migrate later

Azure Pipelines can build from the migrated repositories, so you don't need to rewrite YAML to Actions on day one. Create a new GitHub service connection with the data residency option, point each pipeline at the new repo, and check that triggers and PR validation builds fire. Moving to GitHub Actions can be a separate project with its own timeline.

AB# linking rules that will bite you in week one

The full syntax is in Link GitHub commits and pull requests to work items, but these are the rules that cause support tickets.

Descriptions and commits link, titles and comments don't

AB#123 creates a link when it's in a commit message, a PR description or an issue description. It does nothing in a PR title or a PR comment. Developers coming from Azure Repos, where you linked work items with a picker, will put it in the title because that's where the ticket number always went.

The "only the first item transitions" trap

Fixes AB#123, AB#124, AB#126 links all three work items but only transitions the first one. To close all three, repeat the keyword: Fixes AB#123, Fixes AB#124, Fixes AB#126. The fix, fixes and fixed keywords move an item to the Resolved category, or Completed if your process has no Resolved state. A state name like Closed AB#123 moves it to that exact state.

Transitions only fire on merge to the default branch

A PR merged into a release or feature branch links the work item but leaves its state untouched. If your team uses long-lived release branches, expect stories to sit in Active after their code shipped, and decide whether that's acceptable or whether someone closes them deliberately.

Make correct linking the default with a PR template

Don't rely on memory. Add a .github/pull_request_template.md to every migrated repo:

1## Work items
2<!-- One line per item. Use "Fixes" only if this PR completes it. -->
3AB#
4
5## What changed
6
7## How it was tested

Pair it with a lightweight check in your pipeline that fails a PR description without an AB# reference. That restores most of what the old "Check for linked work items" branch policy gave you.

Your Definition of Done can't live on the PR anymore

What branch policies used to do for you

In many teams the Definition of Done was enforced by accident. A linked work item was mandatory, two reviewers were required, and a build had to pass, so "done" more or less equalled "the PR completed". After migration, those rules are split across GitHub rulesets and your Boards process, and the link between them is a text mention in a PR description.

Move the gate to the work item

The fix is to stop treating the PR as the gate and make the work item the gate. A PR can prove the code was reviewed. It can't prove the release notes were written, the feature flag was configured, the test cases were updated or the product owner accepted the story. Those belong on the story.

This is why I built the Checklist Extension for Azure DevOps: put a Definition of Done checklist template on every user story, map its completion to a field, and add a process rule that blocks the transition to Done until the checklist is complete. I walked through the wiring in Make "Done" Mean Done in Azure DevOps Boards. It works the same whether your code lives in Azure Repos, github.com or ghe.com, because nothing about it touches the repository.

Why process rules matter when merges change states

After the migration, states change from outside Azure DevOps: a merged PR with Fixes AB#123 moves the work item for you. A gate that only lives in someone's head, or in a reminder on the board, never sees that event. A rule on the work item type is evaluated whenever the item is saved, so test it explicitly after cutover: merge a test PR with Fixes AB# against a story with an incomplete checklist, and confirm the story stays where your process says it should.

Copilot on both sides of the hybrid

Assign Boards work items to the Copilot coding agent

Once repos live on GitHub and the Boards connection is in place, you can hand a work item to the GitHub Copilot coding agent straight from Azure Boards. It reads the work item description plus recent comments, opens a draft PR linked back to the item, and shows its status on the board card. It needs the coding agent enabled on the repository, which on Business and Enterprise plans requires admin approval, so add that to the cutover plan.

The Copilot app plugin and the MCP server

The Azure DevOps plugin for the GitHub Copilot app lets developers view, edit and complete work items and PRs without switching tools, and the remote Azure DevOps MCP Server gives agents structured access to your backlog. I covered the permission model in Azure DevOps MCP Server: Connect AI Agents Safely.

Your backlog becomes the prompt

The agent can only be as precise as the work item you hand it. A story titled "fix login" with no acceptance criteria produces a PR that fixes something, just maybe not the right thing. That was true before the migration, and it matters more once agents start opening PRs from your board. ClearSpecs AI is the tool I build for that step: it helps you write and tighten user stories, acceptance criteria and child tasks inside Azure Boards before anyone, human or agent, starts coding. More on that reasoning in Guard AI Development at the Work Item, Not the PR.

A cutover checklist for the Boards side

Before cutover

  • Decide which Azure DevOps organization owns each repository.
  • Inventory every Azure Repos branch policy and map each one to a GitHub ruleset, or to a work item rule.
  • Add your Definition of Done to the work item as a checklist with a blocking rule, and test it.
  • Prepare the PR template and the AB# check.

During cutover

  • Install the Azure Boards app and connect using the data residency option for ghe.com.
  • Repoint pipelines and confirm CI and PR validation triggers fire.
  • Enable the Copilot coding agent on repositories where you want it.

After cutover

  • Merge one test PR with Fixes AB# and check the Development section and the state change.
  • Watch for stories stuck in Active after release branch merges.
  • Run a query for items resolved in the last week without a linked GitHub PR, and fix the habits behind it.

Conclusion

Moving repositories to GitHub is a solved problem; Enterprise Live Migrations handles history, PRs and policies with little downtime. What it doesn't handle is your process. The hybrid works well when you treat Boards as the system of record and set it up on purpose: the right connection type for ghe.com, one organization per repo, AB# habits that actually link, and a Definition of Done that lives on the work item instead of in a branch policy you just left behind.

If your DoD used to be enforced by Azure Repos, now is the moment to give it a new home. The Checklist Extension is free on the Visual Studio Marketplace and takes a few minutes to put a blocking Definition of Done on every story, before your first PR merges on GitHub.

Frequently asked questions

Reacties

Nog geen reacties. Wees de eerste om te reageren.

Plaats een reactie

Profile photo of Funs Janssen

Geschreven door Funs Janssen

Software Consultant

Ik ben Funs Janssen. Ik ontwikkel software en schrijf over de beslissingen die daarbij komen kijken: architectuur, ontwikkelmethoden, AI-tools en de zakelijke impact van technische keuzes. Deze blog is een verzameling praktische aantekeningen van echte projecten: wat schaalbaar is, wat misgaat en wat in blogvriendelijke voorbeelden vaak over het hoofd wordt gezien.

Inhoud