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
89 changes: 87 additions & 2 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ jobs:
- name: Validate runtime handshake
shell: bash
run: |
.wheel-venv/bin/gloss-babeldoc runtime-info --json \
| .wheel-venv/bin/python -c '
cd "$RUNNER_TEMP"
"$GITHUB_WORKSPACE/.wheel-venv/bin/gloss-babeldoc" runtime-info --json \
| "$GITHUB_WORKSPACE/.wheel-venv/bin/python" -c '
import json
import sys
from importlib.metadata import version
Expand All @@ -99,3 +100,87 @@ jobs:
assert payload["runtime_api_version"] == 1
assert payload["upstream"]["version"] == "0.6.4"
'

- name: Validate packaged executor service
shell: bash
env:
BABELDOC_EXECUTOR_ALLOW_FAKE: "1"
run: |
cd "$RUNNER_TEMP"
"$GITHUB_WORKSPACE/.wheel-venv/bin/python" - <<'PY'
import http.client
import json
import os
import secrets
import select
import subprocess
import sys
import tempfile
from pathlib import Path
from urllib.parse import urlparse

from babeldoc.tools.executor.babeldoc_adapter import run_babeldoc_request

del run_babeldoc_request
workroot = Path(tempfile.mkdtemp(prefix="gloss-babeldoc-smoke-"))
workroot.chmod(0o700)
marker = workroot / ".executor-workroot-ready"
marker.write_text("ready\n", encoding="utf-8")
marker.chmod(0o600)
token = secrets.token_urlsafe(32)
token_file = workroot / "token"
token_file.write_text(token + "\n", encoding="utf-8")
token_file.chmod(0o600)
executable = Path(sys.executable).with_name("gloss-babeldoc")
process = subprocess.Popen(
[
str(executable),
"serve",
"--runner",
"fake",
"--work-dir",
str(workroot),
"--token-file",
str(token_file),
],
env=os.environ.copy(),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
try:
assert process.stdout is not None
readable, _, _ = select.select([process.stdout], [], [], 20)
assert readable, "executor service did not report ready"
line = process.stdout.readline().strip()
prefix = "__GLOSS_BABELDOC_SERVICE_READY__"
assert line.startswith(prefix), line
ready = json.loads(line.removeprefix(prefix))
assert "auth_token" not in ready
endpoint = urlparse(ready["endpoint"])
connection = http.client.HTTPConnection(
endpoint.hostname,
endpoint.port,
timeout=5,
)
headers = {"Authorization": f"Bearer {token}"}
connection.request("GET", "/healthz", headers=headers)
response = connection.getresponse()
health = json.loads(response.read())
assert response.status == 200 and health["ok"] is True
connection.request(
"POST",
"/v1/shutdown",
body=b"{}",
headers={**headers, "Content-Type": "application/json"},
)
response = connection.getresponse()
response.read()
connection.close()
assert response.status == 202
assert process.wait(timeout=10) == 0
finally:
if process.poll() is None:
process.kill()
process.wait(timeout=5)
PY
1 change: 1 addition & 0 deletions DOWNSTREAM_PATCHES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ upstream, and the condition under which it can be removed.
| `gloss-0001` | Active | Establish downstream identity, provenance, safe automation, and maintenance policy. | Not applicable: repository governance. | The Gloss downstream is retired. |
| `gloss-0002` | Active | Add a lightweight, versioned runtime capability handshake for Gloss. | Downstream integration boundary. | Upstream exposes an equivalent stable runtime protocol. |
| `gloss-0003` | Active | Add reproducible dependency locking and Linux/macOS package validation. | Candidate upstream CI improvement. | Upstream adopts equivalent locked cross-platform release checks. |
| `gloss-0004` | Active | Add an authenticated, reconnectable single-worker service boundary with targeted cancellation and process isolation. | Candidate upstream executor lifecycle and correctness fixes. | Upstream exposes an equivalent authenticated service contract adopted by Gloss. |

Runtime, performance, and compatibility patches will be added in separate,
focused commits and PRs.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
> This is the **Gloss-maintained downstream** of
> [funstory-ai/BabelDOC](https://github.com/funstory-ai/BabelDOC). It is not an
> upstream release and is not endorsed by the upstream maintainers. See
> [DOWNSTREAM.md](./DOWNSTREAM.md) for support scope, versioning, and the exact
> upstream base.
> [DOWNSTREAM.md](https://github.com/SunChJ/BabelDOC/blob/main/DOWNSTREAM.md)
> for support scope, versioning, and the exact upstream base.

<div align="center">

Expand Down
5 changes: 3 additions & 2 deletions UPSTREAM_BASE.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Gloss downstream provenance. Update this file only in an upstream sync PR.
# Gloss downstream provenance. Update downstream.version for every downstream
# release; update the upstream block only in a reviewed upstream sync PR.
[downstream]
version = "0.6.4+gloss.1"
version = "0.6.4+gloss.2"
runtime_api_version = 1

[upstream]
Expand Down
2 changes: 1 addition & 1 deletion babeldoc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Gloss downstream release identity; see DOWNSTREAM.md.
__version__ = "0.6.4+gloss.1"
__version__ = "0.6.4+gloss.2"
2 changes: 1 addition & 1 deletion babeldoc/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pathlib import Path

# Gloss downstream release identity; see DOWNSTREAM.md.
__version__ = "0.6.4+gloss.1"
__version__ = "0.6.4+gloss.2"

CACHE_FOLDER = Path.home() / ".cache" / "babeldoc"

Expand Down
36 changes: 35 additions & 1 deletion babeldoc/gloss_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
UPSTREAM_REPOSITORY = "https://github.com/funstory-ai/BabelDOC"
UPSTREAM_VERSION = "0.6.4"
UPSTREAM_COMMIT = "17480db9df92ddcb37349ce34b312335226e8ec9"
CAPABILITIES = ("runtime-info.v1",)
CAPABILITIES = (
"executor.events.ndjson.v1",
"executor.http.v1",
"runtime-info.v1",
)


def package_version() -> str:
Expand Down Expand Up @@ -64,12 +68,42 @@ def create_parser() -> argparse.ArgumentParser:
action="store_true",
help="Emit one machine-readable JSON object.",
)
serve = commands.add_parser(
"serve",
help="Run the authenticated loopback PDF executor service.",
)
serve.add_argument("--host", default="127.0.0.1")
serve.add_argument("--port", type=int, default=0)
serve.add_argument(
"--runner",
choices=("babeldoc", "fake"),
default="babeldoc",
)
serve.add_argument("--token-file")
serve.add_argument("--work-dir")
serve.add_argument("--instance-id")
serve.add_argument("--parent-pid", type=int)
serve.add_argument("--parent-start-time", type=float)
return parser


def cli(argv: Sequence[str] | None = None) -> int:
"""Run the lightweight Gloss integration CLI."""
args = create_parser().parse_args(argv)
if args.command == "serve":
from babeldoc.tools.executor.server import serve

serve(
args.host,
args.port,
runner_name=args.runner,
token_file=args.token_file,
work_dir=args.work_dir,
instance_id=args.instance_id,
parent_pid=args.parent_pid,
parent_start_time=args.parent_start_time,
)
return 0
if args.command != "runtime-info": # pragma: no cover - argparse owns routing
raise AssertionError(f"Unexpected command: {args.command}")

Expand Down
2 changes: 1 addition & 1 deletion babeldoc/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

logger = logging.getLogger(__name__)
# Gloss downstream release identity; see DOWNSTREAM.md.
__version__ = "0.6.4+gloss.1"
__version__ = "0.6.4+gloss.2"


def create_parser():
Expand Down
Loading