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 things your machine needs are Docker, an editor that opens dev containers, such as VS Code with the Dev Containers extension, and sh, which Linux and macOS have. On Windows, clone the repository inside WSL and open it from there, or add Git for Windows’ usr\bin directory to the PATH: neither WSL nor Git for Windows’ default install puts sh on the Windows PATH.
-
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. Before it,
src/.devcontainer/generate-env.shwritessrc/.devcontainer/.env, the stack’s data key and database passwords, drawn fresh for your checkout. It runs on your machine, which is why it needssh.
Run the commands below inside the container, from the directory each names, except the npm commands, which run on your own machine.
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.
Browser e2e tests
Section titled “Browser e2e tests”The Playwright suites in e2e/ run against the maintainer’s VPS and need SSH access, which
external contributors don’t have. You’re welcome to write or improve these tests. Follow the
e2e README, run
npm ci and npm run typecheck from e2e/playwright on your machine, and say in your pull request
that the browser suites need a maintainer to run them.
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 npm, so build the site on your own machine, with the Node.js version site/Dockerfile builds it with, 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 has four Go modules:
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 gives AI coding assistants the commands and conventions for working here;
CLAUDE.md is a checked copy. The guides in
docs/development/ cover
authentication, data access, application conventions, UI, tests, guards and package
responsibilities. Read
the guide for the part you’re changing.
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 in the admin console’s settings, turn on Send email and set the host to mailpit, the port to 1025, the encryption to None, and Sender 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.