Testing and command list
Goat groups the most common development operations into .goat scripts located in the herd/ directory.
Instead of manually running successive Docker, generator, migration, test, or frontend tool commands, you can describe the entire process as a single repeatable workflow and run it with one command.
The scripts are executed using Goat's isolation layer. This allows the dependencies and tools required by the project to run in containers, without needing to install them directly on the host system.
This approach provides several benefits:
- standardizes how the project is run across different operating systems,
- reduces dependence on the developer's local machine configuration,
- makes it possible to control versions of Go, Node.js, browsers, and other tools,
- limits the scope of changes made by scripts to resources shared by the project,
- simplifies running the same processes locally and in CI.
Daily work
The most commonly used commands:
| Purpose | Command |
| Start the development environment | goat run:script --path=herd/dev.goat |
| Regenerate the application | goat re |
| Run database migrations | goat run:script --path=herd/db/migrate.goat |
| Clear the local database | goat run:script --path=herd/db/clean.goat |
| Run the full test suite | goat run:script --path=herd/test.goat |
| Synchronize translations | goat run:script --path=herd/translate.goat |
goat run:script
The run:script command runs the specified .goat file:
goat run:script --path=herd/dev.goatThe script file can describe an entire process consisting of multiple steps, for example:
- starting containers,
- preparing dependencies,
- generating code,
- running migrations,
- running tests,
- building the frontend,
- starting the application.
This keeps the development environment logic as part of the project, rather than spreading it across documentation, local scripts, and the configurations of individual developers' machines.
goat re
The command:
goat rereruns the application generation process based on the current model and project configuration.
You will most commonly use it after changes to:
- the domain model,
- entity definitions,
- relationships,
- generator configuration,
- generated code templates.
The generator should make changes in a controlled manner so that the generated application can continue to be developed manually.
After regeneration, it is worth checking the Git diff before committing it.
Testing
You can run the full test suite with:
goat run:script --path=herd/test.goatherd/test.goat defines the complete application verification process.
Before running the actual tests, the script recreates the generated part of the project. This ensures that the code corresponding to the current application model is tested, rather than an arbitrary local state of generated files.
The following are then run, among others:
- Go backend tests,
- frontend application build,
- frontend tests,
- Playwright-based E2E tests.
Where possible, independent stages may run in parallel, reducing the duration of the entire process.
Repeatable test environment
Tests use containers to reduce differences between developers' environments and CI.
This applies in particular to components such as:
- Go,
- Node.js,
- npm,
- browsers used by Playwright,
- PostgreSQL,
- additional tools required when building the application.
As a result, test outcomes should not depend on which version of Node.js or Go a developer currently has installed on their computer.
This is particularly important for E2E tests, which are often sensitive to browser versions and system dependencies.
Isolation during testing and building
Running tools in containers also serves a security purpose.
Operations such as:
npm install
npm test
npm run builddo not need to be performed directly on the host.
Code executed by dependencies runs within a controlled environment and is granted access only to resources exposed by Goat and the project configuration.
This helps reduce, among other things, risks associated with dependency installation scripts such as preinstall, install, or postinstall.
At the same time, isolation does not replace dependency control. It is still worth:
- reviewing library updates,
- using a lockfile,
- controlling dependency sources,
- checking changes before committing them.
Reviewing changes after generation
After running:
goat reor the full test process, it is worth reviewing the changes:
git status
git diffThis makes it possible to see exactly which parts of the application were modified by the generator.
This is particularly useful when changing the domain model. Rather than treating regeneration as an “overwrite the entire application” operation, Goat lets you work with generated changes similarly to manually introduced changes.
You can commit only those files that should actually be included in a given commit.
Debugging scripts
If one of the workflows does not complete successfully, first run the corresponding script directly.
For example, migration issues can be reproduced using:
goat run:script --path=herd/db/migrate.goatand test issues:
goat run:script --path=herd/test.goatSplitting processes into smaller .goat scripts makes it easier to determine whether the issue concerns:
- generation,
- the database,
- the backend,
- the frontend,
- E2E tests,
- environment configuration.
Help for application commands
The generated application also includes its own CLI.
After building it, you can display documentation for individual commands using the --help flag.
For example:
myapp crud:doc:persist --help
myapp db:migrate --help
myapp serve --helpIt is worth using --help instead of relying solely on examples from the documentation, as it shows the parameters available in the currently used version of the application.
Example: crud:doc:persist
The command:
myapp crud:doc:persist --helpdisplays options for creating or updating a document.
Available parameters include, among others:
--lang,--slug,--title,--description,--body-markdown,--body-markdown-file.
For larger content, it is more convenient to provide a file:
myapp crud:doc:persist \
--lang=pl \
--slug=testowanie \
--title="Testowanie" \
--body-markdown-file=./doc/testowanie.mdThis allows documentation content to be stored in the repository and synchronized with the application using the CLI.
Releases
The process for preparing a new release is described in the file:
RELEASING.md
It contains a procedure covering, among other things:
- selecting and setting the new version,
- preparing the required keys,
- building artifacts,
- running tests,
- verifying packages,
- publishing the release.
Do not skip the full test suite before publishing.
Before starting the release process, it is also worth checking:
git statusand ensuring that the repository does not contain any accidental local changes.
A release should only be prepared when:
- the generator works correctly for the current model,
- backend tests pass,
- the frontend builds correctly,
- E2E tests pass,
- the target environment configuration has been verified,
- all changes intended for the release are present in the repository.
Typical workflow
In day-to-day work, the following cycle is usually sufficient:
# modify the application model
vim herd/_model.goat
# generate the resulting changes
goat re
# check the generated code
git diff
# run the tests
goat run:script --path=herd/test.goat
# check the final scope of changes
git statusThis way of working helps maintain a clear separation of responsibilities:
the model describes the intent, the generator produces repeatable code, tests verify the result, and Git remains the ultimate source of information about what has actually changed in the project.