Why a function for three commands?
When a site deploys itself from GitHub, every push starts a workflow: GitHub Actions checks out the code, builds it and copies it to the server. Pushing is only half the job. You still have to find out whether that run went through, and the usual way is to open the repository's Actions tab and wait.
The GitHub CLI can follow a run from the terminal: gh run watch shows each step as it finishes. gpush chains the commit, the push and that watch, so one line takes a change from your editor to the server and tells you how it went.
We use it on our own projects, where a push to the development branch deploys the development server in under a minute, and production only goes out from a merged pull request. gpush works with any workflow that runs on push.
What you need
- A repository with a deploy workflow
- A GitHub Actions workflow in
.github/workflows/that runs onpushto your branch. - The GitHub CLI, logged in
- Install it with Homebrew,
brew install gh, then rungh auth loginonce with the account that owns the repository. - zsh
- The default shell on macOS. The function also works as is in bash: put it in
~/.bashrcinstead.
Add gpush to your shell
-
1
Open your shell profile
In Terminal,
open -e ~/.zshrcopens it in TextEdit. If the file doesn't exist yet, create it first withtouch ~/.zshrc. -
2
Paste the function
Add it at the end of the file and save.
~/.zshrc# Commit tracked files, push, then follow the GitHub Actions run gpush() { if [ -z "$1" ]; then echo "usage: gpush 'commit message'"; return 1; fi git commit -am "$1" && git push || return echo "Waiting for the GitHub Actions workflow…" sleep 5 local run run="$(gh run list --branch "$(git branch --show-current)" --limit 1 --json databaseId -q '.[0].databaseId')" if [ -z "$run" ]; then echo "No workflow found for this branch."; return 0; fi gh run watch "$run" --exit-status } -
3
Load it
Open a new Terminal tab, or run
source ~/.zshrcin the current one.type gpushshould answer gpush is a shell function. -
4
Push a change
In your project folder, give it a commit message:
Terminalgpush 'Home: new opening hours'
What the function does
- Refuses to run without a message
- With no argument it prints the usage and commits nothing.
- Commits and pushes
git commit -amthengit push. If either fails (nothing to commit, push rejected), the function stops there with git's own message.- Gives GitHub five seconds
- The run doesn't exist the instant the push lands. Five seconds is enough for GitHub to create it.
- Finds the run of this branch
gh run listasks for the latest run on the current branch and keeps only its id. A branch without a workflow simply ends with a message.- Watches it to the end
gh run watch --exit-statusshows each step as it runs and makes the command fail if the deployment fails, so a red run is a failedgpush, not a quiet success.
Good to know
-am only takes files git already tracks. A new file (a new page, a new image, a new script) is not committed, so the deployment doesn't have it. Add it first, then gpush.
git add -A && gpush 'message'
git status before a gpush shows what will be committed, and the untracked files, marked ??. Use git add -A some/folder to add only part of the project.
From a Claude Code session, commands typed after the ! prefix run in a shell that doesn't load ~/.zshrc. Load it in the same line:
! source ~/.zshrc && gpush 'message'
Useful commands
For the days a run goes wrong, or you want to look back.
- git status
- Before a gpush: what will be committed, and the untracked files.
- gh run list --limit 5
- The latest runs: status, duration, commit.
- gh run watch
- Pick a run in progress and follow it live.
- gh run view --log-failed
- Only the logs of the failed step of the last run.
- gh run rerun <id>
- Run it again after a network glitch or a server that was down.
If something doesn't work
command not found: gpush
The terminal was opened before you added the function. Run source ~/.zshrc or open a new tab; type gpush should then answer shell function.
Nothing is committed, nothing is pushed
Your only changes are new files, which -am leaves out. git status lists them with ??: git add them, then gpush again.
The deployed site is missing a file
Same cause: a new file that was never committed. The run succeeds, but without it. git status, git add, and push again.
No workflow found for this branch
The push went through, but no workflow runs on this branch, or GitHub took longer than five seconds to create the run. Check the on: push: branches list of your workflow, and if it's only slow, follow it with gh run watch.
The run fails
gh run view --log-failed shows only the step that broke. If it was the network or the server, gh run rerun <id> runs it again without a new commit.