Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Contributing

This file covers the repository layout and the release process. If you just want to debug an Actor,
see the [root README](README.md) and the package READMEs it links to.

## Repository layout

- [`javascript/`](javascript/) — the npm package (`bin/`, `lib/`), its README, and a sample TS Actor
in `example-actor/`.
- [`python/`](python/) — the PyPI package (`src/actor_debugger/`) and its README.
- [`.github/workflows/`](.github/workflows/) — release automation, one manually started workflow per
package (see [Releasing](#releasing) below).

## Releasing

Each package is released independently by its own manually started workflow. Both workflows refuse
to run on any branch other than `master`, and both push their tag and create the GitHub release
themselves — do not create tags or releases by hand.

### npm (`javascript/`)

Publishing to npm is done by [`.github/workflows/publish.yml`](.github/workflows/publish.yml),
started manually from the Actions tab. It publishes via **npm Trusted Publishing** (OIDC) — no npm
token or repository secret, and provenance attestations are generated automatically. The trusted
publisher configured on npmjs.com is: repository `apify/actor-debugger`, workflow `publish.yml`
(the workflow file name must stay exactly that). To cut a release:

1. Bump the version in `javascript/package.json` in a PR and merge it to `master`:

```bash
cd javascript
npm version patch --no-git-tag-version # or minor / major
```

2. Open **Actions → Publish to npm → Run workflow** on `master`.

The workflow refuses to run on any other branch, or if that version is already on npm or its
`vX.Y.Z` tag already exists. It then syntax-checks the sources, smoke-tests both modes (disabled
pass-through and the debug server with `/json/list` + DevTools frontend), checks the pack contents,
runs `npm publish` from `javascript/`, and finally **pushes the `vX.Y.Z` tag and creates the GitHub
release** with generated notes.

### PyPI (`python/`)

Publishing to PyPI is done by
[`.github/workflows/publish_to_pypi.yml`](.github/workflows/publish_to_pypi.yml), started manually
from the Actions tab. It publishes via **PyPI Trusted Publishing** (OIDC) — no API token or
repository secret. The trusted publisher configured on PyPI is: project `actor-debugger`,
repository `apify/actor-debugger`, workflow `publish_to_pypi.yml` (the workflow file name must stay
exactly that). To cut a release:

1. Bump the version in `python/pyproject.toml` and `python/src/actor_debugger/__init__.py` in a
PR and merge it to `master`.
2. Open **Actions → Publish to PyPI → Run workflow** on `master`.

The workflow refuses to run on any other branch, if the two version strings disagree, or if that
version is already on PyPI or its `py-vX.Y.Z` tag already exists. It then installs the package,
smoke tests the CLI and the served debugger UI, builds sdist+wheel, uploads them, and finally
**pushes the `py-vX.Y.Z` tag and creates the GitHub release** with generated notes.
12 changes: 0 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,6 @@ Both variants share the same architecture: your Actor runs under its native debu
inspector, or debugpy for Python), and one HTTP server on `ACTOR_WEB_SERVER_PORT` serves the
frontend and bridges the debug protocol to it. The run log prints the URL to open.

## Repository layout

- [`javascript/`](javascript/) — the npm package (`bin/`, `lib/`), its README, and a sample TS Actor
in `example-actor/`.
- [`python/`](python/) — the PyPI package (`src/actor_debugger/`) and its README.
- [`.github/workflows/`](.github/workflows/) — release automation. Both workflows are started
manually from the Actions tab on `master`: `publish.yml` publishes the version in
`javascript/package.json` to npm and `publish_to_pypi.yml` the version in `python/pyproject.toml`
to PyPI. Each then creates its tag (`vX.Y.Z` for npm, `py-vX.Y.Z` for PyPI) and GitHub release
itself. Both use registry trusted publishing (OIDC), so there are no publishing secrets in the
repository.

## Security

The debug endpoint is unauthenticated: anyone who reaches the container URL can execute code in the
Expand Down
24 changes: 0 additions & 24 deletions javascript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,6 @@ The debug endpoint is **unauthenticated** — anyone who reaches the container U
never ship it in a published Actor, and gate the endpoint (owner-only) before any non-prototype
use.

## Releasing

Publishing to npm is done by
[`.github/workflows/publish.yml`](https://github.com/apify/actor-debugger/blob/master/.github/workflows/publish.yml),
started manually from the Actions tab. It publishes via **npm Trusted Publishing** (OIDC) — no npm
token or repository secret, and provenance attestations are generated automatically. The trusted
publisher configured on npmjs.com is: repository `apify/actor-debugger`, workflow `publish.yml`
(the workflow file name must stay exactly that). To cut a release:

1. Bump the version in `javascript/package.json` in a PR and merge it to `master`:

```bash
cd javascript
npm version patch --no-git-tag-version # or minor / major
```

2. Open **Actions → Publish to npm → Run workflow** on `master`.

The workflow refuses to run on any other branch, or if that version is already on npm or its
`vX.Y.Z` tag already exists. It then syntax-checks the sources, smoke-tests both modes (disabled
pass-through and the debug server with `/json/list` + DevTools frontend), checks the pack contents,
runs `npm publish` from `javascript/`, and finally **pushes the `vX.Y.Z` tag and creates the GitHub
release** with generated notes. Do not create tags or releases by hand.

## Notes

- Depends on `chii` for the prebuilt DevTools frontend (~16 MB of static assets, no runtime browser).
Expand Down
4 changes: 2 additions & 2 deletions javascript/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion javascript/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "actor-debugger",
"version": "0.1.5",
"version": "0.1.6",
"description": "Drop-in remote debugger for Apify Node/TS Actors: one Dockerfile CMD line launches your Actor under the Node inspector, reachable over the run's container URL. No local setup, no rebuild of your own code.",
"type": "module",
"bin": {
Expand Down
39 changes: 0 additions & 39 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,45 +105,6 @@ a restricted run/token, never ship it in a published Actor, and gate the endpoin
before any non-prototype use. This matches the security posture of the Node version; both need
the same hardening pass.

## Design notes: the routes considered

The constraint was: **no platform/infrastructure changes, and nothing but a browser on the
debugging machine.** Everything must therefore run inside the Actor container and be served over
the one exposed web-server port. Options considered:

| Approach | Verdict |
| --- | --- |
| **debugpy + served browser DAP client** (this package) | CPython unchanged, actor code and deps run exactly as in production; debugpy is the canonical Python debugger; image cost ~3 MB. The UI is ours to grow. **Chosen.** |
| **GraalPy `--inspect`** — GraalVM's Python speaks the Chrome DevTools Protocol natively, so the Node version's chii DevTools frontend + CDP proxy would work *unchanged* | Elegant symmetry, but it swaps the runtime under the Actor: a different base image, slower startup, and C-extension compatibility risk for real-world deps (`lxml`, `pydantic`, `cryptography`, …). Debugging a different interpreter than production undermines the point. |
| **DAP→CDP translation shim** — keep CPython + debugpy, translate DAP into the Chrome DevTools Protocol and serve the same chii DevTools frontend the Node version uses | Best possible UI for free, one frontend for both languages, but the DevTools frontend is picky about `Debugger`/`Runtime` lifecycle — a meaningful project on its own. The `/dap` WebSocket this package exposes is where such a shim would slot in later. |
| **code-server / openvscode-server in the container** | Great UX, zero custom code, but ~300 MB and a Node runtime in every Python Actor image, plus auth wiring. Overkill for "set a breakpoint in a run". |
| **`web-pdb` / xterm.js + pdb over WebSocket** | Tiny, but a terminal `pdb` UX (no gutter breakpoints, no variable tree) and pdb can't attach to a running program the way debugpy can. |
| **Jupyter server in the container** (JupyterLab's debugger also speaks debugpy) | The kernel model doesn't fit debugging an already-running script; heavyweight. |
| **[`dap-python`](https://pypi.org/project/dap-python/)** — a typed Python DAP *client* library | The DAP client here is the browser; the container side is a protocol-agnostic byte bridge. Useful only for a server-orchestrated variant, at the cost of a Pydantic dependency and a Python ≥3.12 floor. |

The same architecture extends beyond Python: any language with a DAP adapter (Node via js-debug,
Go via Delve — which speaks DAP natively — Rust via lldb-dap, …) can sit behind the identical
bridge and frontend; only the adapter spawn command and entrypoint detection differ.

## Releasing

Publishing to PyPI is done by
[`.github/workflows/publish_to_pypi.yml`](https://github.com/apify/actor-debugger/blob/master/.github/workflows/publish_to_pypi.yml),
started manually from the Actions tab. It publishes via **PyPI Trusted Publishing** (OIDC) — no API
token or repository secret. The trusted publisher configured on PyPI is: project `actor-debugger`,
repository `apify/actor-debugger`, workflow `publish_to_pypi.yml` (the workflow file name must stay
exactly that). To cut a release:

1. Bump the version in `python/pyproject.toml` and `python/src/actor_debugger/__init__.py` in a
PR and merge it to `master`.
2. Open **Actions → Publish to PyPI → Run workflow** on `master`.

The workflow refuses to run on any other branch, if the two version strings disagree, or if that
version is already on PyPI or its `py-vX.Y.Z` tag already exists. It then installs the package,
smoke tests the CLI and the served debugger UI, builds sdist+wheel, uploads them, and finally
**pushes the `py-vX.Y.Z` tag and creates the GitHub release** with generated notes. Do not create
tags or releases by hand.

## Notes

- Only runtime dependency is `debugpy`; the HTTP server and the RFC 6455 WebSocket implementation
Expand Down
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "actor-debugger"
version = "0.1.2"
version = "0.1.3"
description = "Drop-in remote debugging for Apify Python Actors: debugpy plus a browser debugger UI served over the run's container URL."
readme = "README.md"
license = { text = "Apache-2.0" }
Expand Down
2 changes: 1 addition & 1 deletion python/src/actor_debugger/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""actor-debugger: browser-based remote debugging for Apify Python Actors."""

__version__ = "0.1.2"
__version__ = "0.1.3"
Loading