Back to Experience

ENGINEERING ARTICLE / REPOSITORY MIGRATION

30+ repositories.
Moved to GitHub.

Migrating a repository is easy. Migrating more than thirty while preserving history, handling binaries and branches, replacing delivery pipelines, and introducing security controls is something else entirely.

Read the key decisions Try the migration readiness assessor Download case study brief PDF · 1 page
My contribution
End-to-end technical ownership. Migration execution, stakeholder coordination, GitHub security, delivery workflows and validation.
Environment
Azure DevOps · Team Foundation Server (TFS) · GitHub · Microsoft Azure
Delivery
30+ repositories migrated. Completion required a one-week extension to the original schedule.

01 / THE PROBLEM

Bring source and delivery
into GitHub.

The migration was not just git clone.

All 30+ repositories originated in Azure DevOps or TFS. Years of binary content, complex branch structures, commit history, repository rules, security requirements and existing CI/CD processes made each repository a migration workload rather than a copy operation.

I owned the complete technical scope.

I carried out the migration and implementation work, coordinated with stakeholders and security teams, handled repositories requiring special treatment, enabled GHAS, modernized delivery patterns and validated what arrived.

How the repositories reached GitHub

Repositories followed either the standard transfer path or a transformation path through an interim TFS environment positioned closer to the source. GitHub configuration, delivery modernization, security and validation surrounded the transfer.

SOURCE REPOSITORIES

Azure DevOps and TFS

REPOSITORIES READY FOR TRANSFER

Available migration path

Transfer to GitHub using permitted automation and manual work.

Alternative route

LARGE REPOSITORIES REQUIRING TRANSFORMATION

Interim TFS in Azure

Transform and transfer the repositories to GitHub.

DESTINATION

GitHub · 30+ repositories migrated

GitHub Advanced Security enabled; classic pipelines converted to GitHub Actions.

PLATFORM CONTROLS AND ACCEPTANCE

GHAS + reusable ActionsSecurity controls and shared delivery patterns.

Python validationCounts, branches, history, rules and test checkouts.

02 / CONSTRAINTS & DECISIONS

Adapt the migration
to the constraints.

Constraints, decisions and consequences
ConstraintMy decisionConsequence / tradeoff
Security restrictions limited migration automation.Automate where permitted and complete the remaining work manually.The migration progressed within the security restrictions, with additional hands-on effort where automation was unavailable.
Large TFS repositories needed special handling.Coordinate with stakeholders, then set up an interim TFS instance in Azure to transform and transfer the repositories.The interim environment provided a transformation step before transfer to GitHub, adding environment setup and repository handling to the work.
Stakeholders needed visibility into progress and potential problems.Meet regularly with stakeholders and security teams, raise risks ahead of time, and explain constraints as the work evolved.Technical decisions and delivery constraints were communicated throughout the migration.
The original migration window remained the target.Continue toward that window using permitted automation and manual work, with ongoing stakeholder coordination.Completion required a one-week extension beyond the original schedule.

03 / IMPLEMENTATION

Complete the move.
Establish the workflows.

Repository migration and security

  • Migrated 30+ repositories using permitted automation and controlled manual execution.
  • Used an interim Azure-hosted TFS instance when compute, data size and network proximity made direct handling impractical.
  • Introduced CodeQL, secret scanning, dependency security, Dependabot, policy, remediation practices and developer education through GHAS.

From bespoke pipelines to shared patterns

I deliberately avoided translating every classic pipeline one-for-one. I created reusable GitHub Actions workflows and consolidated common practices so multiple repositories could consume shared delivery patterns.

A newer platform should not inherit every duplication from the old one. This was where migration work became platform engineering.

04 / VALIDATION

Review the reports.
Check out the repositories.

Custom Python reports

I wrote custom Python tooling to compare expected repository counts, required branches, commit histories and repository rules. This made discrepancies explicit across dozens of repositories instead of relying on manual spot checks.

Test checkouts

I paired structural reporting with practical test checkouts. A repository name appearing in GitHub was not acceptance evidence; the transferred source also needed to be usable.

Synthetic pre-migration classification

The companion project classifies four fictional repositories before scheduling work. Unknown facts never become a standard pass, and TFVC or known history rewrites require a transformation path.

Evidence boundary: these are committed synthetic fixtures, not client repository counts. Inspect the structured result

05 / ADOPTION & SCHEDULE

Protect the team,
not merely the date.

Late in the project, one development team decided it needed additional education before migrating. Forcing the cutover to protect the original date would have exchanged schedule risk for adoption and operational risk.

I quickly delivered the education the team needed, coordinated a new migration window and kept stakeholders informed. The project completed with a one-week extension.

A prepared team one week later is a better outcome than an on-time migration that leaves developers unable to operate their new platform.

06 / OUTCOME & LESSONS

Migration delivered.
Tradeoffs made explicit.

30+

Repositories migrated

Completed the migration from Azure DevOps and TFS to GitHub, including large repositories needing an interim transformation step.

GHAS

Security and automation established

Enabled GitHub Advanced Security, converted classic pipelines to GitHub Actions, and delivered initial Terraform modules and automation examples.

1 week

Schedule extension

Delivery required one additional week beyond the original schedule. Regular stakeholder coordination supported the work through completion.

This work brought together migration execution, security constraints, repository validation and stakeholder coordination. The technical approach had to account for all four.

WHAT I WOULD CHANGE NEXT TIME

Classify difficult repositories before scheduling them.

I would automate pre-migration assessment of incoming TFS collections to flag repository size, binaries, branch complexity, unusual history and other risk indicators. Repositories could then be classified as standard migration, review required or transformation required before they enter the delivery schedule.

The larger lesson is simple: automate where it reduces risk, preserve human judgment where constraints demand it, and use the migration as a chance to establish a more consistent platform—not merely reproduce the old one.

Next: From 1:1 Pipelines to Reusable GitHub Actions

LET’S TALK

Bring me the
interesting problems.

I’m looking for Senior DevOps and Platform Engineering opportunities where I can improve cloud delivery, build useful automation and help teams do their best work.

APPLY THE APPROACH TO YOUR ENVIRONMENT

Migration Ritual

Identify repository, history and pipeline blockers before agreeing a migration window.

Separate consulting assessment. The evidence and limitations above remain specific to the original project or demonstration.

Email WitchOps Explore the assessment ↗