Skip to content

Contributing

This page helps you build Goiabada from source, test a change and send it as a pull request.

Bug reports and pull requests are welcome. Code and contributions made with AI tools are welcome too, as long as they’re good quality: correct, tested and in keeping with the code around them, as any change must be. Not sure where to start? Pick something from the GitHub issues.

Everything you need, Go, the linters, the Tailwind CLI and the four databases, runs in a dev container, so the only thing your machine needs is Docker and an editor that opens dev containers, such as VS Code with the Dev Containers extension.

  1. Clone the repository:

    Terminal window
    git clone https://github.com/leodip/goiabada.git
  2. Open the repository’s src folder in your editor, not the repository itself. The dev container is defined in src/.devcontainer, and an editor looks for it in the folder you open.

  3. Reopen the folder in the container. In VS Code, that’s Dev Containers: Reopen in Container from the command palette. The first build takes a few minutes.

Every command below runs inside the container, from the directory it names.

  1. Start the auth server, from src/authserver:

    Terminal window
    make serve
  2. Start the admin console in a second terminal, from src/adminconsole:

    Terminal window
    make serve
  3. Open the admin console at http://localhost:19091 and sign in as the first administrator: email [email protected], password devcontainer-admin-password. The auth server is at http://localhost:19090.

Each rebuilds and restarts when you save a Go file or a template in its own module. A change under src/core isn’t watched: save a file in the server’s module, or run make serve again, to pick it up.

The test suite is one script, run-tests.sh. Run all of it, from src/authserver:

Terminal window
./run-tests.sh

That’s every tier below, the data and integration tiers on all four databases, so it takes a while. While you work, run the tier your change touches with --type:

Tier (--type) What it runs
internal The auth server’s unit tests
core The core module’s unit tests
adminconsole The admin console’s unit tests
setup The setup wizard’s tests
modules internal, core and adminconsole together
data The data layer against a real database
integration End-to-end tests against a running auth server, which the script builds, starts and stops
lint The linters, and the checks that generated files are committed
all Everything. The default

For example, the three unit tiers:

Terminal window
./run-tests.sh --type modules

Three more options narrow a run:

  • --db picks the database for data and integration: mysql, postgres, mssql, sqlite, or all, the default. SQLite is the quickest.
  • --run takes a go test -run pattern. A pattern that matches no test fails the run, so a typo doesn’t pass as green.
  • --race runs the unit tiers and the setup wizard’s tests under Go’s race detector.
Terminal window
./run-tests.sh --type integration --db sqlite --run 'TestToken_'

./run-tests.sh --help lists every option.

Some committed files are written by a tool. When your change touches what one is written from, run its command and commit what it changes:

When you change Run From
A database migration go run ./cmd/schemadump src/authserver
An exported symbol in a core package go run ./cmd/ownershipdump src/core
An interface a mock is generated for ./generate-mocks.sh src/authserver
A template’s CSS classes ./build.sh src/authserver or src/adminconsole, whichever owns the template
A tool version in versions.yaml ./version-manager.sh update src/authserver

schemadump regenerates the schema.golden file of all four databases, which the data tier compares against a freshly migrated database. The lint tier reruns the mocks, the ownership table and the CSS, and fails when any of them differs from what’s committed.

The docs site is in site/, and every page follows site/STYLE.md: the voice, the shape of a page and the words the glossary gives each concept.

The dev container has no Node.js, so build the site on your own machine, with Node.js 22.12 or later, from site/:

Terminal window
npm ci
npm run dev

That serves a live preview at http://localhost:4321. Before you send a change, build the site and run its checks’ tests:

Terminal window
npm run build
npm test

The build fails on a broken link, including a link to the site from the Go code under src/, so move a page or rename a heading in the same change as every link to it.

Goiabada is three Go modules and the setup wizard:

src/
├── authserver/ The auth server: OAuth2 and OpenID Connect, sign-in, the APIs
├── adminconsole/ The admin console, a client of the auth server
├── core/ What both servers share
├── cmd/goiabada-setup/ The setup wizard, a module of its own
└── build/ The release Dockerfiles and build scripts

ARCHITECTURE.md at the repository root says which module owns what, and the unit tiers hold the code to it. AGENTS.md describes the code in depth: the sign-in state machine, the patterns every handler follows and every guard the tests run. It’s written for AI coding assistants, and reads just as well for people. CLAUDE.md is the same file.

Much of what a reviewer would otherwise check is a test that fails: the architecture rules, the logging convention, gofmt, the API error codes and audit events listed in the docs, and the docs pages that state a fact the code decides, this one included. When you change one of those facts, change the page in the same pull request.

The dev container runs MySQL, PostgreSQL and SQL Server beside it, and make serve uses SQL Server. The tests leave that database alone: each data and integration run starts from an empty database of its own. ./run-tests.sh does stop a running make serve, though: it frees ports 19090, 19091 and 19190 before the data and integration tiers and again when it exits, so start make serve again afterwards.

Mailpit runs beside them too. Under Email - SMTP in the admin console’s settings, turn on SMTP enabled and set the host to mailpit, the port to 1025, the encryption to None, and From email to any address, such as [email protected]. Every mail Goiabada sends then lands in Mailpit, at http://localhost:8025.

CI runs the same tiers on every pull request, a job each, and builds the site. The data, integration and race jobs wait until the pull request is out of draft.