Github action check if a file already exists
Asked Answered
A

4

18

I have the following git action which allows me to download an image.

I have to make sure if the file already exists to skip the "Commit file" and the "Push changes"

How can I check if the file already exists if it already exists nothing is done.

on: 
  workflow_dispatch:
  
name: Scrape File
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        name: Check out current commit
     
      - name: Url
        run: |
         URL=$(node ./action.js)
         echo $URL
         echo "URL=$URL" >> $GITHUB_ENV
      
      - uses: suisei-cn/actions-download-file@v1
        id: downloadfile
        name: Download the file
        with:
          url: ${{ env.URL }}
          target: assets/
      - run: ls -l 'assets/'
          
      - name: Commit files
        run: |
         git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
         git config --local user.name "github-actions[bot]"
         git add .
         git commit -m "Add changes" -a
         
      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
         github_token: ${{ secrets.GITHUB_TOKEN }}
         branch: ${{ github.ref }}
Abbe answered 3/3, 2022 at 11:14 Comment(0)
E
17

You can use Github Actions built-in hashFiles function for this. From the docs:

Returns a single hash for the set of files that matches the path pattern. You can provide a single path pattern or multiple path patterns separated by commas. (...) If the path pattern does not match any files, this returns an empty string.

See docs for details: docs.github.com

So you can do like this:

  - name: Commit files
    if: ${{ hashFiles('assets/') != '' }}
    run: |
     git config ...

This won't work for checking directories though, as hashFiles will return empty string for empty directories.

Credits for the solution goes to Peter Bengtsson's blog: peterbe.com/plog

Eisteddfod answered 11/9, 2023 at 12:31 Comment(1)
Just noting this does not work on the job level.. I had to run a step to store the hash as a job output, then check that output in the following job's if:Turne
L
12

There are a few options here - you can go directly with bash and do something like this:

if test -f "$FILE"; then
    #file exists
fi

or use one of the existing actions like this:

- name: Check file existence
  id: check_files
  uses: andstor/file-existence-action@v1
  with:
    files: "assets/${{ env.URL }}"

- name: File exists
  if: steps.check_files.outputs.files_exists == 'true'
  run: echo "It exists !"
Libna answered 3/3, 2022 at 11:51 Comment(2)
The problem is that $ {{env.URL}} is a url like: https: //name.com / .. etc ../ nameFile.ext The name of the file saved in the assets folder is instead nameFile.extAbbe
Than you just need to adapt it to your needs and provide local file checkLibna
E
1

WARNING: Linux (and maybe MacOS) only solution ahead!

I was dealing with a very similar situation some time earlier and developed a method to not just check for added files, but also will be useful if you wanted to check for modified or deleted files or directories as well.


Warning:

This solution works only if the file is added/modified/deleted in git repository.


Introduction:

The command git status --short will return list of untracked, , deleted and modified files. For example:-

 D deleted_foo
 M modified_foo
?? untracked_dir_foo/
?? untracked_file_foo
A  tracked_n_added_foo

Note that we run the same command as git status -s.

Understanding `git status -s` output:

When you read the output, you will see some lines in this form:

** filename
** dirname/

Note that here ** represent the first word of the line (ones like D, ?? etc.).

Here is a summary of all ** in the lines:

** Meaning
D File/dir has been deleted.
M File/dir has been modified.
?? File/dir has been added but not tracked using git add [FILENAME].
A File/dir has been added and also tracked using git add [FILENAME].

NOTE: Take care of the spaces! Using, for example, M instead of M in the following solution will not work as expected!


Solution:

Shell part of solution:

We can grep the output of git status -s to check whether a file/dir was added/modified/deleted.

The shell part of the solution goes like this:

if git status -s | grep -x "** [FILENAME]"; then
  # Do whatever you wanna on match
else
  # Do whatever you wanna on no-match
fi

Note: Get desired ** from the table above and replace [FILENAME] with filename.

For example, to check whether a file named foo was modified, use:

git status -s | grep -x " M foo"

Explanation: We use git status -s to get the output and pipe the output to grep. We also use command line option -x with grep so as to match whole line.

Workflow part of solution:

A very simple solution will go like this:

...
- name: Check for file
  id: file_check
  run: |
    if git status -s | grep -x "** [FILENAME]"; then
      echo "check_result=true" >> $GITHUB_OUTPUT
    else
      echo "check_result=false" >> $GITHUB_OUTPUT
    fi
...
- name: Run dependent step
  if: steps.file_check.outputs.check_result == 'true'
  run: |
    # Do whatever you wanna do on file found to be
    # added/modified/deleted, based on what you set '**' to
...
Erogenous answered 25/1, 2023 at 10:39 Comment(0)
A
1
if [ -d "directory"]; then echo dir exists && echo ok; else echo no dir; fi
Appointee answered 15/5, 2023 at 7:48 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.