Search code examples
gitgithubgithub-actions

Expected behaviour of if-then-else condition in bash while checking for any changes in git is opposite when written in a github actions workflow


If you have a commit statement when there are no changes then it will return an exit code of 1 which will lead to the failure of a GitHub workflow.

As a workaround, I tried to modify the solution from this SO post as well as this answer which is basically to use -

git diff-index --quiet HEAD

On my local bash, it works as expected. When I run echo "$?", the output of 1 or 0 corresponds to what I expect.

Based off of that and this documentation on setting up environment variable in GitHub workflows, I have the following in my workflow file -

- name: Check for changes # This blocks behaviour is just the opposite
  run: |
        if git diff-index --quiet HEAD; then
            echo "changes_exist=true" >> $GITHUB_ENV
        else
            echo "changes_exist=false" >> $GITHUB_ENV
        fi

- name: Debug changes
  run: |
        echo "${{ env.changes_exist }}"

- name: Commit Datasets # It is true whenever there are NO changes and false whenever there are changes, so whenever there are changes it is just skipped due to the "if" condition
  if: env.changes_exist == 'true'
  run: |
        git commit -m "updating datasets"
        git push

However, whenever there are changes to be committed or tracked, the environment variable changes_exist is false and vice-versa.

This is just the opposite of what I am expecting.

As a workaround till I figure this out I use the following which works perfectly in the worker -

git diff-index --quiet HEAD || git commit -m "updating datasets"

Any idea why the above works whereas using if - then - else the behavior opposite to what it is supposed to be?


Solution

  • You are referencing this answer which shows:

    git diff-index --quiet HEAD || git commit -m 'bla'
    

    Which means, there are changes if ! git diff: the commit part is executed only if the git diff part is false, fails, different from 0.
    It could be written as:

    if ! git diff-index --quiet HEAD; then git commit -m 'bla'; fi
    

    In other words, in your case:

    # Equivalent approach using an if statement with negation
    if ! git diff-index --quiet HEAD; then
        echo "changes_exist=true" >> $GITHUB_ENV
    else
        echo "changes_exist=false" >> $GITHUB_ENV
    fi