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
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
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