If, elseif or else in GitHub Actions

One of the lesser-explored yet incredibly powerful features of GitHub Actions is its support for conditional expressions. In this blog post, we’ll dive into the world of conditional expressions, specifically focusing on the ‘if,’ ‘elseif,’ and ‘else’ expressions, and explore how they can be leveraged to create more dynamic and efficient workflows. I did write a similar blog post previous for Azure DevOps, which is very popular – feel free to check it out also: If, elseif or else in Azure DevOps Pipelines

At its core, a conditional expression is a logical statement that evaluates whether a particular condition is met. In the context of GitHub Actions, these expressions allow us to control the execution of jobs and steps within our workflows based on specific criteria. This capability opens up a realm of possibilities, from running steps only when certain conditions are satisfied to tailoring workflows for different branches or pull requests.

Please note: While GitHub Actions natively supports the if key, it does not have built-in support for else if or else. However, you can modify the context to create more complex conditional logic. Contexts are variables that hold information about the current environment, such as the branch name or the commit hash. You can use contexts in combination with the if statement to create more advanced workflows. The syntax for contexts is ${{ <context> }} .

A basic if, elseif or else workflow

Lets start off with a basic workflow, the below will echo out the event type, in my example I am going to echo This is a push event

name: Basic workflow

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: What is the event?
      run: |
        if [ ${{ github.event_name }} == 'pull_request' ]; then
          echo "This is a pull request event"
        elif [ ${{ github.event_name }} == 'push' ]; then
          echo "This is a push event"
        else
          echo "This is an unknown event"
        fi

Reviewing the above in GitHub, we can see it gave the appropriate echo response:

View the full action log in GitHub

GitHub workflow yaml

Integrating further..

The below is two jobs:

  • determine-environment : if , elseif, else statement – to determine which environment from production, staging or test
  • deploy-environment : runs the case statement to determine which environment to run the echo for (can be used to run various scripts etc, this is just an example to show the use case of this)

determine-environment job

This job uses a shell script to determine the environment of the deployment based on the value of the github.event_name context variable. If the event is a push event, the environment is set to production. If the event is a pull_request event, the environment is set to staging Otherwise, the environment is set to test. The environment is then outputted to the $GITHUB_OUTPUT file.

An output of the environment is captured using selected-stage output

  determine-environment:
    runs-on: ubuntu-latest

    steps:
      - name: Select environment
        id: select-environment
        run: |
          if [ "${{ github.event_name }}" == "push" ]; then
            echo "production"
            echo "selected-stage=production" >> "$GITHUB_OUTPUT"
          elif [ "${{ github.event_name }}" == "pull_request" ]; then
            echo "staging"
            echo "selected-stage=staging" >> "$GITHUB_OUTPUT"
          else
            echo "test"
            echo "selected-stage=test" >> "$GITHUB_OUTPUT"
          fi

    outputs:
      selected-stage: ${{ steps.select-environment.outputs.selected-environment }}

deploy-environment job

Each step uses the if statement to determine whether to execute the code block based on the value of ${{ needs.determine-environment.outputs.selected-environment }}.

  • If the value is production, the first step is executed and the message “Deploying to production environment…” is outputted.
  • If the value is staging, the second step is executed and the message “Deploying to staging environment…” is outputted.
  • If the value is test, the third step is executed and the message “Deploying to test environment…” is outputted.
  deploy-environment:
    needs: determine-environment
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Run Production
        if: ${{ needs.determine-environment.outputs.selected-stage == 'production' }}
        run: echo "Deploying to production environment..."

      - name: Run Staging
        if: ${{ needs.determine-environment.outputs.selected-stage == 'staging' }}
        run: echo "Deploying to staging environment..."

      - name: Run Test
        if: ${{ needs.determine-environment.outputs.selected-stage == 'test' }}
        run: echo "Deploying to test environment..."

Lets see an example output:

View the full action log in GitHub

GitHub workflow yaml

Removing the multiple ifs…

Lets look at a slightly more complex pipeline – using the above with a case statement. Cases are used to execute different code blocks based on the value of a variable, often used in combination with the if statement to create more complex conditional logic.

deploy-environment job

The Deploy to environment step uses a case statement to display a deployment message based on the value of the selected-environment output from the determine-environment job.

In this example, the case statement is used to execute different code blocks based on the value of ${{ needs.determine-environment.outputs.selected-environment }}. If the value is production, the deployment message is displayed. If the value is staging, the deployment message is displayed. If the value is anything else, the deployment message is displayed.

  deploy-environment:
    needs: determine-environment
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Deploy to environment
        run: |
          case "${{ needs.determine-environment.outputs.selected-stage }}" in
            production)
              echo "Deploying to production environment..."
              ;;
            staging)
              echo "Deploying to staging environment..."
              ;;
            *)
              echo "Deploying to unknown environment..."
              ;;
          esac

Running the above, an example output:

View the full action log in GitHub

GitHub workflow yaml

Lets finish up

We’ve learned how to use if, elseif, and else statements in GitHub Actions to create more complex conditional logic. While GitHub Actions natively supports the if key, it does not have built-in support for elseif or else. However, we can modify the context to create more advanced workflows.

We’ve seen how to use contexts, which are variables that hold information about the current environment, such as the branch name or the commit hash. We can use contexts in combination with the if statement to create more advanced workflows. The syntax for contexts is ${{ <context> }}.

We’ve also seen how to use the needs keyword to specify dependencies between jobs. By using needs, we can ensure that a job only runs after its dependencies have completed successfully.

Whether you’re deploying code to different environments or running tests on different platforms, using if, elseif, and else statements in GitHub Actions can help you create more complex workflows that fit your specific needs. By automating the conditional logic, we can save time and reduce the risk of errors.

Thank you for following along with this blog post. I hope you found it helpful and informative. Please reach out further with any queries etc!

Leave a Reply