# Development, testing, and releases

The repository does not require a host Rust installation. The Dockerfile uses
musl and produces a `scratch` runtime image containing only the executable.

## Local source build

[`deploy/docker-compose.build.yml`](../deploy/docker-compose.build.yml) builds
the checked-out source. Its build context and bind mounts point back to the
repository root.

```bash
cp config.example.toml config.toml
mkdir -p data
USHORT_UID="$(id -u)" USHORT_GID="$(id -g)" \
  docker compose -f deploy/docker-compose.build.yml up --build -d
```

The production definition,
[`deploy/docker-compose.prod.yml`](../deploy/docker-compose.prod.yml), never
builds source. It pulls the published version instead and is therefore the
recommended quick-start path in the root README.

## Automated tests

Run all Rust targets in the isolated tester stage:

```bash
docker build --target tester .
```

Run the real HTTP trailing-slash suite against a disposable deployment:

```bash
sh tests/smoke.sh https://s.example.com "$API_KEY"
sh tests/smoke.sh https://example.com/s "$API_KEY"
```

The smoke test creates and removes one temporary short URL.

## Multi-architecture release

Buildx can publish AMD64 and ARM64 from the same source:

```bash
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t sodium/ushort:latest \
  --push .
```

Inspect and record the OCI index digest before deployment:

```bash
docker buildx imagetools inspect sodium/ushort:latest
```

The embedded frontend test verifies every file under `static/` byte-for-byte,
so no separate web-root packaging step is required.
