# Development and release This page lists the commands to build, test, and package latchd. The service configuration is `/etc/latchd/config.toml`. ## Toolchain Install Rustup with Rust 1.88, then install the native packages used by the PAM link step: ```sh sudo apt-get install build-essential pkg-config libpam0g-dev libpam-modules ``` Keep `Cargo.lock` with dependency changes. ## Build commands | Command | Result | | --- | --- | | `make deps` | Checks Cargo, rustfmt, pkg-config, and the PAM development files | | `make build` | Builds the optimized binary and copies it to `build/latchd` | | `make run-preview` | Builds the binary and opens preview mode | | `make version` | Prints version, commit, epoch, and target metadata | | `make package` | Creates a deterministic archive and SHA-256 file in `dist/` | | `make clean` | Removes `build/`, `dist/`, and Cargo build output | `make build` reads the version from `Cargo.toml`, embeds the current commit, and uses `SOURCE_DATE_EPOCH` for repeatable package metadata. Set `VERSION`, `TARGET`, or `SOURCE_DATE_EPOCH` when you need a different release value. Build for another Rust target with: ```sh make build TARGET=x86_64-unknown-linux-gnu ``` The target toolchain and system libraries must already be installed. ## Test commands Run the fast checks before the host checks: ```sh make fmt make test make lint make doc make integration-test ``` `make check` runs the first four commands together. The integration script uses preview mode and checks metadata, configuration validation, preflight, and safe CLI paths. Run the optional security audit after you install the tool: ```sh cargo install cargo-audit --locked make audit ``` The Go prototype has its own opt-in checks: ```sh make legacy-check make legacy-build ``` The release build never calls these targets. ## Docker check `make docker-test` builds `Dockerfile.test` as `latchd-test:local`. The image installs the PAM development files, Xvfb, and `xauth`, then runs formatting, workspace tests, Clippy, rustdoc, a release build, the CLI script, the capability probe, and the disposable PAM fixture. The container checks build, test, preview, and fixture paths. Run the host checks in a disposable VM when you need a real VT, user session, compositor, or systemd-logind seat. Remove the local image after a test run if you need the space: ```sh docker image rm latchd-test:local ``` ## PAM fixture `make pam-fixture-test` must run as root because it writes temporary files below `/etc/pam.d/`. The script uses unique service names, runs the ignored Rust fixture tests, and removes the files in its exit trap. The fixture checks authentication failure, password-change failure, selected session metadata, and environment values returned by the session module. ## Host checks Use `make system-e2e` to inspect the binary, PAM library, faillock helper, VT device, Xvfb, Wayland socket, and systemd-logind. Use the strict form only in a disposable VM: ```sh make system-e2e-strict ``` The VM needs a test policy, a real VT, a working logind seat, and the X11 or Wayland stack under test. See [End-to-end testing](e2e-testing.md) for the setup and limits. ## Release archive Run the release gates before packaging: ```sh make check make audit make integration-test make docker-test make package ``` `make package` stages the binary, configuration, login policy, systemd unit, README, license, changelog, and build metadata. It sorts the archive, sets a fixed owner and timestamp, then writes the archive checksum and `dist/release.env`. GitLab CI runs the verification and Docker jobs on branch and merge-request pipelines. A tag that matches the SemVer rule runs the package and release jobs. The package job checks that the tag version matches `Cargo.toml` before it creates the artifact. ## Repository changes Keep Rust source under the workspace crates, keep host scripts in `scripts/`, and put sample service files in `extra/`. Add tests beside the behavior they cover, update the changelog with the implementation detail and the user-visible result, then run `git diff --check` before you commit.