Add and Commit action
Add and Commit is the second (of three!) actions that can be used to push your changes to a repo during a GitHub Actions workflow.
What does it do?
Much like the last spotlight post, today’s action is focused on adding and committing files to a repo. The README does a good job explaining how it’s different to git-auto-commit-action
:
This is heavily inspired by git-auto-commit-action (by Stefan Zweifel): that action automatically detects changed files and commits them. While this is useful for most situations, this doesn't commit untracked files and can sometimes commit unintended changes (such as package-lock.json or similar, that may have happened during previous steps).
It’s also evolved from git-auto-commit
and supports pulling changes if required before a push, removing files with git rm
and makes features such as signoff
an input rather than making you specify --signoff
as a commit_option
How does it work?
add-and-commit
is implemented in TypeScript rather than bash
and is a single 388 line file named main.ts. It uses simple-git to interact with the underlying git
repo and provides a compiled version of the action that includes all dependencies.
main.ts
itself is reasonable easy to follow:
- Add any files that match the pattern provided in
add
- Remove any files if
remove
was provided - If there are no staged files, the action stops execution
- Otherwise it populates
.git/config
using theauthor_email
andauthor_username
provided - As GitHub Actions does a shallow clone, the action then runs
git fetch
to get all branches - This isn’t documented in the README, but the action then switches to a branch with the name specified in the
branch
input. This defaults to the branch that triggered the workflow run - Then it ensures that the branch is up to date. You can choose
NO-PULL
,--no-rebase
,--no-ff
or--rebase
depending on which strategy you prefer - As the working branch may have changed, it then re-adds any changed files
- Before creating a commit using the
author_name
provided and the--signoff
flag if thesignoff
input was set - If the
tag
input was provided, the action also creates a tag named after thetag
input - If the
push
input was set to true, it runsgit push origin <branch> --set-upstream
- If the
push
input provided is a string it runsgit push <input string>
- Finally, if a tag was created it runs
git push --tags
. This part is interesting as it deletes a remote tag and re-pushes when an error is encountered
There are a couple of other interesting things in the action to dig into.
One of the big questions in the Actions world is how to parse structured input. add-and-commit
attempts to parse inputs that can be arrays as both JSON and YAML before falling back to treating it as a simple string.
The action also handles setting defaults in the code rather than using the default
field in action.yml
like git-auto-commit-action
does.
Common use cases
Automatically committing changed files can be useful in a couple of situations. The example shown in the docs is to run eslint --fix
to fix code styling before pushing the changes back to the repo:
yaml
name: Lint source codeon: pushjobs:run:name: Lint with ESLintruns-on: ubuntu-lateststeps:- name: Checkout repouses: actions/checkout@v2- name: Set up Node.jsuses: actions/setup-node@v1with:node-version: 12.x- name: Install dependenciesrun: npm install- name: Update source coderun: eslint "src/**" --fix- name: Commit changesuses: EndBug/add-and-commit@v7with:author_name: Your Namemessage: "Your commit message"add: "*.js"
Another idea is to make sure that your lib
folder for your action (like the one used in add-and-commit
) is always compiled as expected on push:
yaml
name: Automatic Compileon: pushjobs:run:name: Compileruns-on: ubuntu-lateststeps:- name: Checkout repouses: actions/checkout@v2- name: Set up Node.jsuses: actions/setup-node@v1with:node-version: 12.x- name: Install dependenciesrun: npm install- name: Compilerun: npx ncc -o lib- name: Commit changesuses: EndBug/add-and-commit@v7with:author_name: Your Namemessage: "Your commit message"add: "lib"