Skip to content

Contributing

Christian edited this page Sep 29, 2026 · 3 revisions

This page explains how a change gets into the control repository: issues, branches and pull requests, the local checks, what CI runs, SBOMs and releases.

New to the code? Set up your machine with Getting-Started, read Architecture, and follow Code-Style.

Issues, branches and pull requests

Branch Role
master Default branch. Releases are tagged here.
staging Integration branch. Feature pull requests and Dependabot's npm and cargo updates land here; a "Staging into master" pull request brings them to master before a release.
  1. Open an issue with one of the templates: Bug report (title prefix BUG: , asks for machine type, software version, steps and error messages) or Feature request (title prefix Feat: ).
  2. Create a branch from staging named after the issue, as GitHub's "Create a branch" button does: <issue number>-<short title>, for example 1057-retrieve-live-data-from-dryer.
  3. Open the pull request against staging and link the issue. The pull request template asks for:
    • what the pull request does, and screenshots for UI changes;
    • tested locally, and tested on the machine if hardware is involved;
    • no format errors (cargo fmt, npm run format) and no build errors (cargo build, npm run build).
  4. Keep the issue alive. Every Sunday, issue-status-check.yml asks the assignees of open issues for a status update when an issue has no linked pull request and no activity for a week.

Run the checks locally

Rust, from the workspace root:

cargo fmt                                  # format
cargo build
cargo test                                 # all workspace tests
cargo test -p qitech_control extruder_v1   # only the extruder adapter contract tests

The contract tests in qitech_control/src/api/legacy/adapter/extruder_v1.rs pin the legacy adapter that serves both extruders to the schemas and to the frontend:

  • the test fixtures cover exactly the paths in extruder_v1.yaml, and extruder_v2.yaml exposes the same paths;
  • every command the adapter emits exists in the schema;
  • the state and live-values payloads match the Zod schemas in electron/src/machines/extruder/extruder2/extruder2Namespace.ts;
  • enum values are written in snake_case and read back in both spellings.

Run them whenever you change an extruder schema, the adapter or the extruder namespace in the frontend. Clippy is installed with the toolchain, but CI doesn't run it.

Frontend, from electron/:

npm ci
npm run lint        # npm run lint:write fixes what it can
npm run format      # npm run format:write rewrites the files
npx tsc             # type check, as CI does
npm test            # Vitest unit tests
npm run test:e2e    # Playwright tests (not run in CI)
npm run build

Nix, from the repository root:

nix fmt
nix flake check --impure

What CI checks

The workflows live in .github/workflows/. rust.yml, electron.yml and nix.yml run on every push and pull request to master and staging.

Workflow Job What it runs
rust.yml build cargo build --verbose
format cargo fmt --check --verbose
test cargo test --verbose
sbom Rust SBOM, uploaded as rust-sbom.json (see below)
electron.yml build npm ci, tsc, npm run build on Node 24
test npm run test (Vitest)
format npm run format
lint npm run lint
sbom Electron SBOM, uploaded as electron-sbom.json
nix.yml electron, rust nix build .#packages.x86_64-linux.electron and .#packages.x86_64-linux.server, cached in the qitech Cachix cache
build Builds the full NixOS system nixosConfigurations.nixos
format nix fmt -- --fail-on-change
nix-check nix flake check --impure
iso.yml nix-iso ./nixos/nixos-build-iso.sh, uploads the ISO as an artifact. Runs on pushes to master, every Monday at 00:00 UTC and on demand.
issue-status-check.yml check-stale-issues Sundays at 09:00 UTC, see above.

Not covered by CI: cargo clippy and the Playwright tests.

SBOM

Both SBOMs use CycloneDX. BSI TR-03183-2 requires spec 1.6 or later.

# Rust: once
cargo install cargo-cyclonedx --locked
# Rust: writes sbom.json next to each crate's Cargo.toml (spec 1.5)
cargo cyclonedx --all --format json --spec-version 1.5 --override-filename sbom

# Electron: writes electron/sbom.json (spec 1.6)
cd electron && npm run sbom

cargo-cyclonedx stops at spec 1.5, so the sbom job in rust.yml converts qitech_control/sbom.json to 1.6 with cyclonedx convert --output-version v1_6. Both sbom jobs then use jq to mark the dependency graph as complete (compositions) and set the manufacturer URL. Download the results from the workflow run's artifacts.

Releasing

  1. Merge staging into master with a "Staging into master" pull request.
  2. Bump version in electron/package.json and electron/package-lock.json. The Nix packages take their version from there: nixos/packages/server.nix reads electron/package.json, nixos/packages/electron.nix reads electron/package-lock.json.
  3. Add the release to the top of CHANGELOG.md (format below) in a pull request.
  4. Tag the release commit on master with the bare version, for example 3.2.0 or 4.0.0-rc1 (no v prefix), and publish a GitHub release for the tag. Mark release candidates as pre-release.
  5. Panels install the release from Setup → Update: the page lists the repository's tags, checks out the chosen one and runs nixos-install.sh. See Installation-and-Updates.
  6. The installation ISO comes from iso.yml, which builds it on every push to master.

A changelog entry looks like this:

# `3.2.0`
_25.09.2026_

One paragraph on what the release brings (optional).

## Breaking Changes
- **Laser**: What changed and what operators have to do.

## Extruder V2
- [#1669](https://github.com/qitechgmbh/control/pull/1669) Improved heating with the new Observer-PI algorithm.

## Dependencies
- [#1676](https://github.com/qitechgmbh/control/pull/1676) Update nixpkgs

**Full Changelog**: https://github.com/qitechgmbh/control/compare/3.1.0...3.2.0

The newest release goes first. The heading is the tag in backticks, the date is _DD.MM.YYYY_, sections group changes by area (General, a machine, CI & Nix, Dependencies), and each line starts with the pull request link.

Dependabot

.github/dependabot.yml opens update pull requests:

Ecosystem Directory Schedule Target branch Notes
npm /electron Monthly staging Minor-version updates are ignored.
cargo / Monthly staging Minor-version updates are ignored.
GitHub Actions / Weekly master
Nix flake inputs / Weekdays at 08:00 UTC master Merged automatically, see below.

Mergify approves and merges a Dependabot pull request on its own when it only changes flake.lock and the nix-check job passed.

Clone this wiki locally