How to migrate your Azure DevOps Pipeline to GitHub

GitHub Actions

Many of the questions we receive around DevOps transformation usually involve one of two topics.

They concern either migrating source code to GitHub or leveraging the power of GitHub Actions to rebuild Azure Pipelines after a successful code migration. Today we’ll talk about the second topic.

Key points:

  • How to migrate an Azure Pipeline to GitHub actions?
  • What should you consider during configuration?
  • What are the typical challenges with migrating to GitHub?

At a very basic level, GitHub Actions and Azure Pipelines share the same fundamental elements which empower Continuous Delivery.

The difference is that Azure DevOps is more often used in enterprises, whereas GitHub Actions works for everyone “beyond code” using YAML.

How to migrate an Azure Pipeline?

Let’s take a look at one such migration from Azure Pipelines to GitHub Actions. I have built a sample to demonstrate just how easy it can be.

Here is a summary of our steps:

  • Move the YAML file
  • Publish the YAML file
  • Add the Triggers
  • Define the environment variables
  • Modify steps
  • Open the Runner and validate

If you would like to follow along, the Azure Pipeline build is available under this link and the source code is located on GitHub.

Tip: Start simple and build upon your success!

This Azure Pipeline is relatively straightforward. Here’s the breakdown: Every merge to the master triggers the pipeline, builds the code, and publishes the results to NuGet.

Azure Pipelines Editor screenshot

Azure pipelines editor

At first glance, the GitHub Actions editor looks quite similar to the Azure Pipeline interface in Azure DevOps. The interface is very intuitive. On the right, you can easily discover tasks that are available to use out of the box.

Github Actions online editor screenshot

Github Actions online editor

While the number and variety of tasks available are quite impressive, they are tiny in comparison to what has been made available by GitHub users.

Not all of the Azure Pipeline tasks are available as GitHub Actions, but if you can’t find what you need, you can always build it yourself and contribute to the community!

Move and publish the YAML file

To begin our migration, we have to move our YAML file to “.github/workflows.” GitHub Actions requires that it be stored in the .github/workflows folder. After publishing, GitHub will automatically detect a new Action to perform.

Creating GitHub Action folder gif

Creating a GitHub Action folder

Add the triggers

Next, we will begin to add the required to support our automation. A trigger is a definition of what and how our action will be run. The same mechanism is available in the Azure Pipeline but it is not quite as elaborate.

The screenshot below highlights the key differences in the structure of this workflow when comparing Azure Pipelines to GitHub Actions.

Difference between azure pipelines and Github action in defining triggers

Defining triggers in Azure Pipelines vs GitHub Actions

Right now, pr and trigger are combined with one object called “on”. This is broken down further into two sections; “push” and “pull_request.” When comparing the two workflows, think of “push” as “trigger” and “pull_request” as “pr”.

GitHub Actions is more generous on build triggers than Azure pipelines. You can trigger your GitHub Actions for a wide variety of event types. Just a few examples are:

  • fork
  • issues
  • label
  • milestone
  • page build
  • public
  • release
  • watch
  • discussion

and many more. If you’d like to see just how many triggers are available to you, see GitHub’s documentation.

Enjoying your read? Leave your email address to get the latest insights every two weeks. Subscribe

Define GitHub Actions environment variables

A crucial part of Azure Pipelines are the Jobs. As you most likely already know, Jobs are stored steps that run to achieve a required result using pre-defined variables.

By comparison, GitHub actions don’t have private variables. Everything is stored as an Environment variable.

This is a key difference between the two tools. In Azure Pipelines, you can define global variable groups that can be declared and called from within Jobs. In GitHub Actions, you will define variables as environment variables only at the workflow level.

This provides a tremendous amount of flexibility in the architecture and use of your GitHub Actions.

How do jobs work in GitHub?

Inside a job, you will define the permissions required to complete the necessary steps.

For example, you can write instructions that allow this job to create a pull request and approve it as part of the same set of steps.

In Azure DevOps, it is possible to define this level of permissions as well, but the issue is that these changes would then be global for the entire organization. This is not something our InfoSec teams would be very happy about.

The flexibility and variety of jobs within GitHub Actions allow us to be very creative in meeting the business requirements of our organization in as efficient a manner as possible.

Another key difference between GitHub Actions and Azure Pipelines lies in GitHub’s ability to pass the output of one job so that it may be used by another job.

In Azure Pipelines, you can’t manifestly expose the output from one job to be used by a dependent job. We accomplish this in GitHub by leveraging the Outputs section.

Difference between azure pipelines and Github action in defining jobs

Defining jobs in Azure Pipelines vs GitHub actions

Modify steps

The biggest hurdle for most users making the move from Azure Pipelines to GitHub Actions will be the significant syntax change is in the steps area.

Azure Pipeline tasks are incredibly easy to use. In GitHub Actions, we don’t have tasks, but we can use actions or script against the shell by using JavaScript or container that encompasses a group of steps, pre-defined activities, the installation of SDK, etc.

As a best practice, the preferred method is to use the shell.

In our case, we use a setup-dotnet action to install dotnet on the job machine Dotnet Core Tool, and then we use a shell script to build and pack everything up in a convenient way for reuse.

Difference between azure pipelines and Github action in defining task and actions

Defining tasks and actions in Azure Pipelines vs GitHub actions

All actions are available on the official GitHub Marketplace.

Using a shell instead of depending on a task is a good approach when considering quality and reliability.

In addition, it’s easier to reproduce steps from your local machine to your actions if you do run into a problem requiring debug work.

Open the Runner and validate

The last thing I’d like to mention as part of our migration outline tutorial is the Runner window. The Runner is a single instance of our action where everything is invoked.

Everything that is defined in the YAML file is generated and filled with the required data using the appropriate context and triggers; including necessary pull requests to support the action.

Inside the Runner, we can find all logs, artifacts, and an intuitive UI of our definitions.

GitHub action runner board screenshot

GitHub action runner board

The final note on GitHub Actions

In conclusion, while GitHub Actions offer tremendous flexibility and creativity to accomplish automation beyond code, they are still missing a few required components if we want to fully replace our enterprise pipelines at scale.

A good example of this lies in centrally managing variables for many GitHub Actions, changing the name of the build dynamically, or keeping many dependent stages in a single GitHub Action.

Tip: GitHub Actions do not include service connections. There are only webhooks. This is not enough to orchestrate many environments in the cloud.

Build full Proof of Concept implementations to make sure the functionality you need is available or contact me, so that I can save you time and money in your move from Azure Pipelines to GitHub Actions!

Watching the roadmap and documentation, it’s apparent that GitHub will resolve this key requirement for enterprise organizations very soon.

Microsoft is introducing new features and functionalities every day. Some upcoming features I am particularly looking forward to are templates and reusable templates.

So, what are some features that you love about GitHub? Let me know! Do you have a topic you would like me to cover in an upcoming article? I’ll happy to do that as well.

Keep an eye on this blog, as in future articles I will cover GitHub’s native code scanning, strong security community, GitHub Apps, Octocat, and much more. Until next time!

P.S. Here is a comparison of common Pipeline concepts and how they map to GitHub Actions:

feature comparison: Azure Pipelines vs GitHub actions

Azure Pipelines vs GitHub actions: Feature comparison (click to view full-size)

Key takeaways:

  1. GitHub Actions have largely equivalent or similar features to Azure Pipelines, meaning it’s possible to easily migrate from one to another.
  2. The recommended way to modify action steps is to use shell script.
  3. If there are any features you need that are not currently available in GitHub, you can write them yourself and share them with the community as open source code.

Interested in Azure DevOps and GitHub?