Deploy to App Service using GitHub Actions

Get started with GitHub Actions to automate your workflow and deploy to Azure App Service from GitHub.

Prerequisites

Workflow file overview

A workflow is defined by a YAML (.yml) file in the /.github/workflows/ path in your repository. This definition contains the various steps and parameters that make up the workflow.

The file has three sections:

Section Tasks
Authentication 1. Define a service principal or publish profile.
2. Create a GitHub secret.
Build 1. Set up the environment.
2. Build the web app.
Deploy 1. Deploy the web app.

Use the Deployment Center

You can quickly get started with GitHub Actions by using the App Service Deployment Center. This will automatically generate a workflow file based on your application stack and commit it to your GitHub repository in the correct directory.

  1. Navigate to your webapp in the Azure portal
  2. On the left side, click Deployment Center
  3. Under Continuous Deployment (CI / CD), select GitHub
  4. Next, select GitHub Actions
  5. Use the dropdowns to select your GitHub repository, branch, and application stack
    • If the selected branch is protected, you can still continue to add the workflow file. Be sure to review your branch protections before continuing.
  6. On the final screen, you can review your selections and preview the workflow file that will be committed to the repository. If the selections are correct, click Finish

This will commit the workflow file to the repository. The workflow to build and deploy your app will start immediately.

Set up a work manually

You can also deploy a workflow without using the Deployment Center. To do so, you will need to first generate deployment credentials.

Generate deployment credentials

The recommended way to authenticate with Azure App Services for GitHub Actions is with a publish profile. You can also authenticate with a service principal but the process requires more steps.

Save your publish profile credential or service principal as a GitHub secret to authenticate with Azure. You'll access the secret within your workflow.

A publish profile is an app-level credential. Set up your publish profile as a GitHub secret.

  1. Go to your app service in the Azure portal.

  2. On the Overview page, select Get Publish profile.

  3. Save the downloaded file. You'll use the contents of the file to create a GitHub secret.

Configure the GitHub secret

In GitHub, browse your repository, select Settings > Secrets > Add a new secret.

To use app-level credentials, paste the contents of the downloaded publish profile file into the secret's value field. Name the secret AZURE_WEBAPP_PUBLISH_PROFILE.

When you configure your GitHub workflow, you use the AZURE_WEBAPP_PUBLISH_PROFILE in the deploy Azure Web App action. For example:

- uses: azure/webapps-deploy@v2
  with:
    publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}

Set up the environment

Setting up the environment can be done using one of the setup actions.

Language Setup Action
.NET actions/setup-dotnet
ASP.NET actions/setup-dotnet
Java actions/setup-java
JavaScript actions/setup-node
Python actions/setup-python

The following examples show how to set up the environment for the different supported languages:

.NET

    - name: Setup Dotnet 3.3.x
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: '3.3.x'

ASP.NET

    - name: Install Nuget
      uses: nuget/setup-nuget@v1
      with:
        nuget-version: ${{ env.NUGET_VERSION}}

Java

    - name: Setup Java 1.8.x
      uses: actions/setup-java@v1
      with:
        # If your pom.xml <maven.compiler.source> version is not in 1.8.x,
        # change the Java version to match the version in pom.xml <maven.compiler.source>
        java-version: '1.8.x'

JavaScript

env:
  NODE_VERSION: '14.x'                # set this to the node version to use

jobs:
  build-and-deploy:
    name: Build and Deploy
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
    - name: Use Node.js ${{ env.NODE_VERSION }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ env.NODE_VERSION }}

Python

    - name: Setup Python 3.x 
      uses: actions/setup-python@v1
      with:
        python-version: 3.x

Build the web app

The process of building a web app and deploying to Azure App Service changes depending on the language.

The following examples show the part of the workflow that builds the web app, in different supported languages.

For all languages, you can set the web app root directory with working-directory.

.NET

The environment variable AZURE_WEBAPP_PACKAGE_PATH sets the path to your web app project.

- name: dotnet build and publish
  run: |
    dotnet restore
    dotnet build --configuration Release
    dotnet publish -c Release -o '${{ env.AZURE_WEBAPP_PACKAGE_PATH }}/myapp' 

ASP.NET

You can restore NuGet dependencies and run msbuild with run.

- name: NuGet to restore dependencies as well as project-specific tools that are specified in the project file
  run: nuget restore

- name: Add msbuild to PATH
  uses: microsoft/setup-msbuild@v1.0.0

- name: Run msbuild
  run: msbuild .\SampleWebApplication.sln

Java

- name: Build with Maven
  run: mvn package --file pom.xml

JavaScript

For Node.js, you can set working-directory or change for npm directory in pushd.

- name: npm install, build, and test
  run: |
    npm install
    npm run build --if-present
    npm run test --if-present
  working-directory: my-app-folder # set to the folder with your app if it is not the root directory

Python

- name: Install dependencies
  run: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt

Deploy to App Service

To deploy your code to an App Service app, use the azure/webapps-deploy@v2 action. This action has four parameters:

