Background

I have an Azure Static Website that is built from a GitHub hosted repo using the default Action Workflow automation created by Azure when setting up the static site.

A really nice feature of this configuration is that when a PR is created in GitHub a test static website environment site is built in Azure to review the changes. When the PR is closed the test environment site is deleted.

This functionality is working fine for manually created PRs irrespective of whether the PR is manually merged and closed, or completed using the Github auto-merged feature.

Issue

The problem occurs if Github Dependabot and Actions based automation is used.

If a PR is created by Dependabot and manually merged, all the workflows trigger correctly to deploy the updated site and delete the test environment, as expected.

However, if I use a version of the Github documented ‘approve a Dependabot pull request’ action workflow to approve any Dependabot created PRs, as follows

name: Dependabot auto-merge
on: pull_request

permissions:
  pull-requests: write
  contents: write

jobs:
  dependabot:
    runs-on: ubuntu-latest
    if: ${{ github.actor == 'dependabot[bot]' }}
    steps:
      - name: Dependabot metadata
        id: metadata
        uses: dependabot/fetch-metadata@v1.1.1
        with:
          github-token: "${{ secrets.GITHUB_TOKEN }}"
      - name: Enable auto-merge for Dependabot PRs
        if: ${{steps.metadata.outputs.update-type == 'version-update:semver-patch'}}
        run: | 
          gh pr review --approve "$PR_URL"
          gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

it is not working as expected. What is happening is the PR is merged, but other workflows are not triggered, so the site is not redeployed off main and the test environment is not deleted, so I soon reach the limit for the maximum number of test environments I can have, so future PRs fail through lack of available Azure environment slots.

Analysis

The issue was the use of the GITHUB_TOKEN, the automatically generated action session token. I had not considered that GitHub Actions triggers do not happen when an operation is performed with the GITHUB_TOKEN, as documented by Github

This is still true then the action is triggered by the gh command line tool, as in the above example. It is the use of the GITHUB_TOKEN that is the key factor.

Thanks to Rob Bos for reminding of this constraint, and also letting me know I was not the only one to have been recently caught out by this, as can be seen in William Brawner’s recent blog post.

Solution

Armed with this information and using Rob’s blog post on using Github Apps for authentication, I performed the following steps:

  1. Created a Github App with the following permissions

    • Repo - Contents: Read & Write
    • Repo - Metadata: Read-only (automatically selected)
    • Repo - Pull Requests: Read & Write
  2. Created secrets (Settings > Secrets & Variables > Dependabot) to provide the Dependabot triggered workflow with the App ID and Key need to get a short-lived token for the workflow to use.

    Remember Dependabot cannot access Actions secrets or variables, it has its own set of secrets to minimise any potential secret leakage

  3. Updated the workflow to use a token generated from a GitHub App

name: Dependabot auto-merge
on: pull_request

permissions:
  pull-requests: write
  contents: write

jobs:
  dependabot:
    runs-on: ubuntu-latest
    if: ${{ github.actor == 'dependabot[bot]' }}
    steps:
      - name: Get Token
        id: get_workflow_token
        uses: peter-murray/workflow-application-token-action@v3
        with:
          application_id: ${{ secrets.GH_APP_ID }}
          application_private_key: ${{ secrets.GH_APP_KEY }}
    
      - name: Dependabot metadata
        id: metadata
        uses: dependabot/fetch-metadata@v1.1.1
        with:
          github-token: "${{ steps.get_workflow_token.outputs.token }}"
      - name: Enable auto-merge for Dependabot PRs
        if: ${{steps.metadata.outputs.update-type == 'version-update:semver-patch'}}
        run: | 
          gh pr review --approve "$PR_URL"
          gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GITHUB_TOKEN: ${{ steps.get_workflow_token.outputs.token }}

Once all these changes were made the workflows operated as expected. The test environment was deleted and the site redeployed off main as soon as the PR was closed, whether merged or not.

So an interesting little learning experience. I hope the steps in this post helps others who have been caught out by this issue.