Pushing a commit to learn whether a workflow works is slow. nektos/act 72,126 (https://github.com/nektos/act 72,126 ) (MIT) reads .github/workflows and runs each job in a Docker 514 container on your machine: run steps execute as written, JavaScript actions are cloned and run with the container's Node.js 2,131 , checking out your own repository becomes a copy of the working tree, and services: become sibling containers. Besides the release binary it installs with brew 6,457 install act, winget 26,463 install act, choco 15,799 install act or gh 29 extension install nektos/gh-act.
curl -sSL -o act.tgz \
https://github.com/nektos/act/releases/download/v0.2.89/act_Linux_x86_64.tar.gz
tar xzf act.tgz act && rm act.tgz && ./act --version
./act pull_request -W .github/workflows/ci.yml -j test \
--matrix os:ubuntu-24.04 --matrix node:24 -P ubuntu-24.04=node:24-slim --rm \
--artifact-server-path /home/dev/v5-ch3/act-artifactsact version 0.2.89 ... [CI/test (ubuntu-24.04, node 24)] ✅ Success - Main npm ci [2.394869626s] ... [CI/test (ubuntu-24.04, node 24)] | ℹ tests 16 [CI/test (ubuntu-24.04, node 24)] | ℹ pass 16 [CI/test (ubuntu-24.04, node 24)] | ℹ fail 0 ... [CI/test (ubuntu-24.04, node 24)] ❌ Failure - Main actions/upload-artifact@v7 [27.105907555s] ... [CI/test (ubuntu-24.04, node 24)] 🏁 Job failed
act maps each runs-on label to an image; its defaults (catthehacker/ubuntu:act-*) imitate GitHub 29 's only in part, and -P substitutes slim Node.js here. --matrix picks one leg; --artifact-server-path starts a local artifact service. On this shared machine DOCKER_HOST pointed act at a private Docker-in-Docker daemon, so port 5432 could not collide with anyone else's.
All 16 tests passed against the PostgreSQL 1,289 service, yet the job failed: act 0.2.89's artifact server rejects a field that actions/upload-artifact@v7 sends. act reimplements GitHub's services, so such gaps are normal. Skip those steps locally with if: ${{ !env.ACT }} (act sets ACT=true), and pass --rm, or a failed job's containers keep running. act checks run steps and expressions fast; the real runner has the final word.