Parameter Explanation
app-name (Required) Name of the App Service app
publish-profile (Optional) Publish profile file contents with Web Deploy secrets
package (Optional) Path to package or folder. The path can include *.zip, *.war, *.jar, or a folder to deploy
slot-name (Optional) Enter an existing slot other than the production slot

.NET Core

Build and deploy a .NET Core app to Azure using an Azure publish profile. The publish-profile input references the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.

name: .NET Core CI

on: [push]

env:
  AZURE_WEBAPP_NAME: my-app-name    # set this to your application's name
  AZURE_WEBAPP_PACKAGE_PATH: '.'      # set this to the path to your web app project, defaults to the repository root
  DOTNET_VERSION: '3.1.x'           # set this to the dot net version to use

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # Checkout the repo
      - uses: actions/checkout@master
      
      # Setup .NET Core SDK
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: ${{ env.DOTNET_VERSION }} 
      
      # Run dotnet build and publish
      - name: dotnet build and publish
        run: |
          dotnet restore
          dotnet build --configuration Release
          dotnet publish -c Release -o '${{ env.AZURE_WEBAPP_PACKAGE_PATH }}/myapp' 
          
      # Deploy to Azure Web apps
      - name: 'Run Azure webapp deploy action using publish profile credentials'
        uses: azure/webapps-deploy@v2
        with: 
          app-name: ${{ env.AZURE_WEBAPP_NAME }} # Replace with your app name
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE  }} # Define secret variable in repository settings as per action documentation
          package: '${{ env.AZURE_WEBAPP_PACKAGE_PATH }}/myapp'

ASP.NET

Build and deploy an ASP.NET MVC app that uses NuGet and publish-profile for authentication.

name: Deploy ASP.NET MVC App deploy to Azure Web App

on: [push]

env:
  AZURE_WEBAPP_NAME: my-app    # set this to your application's name
  AZURE_WEBAPP_PACKAGE_PATH: '.'      # set this to the path to your web app project, defaults to the repository root
  NUGET_VERSION: '5.3.x'           # set this to the dot net version to use

jobs:
  build-and-deploy:
    runs-on: windows-latest
    steps:

    - uses: actions/checkout@master  
    
    - name: Install Nuget
      uses: nuget/setup-nuget@v1
      with:
        nuget-version: ${{ env.NUGET_VERSION}}
    - name: NuGet to restore dependencies as well as project-specific tools that are specified in the project file
      run: nuget restore
  
    - name: Add msbuild to PATH
      uses: microsoft/setup-msbuild@v1.0.0

    - name: Run MSBuild
      run: msbuild .\SampleWebApplication.sln
       
    - name: 'Run Azure webapp deploy action using publish profile credentials'
      uses: azure/webapps-deploy@v2
      with: 
        app-name: ${{ env.AZURE_WEBAPP_NAME }} # Replace with your app name
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE  }} # Define secret variable in repository settings as per action documentation
        package: '${{ env.AZURE_WEBAPP_PACKAGE_PATH }}/SampleWebApplication/'

Java

Build and deploy a Java Spring app to Azure using an Azure publish profile. The publish-profile input references the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.

name: Java CI with Maven

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: Build with Maven
      run: mvn -B package --file pom.xml
      working-directory: my-app-path
    - name: Azure WebApp
      uses: Azure/webapps-deploy@v2
      with:
        app-name: my-app-name
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: my/target/*.jar

To deploy a war instead of a jar, change the package value.

    - name: Azure WebApp
      uses: Azure/webapps-deploy@v2
      with:
        app-name: my-app-name
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: my/target/*.war

JavaScript

Build and deploy a Node.js app to Azure using the app's publish profile. The publish-profile input references the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.

# File: .github/workflows/workflow.yml
name: JavaScript CI

on: [push]

env:
  AZURE_WEBAPP_NAME: my-app-name   # set this to your application's name
  AZURE_WEBAPP_PACKAGE_PATH: 'my-app-path'      # set this to the path to your web app project, defaults to the repository root
  NODE_VERSION: '14.x'                # set this to the node version to use

jobs:
  build-and-deploy:
    name: Build and Deploy
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
    - name: Use Node.js ${{ env.NODE_VERSION }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ env.NODE_VERSION }}
    - name: npm install, build, and test
      run: |
        # Build and test the project, then
        # deploy to Azure Web App.
        npm install
        npm run build --if-present
        npm run test --if-present
      working-directory: my-app-path
    - name: 'Deploy to Azure WebApp'
      uses: azure/webapps-deploy@v2
      with: 
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

Python

Build and deploy a Python app to Azure using the app's publish profile. Note how the publish-profile input references the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.

name: Python CI

on:
  [push]

env:
  AZURE_WEBAPP_NAME: my-web-app # set this to your application's name
  AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up Python 3.x
      uses: actions/setup-python@v2
      with:
        python-version: 3.x
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
    - name: Building web app
      uses: azure/appservice-build@v2
    - name: Deploy web App using GH Action azure/webapps-deploy
      uses: azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

Next steps

You can find our set of Actions grouped into different repositories on GitHub, each one containing documentation and examples to help you use GitHub for CI/CD and deploy your apps to Azure.