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.
Open the dev container
Section titled “Open the dev container”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.
-
Clone the repository:
Terminal window git clone https://github.com/leodip/goiabada.git -
Open the repository’s
srcfolder in your editor, not the repository itself. The dev container is defined insrc/.devcontainer, and an editor looks for it in the folder you open. -
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.
Run Goiabada from source
Section titled “Run Goiabada from source”-
Start the auth server, from
src/authserver:Terminal window make serve -
Start the admin console in a second terminal, from
src/adminconsole:Terminal window make serve -
Open the admin console at http://localhost:19091 and sign in as the first administrator: email
[email protected], passworddevcontainer-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.
Run the tests
Section titled “Run the tests”The test suite is one script, run-tests.sh. Run all of it, from src/authserver:
./run-tests.shThat’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:
./run-tests.sh --type modulesThree more options narrow a run:
--dbpicks the database fordataandintegration:mysql,postgres,mssql,sqlite, orall, the default. SQLite is the quickest.--runtakes ago test -runpattern. A pattern that matches no test fails the run, so a typo doesn’t pass as green.--raceruns the unit tiers and the setup wizard’s tests under Go’s race detector.
./run-tests.sh --type integration --db sqlite --run 'TestToken_'./run-tests.sh --help lists every option.
Commit what you generate
Section titled “Commit what you generate”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.
Write docs
Section titled “Write docs”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/:
npm cinpm run devThat serves a live preview at http://localhost:4321. Before you send a change, build the site and run its checks’ tests:
npm run buildnpm testThe 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.
The project
Section titled “The project”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 scriptsARCHITECTURE.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.
Many checks are tests
Section titled “Many checks are tests”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 databases and mail
Section titled “The databases and mail”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.