Skip to content

Testing GitHub Actions Locally with gh and act

Santiago Casas edited this page Jul 24, 2026 · 1 revision

Testing GitHub Actions Locally with gh and act

Why Use Them?

gh is GitHub’s command-line interface. It lets us inspect pull requests, workflow runs, logs, and check results without leaving the terminal.

act runs GitHub Actions workflows locally using Docker. This helps detect workflow, dependency, compiler, and test failures before pushing changes and waiting for GitHub CI.

Local act runs approximate GitHub-hosted runners but are not an exact replacement for the official CI environment. Final validation must still happen on GitHub.

Installation

Install and authenticate the GitHub CLI:

gh auth login
gh auth status

Install act as a gh extension:

gh extension install https://github.com/nektos/gh-act
gh act --version

Docker must be installed and running.

Main Commands

List the jobs detected in the workflows:

gh act -l

Validate workflow parsing and job dependencies without executing them:

gh act push -n \
  -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest

Run only the style job:

gh act push -j style \
  -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest \
  --rm

Run the tests job:

gh act push -j tests \
  -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest \
  --rm

If tests declares needs: style, act will run the style job first.

Safe Disposable Checkout

Some pre-commit hooks modify files. To protect the working repository, run act from a disposable clone:

SOURCE=/path/to/repository
ACT_WORK=$(mktemp -d /tmp/project-act.XXXXXX)

git clone "$SOURCE" "$ACT_WORK"
cd "$ACT_WORK"

gh act push -j tests \
  --bind \
  -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest \
  --rm

The disposable clone provides valid Git metadata while isolating any changes made by workflow steps.

Inspecting GitHub CI

List recent workflow runs:

gh run list

Inspect a run:

gh run view RUN_ID

Show logs from failed steps:

gh run view RUN_ID --log-failed

Inspect the checks associated with a pull request:

gh pr checks PR_NUMBER