originv0.2.0

Updating a project

Scaffold a product with cargo xtask new and keep it current with tested migrations.

Decisions: ADR-0025, ADR-0026.

Two kinds of change

library code        →  cargo / pnpm dependency bump
project structure   →  cargo xtask update

The first is solved by package managers. The second is what makes the difference between a maintainable base and a template that was copied once — and it is what update is for.

Running it

cargo xtask update --dry-run   # report what would change
cargo xtask update             # run the migrations, regenerate, record the version

Each project records the version it tracks:

[origin]
version = "0.2.0"

update runs the migrations between that and the current version, in order, then regenerates and writes the new version back. Comments and layout in app.toml survive — it is a file a human wrote and will read again.

A project tracking a newer version than the running build is refused rather than downgraded: upgrade the Origin dependency instead.

What a migration will not do

  • It never edits product-owned files (ADR-0022).
  • It never guesses where a decision is needed.

Both cases become a checklist:

origin 0.1.0 → 0.2.0
  capability files are generated from app.toml

  Manual steps required:
  → src-tauri/capabilities/default.json grants permissions no profile covers
    (fs:allow-write-text-file, dialog:allow-open). Choose a profile in app.toml, or
    declare `hand_written_capabilities = true` under [origin.overrides].

That is the common case for an application that predates Origin. Widening a security profile to fit is exactly the decision a migration must not make on someone’s behalf.

Deliberate deviations

[origin.overrides]
hand_written_capabilities = true

A migration skips what is listed here and reports it as skipped, rather than overwriting a decision someone made on purpose (§46).

How migrations are tested

Against frozen fixture projects in crates/origin-xtask/tests/fixtures/, copied into a scratch directory and migrated. The tests cover the parts that are easy to get wrong:

  • a convertible capability is replaced by a generated one
  • one that no profile covers is left untouched, with the question handed back
  • running twice changes nothing the second time
  • --dry-run writes nothing
  • comments in app.toml survive
  • a project from the future is refused

Without fixtures, migrations are code that runs exactly once — in someone else’s repository.

Starting a new project

cargo xtask new my-app --name "My App" --id dev.example.myapp

The result is not a blank window: it is the architecture contract, logging, error handling, settings, secrets, storage, a security profile, CI, and a module that is already testable without a desktop session. Its xtask is three lines, so the rules and the generator arrive with a version bump.

Scaffolding uses released registry versions by default. Pass --local to point the generated project at the current Origin checkout instead. Origin’s own CI always tests that local form against main (ADR-0026).

Edit this page on GitHub · Docs for v0.2.0