Suppose you have a GitHub Action workflow that does some computation and a possible outcome is that file comes into existence. How do you run a follow-up step based on whether a file was created?

tl;dr


- name: Is file created?
  if: ${{ hashFiles('test.txt') != '' }}
  run: echo "File exists"

The "wrong" way

Technically, there's no wrong way, but an alternative might be to rely on exit codes. This would work.


- name: Check if file was created
  run: |
      if [ -f test.txt ]; then
          echo "File exists"
          exit 1
      else
          echo "File does not exist"
      fi
- name: Did the last step fail?
  if: ${{ failure() }}
  run: echo "Last step failed, so file must have maybe been created"

The problem with this is that not only leaves a red ❌ in the workflow logs, but it could also lead to false positives. For example, if the step that might create a file is non-trivial, you don't want to lump the creation of the file with a possible bug in your code.

A use case

What I needed this for was a complex script that was executed to find broken links in a web app. If there were broken links, only then do I want to file a new issue about that. If the script failed for some reason, you want to know that and work on fixing whatever its bug might be. It looked like this:


  - name: Run broken link check
    run: |
      script/check-links.js broken_links.md

  - name: Create issue from file
    if: ${{ hashFiles('broken_links.md') != '' }}
    uses: peter-evans/create-issue-from-file@433e51abf769039ee20ba1293a088ca19d573b7f
    with:
      token: ${{ env.GITHUB_TOKEN }}
      title: More than one zero broken links found
      content-filepath: ./broken_links.md
      repository: ${{ env.REPORT_REPOSITORY }}
      labels: ${{ env.REPORT_LABEL }}

That script/check-links.js script is given an argument which is the name of the file to write to if it did indeed find any broken links. If there were any, it generates a snippet of Markdown about them which is the body of filed new issue.

Demo

To be confident this works, I created a dummy workflow in a test repo to test. It looks like this: .github/workflows/maybe-fail.yml

Comments

eliezer cazares

How to do it for file contains?
In this case, I run automated tests, if the framework fails, I continue the workflow with continue-on-error.

I am trying to send notifications to Slack only on failure.
I can do it on all cases currently, but I want to send the notification only if test reports contain the word Failed at least once.

Thanks

Peter Bengtsson

In the sample code of this blog post it uses:

  script/check-links.js broken_links.md

And that script will create the file if and only if there *are* broken links.
So you can write something similar yourself.
E.g.

    script/did-it-fail.js it-failed.log

But another option is simpler. If the tests failed, that step of the Actions workflow will exit non-zero.
Example https://github.com/github/docs/blob/44d96b002ba8aeb32a33a8b1d31ef7919b09bd5e/.github/workflows/orphaned-assets-check.yml#L71-L78

Your email will never ever be published.

Previous:
Automatically 'npm install' April 6, 2023 Node, JavaScript
Next:
Be careful with Date.toLocaleDateString() in JavaScript May 8, 2023 Node, JavaScript, macOS
Related by category:
Useful GitHub.com trick I learned today: l March 19, 2025 GitHub
How I built an index of my blog posts on my GitHub profile page December 13, 2024 GitHub
Search GitHub issues by title, only May 31, 2024 GitHub
Programmatically control the matrix in a GitHub Action workflow November 30, 2022 GitHub
Related by keyword:
How to install Python Poetry in GitHub Actions in MUCH faster way July 27, 2021 Python
How to know if a PR has auto-merge enabled in a GitHub Action workflow May 24, 2022 GitHub