Search code examples
yamldevopsgithub-actionsjobsskip

How can I easily make Github Actions skip subsequent jobs execution on certain condition?


I have an YAML Github Action script, which consists on three jobs. The nightly script should check if there are any user commits (which are not coming from an automatic jobs) and then perform nightly release build and deploy the build to the testing environment.

I am struggling with using one single point where I could skip the execution of the whole second and the third jobs if there are no recent commits in the repositories others than autocommits.

As far as I understand, I should either fail the script to skip any further actions or set the if condition to every step of every job I have, which doesn't look concise.

I tried to put the if condition on the job itself, but it does not work. The job executes even if the if condition value is false. Is there any better or elegant solution other to fail the job if repository is stale?

name: Nightly script

on:
  workflow_dispatch:
  schedule:
    - cron: "0 1 * * *"  

jobs:
  check-if-there-are-commits:
    runs-on: ubuntu-latest
    outputs:
      alive: ${{ steps.check.outputs.alive }}
    steps:
      ### Activity check
      ### uses GitHub API to check last non-automagic commit in repository
      ### if it's older than a week, all other steps are skipped
      - name: Activity check
        id: "check"
        run: |
          curl -sL  -H "Authorization: bearer ${{secrets.REPO_BEARER_TOKEN}}" https://api.github.com/repos/$GITHUB_REPOSITORY/commits?sha=dev | jq -r '[.[] | select(.author.type != "Bot")][0]' > $HOME/commit.json
          echo $GITHUB_REPOSITORY
          echo $HOME
          echo $(cat $HOME/commit.json)

          date="$(jq -r '.commit.author.date' $HOME/commit.json)"
          echo "Date: $date"
          timestamp=$(date --utc -d "$date" +%s)
          echo "Timestamp: $timestamp"
          echo "Current date: $(date --utc +%s)"
          echo "Difference between the current date and time of the last commit: $(( ( $(date --utc +%s) - $timestamp ) ))"
          days=$(( ( $(date --utc +%s) - $timestamp ) / 86400 ))
          echo "Days: $days"

          alive=0

          echo "Date: $date"
          echo "timestamp: $timestamp"
          echo "days: $days"

          if [ $days -lt 1 ]; then
            echo Repository active : $days days
            alive=1
          else
            echo "[WARNING] Repository not updated : event<${{ github.event_name }}> not allowed to modify stale repository"
          fi
          echo "Alive? $alive"
          if [ $alive -eq 1 ]; then
            echo "REPO_ALIVE=true" >> $GITHUB_ENV
            echo "::set-output name=alive::true"
          else
            echo "REPO_ALIVE=false" >> $GITHUB_ENV
            echo "::set-output name=alive::false"
          fi
          echo "REPO_ACTIVITY=$days" >> $
          echo "::set-output name=days::$days"

  release:
    needs: check-if-there-are-commits
    if: ${{needs.check-if-there-are-commits.outputs.alive}} == 'true'
    runs-on: ubuntu-latest
    steps:
      - name: "Verify"
        run: |
          echo "Alive? ${{needs.check-if-there-are-commits.outputs.alive}}"
          alive=${{needs.check-if-there-are-commits.outputs.alive}}
          if [ $alive == "true" ]; then
            echo "Alive"
          else
            echo "Dead"
            exit 1;
          fi

      - name: Next step
        if: ${{needs.check-if-there-are-commits.outputs.alive}} == 'true'
        run: |
          ...

      #- other steps...

  deploy:
    needs: [check-if-there-are-commits, release]
    if: ${{needs.check-if-there-are-commits.outputs.alive}} == 'true'
    runs-on: ubuntu-latest
    steps:
      #- other steps 

Solution

  • According to the documentation:

    When you use expressions in an if conditional, you may omit the expression syntax (${{ }}) because GitHub automatically evaluates the if conditional as an expression, unless the expression contains any operators. If the expression contains any operators, the expression must be contained within ${{ }} to explicitly mark it for evaluation.

    That means your if must be defined as:

    if: ${{ needs.check-if-there-are-commits.outputs.alive == 'true' }}