Development
This page describes our development workflow for building ShopiTerm.
Project Structure
ShopiTerm is a Rust project organized as a workspace with multiple components:
shopiterm_api_client— API client (library)shopiterm_catalogue— Inventory managementshopiterm_client— TUI client (library)shopiterm_common— Commonly shared data structures (library)shopiterm_notificator— Email notificationsshopiterm_orders— Order processingshopiterm_payment— Payment handling with Talershopiterm_recommendations— Product recommendation engineshopiterm_ssh— SSH terminal interfaceshopiterm_warehouse— Stock and warehouse management
For details on the architecture of ShopiTerm, see the corresponding page.
Prerequisites
Building
The entire project is built using a Nix flake. To build the whole project, use:
nix build
The resulting binaries are placed at result.
To build specific services, use:
nix build .#catalogue
nix build .#warehouse
nix build .#orders
[!TIP] When building via Nix, unit tests are automatically run after the build.
Formatting
We use treefmt with:
nixfmt— Nix code formattingrustfmt— Rust code formatting
Format all code:
nix fmt
Linting
Rust linting using clippy is performed when doing a Nix check:
nix flake check -L
Testing
Unit Tests
As stated above, unit tests are automatically run on a Nix build. When having a Rust toolchain installed, they can also be run via Cargo:
cargo test --workspace
Integration Tests
Integration tests are implemented as Nix testers.
These tests spin up virtual machines with the ShopiTerm services and the respective databases configured.
They live in nix/testers.
Inside nix/testers/lib you can find utilities for creating curl requests and mock instances of API items.
nix build .#catalogueTest
nix build .#recommendationsTest
nix build .#sshTest
nix build .#warehouseTest
[!NOTE] These integration tests are not run during a nix build but have to be specifically called.
Live System
There is a special tester running the whole software system for interactive testing:
nix run .#interactiveTest
Git Commit Messages
We enforce Conventional Commits using commitlint:
nix run .#commitlint
Continuous Integration
GitHub Actions (.github/workflows/CI.yaml) runs on every push:
| Job | Description |
|---|---|
| Check | Validates commit messages, runs nix flake check (format + lint) |
| Build | Builds all packages with nix build -L |
| Test | Runs Nix integration tests |
| Container | Builds and pushes container images to registry |
Containers
Each service comes with a container that can be built using Nix:
nix build .#<service>Container
The result will be an OCI image that can be imported:
podman load < result
[!NOTE] Images for each branch are pushed to Quay.io by CI.
Caching
We use Cachix for caching Nix builds. It is enabled in CI, but can also be used locally:
nix run nixpkgs#cachix use shopiterm
Workflow Summary
Here is an overview of what the workflow looks like:
# changes ...
↓
# build
nix build -L
↓
# format
nix fmt
↓
# lint & check
nix flake check -L
↓
# (when related) integration tests
nix build .#<service>Test
↓
# push
git push
↓
# CI checks all above stages (+ commit message)
↓
# CI builds & pushes containers