February’s Action Spotlight theme is all about committing changes that you’ve made back to your GitHub repo, starting with stefanzweifel/git-auto-commit-action.
What does it do?
The GitHub Action for committing files for the 80% use case.
By default, any changes made to the workspace when running a GitHub Action are discarded when the job ends. This means that whilst Actions is great for running tools such as
eslint to check your code style, if you wanted to use
eslint --fix to automatically fix any violations and push those changes to a pull request you’re out of luck.
Until now, that is.
git-auto-commit-action will automatically add, commit and push any created or changed files back to your repo automatically.
How does it work?
entrypoint.sh script. This seems odd as shell scripts are usually run using the Docker runtime.
index.js, things become a little clearer.
git-auto-commit-action uses a shim to trick Actions into running a shell script directly on the runner machine rather than building a Docker container. This works as the runner machines have
bash preinstalled (here’s the list of software for Ubuntu 20.04).
The bash script is well architected, with well named functions and good debugging information. It also uses
set -eu to make the script very brittle (this is a good thing!) ensuring that it fails fast. The
-e flag will automatically stop execution of the script if any command executed fails, and the
-u flag treats missing variables as an error when trying to use them. These two options combined mean that if any variables are missing, the script will exit instantly.
_main function is our entrypoint into the script. The first thing it does is change to the specified directory. By default the
repository input is
. which means that the script will run in the current directory, which is the repository root.
Any action inputs are available as variables prefixed with
INPUT_in GitHub Actions
Next, it checks if there have been any changes made. If not, the
changes_detected output is set to false and the script exits. You can disable this check by setting the
skip_dirty_check input to
If changes were detected,
changes_detected is set to true and the real work starts.
In order, the following steps are executed:
- Check out the specified branch (defaults to
- Add required files. By default all files will be added with
.. You can specify a pattern such as
- Create a commit containing the changes. The default identity will commit the changes as GitHub Actions, with the change author being set to the person that triggered the workflow run. You can also specify
--signoffto add a trailer.
- If you provide a
tagging_messagea tag will be created pointing to the commit that was just created.
- Finally, the commit (and possibly a tag) will be pushed to GitHub. You can specify
push_optionsto add additional flags to
The default behaviour is the most useful to the majority of people, but having the configuration options available are useful. Imagine setting
--amend --no-edit and
--force to automatically fix code style issues in the same commit rather than adding a new one, or passing
repository: src to only commit changes in the
Writing the action in bash allows
stefanzweifel to make the most of the
index.js shim which adds support for Windows and MacOS runners (in addition to making the action run fast) as Windows and MacOS don’t support Docker actions, but they do support Bash. The combination of
index.js provides portability and speed without needing to rebuild the
git command line tooling used.