Requirements:
- Elixir 1.15+ (CI uses 1.17.3)
- OTP 26+ (CI uses OTP 27.0)
- PostgreSQL 14+ (PostgreSQL 16 recommended; matches CI and
docker-compose.yml)
-
Clone the repository.
-
Install dependencies:
mix deps.get -
Start PostgreSQL — no manual
createdbrequired: the test helper createsthreadline_testwhen missing.docker compose up -d
Wait until Postgres is healthy (
docker compose ps).Port 5432 already in use (e.g. Homebrew PostgreSQL): Compose maps the container to host port
5433by default (THREADLINE_DB_PORTindocker-compose.yml). Point Mix at it:DB_PORT=5433 mix ci.all
-
Run the full local gate (same steps CI runs, modulo Postgres). The project sets
preferred_envs: ["ci.all": :test]inmix.exs, so the whole chain (format, credo, compile strict, tests, Threadline trigger coverage, doc contract tests) runs in the test environment and picks upconfig/test.exs.MIX_ENV=test mix ci.all
mix ci.allis equivalent when invoked withoutMIX_ENVbecause ofpreferred_envs.With the alternate Compose port:
DB_PORT=5433 mix ci.all.
mix verify.test # format of CI: full suite (needs PostgreSQL)
mix test test/path.exs # single fileIntegration tests use a real database and triggers; they are not excluded from mix test.
Environment: DB_HOST defaults to localhost; DB_PORT defaults to 5432 (see config/test.exs). Override if Postgres listens on another port (e.g. DB_PORT=5433 with the default docker-compose.yml mapping).
GitHub Actions workflow: .github/workflows/ci.yml. Live runs (branch main): https://github.com/szTheory/threadline/actions?query=branch%3Amain — Stable job keys (do not rename; used by docs, act, and branch protection):
| Job key | Purpose |
|---|---|
verify-format |
mix verify.format |
verify-credo |
mix verify.credo |
verify-compile-no-optional |
mix verify.compile_no_optional (compile without optional deps; gates against missing Phoenix/LiveView) |
verify-test |
compile --warnings-as-errors + mix verify.test (Postgres service) |
verify-pgbouncer-topology |
Postgres + PgBouncer (POOL_MODE=transaction) — priv/ci/topology_bootstrap.exs on direct Postgres, then mix verify.topology + mix verify.threadline on the pooler port |
verify-docs |
MIX_ENV=dev — mix docs (ExDoc + extras) |
verify-hex-package |
mix hex.build + assert tarball contains lib/ |
verify-release-shape |
bin/verify-release-shape — @version / dated CHANGELOG for release versions |
Hex publish (after a SemVer tag v* is pushed) runs from .github/workflows/hex-publish.yml using the HEX_API_KEY repository secret — see Hex publish (maintainers) below.
For running the test job locally with nektos/act, see scripts/ci/README.md.
docker-compose.yml includes pgbouncer (transaction mode) on host port 6432 by default (THREADLINE_PGBOUNCER_PORT), alongside Postgres on 5433 (THREADLINE_DB_PORT).
-
docker compose up -dand wait until both services are healthy. -
Bootstrap migrations + topology fixture on direct Postgres (DDL does not go through PgBouncer):
MIX_ENV=test DB_HOST=localhost DB_PORT=5433 THREADLINE_TOPOLOGY_BOOTSTRAP=1 mix run priv/ci/topology_bootstrap.exs
-
Run topology tests +
verify.threadlinethrough the pooler:MIX_ENV=test DB_HOST=localhost DB_PORT=6432 THREADLINE_PGBOUNCER_TOPOLOGY=1 mix verify.topology MIX_ENV=test DB_HOST=localhost DB_PORT=6432 THREADLINE_PGBOUNCER_TOPOLOGY=1 mix verify.threadline
mix verify.topology requires THREADLINE_PGBOUNCER_TOPOLOGY=1 so it cannot accidentally pass against direct Postgres only.
Host staging / pooler parity (requirements STG-01–STG-03) is integrator-owned attestation: detailed topology, logs, and runbooks live in your repo or docs under your control. Threadline maintainers do not operate your staging stack.
To contribute a short in-repo index (tables, links, redacted excerpts) that helps other operators, use a fork and open a pull request against this repository. Maintainers merge for modesty of claims, redaction, and link hygiene only — not to vouch for third-party environments.
Fill the canonical scaffolds in guides/adoption-pilot-backlog.md: search for STG-HOST-TOPOLOGY-TEMPLATE (fixed-field topology narrative) and STG-AUDITED-PATH-RUBRIC (HTTP + job paths with OK / Issue / N/A / Not run and evidence pointers). Long-form evidence stays in integrator-controlled artifacts; the PR updates the small, reviewable surface in main.
- Fork the repository and create a branch from
main. - Make your changes and run the full gate:
mix ci.all(requires PostgreSQL — see Setup above). - Open a pull request against
main. Describe what changed and why. - All CI checks on the PR must pass (including
verify-docs,verify-hex-package, andverify-release-shapewhen present onmain).
In GitHub repository settings, require these checks on main (names match the workflow name: fields or job summaries as shown in the PR UI):
- Check formatting (
verify-format) - Run Credo (strict) (
verify-credo) - Run test suite (
verify-test) - PgBouncer transaction topology (
verify-pgbouncer-topology) - Build ExDoc (dev) (
verify-docs) - Hex package tarball (
verify-hex-package) - Release metadata (version / changelog) (
verify-release-shape)
Exact labels depend on GitHub’s UI; map them to the job keys above.
Tag-triggered publish: pushing an annotated SemVer tag matching vMAJOR.MINOR.PATCH runs .github/workflows/hex-publish.yml. It checks that GITHUB_REF_NAME (e.g. v0.3.0) matches @version in mix.exs (e.g. 0.3.0), then runs mix hex.publish --yes with HEX_API_KEY.
-
Add repository secret
HEX_API_KEY(Hex.pm API key with publish permission for this package). -
Run
mix verify.releasefrom a clean working tree to validate the exact tree you are about to tag. -
Ensure
mainis green and the release commit has the correct@versionandCHANGELOG.mdsection. -
Tag and push (no
--forceon refs):git tag -a v0.3.0 -m "Release v0.3.0" git push origin main # if needed git push origin v0.3.0
-
Watch the Hex publish workflow on the Actions tab; confirm with
mix hex.info threadlineafter the registry updates.
Manual runbook (optional): you can still run mix hex.publish --dry-run and mix hex.publish locally with mix hex.user auth instead of relying on CI.
Use this when preparing or debugging the v0.3.0 release (no secrets in logs):
- Clean tree:
git status --porcelainempty. - Run
mix verify.release. - Run
DB_PORT=5433 mix ci.all(ormix ci.all) with Postgres up for the broader contributor gate. - wait for green CI on
mainbefore tagging. - Tag
v0.3.0so it matches@version "0.3.0"inmix.exs, then push the branch (if needed) and the tag. - Verify the Hex publish workflow and confirm with
mix hex.info threadlineafter the registry updates.