Skip to content

How to Migrate from Azure DevOps Pipelines into GitHub Actions

Photo by Soly Moses: https://www.pexels.com/photo/transformers-sculptures-under-the-blue-sky-12334692/

Migrating from Azure DevOps Pipelines to GitHub Actions can be a challenging task, especially if you have a large project with complex build definitions. However, the process can be simplified with the help of the GitHub CLI Migration Extension. In this blog post, we will go through the steps involved in using this extension to migrate from Azure DevOps Pipelines to GitHub Actions.

Before We Get Started

Before we jump into migration I must note that migration from Azure DevOps to GitHub is a huge task (at least if you have 20+ pipelines) and you should always plan your migration very carefully. You don’t have to migrate all pipelines at once, but living with two systems can be a pain in the ass, so try to keep it as short as possible.

Install GitHub CLI and Migration Extension

Ok let’s get started with our migration. The first step in using the GitHub CLI migration extension is to install the GitHub CLI itself. The GitHub CLI provides a command-line interface to interact with GitHub repositories and can be installed on various platforms. To install the GitHub CLI visit https://cli.github.com and follow the page instructions.

Next open up terminal (or command prompt) and install the gh-actions-importer extension

gh extension install github/gh-actions-importer

You can verify that the extension works by running following command

gh actions-importer -h

PAT tokens

To run the migration we need two PAT tokens. One for the GitHub and another for the Azure DevOps.

To create a token for GitHub see this guide: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-personal-access-token-classic

GitHub token requires workflow scope to work.

For Azure DevOps see this guide: https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#create-a-pat

Azure DevOps token requires following permissions to work:

  • Agents Pool: Read
  • Build: Read
  • Code: Read
  • Release: Read
  • Service Connections: Read
  • Task Groups: Read
  • Variable Groups: Read

Now we have everything set and we can configure the GH CLI extension by running configure command.

gh actions-importer configure

Answer the questions that wizard asks and use default for GitHub and Azure DevOps base URLs. Don’t add your organization names to these.

Next we need to update the actions importer, even though that we just installed it. I don’t know why this needs to be done, but without it the migration will most probably produce an error. Run update with following command:

gh actions-importer update

Now we are ready to simulate the migration and see how well this tool can handle all of our pipeline quirks. To run the simulation use Audit command with output directory.

gh actions-importer audit azure-devops --output-dir tmp

output-dir needs to be relative path. Giving absolute path like c:\temp will not work. This commands goes through your Azure DevOps pipelines for given project and creates a report how well it can convert pipelines into GitHub Actions. The report gives you some directions, but it is not full truth. The report can say, that importer is able to migrate the pipeline, but it won’t work at GitHub without little tweaking.

For example if you use **/*.csproj paths in your Azure DevOps Pipelines the importer will bring the setting like that into GitHub Actions and it won’t work. To fix this you have two options: Extend the importer or manually fix the paths at GitHub into something like MyProject/MyProject.csproj.

Migration

Finally we can run our importer and do the actual migration. Great thing about this tool is that it will create pull request about the imported action. It won’t just magically create things into your GitHub repository. To be able to create a pull request is a powerful tool to inspect the final result, maybe create an extension and rerun the the migration. Pull request can also be reviewed by your co-workers, so you get that extra security and safety over what you are doing.

Migration is run with migrate azure-devops pipeline command. You need to pass the pipeline-id (if you want to run it just for one pipeline), GitHub target URL and directory for logs. You can find the pipeline id easily by editing a pipeline at Azure DevOps and check the URL.

gh actions-importer migrate azure-devops pipeline --pipeline-id (pipeline id at Azure DevOps) --target-url https://github.com/(your organization)/(your repository) --output-dir ghactionsmigrate

Extending the Importer

If you need to migrate multiple pipelines, it might not be practical to fix all the migration errors one-by-one at GitHub pull request. Luckily we can extend the importer and write our own Ruby scripts, which can convert those pesky paths into proper GitHub Action paths. I will later provide a guide about how to extend the importer, but you should be able to find some good examples at GitHub.

Photo by Ann H: https://www.pexels.com/photo/yellow-cable-3541555/
You can easily extend the migration tool

Final Thoughts

Migrating Azure DevOps pipelines into GitHub can be a cumbersome job. You need to plan your migration carefully and then decide what tools to use. You might want to also think about upgrading pipelines into better suitable actions and not just go with the lift and shift approach. If you want to do the later, then GitHub actions-importer is a great tool for that. Happy migration!