Skip to the tutorial
webmasterbulletin.net All tutorials

Commit, push and watch the deployment in one command

A small zsh function, gpush, commits your changes, pushes them to GitHub and follows the GitHub Actions deployment live in the terminal. No browser tab to refresh: when the command ends, the site is deployed, or you know why it isn't.

Get the function
  • macOS or Linux, zsh
  • About 5 minutes
  • Needs git and GitHub CLI

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 on push to your branch.
The GitHub CLI, logged in
Install it with Homebrew, brew install gh, then run gh auth login once with the account that owns the repository.
zsh
The default shell on macOS. The function also works as is in bash: put it in ~/.bashrc instead.

Add gpush to your shell

  1. 1

    Open your shell profile

    In Terminal, open -e ~/.zshrc opens it in TextEdit. If the file doesn't exist yet, create it first with touch ~/.zshrc.

  2. 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. 3

    Load it

    Open a new Terminal tab, or run source ~/.zshrc in the current one. type gpush should answer gpush is a shell function.

  4. 4

    Push a change

    In your project folder, give it a commit message:

    Terminal
    gpush '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 -am then git 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 list asks 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-status shows each step as it runs and makes the command fail if the deployment fails, so a red run is a failed gpush, 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.

Terminal
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:

Claude Code
! 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.

Edit the texts with Skrid, publish with gpush

Skrid writes your changes into the site’s own HTML files. When that site lives in a GitHub repository, one gpush takes those changes to the server.