actdbg
Run your GitHub Actions workflow locally — with a debugger.
act runs workflows locally; actdbg lets you debug them. Pause between
steps, drop into a shell at the exact failure point, and re-run one step
without re-running the whole job.
$ actdbg run .github/workflows/ci.yml -j test
── step 4/6: Test
│ testing version 1.2.3
│ FAIL: fix.marker missing
✗ failed (exit 1)
[actdbg] step 4 (Test) failed with exit 1
try: `shell` to poke around, `retry` after fixing, `rerun` for a clean replay
(actdbg) shell # bash inside the job, exact env + filesystem of the failure
(actdbg) retry # re-run just that step, keeping your fix
(actdbg) continue # finish the job
Why not just act?
act replays the whole job from scratch every time. When step 7 of 9 fails,
you edit, re-run, and wait through steps 1–6 again — and you can never look
inside the job at the moment of failure. actdbg keeps the job alive as a
persistent environment and snapshots it before every step:
act |
actdbg |
|
|---|---|---|
| Run workflow locally | ✅ | ✅ |
| Pause between steps / breakpoints | ❌ | ✅ break, next |
| Shell at the failure point (exact env + files) | ❌ | ✅ shell |
| Re-run one step without re-running the job | ❌ | ✅ rerun / retry |
| Time-travel to before any earlier step | ❌ | ✅ goto |
Full uses: action emulation |
✅ | ⚠️ shims (see below) |
Install
pip install actdbg # from PyPI
pip install -e ".[dev]" # from a checkout, for hacking
Requires Python ≥ 3.10. Docker is optional but recommended (Linux parity +
docker commit snapshots). Without Docker, steps run on the host in a
throwaway copy of your repo, with directory-copy snapshots.
Usage
actdbg run # auto-discovers .github/workflows/*.yml
actdbg run ci.yml -j test # pick a workflow + job
actdbg run -i # start paused, step through from the top
actdbg run -b 4 -b Test # breakpoints by number or name substring
actdbg run --backend host # skip Docker
actdbg run --platform linux/amd64 # x86_64 parity with GitHub runners on ARM hosts
actdbg run --matrix python=3.12 # pick a matrix combination
actdbg run --ci # no debugger; exit 1 on failure (for scripts)
actdbg list # show workflows, jobs, steps
On failure (or -i, or a breakpoint) you land in the debugger:
| Command | What it does |
|---|---|
list |
step list with status; > marks the next step, * a breakpoint |
next / continue |
run one step / run until breakpoint, failure, or end |
break N |
toggle breakpoint |
shell |
interactive shell inside the job — same env, same filesystem |
! CMD / shell CMD |
run one command inside the job (pipe-friendly for scripted sessions) |
rerun [N] |
replay step N from its pre-step snapshot (clean, deterministic) |
retry [N] |
re-run step N against the current filesystem (keeps your shell fixes) |
goto N |
restore filesystem + job state (env, outputs, PATH) to just before step N |
skip |
skip the next step |
logs [N], env, outputs, where |
inspect captured output and job state |
rerun vs retry is the core distinction: rerun answers "is this step
deterministic / did my last change fix it at source?", retry answers
"does the job pass if I patch the state right here?"
How it works
- One persistent environment per job. Docker mode starts one container and
docker execs each step into it (your repo is copied in, not mounted). Host mode runs steps in a temp copy of your repo. - Snapshots before every step. Docker:
docker commit; host: workspace copy. Job-level state that lives outside the filesystem —GITHUB_ENVaccumulations, step outputs,GITHUB_PATHadditions, job status — is tracked in Python and snapshotted alongside. That's whyrerun/gotoare exact, not approximate. - Real Actions semantics for the things that matter while debugging:
${{ }}expressions (env,steps.*.outputs,secrets,github,matrix,success()/failure()/always(), …),if:conditions,continue-on-error,GITHUB_OUTPUT/GITHUB_ENV(including heredocs),working-directory,defaults.run, secret masking in logs, and post-failure behavior (latersuccess()-gated steps skip,failure()/always()steps still run).
uses: actions
actdbg focuses on debugging run: steps. actions/checkout is native (your
workspace is the checkout). Other actions are skipped with a warning unless
you shim them in .actdbg.yml at your repo root:
# .actdbg.yml
backend: docker # or host
image: catthehacker/ubuntu:act-latest
platform: linux/amd64 # optional: match GitHub's x86_64 runners
shims:
actions/setup-python: |
echo "using system python: $(python3 --version) (wanted $INPUT_PYTHON_VERSION)"
actions/cache: "true" # no-op
Shims run as bash with the action's with: inputs exposed as INPUT_*,
same as a real action would see.
Secrets load from .secrets or .env (KEY=value lines) or
--secrets-file, are available as ${{ secrets.* }}, and are masked as
*** in all output.
Limitations (v0.1)
- Single job per invocation;
needsinter-job outputs aren't wired. - Matrix runs one combination at a time (
--matrixto choose). - No composite/JS/Docker action execution — shims instead.
shell:supportsbash,sh,python.- Host mode runs with your host toolchain — full parity needs Docker.
Development
python -m pytest
MIT license.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file actdbg-0.1.0.tar.gz.
File metadata
- Download URL: actdbg-0.1.0.tar.gz
- Upload date:
- Size: 28.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93c70c9da651e57e3501b6bd2bc1239cf242beb72c416de16c3460f7617145bb
|
|
| MD5 |
983e97d43d17233b90692f10ff66b2f9
|
|
| BLAKE2b-256 |
fa98115e27e1656baf7b17ff24e33a6dfb036d81296bd21bd6003225a147cee1
|
Provenance
The following attestation bundles were made for actdbg-0.1.0.tar.gz:
Publisher:
release.yml on sophie-nguyenthuthuy/actdbg
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
actdbg-0.1.0.tar.gz -
Subject digest:
93c70c9da651e57e3501b6bd2bc1239cf242beb72c416de16c3460f7617145bb - Sigstore transparency entry: 2388032357
- Sigstore integration time:
-
Permalink:
sophie-nguyenthuthuy/actdbg@d4871dbb53e15a346e58c2ad31ec63f0ff7a49d9 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/sophie-nguyenthuthuy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d4871dbb53e15a346e58c2ad31ec63f0ff7a49d9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file actdbg-0.1.0-py3-none-any.whl.
File metadata
- Download URL: actdbg-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1fd4691f725676c021cb47f27e8554ad1ea347b6f5ca9e2bdcee97b5f178c8f
|
|
| MD5 |
a6856b228bcf1907382612331fa2fb25
|
|
| BLAKE2b-256 |
77c1429acff5cb7f4e6e0f2666c7df0330d4992f204140d5e498250bd008fc32
|
Provenance
The following attestation bundles were made for actdbg-0.1.0-py3-none-any.whl:
Publisher:
release.yml on sophie-nguyenthuthuy/actdbg
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
actdbg-0.1.0-py3-none-any.whl -
Subject digest:
e1fd4691f725676c021cb47f27e8554ad1ea347b6f5ca9e2bdcee97b5f178c8f - Sigstore transparency entry: 2388032373
- Sigstore integration time:
-
Permalink:
sophie-nguyenthuthuy/actdbg@d4871dbb53e15a346e58c2ad31ec63f0ff7a49d9 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/sophie-nguyenthuthuy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d4871dbb53e15a346e58c2ad31ec63f0ff7a49d9 -
Trigger Event:
push
-
Statement type: