I was recently working with some software that could push a
zip archive of content to a Git repository. However, what I really wanted was for the contents of the archive to be pushed to the repository. So I created a GitHub Action to do that for me. I’ve covered the format of GitHub Actions before. But to recap:
- name is what gets displayed in the actions list.
- on sets the triggers:
- push and pull trigger the script on push and pull requests. If you don’t specify branches, they default to main.
- paths specifies the paths to match. In this case, the script will trigger when a
zipfile is pushed.
- worklflow_dispatch enables you to manually trigger the script from the actions list.
- jobs defines one or more named tasks, in this example unzip.
- runs-on specifies the VM environment. If you can use Ubuntu, it’s the cheapest option with hosted runners.
- steps can be used to invoke actions such as checkout (which fetches a copy of the repository to the VM) and to execute shell commands with name: run.
- run with a pipe character ( | ) executes a multi-line script. Without it, a single line is executed.
And here’s the action I created:
name: extract a zip file on: push: paths: - 'uploads/**.zip' workflow_dispatch: jobs: unzip: runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v2 - name: run: | rm -r uploads/extracted filename=$(basename -s .zip *.zip) unzip *.zip rm *.zip mv $filename temp mv temp/out/* . rm -r temp git config --local user.email "email@example.com" git config --local user.name "github-actions" git add . git commit -m "unzip" git push origin main
The script is written for the Linux command line. Let’s break it down.
rm -r css
The idea here is that the contents of the zip file should replace what is already in that particular folder of the repository. You might want to call the folder
uploads. The checkout action has already been run, but it’s a good idea to clear out any known folders. The
-r tag makes the action recursive.
filename=$(basename -s .zip *.zip) unzip *.zip rm .zip mv $filename temp
This script assumes that we don’t know the name of the
zip file, but that there is only one file. It will determine the name, unzip the file to the root, remove the
zip file and rename the folder containing the zip to
mv temp/out/ . rm -r temp
In this example, the contents of the
zip file are two folders deep (in the
out folder). This moves the contents from the nested folder to the root, and then removes the
temp folder and its contents (the empty
out folder). The dot (
.) represents the current working directory (where the repo was checked out on the VM).
git config user.name "firstname.lastname@example.org" git config --local user.name "github-actions" git add . git commit -m "unzip" git push origin main
This part of the script pushes the changes back to the repository.
Image: Detail from The Unarchiver zip file icon. I looked for an appropriate unzip image with a Creative Commons license, but the results were not safe for work.