Developing¶
You need the .NET 10 SDK and Docker: the tests start PostgreSQL in a container, so they run against the database TalkWatch actually uses rather than a stand-in.
dotnet build
dotnet test
git config core.hooksPath .githooks # once per clone: the fixture guard
A change comes with a test that fails without it. For a bug fix, write the test first and watch it fail. CONTRIBUTING.md says what makes a contribution easy to take.
Test data from a real console¶
TalkWatch is built against a capture of a real console's traffic, replayed in the tests and in the demo. Nothing captured from a console goes in as it came: Capturing the Talk API explains how a capture is taken, sealed and pseudonymised into fixtures.
The fixture guard refuses any commit that puts a phone number outside the
fictional ranges (Ofcom's drama numbers, North American 555-0100 to 555-0199)
into tests/fixtures, or audio that isn't listed in
tests/fixtures/synthetic-audio.sha256. It runs as a commit hook and again on
every release. It can't catch everything, so read fields.txt in any fixtures
you make before committing them.
CI¶
Day-to-day CI runs on the maintainer's own Docker rather than on hosted runners, so it costs nothing per push. On a branch:
scripts/ci.sh
It tests the committed HEAD in a clean SDK container (through git archive, so
stray local edits can't make a run pass), runs the fixture guard, builds the
documentation strictly, builds the image and checks the upgrade from the last
release. It posts the result to GitHub as the commit's local-ci status, which
the pull request shows.
After a merge, scripts/ci.sh --publish on an up-to-date main does the same
and pushes the image as edge, live and demo to the registry named by
REGISTRY_HOST or git config talkwatch.registry. The maintainer's live and
demo installs each follow their own tag, so one updating can't leave the other
behind on a tag it already thinks is current.
A release is a tag. Pushing v1.2.3 runs .github/workflows/release.yml on
GitHub Actions: the tests and fixture guard again, the upgrade from the last
release, images for amd64 and arm64 on GHCR, this site, and a GitHub release.
The pictures in these pages¶
The screenshots and animations here are taken of the demo, in Windows Sandbox rather than on anyone's own desktop, so no browser window opens and nothing is clicked on the machine doing it:
pwsh tools/docs-capture/run.ps1 # after scripts/ci.sh has built talkwatch:ci
It starts the demo from the image with a throwaway database, hands Sandbox a
copy of Node and Playwright, which drive Sandbox's own Edge headless, and makes
the GIFs from the recorded frames once Sandbox has closed. The animations of
Now are cut from four minutes of the board left running, around the first ride,
arrival and missed call it catches, so a run that catches none of one kind says
so rather than inventing it. Everything lands in a staging folder to look over
before it's copied into docs/images.
The Railway template¶
Deploying on Railway is the guide for anyone deploying; this is how the template behind it is built. Railway's template composer, in the Railway dashboard, builds it once, and each deployment is a copy in the deployer's own account. Railway reviews a template before verifying it, so keep it and the guide in step. Each value below is what the template holds.
Postgres: add Railway's PostgreSQL database.
TalkWatch: a service from the Docker image
ghcr.io/thecodesaiyan/talkwatch:latest.
- Settings: health check path
/healthz; public networking over HTTP with target port8080. - Volume: attach one, mounted at
/data/audio. - Variables:
ConnectionStrings__TalkWatch=Host=${{Postgres.PGHOST}};Port=${{Postgres.PGPORT}};Database=${{Postgres.PGDATABASE}};Username=${{Postgres.PGUSER}}
Database__Password=${{Postgres.PGPASSWORD}}
Site__PublicUrl=https://${{RAILWAY_PUBLIC_DOMAIN}}
Bootstrap__AdminUsername=admin
Bootstrap__AdminPassword=${{secret(32)}}
RAILWAY_RUN_UID=0
Site__Name=
Site__Region=
Site__TimeZone=
Railway wants a description on every variable before it publishes: the empty
ones take theirs from Configuration, so the deployer knows
what to put there, and the rest say they're filled in. The service's icon is
https://thecodesaiyan.github.io/talkwatch/assets/mark.svg. There are no
Talk__ variables: the console and the way to it are set on the Console page
after deploying, which keeps the WireGuard or Tailscale secrets out of
Railway's variables.
The template is published as TalkWatch. The README's Deploy on Railway button links to it with the maintainer's referral code, from the Share button on the template's page in the dashboard.
Redeploying your own Railway instance on a release¶
The release workflow can redeploy a TalkWatch you run on Railway as soon as the new image is on GHCR, without waiting for a maintenance window. On the repository, under Settings → Secrets and variables → Actions:
- the secret
RAILWAY_TOKEN: a project token for that project and environment, made in the project's settings; - the variable
RAILWAY_SERVICE: the TalkWatch service's name.
With RAILWAY_SERVICE unset, the step is skipped. It runs for a release, not a
pre-release, since a pre-release doesn't move latest.