Skip to content

build: declare dependencies, add a container image, fix reference URLs - #11

Merged
howethomas merged 4 commits into
mainfrom
thomashowe/con-1084-packaging-container
Sep 25, 2026
Merged

howethomas merged 4 commits into
mainfrom
thomashowe/con-1084-packaging-container

Conversation

@howethomas

Copy link
Copy Markdown
Contributor

Stacked on #10. Base is that branch, so this diff shows only this change. Merge #10 first; GitHub retargets this to main when that branch is deleted.

The package could not be installed or deployed cleanly: vcon was never declared, CI pulled vcon-lib from git, and there was no container image.

Changes

  • Dependencies declared. vcon>=0.9.4 from PyPI (locks to 0.9.5) and cryptography are runtime dependencies. boto3 is an optional s3 extra, since only MEDIA_BACKEND=s3 imports it. requirements.txt now defers to pyproject.toml.
  • CI installs from pyproject.toml alone (pip install -e ".[dev,s3]"), no git installs.
  • Dockerfile. python:3.12-slim, non-root user, adapter name as the command (docker run <image> twilio), HEALTHCHECK on /health. .dockerignore keeps .env, venvs and caches out of the image. compose.example.yaml shows one service per adapter.
  • Image publishing. New workflow builds and pushes ghcr.io/<repo> on v* tags only, with GITHUB_TOKEN.
  • Reference-URL fix. In reference mode the base builder appended .wav/.mp3 to the provider URL. Bandwidth's mediaUrl has no extension, and Asterisk and FreeSWITCH URLs already carry one, so all three produced URLs that do not resolve. Each now passes the provider URL through unchanged. Twilio's appended format is correct and unchanged.
  • README install and Docker sections updated to match.

Verification

Known nit

The Dockerfile purges build-essential in a later layer than it installed it in, so the image does not actually shrink. The build tools are probably unnecessary since cryptography ships wheels. Cosmetic; can follow up.

Refs CON-1084

🤖 Generated with Claude Code

@howethomas
howethomas added this pull request to stack #13 September 25, 2026 21:49
Base automatically changed from thomashowe/con-1082-webhook-fail-closed to main September 25, 2026 21:49
howethomas and others added 4 commits September 25, 2026 17:49
vcon was installed from git in CI (.github/workflows/tests.yml) and not
declared anywhere else, so `pip install .` never worked. Pin it to the
released PyPI package (>=0.9.4, verified as the vcon-dev library by its
import path: `from vcon import Vcon`, `vcon.dialog`, `vcon.party`).

boto3 (core/media_publisher.py S3Publisher) becomes an optional `[s3]`
extra since most deployments don't use MEDIA_BACKEND=s3. cryptography
(Telnyx Ed25519 signature verification) becomes a main dependency so
signature validation isn't silently skipped when it happens to be
missing.

CI now installs from pyproject.toml alone, no git install. requirements.txt
points at the package instead of duplicating the dependency list. uv.lock
regenerated with `uv lock`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…edia URL

In reference mode (no download, no publisher) the base builder's default
_reference_url appends `.{format}` to the recording URL, because Twilio's
recording URI is extension-less by design. Bandwidth's mediaUrl
(`.../recordings/{id}/media`), FreeSWITCH's recording_url/recording_file,
and Asterisk's target_uri are already complete, extension-carrying
endpoints, so the same default corrupts them into a URL the platform does
not serve. Telnyx already overrode this for the same reason (pre-signed,
per-format URLs); this applies the same override to Bandwidth, FreeSWITCH
and Asterisk.

Adds a Bandwidth test asserting the reference-mode dialog URL is emitted
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was no Dockerfile, compose file, or systemd unit; deployment was
`python main.py <adapter>` by hand. Adds one slim, non-root Dockerfile
that takes the adapter name as its command (ENTRYPOINT python main.py,
default CMD twilio), with a HEALTHCHECK against GET /health on PORT
(default 8080, confirmed from core/base_config.py and each adapter's
webhook.py). .dockerignore keeps .env, venvs, caches and .git out of the
build context. compose.example.yaml shows running one or more adapters
with env_file pointing at a .env.

Updates README Installation/Requirements (stale git+vcon-lib install
instructions, now a declared dependency) and Deployment sections to match;
left the per-adapter config tables untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds a workflow triggered only by v* tag pushes that builds the Dockerfile
and pushes ghcr.io/<repo> using the built-in GITHUB_TOKEN (packages:
write). Not triggered as part of this change; no tag is pushed here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@howethomas
howethomas force-pushed the thomashowe/con-1084-packaging-container branch from 1426a5c to b19f0f8 Compare September 25, 2026 21:49
@howethomas
howethomas merged commit c7ff420 into main Sep 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant