4
votes

I have the following .github/workflows/ci.yml file for GitHub Actions (some code removed to make it easier to understand for this question):

name: CI
on:
  push:
  release:
    types: [published]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      # ...
  deploy-staging:
    runs-on: ubuntu-latest
    needs: test
    if: github.event_name == 'push' && github.ref == 'staging'
    steps:
      # ...

I went through the following steps:

  1. Make some commits on the develop branch, and push those changes.
  2. After build passes on GitHub Actions I did a fast forward merge from develop into staging.

I expected GitHub Actions to run both the test and deploy-staging jobs after item 2. But instead it just ran test again without running deploy-staging.

GitHub Actions Workflow Runs

As you can see above even after pushing to staging it still ran it on the develop branch instead of the staging branch. I'm kinda assuming this might be due to some weird behavior with fast forward merges. But GitHub obviously recognized that I pushed to staging as it offered to create a PR from that branch into master.

GitHub offering to create a PR for <code>staging</code>

So that makes me rethink my theory about why it's trying to run on develop instead of staging.

Why would this be happening? Is there anyway to fix this so merging into staging actually runs the workflow on staging as opposed to develop?

2
Did it actually run i.e. execute any of the steps for the deploy-staging job, on the development branch, or did it simply fail but did not run any steps? Github actions has a bug where it marks jobs which do not meet a condition as failed rather than as "Not run". That's why you need to specify exactly what happened. There are other ways to fix the issue you are having, but I need to know exactly what you experienced. - smac89

2 Answers

0
votes

${{ github.ref }} will be refs/heads/staging not just staging.

The best thing to do in these situations is simply to echo the variable values you want to check in a step before it:

    steps:
      - name: Check inputs
        run: |
          echo github.ref is: ${{ github.ref }}
          echo github.event_name is: ${{ github.event_name }}
-1
votes

My approach would be so separate the triggers and related jobs into different workflows.

So, to mimic your example, instead of a ci.yml I would have two files:

  • test.yml
  • deploy-staging.yml

In .github/workflows/test.yml:

name: Test
on: push

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      # ...

In .github/workflows/release-staging.yml:

name: Release Staging

on:
  push:
    branches:
      - staging

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    steps:
      # test steps ...
      # release ...

Admittedly this is annoying because the release doesn't run on the same test run as the test, but you want to make sure the tests all pass before deploying.

If you wanted to chain the test run workflow to run the deploy workflow I might change release-staging to use the Check suite event instead of push.