Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 management
  • shopiterm_client — TUI client (library)
  • shopiterm_common — Commonly shared data structures (library)
  • shopiterm_notificator — Email notifications
  • shopiterm_orders — Order processing
  • shopiterm_payment — Payment handling with Taler
  • shopiterm_recommendations — Product recommendation engine
  • shopiterm_ssh — SSH terminal interface
  • shopiterm_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 formatting
  • rustfmt — 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:

JobDescription
CheckValidates commit messages, runs nix flake check (format + lint)
BuildBuilds all packages with nix build -L
TestRuns Nix integration tests
ContainerBuilds 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