DEV Community

loading...
Cover image for Github Actions: deploy to multiple environments from single workflow

Github Actions: deploy to multiple environments from single workflow

maxivanov profile image Max Ivanov Originally published at maxivanov.io ・2 min read

Github Actions is awesome and you can automate so much with it. One lacking feature though is support for code reuse in workflow yaml files.

One particular use case where it would be useful is continuous deployment workflow that publishes latest code to the remote system. Deployment target is dictated by the git branch that receives the update.

E.g. pushes to dev branch should deploy to the staging environment and pushes to master should publish the code to prod.

Here's a workaround to deploy to multiple environments from a single workflow yaml file.

Example workflow file

As an example, I'll take a Github Action that deploys an Azure Function app.

In order to publish code to Azure, it expects 2 variables: function app name and publish profile (deployment key).

Each environment has its own publish profile defined in an individual Github Repository Secret.

github repository secrets

Below is the relevant parts of the workflow yaml. You can see it in full here.

First, we want to trigger the workflow only on branches that should be deployed on commit:

on:
  push:
    branches:
      - dev
      - master
Enter fullscreen mode Exit fullscreen mode

Next, in the very beginning of the workflow definition, we add conditional steps to set correct environment variables, depending on the current branch:

  • Function app name
  • Publish profile secret name
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Set env vars (dev)
        if: endsWith(github.ref, '/dev')
        run: |
          echo "AZURE_FUNCTIONAPP_NAME=azfunccdgh-dev-function-app" >> $GITHUB_ENV
          echo "PUBLISH_PROFILE_VAR_NAME=AZURE_FUNCTIONAPP_PUBLISH_PROFILE_DEV" >> $GITHUB_ENV
      - name: Set env vars (prod)
        if: endsWith(github.ref, '/master')
        run: |
          echo "AZURE_FUNCTIONAPP_NAME=azfunccdgh-prod-function-app" >> $GITHUB_ENV
          echo "PUBLISH_PROFILE_VAR_NAME=AZURE_FUNCTIONAPP_PUBLISH_PROFILE_PROD" >> $GITHUB_ENV
Enter fullscreen mode Exit fullscreen mode

Following would be the steps that are shared between environments. These are not relevant to the multi-env deployment and are not listed here. In my case it's checking out the code, caching, installing dependencies and building the project.

Finally, the deployment step uses the environment variables set above to publish the code to the correct target environment.

      - name: Run Azure Functions action
        uses: Azure/functions-action@v1
        id: fa
        with:
          app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
          package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
          publish-profile: ${{ secrets[env.PUBLISH_PROFILE_VAR_NAME] }}
          respect-funcignore: true
Enter fullscreen mode Exit fullscreen mode

References

...

Still, this is a hack I'm not very happy about but I feel like it's better than having copies of the entire workflow file per environment.

If you know a better way to deploy to multiple environments from Github Actions, let me know!

If you like this type of content you can follow me on Twitter for the latest updates.

Discussion (0)

pic
Editor guide