A beginner-friendly guide to using the Ampel Makefile for development, testing, and deployment.
- What is a Makefile?
- Quick Reference
- Development Commands
- Build Commands
- Testing Commands
- Code Quality Commands
- Security & Dependencies
- Docker Commands
- Deployment Commands
- GitHub Actions Integration
- Internationalization (i18n) Commands
- Customizing the Makefile
- Troubleshooting
A Makefile is a build automation tool that simplifies complex command sequences into simple, memorable commands. Instead of typing long commands like:
cd frontend && pnpm install && cd .. && cargo build --releaseYou can just run:
make install build-release- Unified Interface: Single command structure for backend (Rust) and frontend (React/TypeScript)
- Reduced Complexity: Hides implementation details behind intuitive commands
- Consistency: Same commands work for all developers regardless of environment
- Documentation: Self-documenting through the
make helpcommand - Automation: Chains multiple operations together (build → test → deploy)
| Command | Description | When to Use |
|---|---|---|
make help |
Show all available commands | When you forget a command |
make install |
Install all dependencies | First time setup, after pulling changes |
make dev-api |
Start API server | Backend development |
make dev-frontend |
Start frontend dev server | Frontend development |
make test |
Run all tests | Before committing code |
make test-integration |
Run integration tests with PostgreSQL | Mimicking CI locally |
make lint-fix |
Auto-fix code issues | Before committing, during development |
make docker-up |
Start all services with Docker | Full-stack development, testing integrations |
make build-i18n |
Build ampel-i18n CLI tool | Developing i18n features |
make i18n ARGS='...' |
Run ampel-i18n with custom arguments | Managing translations |
First-time setup:
make install # Install dependencies
make docker-up # Start database and Redis
make dev-api # In terminal 1: Start API
make dev-frontend # In terminal 2: Start frontendDaily development:
make test # Run tests before starting work
make dev-api # Start backend
make lint-fix # Fix any linting issues
make test # Run tests before committingBefore committing:
make format # Format all code
make lint # Check for issues
make test # Run all testsInstalls all project dependencies (backend Rust toolchain + frontend npm packages).
What it does:
- Verifies Rust toolchain installation
- Runs
pnpm installin the frontend directory
When to use:
- First time cloning the repository
- After pulling changes that modify dependencies
- When dependency errors occur
Example output:
$ make install
==> Checking Rust toolchain...
active toolchain
----------------
1.92.0-x86_64-unknown-linux-gnu (default)
rustc 1.92.0 (ded5c06cf 2025-12-08)
==> Installing frontend dependencies...
Packages: +243
Progress: resolved 243, reused 243, downloaded 0, added 243, doneTroubleshooting:
- "rustup: command not found": Install Rust from rustup.rs
- "pnpm: command not found": Install pnpm with
npm install -g pnpm
Starts the backend API server in development mode.
What it does:
- Runs
cargo run --bin ampel-api - Starts API server on
http://localhost:8080 - Enables hot-reloading with cargo watch (if installed)
When to use:
- Backend development
- Testing API endpoints
- Debugging backend issues
Prerequisites:
- Database running (use
make docker-upto start PostgreSQL) .envfile configured withDATABASE_URL
Example:
$ make dev-api
==> Starting API server...
2025-12-22T12:00:00.000Z INFO [ampel_api] Starting Ampel API server
2025-12-22T12:00:00.001Z INFO [ampel_api] Listening on 0.0.0.0:8080
2025-12-22T12:00:00.002Z INFO [ampel_api] API documentation at http://localhost:8080/api/docsAccess:
- API:
http://localhost:8080 - Swagger docs:
http://localhost:8080/api/docs
Troubleshooting:
- "Connection refused": Ensure database is running with
make docker-up - "Port already in use": Stop existing API process or change port in
.env - Compilation errors: Run
make clean buildto rebuild
Starts the background job worker in development mode.
What it does:
- Runs
cargo run --bin ampel-worker - Processes background jobs (PR syncing, notifications, etc.)
- Connects to PostgreSQL and Redis
When to use:
- Developing background job features
- Testing async task processing
- Full-stack development requiring job processing
Prerequisites:
- Database and Redis running (
make docker-up) .envconfigured withDATABASE_URLandREDIS_URL
Example:
$ make dev-worker
==> Starting background worker...
2025-12-22T12:00:00.000Z INFO [ampel_worker] Starting Apalis worker
2025-12-22T12:00:00.001Z INFO [ampel_worker] Connected to PostgreSQL
2025-12-22T12:00:00.002Z INFO [ampel_worker] Worker ready for jobsTroubleshooting:
- "Failed to connect to Redis": Ensure Redis is running (
docker ps) - Jobs not processing: Check database connection and job queue tables
Starts the frontend development server with hot-reloading.
What it does:
- Runs
cd frontend && pnpm run dev - Starts Vite dev server on
http://localhost:5173 - Enables hot module replacement (HMR)
When to use:
- Frontend development
- UI/UX work
- Testing React components
Prerequisites:
- Frontend dependencies installed (
make install) - API server running (
make dev-api) for full functionality
Example:
$ make dev-frontend
==> Starting frontend dev server...
VITE v5.0.0 ready in 324 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show helpAccess:
- Frontend:
http://localhost:5173
Troubleshooting:
- Blank page: Check browser console for API connection errors
- "Module not found": Run
make installto install dependencies - Slow HMR: Clear Vite cache with
rm -rf frontend/node_modules/.vite
Reminder command that shows how to start all services for full-stack development.
What it does:
- Prints instructions for starting API, worker, and frontend
- Suggests using Docker Compose as an alternative
Output:
$ make dev
Starting all services...
Run these in separate terminals:
make dev-api
make dev-worker
make dev-frontend
Or use: docker compose upRecommended workflow:
Use 3 separate terminal windows/tabs:
# Terminal 1
make dev-api
# Terminal 2
make dev-worker
# Terminal 3
make dev-frontendOr use Docker for simplicity:
make docker-upBuilds the entire project in debug mode (faster compilation, slower runtime).
What it does:
- Runs
cargo buildfor backend - Runs
pnpm run buildfor frontend
When to use:
- Testing build process locally
- Debugging build issues
- Verifying all code compiles
Example:
$ make build
==> Building backend...
Compiling ampel-api v0.1.0
Compiling ampel-worker v0.1.0
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 13s
==> Building frontend...
vite v5.0.0 building for production...
✓ 1234 modules transformed.
dist/index.html 0.45 kB │ gzip: 0.30 kB
dist/assets/index-abc123.js 543.21 kB │ gzip: 123.45 kB
✓ built in 12.34sOutput locations:
- Backend:
target/debug/ampel-api,target/debug/ampel-worker - Frontend:
frontend/dist/
Troubleshooting:
- Compilation errors: Check error messages, ensure dependencies are installed
- Disk space issues: Run
make cleanto free space
Builds the project in release mode (slower compilation, optimized runtime).
What it does:
- Runs
cargo build --releasefor backend - Runs
pnpm run buildfor frontend (production mode)
When to use:
- Before deployment
- Performance testing
- Creating production binaries
Example:
$ make build-release
==> Building backend (release)...
Compiling ampel-api v0.1.0
Compiling ampel-worker v0.1.0
Finished `release` profile [optimized] target(s) in 5m 34s
==> Building frontend...
[Production build output]Output locations:
- Backend:
target/release/ampel-api,target/release/ampel-worker - Frontend:
frontend/dist/
Performance:
- Release builds are ~10-100x faster at runtime
- Compilation takes 2-3x longer
- Binary size may be larger (contains optimizations)
Removes all build artifacts to free disk space or fix build issues.
What it does:
- Runs
cargo clean(removestarget/directory) - Removes
frontend/distand Vite cache
When to use:
- Build errors that persist after code changes
- Freeing disk space (Rust builds can use 1-5 GB)
- Switching between debug and release builds
Example:
$ make clean
==> Cleaning backend...
==> Cleaning frontend...Note: After cleaning, you'll need to rebuild with make build.
Runs all tests (backend + frontend) in one command.
What it does:
- Runs
cargo test --all-featuresfor Rust tests - Runs
pnpm run test -- --runfor Vitest tests
When to use:
- Before committing code
- Verifying changes don't break existing functionality
- CI/CD validation locally
Example:
$ make test
==> Running backend tests...
Compiling ampel-api v0.1.0
Finished `test` profile [unoptimized + debuginfo] target(s) in 1m 23s
Running unittests src/lib.rs (target/debug/deps/ampel_api-...)
running 47 tests
test auth::tests::test_jwt_creation ... ok
test db::tests::test_connection_pool ... ok
...
test result: ok. 47 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
==> Running frontend tests...
✓ src/components/Dashboard.test.tsx (3 tests) 234ms
✓ src/api/auth.test.ts (5 tests) 123ms
...
Test Files 12 passed (12)
Tests 43 passed (43)
Start at 12:34:56
Duration 2.34sExit codes:
0: All tests passed101: Tests failed
Troubleshooting:
- Database connection errors: Use SQLite in-memory for tests (see TESTING.md)
- Flaky tests: Run individual test with
cargo test test_nameorpnpm test path/to/test.tsx - Timeout errors: Increase timeout in test configuration
Runs only backend tests (faster than full test suite).
What it does:
- Runs
cargo test --all-features - Includes unit tests and integration tests
When to use:
- Backend-only changes
- Faster iteration during backend development
- Debugging backend test failures
Example:
$ make test-backend
==> Running backend tests...
running 47 tests
test result: ok. 47 passed; 0 failedTest filtering:
Run specific tests:
cargo test auth # Tests with "auth" in name
cargo test test_login # Specific test
cargo test --lib # Only unit tests
cargo test --test integration # Only integration testsRuns integration tests with PostgreSQL using the same configuration as CI.
What it does:
- Installs
cargo-nextestif not present - Starts PostgreSQL via Docker Compose
- Creates
ampel_testdatabase if needed - Sources
JWT_SECRETandENCRYPTION_KEYfrom.env - Runs tests with retries and parallel execution (same as GitHub Actions)
When to use:
- Validating changes pass CI before pushing
- Testing PostgreSQL-specific code paths (skipped in SQLite mode)
- Debugging CI failures locally
Prerequisites:
- Docker installed and running
.envfile configured withJWT_SECRETandENCRYPTION_KEY
Example:
$ make test-integration
==> Running integration tests with PostgreSQL (CI mode)...
Waiting for PostgreSQL to be ready...
────────────
Nextest run ID abc123 with nextest profile: default
Starting 200 tests across 24 binaries
PASS [ 0.234s] ampel-api::auth_tests test_login_success
PASS [ 0.123s] ampel-api::auth_tests test_register_success
...
Summary [ 45.678s] 200 tests run: 200 passed, 0 skippedTest configuration (mirrors CI):
--all-features: Enable all Cargo features--no-fail-fast: Run all tests even if some fail--test-threads 2: Run 2 tests in parallel--retries 3: Retry flaky tests up to 3 times
Troubleshooting:
- "Cannot connect to Docker": Ensure Docker daemon is running
- Database errors: Run
make docker-downthen try again - Missing secrets: Ensure
.envhasJWT_SECRETandENCRYPTION_KEY
Runs only frontend tests with Vitest.
What it does:
- Runs
cd frontend && pnpm run test -- --run - Executes all
.test.tsand.test.tsxfiles
When to use:
- Frontend-only changes
- UI component testing
- Faster iteration during frontend development
Example:
$ make test-frontend
==> Running frontend tests...
Test Files 12 passed (12)
Tests 43 passed (43)Watch mode (for development):
cd frontend && pnpm testGenerates code coverage reports for both backend and frontend.
What it does:
- Installs
cargo-llvm-covif not present (5-10x faster than tarpaulin) - Runs backend tests with LLVM source-based coverage instrumentation
- Runs frontend tests with coverage
- Generates HTML and LCOV reports
When to use:
- Verifying test coverage meets standards (target: 80%)
- Finding untested code paths
- Before major releases
Example:
$ make test-coverage
==> Running backend tests with coverage (cargo-llvm-cov)...
Installing cargo-llvm-cov... # First time only
[Progress...]
==> Backend coverage report: coverage/html/index.html
==> Running frontend tests with coverage...
==> Coverage reports generated:
Backend: coverage/lcov.info, coverage/html/
Frontend: frontend/coverage/Viewing reports:
# Backend
open coverage/html/index.html
# Frontend
open frontend/coverage/index.htmlInterpreting coverage:
- Green: Well-tested code (80%+ coverage)
- Yellow: Moderate coverage (50-80%)
- Red: Under-tested code (<50%)
Troubleshooting:
- Missing llvm-tools: Run
rustup component add llvm-tools-preview - Missing coverage: Ensure tests actually execute the code paths
Backend-only coverage report (faster than full coverage).
Output: coverage/html/index.html and coverage/lcov.info
Frontend-only coverage report.
Output: frontend/coverage/index.html
Runs all linters (backend Clippy, frontend ESLint, markdown linter).
What it does:
cargo clippy --all-targets --all-features -- -D warningscd frontend && pnpm run lint && pnpm run type-checkpnpm run lint:md
When to use:
- Before committing code
- Catching common mistakes and anti-patterns
- Enforcing code style consistency
Example:
$ make lint
==> Linting backend...
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s
Checking ampel-api v0.1.0
==> Linting frontend...
✓ No linting errors found
==> Linting markdown files...
✓ All markdown files are validCommon issues:
- Clippy warnings: Follow suggestions to improve code quality
- ESLint errors: Run
make lint-fixto auto-fix - Type errors: Fix TypeScript type mismatches
Troubleshooting:
- Too strict: Clippy is configured with
-D warnings(all warnings are errors) - False positives: Use
#[allow(clippy::specific_lint)]sparingly with justification
Auto-fixes linting issues where possible.
What it does:
cargo clippy --fix --allow-dirty --allow-stagedcd frontend && pnpm run lint --fixpnpm run lint:md:fix
When to use:
- After writing code with minor style issues
- Before committing to clean up code
- Bulk formatting fixes
Example:
$ make lint-fix
==> Auto-fixing backend lint issues...
Fixed 12 issues automatically
==> Auto-fixing frontend lint issues...
✔ 8 problems fixed
==> Auto-fixing markdown lint issues...
Fixed 3 formatting issuesNote: Not all issues can be auto-fixed. Review remaining warnings manually.
Formats all code (Rust with rustfmt, frontend with Prettier, markdown with Prettier).
What it does:
cargo fmt --allcd frontend && pnpm run formatpnpm run format(markdown)
When to use:
- Before every commit
- After bulk code changes
- Team collaboration (ensures consistent style)
Example:
$ make format
==> Formatting backend...
==> Formatting frontend...
==> Formatting markdown files...Configuration:
- Backend:
rustfmt.toml - Frontend:
.prettierrc - Markdown:
.prettierrc
Checks if code is formatted without making changes.
What it does:
cargo fmt --all -- --checkcd frontend && pnpm run format:checkpnpm run format:check
When to use:
- CI/CD pipelines
- Pre-commit hooks
- Verifying code is ready to commit
Example:
$ make format-check
==> Checking backend formatting...
✓ All files are formatted correctly
==> Checking frontend formatting...
✓ All files are formatted correctly
==> Checking markdown formatting...
✓ All markdown files are formatted correctlyExit codes:
0: All files formatted correctly1: Some files need formatting (runmake format)
Runs security audits on all dependencies.
What it does:
- Installs
cargo-auditif missing - Runs
cargo auditfor Rust dependencies - Runs
pnpm auditfor npm dependencies
When to use:
- Weekly security checks
- Before deployments
- After updating dependencies
Example:
$ make audit
==> Auditing backend dependencies...
Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
Loaded 567 security advisories (from /home/user/.cargo/advisory-db)
Scanning Cargo.lock for vulnerabilities (234 crate dependencies)
✓ No vulnerabilities found
==> Auditing frontend dependencies...
found 0 vulnerabilitiesHandling vulnerabilities:
# View details
cargo audit
# Update vulnerable dependencies
make upgrade
# If no fix available, assess risk and document exceptionVerifies license compliance for all dependencies.
What it does:
- Installs
cargo-denyif missing - Runs
cargo deny check licenses - Runs
npx license-checker --summaryfor frontend
When to use:
- Before adding new dependencies
- Legal compliance reviews
- Open-source releases
Example:
$ make license-check
==> Checking backend license compliance...
✓ All licenses are approved
==> Checking frontend license compliance...
├─ MIT: 189
├─ ISC: 34
├─ Apache-2.0: 23
└─ BSD-3-Clause: 12Configuration:
- Backend:
deny.toml(allowed licenses) - Review licenses before accepting new dependencies
Lists outdated dependencies (but doesn't update them).
What it does:
- Installs
cargo-outdatedif missing - Runs
cargo outdated -R(root dependencies only) - Runs
pnpm outdatedfor frontend
When to use:
- Monthly dependency reviews
- Before planning updates
- Security maintenance
Example:
$ make outdated
==> Checking for outdated backend dependencies...
Name Project Compat Latest Kind
---- ------- ------ ------ ----
axum 0.6.0 0.6.20 0.7.0 Normal
tokio 1.32.0 1.35.1 1.35.1 Normal
==> Checking for outdated frontend dependencies...
Package Current Wanted Latest
react 19.0.0 19.0.0 19.0.1
vite 5.0.0 5.0.0 5.1.0Interpretation:
- Project: Current version
- Compat: Latest compatible with semver
- Latest: Newest version (may require breaking changes)
Updates dependencies to latest compatible versions (respects semver).
What it does:
- Runs
cargo update(updatesCargo.lock) - Runs
cd frontend && pnpm update(updatespnpm-lock.yaml)
When to use:
- Monthly maintenance updates
- After reviewing
make outdated - Security patches
Example:
$ make upgrade
==> Upgrading backend dependencies...
Updating crates.io index
Updating axum v0.6.0 -> v0.6.20
Updating tokio v1.32.0 -> v1.35.1
Dependencies updated in Cargo.lock
==> Upgrading frontend dependencies...
Progress: resolved 243, reused 241, downloaded 2, added 0, done
Dependencies updated in pnpm-lock.yamlAfter upgrading:
make test # Verify nothing broke
make audit # Check for new vulnerabilities
git add Cargo.lock pnpm-lock.yaml
git commit -m "chore: update dependencies"Updates to latest versions (may break semver, use cautiously).
What it does:
- Installs
cargo-editif missing - Runs
cargo upgradethencargo update - Runs
cd frontend && pnpm update --latest
When to use:
- Major version upgrades
- Migration to new library versions
- After thorough testing in a branch
Example:
$ make upgrade-latest
==> Upgrading backend to latest versions...
Updating axum v0.6.0 -> v0.7.0 (BREAKING)
Updating tokio v1.32.0 -> v1.35.1
==> Upgrading frontend to latest versions...
Updating react v19.0.0 -> v19.0.1Warning: This may introduce breaking changes. Test thoroughly.
Builds all Docker images locally.
What it does:
- Runs
cd docker && docker compose build - Builds images for API, worker, frontend, database, Redis
When to use:
- After changing Dockerfiles
- Testing production builds locally
- Preparing for deployment
Example:
$ make docker-build
==> Building Docker images...
[+] Building 234.5s (45/45) FINISHED
=> [api internal] load build definition from Dockerfile.api
=> [worker internal] load build definition from Dockerfile.worker
=> [frontend internal] load build definition from Dockerfile.frontendStarts all services with Docker Compose in detached mode.
What it does:
- Runs
cd docker && docker compose up -d - Starts PostgreSQL, Redis, API, worker, frontend
When to use:
- Full-stack development
- Testing integrations
- Simplifying local setup (no need for 3 terminals)
Example:
$ make docker-up
==> Starting Docker services...
[+] Running 5/5
✔ Container ampel-postgres Started
✔ Container ampel-redis Started
✔ Container ampel-api Started
✔ Container ampel-worker Started
✔ Container ampel-frontend StartedAccess:
- Frontend:
http://localhost:5173 - API:
http://localhost:8080 - API Docs:
http://localhost:8080/api/docs - PostgreSQL:
localhost:5432(user:ampel, password:ampel) - Redis:
localhost:6379
Viewing logs:
make docker-logsStops all Docker services.
What it does:
- Runs
cd docker && docker compose down - Stops containers but preserves volumes (database data)
When to use:
- Ending development session
- Freeing system resources
- Before rebuilding images
Example:
$ make docker-down
==> Stopping Docker services...
[+] Running 5/5
✔ Container ampel-frontend Stopped
✔ Container ampel-worker Stopped
✔ Container ampel-api Stopped
✔ Container ampel-redis Stopped
✔ Container ampel-postgres StoppedStops services, rebuilds images, and starts them again.
What it does:
- Runs
cd docker && docker compose down && docker compose up -d --build
When to use:
- After changing Dockerfiles
- Applying code changes to running containers
- Troubleshooting container issues
Example:
$ make docker-restart
==> Restarting Docker services with rebuild...
[Rebuilding and restarting all services]Shows live logs from all Docker containers.
What it does:
- Runs
cd docker && docker compose logs -f - Streams logs with color coding by service
When to use:
- Debugging issues
- Monitoring application behavior
- Viewing startup messages
Example:
$ make docker-logs
ampel-api | 2025-12-22T12:00:00Z INFO [ampel_api] Starting API server
ampel-worker | 2025-12-22T12:00:00Z INFO [ampel_worker] Processing job: sync_prs
ampel-frontend | VITE v5.0.0 ready in 324 msFiltering logs:
# Single service
cd docker && docker compose logs -f api
# Last 100 lines
cd docker && docker compose logs --tail 100Removes all Docker resources including volumes (deletes database data).
What it does:
- Runs
cd docker && docker compose down -v --rmi local - Deletes containers, volumes, networks, and local images
When to use:
- Complete reset of Docker environment
- Freeing disk space
- Troubleshooting persistent issues
Example:
$ make docker-clean
==> Cleaning Docker resources...
[+] Running 8/8
✔ Container ampel-frontend Removed
✔ Container ampel-api Removed
✔ Volume ampel_postgres_data Removed
✔ Network ampel_default RemovedWarning: This deletes all database data. Backup first if needed.
Deploys all services to Fly.io (API, worker, frontend).
What it does:
- Runs
fly deployfor each service with respective configs - Deploys API, worker, and frontend in sequence
Prerequisites:
- Fly.io CLI installed:
brew install flyctl - Authenticated:
fly auth login - Fly.io apps created (see deployment docs)
When to use:
- Production deployments
- Staging environment updates
Example:
$ make deploy-fly
==> Deploying API to Fly.io...
==> Building image
--> Building image done
==> Pushing image to fly
==> Creating release
--> Release v5 created
==> Deploying worker to Fly.io...
[Worker deployment output]
==> Deploying frontend to Fly.io...
[Frontend deployment output]
==> Deployment complete!Individual deployments:
make deploy-fly-api # API only
make deploy-fly-worker # Worker only
make deploy-fly-frontend # Frontend onlyTroubleshooting:
- Build failures: Check Docker configuration and logs
- Health check failures: Verify service starts correctly locally first
- Database connection errors: Ensure database secrets are set in Fly.io
These commands require the GitHub CLI (gh).
Triggers the CI workflow on your current branch.
What it does:
- Gets current branch name
- Runs
gh workflow run ci.yml --ref <branch>
When to use:
- Testing CI before pushing
- Re-running failed CI builds
- Manual CI triggers
Example:
$ make gh-ci
==> Triggering CI workflow...
CI workflow triggered on branch: feature/new-auth
Run 'make gh-watch' to monitor progressMonitoring:
make gh-watch # Watch live progress
make gh-status # View recent CI runsCreates and pushes a release tag, triggering the release workflow.
What it does:
- Creates annotated git tag
v<version> - Pushes tag to GitHub
- Triggers automated release workflow
When to use:
- Creating new releases
- Deploying to production
Example:
$ make gh-release V=1.2.3
==> Creating release v1.2.3...
Release v1.2.3 tag pushed. Release workflow will start automatically.
Run 'make gh-watch' to monitor progressRequirements:
- Version must follow semver (e.g.,
1.2.3, notv1.2.3) - Tag must not already exist
- You must be on the correct branch (usually
main)
Troubleshooting:
- "Tag already exists": Use
git tag -d v1.2.3to delete locally,git push origin :refs/tags/v1.2.3to delete remotely - Failed workflow: Check GitHub Actions tab for errors
Watches the latest workflow run with live updates.
What it does:
- Runs
gh run watch - Shows real-time progress of CI/CD jobs
When to use:
- After triggering CI with
make gh-ci - After creating a release
- Monitoring deploy progress
Example:
$ make gh-watch
==> Watching latest workflow run...
✓ backend-tests 3s
✓ frontend-tests 2s
* docker-build Running...
deploy PendingLists the 10 most recent workflow runs.
What it does:
- Runs
gh run list --limit 10
Example:
$ make gh-runs
STATUS TITLE WORKFLOW BRANCH EVENT ID
✓ CI CI main push 123456789
✗ CI CI feat/auth pull_request 123456788
✓ Release v1.2.2 Release main push 123456787Shows status of the 5 most recent CI workflow runs.
What it does:
- Runs
gh run list --workflow=ci.yml --limit 5
Example:
$ make gh-status
STATUS TITLE WORKFLOW BRANCH EVENT ID
✓ CI CI main push 123456789
✓ CI CI feat/auth push 123456788These commands help build, test, and use the ampel-i18n CLI tool for managing translations in the Ampel project.
Builds the ampel-i18n CLI tool in debug mode.
What it does:
- Runs
cargo build --package ampel-i18n-builder --bin ampel-i18n - Compiles the translation automation tool
When to use:
- Developing i18n features
- Testing the CLI tool locally
- Before running i18n commands
Example:
$ make build-i18n
==> Building ampel-i18n CLI tool...
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.34sOutput: target/debug/ampel-i18n
Builds the ampel-i18n CLI tool in release mode with optimizations.
What it does:
- Runs
cargo build --package ampel-i18n-builder --bin ampel-i18n --release - Creates optimized binary for production use
When to use:
- Installing the tool for regular use
- Performance-critical translation tasks
- CI/CD pipelines
Example:
$ make build-i18n-release
==> Building ampel-i18n CLI tool (release)...
Finished `release` profile [optimized] target(s) in 4.56sOutput: target/release/ampel-i18n
Runs all tests for the i18n-builder crate.
What it does:
- Runs
cargo test --package ampel-i18n-builder --all-features - Tests translation automation, API clients, code generation
When to use:
- After modifying i18n code
- Verifying i18n functionality
- Before committing i18n changes
Example:
$ make test-i18n
==> Running i18n-builder tests...
Finished `test` profile [optimized + debuginfo] target(s) in 20.99s
Running unittests src/lib.rs
running 20 tests
test codegen::rust::tests::test_rust_generator ... ok
test translator::deepl::tests::test_deepl_translate ... ok
test formats::json::tests::test_parse_simple_json ... ok
...
test result: ok. 20 passed; 0 failed; 0 ignored; 0 measuredTest coverage:
- Unit tests for code generators (Rust/TypeScript)
- Integration tests for translation APIs (DeepL, OpenAI)
- Format parser tests (JSON, YAML)
- CLI command tests
Generates code coverage report for the i18n-builder crate.
What it does:
- Installs
cargo-llvm-covif not present - Runs tests with coverage instrumentation
- Generates HTML report in
coverage/i18n/
When to use:
- Verifying i18n test coverage
- Finding untested code paths
- Before releasing i18n features
Example:
$ make test-i18n-coverage
==> Running i18n-builder tests with coverage...
Installing cargo-llvm-cov... # First time only
==> I18n coverage report: coverage/i18n/index.htmlViewing report:
open coverage/i18n/index.htmlInstalls the ampel-i18n tool to ~/.cargo/bin for system-wide use.
What it does:
- Runs
cargo install --path crates/ampel-i18n-builder --bin ampel-i18n --force - Installs tool to Cargo's bin directory
- Makes
cargo i18navailable globally
When to use:
- First-time setup for translation workflow
- After updating i18n tool code
- For regular translation management
Example:
$ make install-i18n
==> Installing ampel-i18n CLI tool...
Installing ampel-i18n v0.1.0
Finished `release` profile [optimized] target(s) in 5.23s
Installing ~/.cargo/bin/ampel-i18n
ampel-i18n installed to ~/.cargo/bin/ampel-i18n
Run 'cargo i18n --help' to get startedVerification:
$ cargo i18n --help
Translation automation for Ampel
Usage: cargo i18n <COMMAND>
Commands:
translate Translate missing keys using AI translation service
sync Sync all languages from source language
validate Validate translation files for errors
coverage Check translation coverage statistics
...Troubleshooting:
- "cargo i18n: command not found": Ensure
~/.cargo/binis in yourPATH - Permission errors: Check file permissions in
~/.cargo/bin
Removes i18n-builder build artifacts to free disk space.
What it does:
- Runs
cargo clean --package ampel-i18n-builder - Cleans only i18n crate artifacts
When to use:
- Freeing disk space
- Fixing i18n build issues
- After major i18n changes
Example:
$ make clean-i18n
==> Cleaning i18n-builder artifacts...Runs the ampel-i18n tool with custom arguments (without installing).
What it does:
- Runs
cargo run --package ampel-i18n-builder --bin ampel-i18n -- <ARGS> - Executes i18n commands directly from source
When to use:
- Running i18n commands during development
- Testing CLI changes without installing
- Quick translation tasks
Common usage examples:
# Show help
make i18n ARGS='--help'
# Translate missing keys to Spanish
make i18n ARGS='translate --lang es'
# Sync all languages from English source
make i18n ARGS='sync --source en'
# Validate all translation files
make i18n ARGS='validate'
# Check translation coverage
make i18n ARGS='coverage'
# Export translations for external service
make i18n ARGS='export --lang fr --format xliff'
# Import translations from external service
make i18n ARGS='import --lang fr --file translations.xliff'Example output:
$ make i18n ARGS='coverage'
==> Running ampel-i18n...
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.24s
Running `target/debug/ampel-i18n coverage`
Translation Coverage Report:
╭──────────┬────────────┬──────────┬──────────╮
│ Language │ Total Keys │ Translated│ Coverage │
├──────────┼────────────┼──────────┼──────────┤
│ en │ 245 │ 245 │ 100.0% │
│ es │ 245 │ 198 │ 80.8% │
│ fr │ 245 │ 156 │ 63.7% │
│ de │ 245 │ 102 │ 41.6% │
╰──────────┴────────────┴──────────┴──────────╯Troubleshooting:
- API errors: Ensure translation API keys are configured in
.env - File not found: Check that translation files exist in expected locations
- Rate limiting: Use caching features to reduce API calls
Complete translation workflow:
# 1. Build the tool
make build-i18n
# 2. Check current coverage
make i18n ARGS='coverage'
# 3. Validate existing translations
make i18n ARGS='validate'
# 4. Translate missing keys (requires API keys)
make i18n ARGS='translate --lang es --provider deepl'
make i18n ARGS='translate --lang fr --provider openai'
# 5. Check updated coverage
make i18n ARGS='coverage'
# 6. Run tests
make test-i18n
# 7. Install for regular use
make install-i18nUsing installed tool:
# After installation
cargo i18n coverage
cargo i18n translate --lang de
cargo i18n validateEdit the Makefile and add a new target:
.PHONY: my-command
my-command:
@echo "==> Running my custom command..."
cargo run --example my_exampleThen run:
make my-commandDefine variables at the top of the Makefile:
PORT ?= 8080
DATABASE_URL ?= postgres://localhost/ampel
dev-api:
DATABASE_URL=$(DATABASE_URL) cargo run --bin ampel-apiOverride from command line:
make dev-api DATABASE_URL=postgres://prod-db/ampelCombine multiple targets:
deploy: test build-release deploy-fly
@echo "==> Deployed successfully!"Run with:
make deploy # Runs test → build-release → deploy-flyCheck for prerequisites:
check-env:
@test -f .env || { echo "Error: .env not found"; exit 1; }
dev-api: check-env
cargo run --bin ampel-api"make: command not found"
Install Make:
# macOS
brew install make
# Ubuntu/Debian
sudo apt install make
# Windows (Git Bash)
# Make is included with Git for Windows"No rule to make target"
You may have a typo in the command name. Run make help to see available commands.
"Permission denied"
Some commands require Docker or system permissions:
# Add user to docker group (Linux)
sudo usermod -aG docker $USER
newgrp dockerDatabase connection errors
Ensure services are running:
make docker-up
docker ps # Verify containers are runningCheck .env file has correct DATABASE_URL:
DATABASE_URL=postgres://ampel:ampel@localhost:5432/ampelPort already in use
Find and kill the process:
# Find process on port 8080
lsof -i :8080
# Kill process
kill -9 <PID>
# Or change port in .env
PORT=8081Rust compilation errors
Clean and rebuild:
make clean
make buildEnsure Rust toolchain is up to date:
rustup updateFrontend build errors
Clear caches:
cd frontend
rm -rf node_modules/.vite dist
pnpm installDocker build failures
Check Docker daemon is running:
docker psFree up disk space:
docker system prune -aTests failing unexpectedly
Run tests individually to isolate failures:
# Backend
cargo test specific_test_name -- --nocapture
# Frontend
cd frontend && pnpm test src/components/MyComponent.test.tsxCheck for environment issues:
# Use in-memory SQLite for tests
export DATABASE_URL="sqlite::memory:"
cargo test- Check the help:
make help - Read documentation: TESTING.md, ARCHITECTURE.md
- View logs:
make docker-logs - Ask the team: Open an issue or discuss in team chat
# First-time setup
make install
make docker-up
# Daily development
make dev-api # Terminal 1
make dev-frontend # Terminal 2
make dev-worker # Terminal 3 (if needed)
# Before committing
make format
make lint-fix
make test
# Match CI locally (PostgreSQL integration tests)
make test-integration
# Deployment
make build-release
make deploy-fly
# Internationalization
make build-i18n # Build i18n tool
make i18n ARGS='coverage' # Check translation coverage
make test-i18n # Test i18n crate
# Maintenance
make audit
make outdated
make upgradeHappy developing with Ampel! 🚦