Development
Run Garage and PostgreSQL with the Web UI locally:
make run
Sign in with admin token local-garage-admin-token. Development credentials are only for the disposable local stack.
Checks
make test
make test-e2e
The E2E target builds the application and starts isolated Garage and PostgreSQL containers. Playwright exercises admin-token creation, editing, revocation, scoped permissions, S3 bucket restrictions, read-only enforcement, and object operations. Cleanup removes only the disposable project and volumes. To include large multipart transfers, use E2E_LARGE_UPLOAD=1 make test-e2e.
PostgreSQL integration tests require GARAGE_WEBUI_TEST_DATABASE_URL. Set it to a test database and run go test -count=1 ./... to bypass the test cache. Tests use isolated schemas. CI provides the database automatically.
Screenshots
make screenshots
This target starts the same isolated stack and captures the real UI with Playwright. Screenshots are written to docs/content/assets/screenshots and referenced by the README and documentation.
SQLite storage tests run without external services. Run the complete browser suite against SQLite with E2E_DATABASE=sqlite make test-e2e; this starts Garage without a PostgreSQL container and removes the disposable SQLite database on completion. CI runs the browser suite against both databases.
Background deletion checks
The job worker is started during application bootstrap. Both PostgreSQL and SQLite apply a deletion-job schema migration automatically. SQLite job tests cover lease takeover and cancellation; the job integration test uses a fake Garage S3 API to verify nested deletion. Run go test ./internal/application/jobs/... ./internal/auth/... ./internal/sqlite/... and make test-e2e after applying these files. Large recursive deletions are destructive: use a disposable Garage bucket for manual verification.