Files
ihasmail-oneshot/CONTRIBUTING.md
T
jcoffey-dev 4f2a06ebbf
ci / test (pull_request) Skipped
ci / release (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Failing after 1m12s
ci / announce (pull_request) Skipped
Deploy Stalwart 0.16.27 by default, and say what is supported
The default Stalwart image moves from v0.16.22 to v0.16.27, the last 0.16
release and the one ihasmail now tests against. A loopback deploy
(--local) against it set up Stalwart, created a mailbox and signed in to
ihasmail 2026.10.27.

The README gets a Support section: 0.16.27 supported and the default, other
0.16 releases untested, 1.0 not supported because its first-run setup
changed. Troubleshooting's known limits say the same.

The README and CONTRIBUTING said the end-to-end test runs every Monday. It
has been a job run by hand on a GitHub runner since the move to Gitea.
2026-10-27 22:13:37 -07:00

4.4 KiB

Contributing to ihasmail-oneshot

How to build and test the tool, how the code is organized, and how versions and releases work. Back to the README.

Sending a change

New accounts on git.coffeylabs.org can file issues but can't push or fork. Until you have repository access, open an issue for the change, or say hello on community.coffeylabs.org, and attach the change to the issue as a patch:

git format-patch origin/main --stdout > my-change.patch

Repository access goes to volunteers we have worked with; a few good issues or patches is the usual way in. After that you push a branch here and open a pull request. The GitHub copy is a read-only mirror, so pull requests opened there are not merged.

Building

With Go 1.26.8 or newer:

go build -o ihasmail-oneshot ./cmd/ihasmail-oneshot

Testing

go vet ./...
go test ./...          # unit tests: validation, rendered files, the Stalwart client
e2e/public.sh          # the whole mail-host deploy, for real, on this machine

e2e/public.sh runs a complete mail-host deployment with no internet involved. Pebble, the ACME test server, stands in for Let's Encrypt, and a DNS stub answers every name with the host's own address. Caddy and Stalwart both obtain real certificates from it, through the real ports and the real Caddyfile. It then checks, among other things, that:

  • the deploy completes, links ihasmail and Stalwart, and reports both kinds of certificate;
  • credentials.txt and .env are private, and the bootstrap credential is gone from the Stalwart container;
  • Stalwart's IMAPS (993) and submission (465) ports present certificates that verify for the mail host;
  • the webmail, Stalwart's JMAP and autoconfig are served over verified HTTPS, and a user signs in through the webmail;
  • dns-records.zone holds the MX and DKIM records, and certs recognizes an existing certificate;
  • a scanner probing through Caddy is banned by its own address, not Caddy's, and other clients still get through;
  • ihasmail is exempt from bans, and a user still signs in after failed attempts.

It publishes ports 25, 80, 443, 465, 993, 995 and 4190 on the machine while it runs, and removes everything it created when it ends, pass or fail. KEEP=1 e2e/public.sh leaves the stack up to inspect.

How the code is laid out

Package Does
cmd/ihasmail-oneshot Commands, flags, confirmation, the summary
internal/config Validates the command line into a plan: names, addresses, images
internal/render Renders compose.yaml and the Caddyfile; writes files without ever overwriting
internal/docker Drives the docker and docker compose CLIs
internal/stalwart The JMAP client and every Stalwart registry call: bootstrap, ACME, bans, mailboxes, DNS zone
internal/webmail ihasmail's health check and the sign-in that proves the link
internal/deploy Preflight, the deploy sequence, certs, destroy

Versions and releases

Releases are tagged by date, like ihasmail's: v2026.9.13, with .1, .2 added for another release the same day. Each release pins the Stalwart and Caddy images it was tested with as its defaults. A newer release of the tool generally means newer tested versions of those.

ihasmail is the exception: a deploy takes its newest release, so a new ihasmail needs no new release of this tool. What keeps that safe is the end-to-end test, run by hand against ihasmail's newest release after ihasmail publishes it (the e2e job in .github/workflows/ci.yml, on a GitHub runner, because it needs a throwaway VM). Stalwart is never taken this way — an upgrade migrates its data with no way back, so its version only changes in a release of this tool.

Binaries for linux/amd64 and linux/arm64 and a SHA256SUMS file are attached to every release.

Every release is built by the release workflow from a tagged commit on main, after the tests and a known-vulnerabilities check pass. The archives are reproducible: scripts/build-release.sh builds the same bytes from the same commit.

That weekly run is e2e.yml, Mondays at 12:00 UTC. It can also be started by hand from the Actions tab.