Skip to content

Instantly share code, notes, and snippets.

Created February 16, 2024 10:57
Show Gist options
  • Save ehrnst/a4f6791c1c19be1b235d66e182dd1c68 to your computer and use it in GitHub Desktop.
Save ehrnst/a4f6791c1c19be1b235d66e182dd1c68 to your computer and use it in GitHub Desktop.
PowerShell script using GH CLI to migrate Azure DevOps repositories to GitHub
[Parameter(HelpMessage="The Azure DevOps organization.")]
[string]$adoOrg = "Adatum",
[Parameter(Mandatory=$true, HelpMessage="The Azure DevOps team project.")]
[Parameter(Mandatory=$true, HelpMessage="The Azure DevOps repository.")]
[Parameter(HelpMessage="The GitHub organization.")]
[string]$githubOrg = "Adatum",
[Parameter(HelpMessage="The GitHub repository.")]
[bool]$lockAdoRepo = $false,
[Parameter(HelpMessage="Repository owner.", Mandatory=$true)]
# Use the Azure DevOps repository name as the GitHub repository name
[string]$githubRepo = $adoRepo
gh auth login --with-token $env:GH_TOKEN
$repoExists = $null
$repoExists = gh repo view $githubOrg/$githubRepo
if ($null -eq $repoExists) {
# Use the custom extension to migrate the repository
try {
gh ado2gh migrate-repo --ado-org $adoOrg --ado-team-project $adoTeamProject --ado-repo $adoRepo --github-org $githubOrg --github-repo $githubRepo --target-repo-visibility 'internal'
# get default branch and set branch protection
Write-Output "Setting branch protection..."
$defaultBranch = gh repo view "${githubOrg}/${githubRepo}" --json defaultBranchRef --jq ''
gh api repos/$githubOrg/$githubRepo/branches/$defaultBranch/protection --method PUT `
-H "Accept: application/vnd.github+json" `
-F "required_pull_request_reviews[required_approving_review_count]=1" `
-F "required_status_checks=null" `
-F "restrictions=null" `
-F "enforce_admins=true" `
# setting the repo admin
gh api repos/$githubOrg/$githubRepo/collaborators/$repoOwner --method PUT -F permission=admin
Write-Output "creating environments..."
gh api repos/$githubOrg/$githubRepo/environments/production --method PUT `
-H "Accept: application/vnd.github+json" `
-F "deployment_branch_policy[protected_branches]=true" `
-F "deployment_branch_policy[custom_branch_policies]=false"
gh api repos/$githubOrg/$githubRepo/environments/dev --method PUT `
-H "Accept: application/vnd.github+json"
gh api repos/$githubOrg/$githubRepo/environments/qa --method PUT `
-H "Accept: application/vnd.github+json"
catch {
if ($LASTEXITCODE -eq 1) {
Write-Output "Migration failed. Aborting..."
gh ado2gh abort-migration --ado-org $adoOrg --ado-team-project $adoTeamProject --ado-repo $adoRepo --github-org $githubOrg --github-repo $githubRepo
if ($lockAdoRepo) {
Write-Output "Disabling Azure DevOps repository..."
gh ado2gh disable-ado-repo --ado-org $adoOrg --ado-team-project $adoTeamProject --ado-repo $adoRepo
} else {
Write-Output "Repository already exists. Migration skipped."
name: Migrate DevOps Repo
description: 'Azure DevOps team project'
required: true
description: 'Azure DevOps repository'
required: true
description: 'Lock Azure DevOps repository'
required: false
type: boolean
default: false
name: Migrate repo, ${{ github.event.inputs.adoRepo }}
runs-on: ubuntu-latest
- name: Checkout code
uses: actions/checkout@v4
persist-credentials: false
ref: ${{ github.head_ref }}
- name: Install GH CLI Extension
run: |
gh extension install github/gh-ado2gh
- name: Run PowerShell script
shell: pwsh
run: |
.\scripts\migrate-devops-repo.ps1 -adoTeamProject "${{ github.event.inputs.adoTeamProject }}" -adoRepo "${{ github.event.inputs.adoRepo }}" -repoOwner "${{ github.triggering_actor }}"
GH_PAT: ${{ secrets.GH_PAT }}
ADO_PAT: ${{ secrets.ADO_PAT }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment