AZ-400: Designing and Implementing Microsoft DevOps Solutions

Design and Implement Pipeline Automation

Orchestration of GitHub Actions and Azure Pipelines

In this guide, we explain how to orchestrate GitHub Actions and Azure Pipelines to build and deploy a Node.js application from GitHub. We’ll walk through triggering a GitHub Actions workflow using an Azure Pipeline, similar to the KodeKloud Coffee repository scenario where GitHub Actions run on changes.

A popular approach is to merge pull requests, which automatically triggers the build process. For example, consider the following view from GitHub Actions that displays workflow runs and their statuses:

The image shows a GitHub Actions page for the "KodeKloudCoffee" repository, displaying a list of workflow runs with their statuses and details.

After merging a pull request, the GitHub user interface confirms the merge and offers an option to delete the branch:

The image shows a GitHub pull request page where a pull request has been successfully merged and closed. There is an option to delete the branch, and a section to add comments.

A green check mark indicates the success of both the merge and the subsequent workflow run.

Next, let’s review the workflow file. This file is configured to deploy the application to Azure when a push occurs on the main branch. The following diagram illustrates a list of workflow runs—displaying event types, statuses, and timestamps—which confirms that the build executes whenever code is pushed:

The image shows a GitHub Actions page displaying a list of workflow runs for a repository, with details such as event types, status, and timestamps.

The key question now is: how can Azure DevOps trigger this GitHub Actions workflow? Let’s dive into the process.

Obtaining a Personal Access Token on GitHub

The first step involves obtaining a Personal Access Token (PAT). Follow these steps:

  1. Navigate to your GitHub settings.
  2. Under "Developer Settings", select "Personal Access Tokens".
  3. Choose between using the new fine-grained tokens (in beta) or generating a classic token. For this guide, a classic token will be used.

The image shows the GitHub Developer Settings page for managing personal access tokens, with options to generate new tokens and a list of existing tokens with their expiration dates.

Name the token "push to Azure" and set its expiration to 30 days. Under scopes, ensure that you select both repo and workflow. The repo scope allows access to the repository and its statuses, while the workflow scope permits updating GitHub Actions workflows.

The image shows a GitHub settings page for creating a new personal access token, with various scopes and permissions options available for selection.

Click "Generate token" to create your PAT. Note that the token is only displayed once; if you close the window, you will need to generate a new token.

Modifying the GitHub Actions Workflow

To enable triggering from Azure Pipelines, modify your GitHub Actions workflow file (commonly named main.yml) to include a repository dispatch trigger. Insert the lines shown below above the existing workflow_dispatch configuration:

name: Deploy to Azure
on:
  push:
    branches: [ main ]
  workflow_dispatch:
env:
  AZURE_WEBAPP_NAME: kodekloudcoffee
  AZURE_WEBAPP_PACKAGE_PATH: '.'
  NODE_VERSION: '20.x'
permissions:
  contents: read
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm test --if-present

Commit these changes before moving on to configuring Azure DevOps.

Configuring Azure Pipeline to Trigger GitHub Actions

In Azure DevOps, follow these steps to create a new pipeline that will trigger the GitHub Actions workflow:

  1. Create a new pipeline.

  2. Select the repository (in this case, KodeKloud Coffee) from GitHub to establish a connection between Azure Pipelines and GitHub.

  3. Choose a starter pipeline and disable automatic triggering by configuring:

    # Starter pipeline
    # Start with a minimal pipeline that you can customize to build and deploy your code.
    # Add steps that build, run tests, deploy, and more:
    # https://aka.ms/yaml
    trigger:
      - none
    
    pool:
      vmImage: 'ubuntu-latest'
    
    steps:
    - script: echo Hello, world!
      displayName: 'Run a one-line script'
    
    - script: |
        echo Add other tasks to build, test, and deploy your project.
        echo See https://aka.ms/yaml
      displayName: 'Run a multi-line script'
    

    The command trigger: none ensures that the pipeline is only manually activated from Azure DevOps.

Triggering the GitHub Actions Workflow from Azure Pipelines

To trigger the GitHub Actions workflow from Azure Pipelines, add a PowerShell task to your pipeline that sends an HTTP POST request to the GitHub API. This request uses the PAT (stored as a secret variable in Azure Pipelines) for authentication.

First, add this PowerShell script task to invoke the API:

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more: https://aka.ms/yaml
trigger:
  - none

pool:
  vmImage: 'ubuntu-latest'
  name: 'Default'

steps:
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      $headers = @{
        'Authorization' = 'Bearer $(github_token)'
        'Accept' = 'application/vnd.github+json'
        'X-GitHub-Api-Version' = '2022-11-28'
      }
      Invoke-RestMethod -Uri 'https://api.github.com/repos/jeremykodekloud/KodeKloudCoffee/actions/workflows/main.yml/dispatches' -Method 'POST' -Headers $headers -Body '{"ref":"main"}'
  displayName: 'Send Update to GitHub to Trigger Build'

Ensure you add a secret variable named GITHUB_TOKEN with the value of your personal access token in your Azure Pipeline settings. This secret guarantees secure communication with GitHub and triggers the workflow.

For enhanced clarity and JSON conversion, you might prefer the following version:

# Starter pipeline
# Start with a minimal pipeline to build and deploy your code.
# https://aka.ms/yaml
trigger:
  - none

pool:
  vmImage: 'ubuntu-latest'
  name: 'Default'

steps:
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      $body = @{ 'ref' = 'refs/heads/main' }
      $headers = @{
        'Authorization' = "Bearer $($github_token)"
        'Accept' = 'application/vnd.github+json'
        'X-GitHub-Api-Version' = '2022-11-28'
      }
      Invoke-RestMethod -Uri 'https://api.github.com/repos/jeremykodekloud/KodeKloudCoffee/actions/workflows/main.yml/dispatches' -Method 'POST' -Headers $headers -Body ($body | ConvertTo-Json) -ContentType 'application/json'
  displayName: 'Send Update to GitHub to Trigger Build'

After committing these changes to your pipeline configuration and saving, run the pipeline manually. This action sends a dispatch request to GitHub, thus triggering the workflow for deploying the application to Azure.

The following image shows the GitHub Actions page where the workflow runs appear after the dispatch:

The image shows a GitHub Actions page displaying workflow runs for a repository, with details such as event, status, branch, and actor.

Triggering Deployment and Monitoring the Workflow

Return to Azure Pipelines and manually run the pipeline (ensure you select the branch: main). Once triggered, monitor the build process and check GitHub for the new workflow run initiated by Azure Pipelines. Click on the main.yml workflow in GitHub to see detailed logs and statuses:

The image shows a GitHub Actions page for a repository named "KodeKloudCoffee," displaying workflow runs for "Deploy to Azure" with various statuses and timestamps.

This workflow is designed to be triggered in three ways:

  1. A push to the main branch (i.e., any code update).
  2. A repository dispatch via the GitHub API.
  3. A manual workflow dispatch directly from GitHub.

Below is a sample configuration of the GitHub Actions workflow:

name: Deploy to Azure

on:
  push:
    branches: [ main ]
  repository_dispatch:
  workflow_dispatch:

env:
  AZURE_WEBAPP_NAME: kodekloudcoffee
  AZURE_WEBAPP_PACKAGE_PATH: '.'
  NODE_VERSION: '20.x'

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm test --if-present

Deployment Control

If you want to enforce a strict deployment policy, you can remove the workflow_dispatch and push triggers so that deployments only occur via a repository dispatch. This approach is ideal when a team lead must approve deployments manually.

The illustration below shows the Azure DevOps interface listing recent pipelines. Notice that the "KodeKloudCoffee" pipeline was manually triggered:

The image shows an Azure DevOps interface displaying a list of recently run pipelines, with one pipeline named "jeremykodekloud.KodeKloudCoffee" that was manually triggered and completed 3 minutes ago.

Conclusion

By integrating GitHub Actions with Azure Pipelines, you gain a flexible deployment workflow for your Node.js application on Azure. Deployments can be triggered automatically on code pushes, manually through the GitHub interface, or via an explicit dispatch from Azure DevOps—ideal for situations requiring a controlled approval process.

Thank you for reading this guide. For more details, explore further documentation on GitHub Actions and Azure Pipelines.

Watch Video

Watch video content

Previous
Understanding Code Coverage