From 0d5a140dc9b8fade5617583285acf4488d0b69e4 Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Tue, 1 Sep 2026 14:51:03 +0200 Subject: [PATCH 01/15] docs: add release process guide Operator README for the whole release: the component reference, what to click to cut a release, how publish and deploy work, the approval gate, and the one-time environment setup. --- RELEASE.md | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 RELEASE.md diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..cb5ff17bb --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,86 @@ +# Orbit release process + +A release has three phases: cut, publish, deploy. Cutting and publishing are one flow that ends in a GitHub release with the built artifact attached. Deploying is what puts that artifact on the live canisters. All of it runs from the Actions tab. This is the guide to what to click. + +Most of this used to be manual, run from a laptop with the production key. It is now three workflows: **Cut release**, **Deploy frontend**, **Deploy backend**. Publishing was already automated and has not changed. + +## Components + +There is no single "Orbit release". There are independently versioned projects, and nx bumps each one on its own from the conventional commits that touched it. Six produce a deployable artifact. The rest are internal crates that only exist to cascade a version bump. + +The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the artifact name, and the build target, so renaming it is a real change, not a label. The proposed name is the clearer one we would move to in a separate PR if we decide to. + +| Current name | Proposed name | Type | Role and where it deploys | Ships alone | +| --- | --- | --- | --- | --- | +| `wallet-dapp` | `wallet-app` | Frontend | The wallet UI users log into. Asset tarball to the wallet canister (`5fu67`, app.orbit.global). | Yes | +| `marketing-dapp` | `landing-page` | Frontend | The public marketing site. Asset tarball to the marketing canister (orbit.global). | Yes | +| `docs-portal` | `docs-site` | Frontend | The documentation site. Asset tarball to the docs canister (docs.orbit.global). | Yes | +| `station` | `station` | Backend | Per-wallet backend, one deployed per org. Wasm to the control-panel registry, stations self-upgrade. | Yes | +| `upgrader` | `upgrader` | Backend | Per-station helper that performs safe upgrades, paired one-to-one with a station. Wasm to the registry. | Yes | +| `control-panel` | `control-panel` | Backend | The single global registry and directory. Deploys stations. Wasm, deployed as the control-panel canister. | Yes | +| `dfx-orbit` | `orbit-cli` | CLI | The CLI we ship to users. Git tag and GitHub release, users install it themselves. | Yes | +| `*-api`, `orbit-essentials` | (unchanged) | Crates | Shared Candid and types. No artifact, deploys nowhere. | Bumped automatically | + +Things worth stating plainly, because they are the usual source of confusion: + +* The three frontends are separate projects with separate versions and separate asset canisters. They are not one "wallet dapp" bundle. +* Only the Control Panel is a singleton. There is one global instance. Station and Upgrader are multi-instance: the Control Panel deploys a fresh Station per org, and each Station comes paired with its own Upgrader. Station and Upgrader deploy and control each other, which is what makes a station upgrade safe. +* The `station-api` / `upgrader-api` / `control-panel-api` crates are the contract, just the Candid interface and shared types. The bare name (`station`) is the canister that runs; the `-api` crate compiles to no canister. Bumping an api crate cascades a bump into whatever depends on it, which is why one small change can move several version numbers at once. +* `dfx-orbit` and `orbit-cli` are not the same tool. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. + +## Phase 1: cut a release + +Actions tab, run the **Cut release** workflow. The form: + +* **projects**: comma-separated project names, for example `wallet-dapp,station`. Empty releases everything that changed since the last release. This is where you pick the whole batch or a subset. +* **version_specifier**: `auto` lets the conventional commits decide the bump. Override with `patch` / `minor` / `major` if you need to. +* **pre_release**: `none`, or `alpha` / `beta` / `rc` for a pre-release. +* **dry_run**: computes the versions and changelogs and opens nothing, so you can preview. + +It runs `orbit-cli release prepare`, which bumps the versions, writes the changelogs, and updates `.release.json` in one commit, then opens a PR whose body lists exactly what is being released. Review the versions and merge it. If nothing changed, it says so and opens no PR. + +## Phase 2: publish (automatic) + +Merging the release PR touches `.release.json`, which fires the existing **Release** workflow (`release.yaml`). It builds each artifact, creates the `@orbit/-v` tag, and creates the GitHub release with the artifact attached. You do not click anything. + +This stops at the GitHub release. Nothing is on a live canister yet. That is phase 3. + +## Phase 3: deploy + +Two workflows, same shape. Pick a subset or the whole set, deploy to playground with no gate, then promote to production behind a single approval. One approval covers the whole selection. + +### Deploy frontend + +Actions tab, run **Deploy frontend**. Tick the apps you want (wallet on by default, marketing and docs off), and leave **promote_to_production** on unless you want a playground-only run. + +* The **playground** job builds each app for playground and uploads it. Go test at the playground URL. +* The **production** job pauses for approval. Once approved, it uploads the released tarball to production. + +Frontend config is baked in at build time, so playground gets its own build while production deploys the released production tarball. + +### Deploy backend + +Actions tab, run **Deploy backend**. Tick station, upgrader, or control-panel, and leave promote on unless it is a playground-only run. The two backend types deploy differently: + +* **station / upgrader**: `orbit-cli registry publish` loads the wasm into the control-panel registry. This only makes the version available. Each production station still upgrades itself, or its upgrader, only when that station's own admins submit and approve the request (finance being 2-of-N). Publishing station also publishes upgrader, its dependency. +* **control-panel**: a direct `dfx canister install --mode upgrade` of the one canister. There is no registry and no per-wallet buffer, so the approval gate is the only thing between this and every wallet. Handle with care. + +### The approval gate + +The gate is native **GitHub Environments**. A `playground` environment that runs freely, and a `production` environment that requires a named approver. When a run reaches the production job, GitHub pauses it and shows a "review pending deployments" banner. A reviewer clicks approve and the job runs. If you are not on the reviewer list, the run stops at playground. Reviewers are set in Settings, Environments, production, Required reviewers. + +## One-time setup + +The deploy workflows need this in place before they can run: + +* Create the `playground` and `production` GitHub Environments. +* Add the signing key as a secret on each: `DEPLOY_IDENTITY_PEM` for the frontend workflow, `BACKEND_IDENTITY_PEM` for the backend workflow, each scoped to the environment so a job only ever sees its own key. The backend identity must be both a registry admin on the control-panel and a controller of the control-panel canister. +* Add required reviewers to `production`. That is the approval gate. +* Fix the playground `derivationOrigin` so Internet Identity login works there, ideally by making it come from an env var. +* Stand up a persistent test station so backend wasms published to the playground registry can be exercised by a real self-upgrade before production. + +One decision affects the frontend production job: whether the production key lives in the `production` environment as a secret, or stays off CI. In CI, production is a one-approval click. Off CI, production stays a local `scripts/deploy-app` run reading the key from 1Password, and the master key never touches GitHub. A reasonable start is production local, playground automated, and move production into the protected environment once the flow is trusted. + +## Release cadence + +We don't have a set release cadence today. I'd propose a bi-weekly one, every second Thursday. It would be best-effort, but it gives us a bit of urgency and a rhythm to work to. A recurring Google Calendar event can act as the soft reminder. From 3f17b8342a82be66d608969b237bcbd83b3ea4ab Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Wed, 2 Sep 2026 12:01:34 +0200 Subject: [PATCH 02/15] docs(release): drop cadence section and secret-handling detail This repo is public, so the guide no longer names credential secrets or describes where signing keys are kept. It points at the workflows for the required names instead. --- RELEASE.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index cb5ff17bb..4c53371a6 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,7 +2,7 @@ A release has three phases: cut, publish, deploy. Cutting and publishing are one flow that ends in a GitHub release with the built artifact attached. Deploying is what puts that artifact on the live canisters. All of it runs from the Actions tab. This is the guide to what to click. -Most of this used to be manual, run from a laptop with the production key. It is now three workflows: **Cut release**, **Deploy frontend**, **Deploy backend**. Publishing was already automated and has not changed. +Most of this used to be manual. It is now three workflows: **Cut release**, **Deploy frontend**, **Deploy backend**. Publishing was already automated and has not changed. ## Components @@ -74,13 +74,7 @@ The gate is native **GitHub Environments**. A `playground` environment that runs The deploy workflows need this in place before they can run: * Create the `playground` and `production` GitHub Environments. -* Add the signing key as a secret on each: `DEPLOY_IDENTITY_PEM` for the frontend workflow, `BACKEND_IDENTITY_PEM` for the backend workflow, each scoped to the environment so a job only ever sees its own key. The backend identity must be both a registry admin on the control-panel and a controller of the control-panel canister. +* Configure each environment with the deployment credentials its jobs expect. The required names are declared at the top of the deploy workflows, and the values are held by the team that administers releases. * Add required reviewers to `production`. That is the approval gate. * Fix the playground `derivationOrigin` so Internet Identity login works there, ideally by making it come from an env var. * Stand up a persistent test station so backend wasms published to the playground registry can be exercised by a real self-upgrade before production. - -One decision affects the frontend production job: whether the production key lives in the `production` environment as a secret, or stays off CI. In CI, production is a one-approval click. Off CI, production stays a local `scripts/deploy-app` run reading the key from 1Password, and the master key never touches GitHub. A reasonable start is production local, playground automated, and move production into the protected environment once the flow is trusted. - -## Release cadence - -We don't have a set release cadence today. I'd propose a bi-weekly one, every second Thursday. It would be best-effort, but it gives us a bit of urgency and a rhythm to work to. A recurring Google Calendar event can act as the soft reminder. From 4dab32110e5ee7dfe83bdf400df786909b18ca65 Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Thu, 3 Sep 2026 15:35:42 +0200 Subject: [PATCH 03/15] docs(release): document production deploys as an operator command Playground stays a workflow. Production is a script run from a machine that can read the key, so the production credential never becomes a repo secret. Also fixes the Phase 1 section, which still described a comma-separated projects field after that input became checkboxes. --- RELEASE.md | 53 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 4c53371a6..ca294bba9 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,6 +1,6 @@ # Orbit release process -A release has three phases: cut, publish, deploy. Cutting and publishing are one flow that ends in a GitHub release with the built artifact attached. Deploying is what puts that artifact on the live canisters. All of it runs from the Actions tab. This is the guide to what to click. +A release has three phases: cut, publish, deploy. Cutting and publishing are one flow that ends in a GitHub release with the built artifact attached. Deploying is what puts that artifact on the live canisters. Everything up to and including a playground deploy runs from the Actions tab; production is a command an operator runs. This is the guide to both. Most of this used to be manual. It is now three workflows: **Cut release**, **Deploy frontend**, **Deploy backend**. Publishing was already automated and has not changed. @@ -32,9 +32,9 @@ Things worth stating plainly, because they are the usual source of confusion: Actions tab, run the **Cut release** workflow. The form: -* **projects**: comma-separated project names, for example `wallet-dapp,station`. Empty releases everything that changed since the last release. This is where you pick the whole batch or a subset. +* **one checkbox per project**: tick `wallet-dapp`, `station`, and so on. Tick nothing and it releases everything that changed since the last release, which nx works out from the commits. This is where you pick the whole batch or a subset. * **version_specifier**: `auto` lets the conventional commits decide the bump. Override with `patch` / `minor` / `major` if you need to. -* **pre_release**: `none`, or `alpha` / `beta` / `rc` for a pre-release. +* **pre_release**: `none`, or `alpha` / `beta` / `rc` to cut something like `0.8.0-rc.0` instead of `0.8.0`. Only valid with `auto` or `prerelease`. * **dry_run**: computes the versions and changelogs and opens nothing, so you can preview. It runs `orbit-cli release prepare`, which bumps the versions, writes the changelogs, and updates `.release.json` in one commit, then opens a PR whose body lists exactly what is being released. Review the versions and merge it. If nothing changed, it says so and opens no PR. @@ -47,34 +47,53 @@ This stops at the GitHub release. Nothing is on a live canister yet. That is pha ## Phase 3: deploy -Two workflows, same shape. Pick a subset or the whole set, deploy to playground with no gate, then promote to production behind a single approval. One approval covers the whole selection. +Playground and production are deployed differently on purpose. -### Deploy frontend +**Playground is a workflow.** Two of them, same shape: tick what you want, run it, done. No gate, because nothing user-facing is behind it. -Actions tab, run **Deploy frontend**. Tick the apps you want (wallet on by default, marketing and docs off), and leave **promote_to_production** on unless you want a playground-only run. +**Production is a command you run.** The key that signs a production deploy is not a repo secret, so there is no button for it. You run one script from a machine that can read the key. The reason is blast radius: a production frontend sync is live to every user the moment it finishes, and a control-panel upgrade has no buffer either, so we would rather the credential not sit somewhere a merged pull request can reach it. -* The **playground** job builds each app for playground and uploads it. Go test at the playground URL. -* The **production** job pauses for approval. Once approved, it uploads the released tarball to production. +Both halves run the same two scripts, `scripts/deploy-app` and `scripts/deploy-backend`. The workflows are wrappers around them, so CI and a laptop do the same thing. -Frontend config is baked in at build time, so playground gets its own build while production deploys the released production tarball. +### Frontends to playground -### Deploy backend +Actions tab, run **Deploy frontend**. Tick the apps you want (wallet on by default, marketing and docs off) and run it. It builds each app for playground and uploads it. Go test at the playground URL. -Actions tab, run **Deploy backend**. Tick station, upgrader, or control-panel, and leave promote on unless it is a playground-only run. The two backend types deploy differently: +Leave **promote_to_production** unchecked. It is off by default and only does anything if a production key has been put on the environment, which is not how this is set up. + +### Backends to playground + +Actions tab, run **Deploy backend**. Tick station, upgrader, or control-panel and run it. Same as above: leave promote unchecked. The two backend types deploy differently: * **station / upgrader**: `orbit-cli registry publish` loads the wasm into the control-panel registry. This only makes the version available. Each production station still upgrades itself, or its upgrader, only when that station's own admins submit and approve the request (finance being 2-of-N). Publishing station also publishes upgrader, its dependency. -* **control-panel**: a direct `dfx canister install --mode upgrade` of the one canister. There is no registry and no per-wallet buffer, so the approval gate is the only thing between this and every wallet. Handle with care. +* **control-panel**: a direct `dfx canister install --mode upgrade` of the one canister. There is no registry and no per-wallet buffer, so nothing stands between this and every wallet. Handle with care. + +### Production + +Run it from a machine that can read the signing key. `--op` takes a 1Password secret reference and reads the key into a temp file that is deleted when the script exits, so nothing is written down by hand. `--pem` takes a path if you already have the key on disk. + +Frontends. This deploys the released tarball, not a local build: + +``` +./scripts/deploy-app --app wallet --env production --tag latest --op "op:////identity.pem" +``` + +Backends. One target per run, and `station` publishes `upgrader` with it: + +``` +./scripts/deploy-backend --target station --network production --op "op:////identity.pem" +``` -### The approval gate +Both print what they are about to do and ask for confirmation. Both verify the artifact's published checksum before shipping it. `deploy-backend` also refuses to run if your checkout is not the release you are deploying, because the registry labels the entry with the version from your working tree rather than from the artifact, so a stale checkout would publish the right wasm under the wrong version. If it stops for that reason, check out the tag it names and run it again. -The gate is native **GitHub Environments**. A `playground` environment that runs freely, and a `production` environment that requires a named approver. When a run reaches the production job, GitHub pauses it and shows a "review pending deployments" banner. A reviewer clicks approve and the job runs. If you are not on the reviewer list, the run stops at playground. Reviewers are set in Settings, Environments, production, Required reviewers. +Ask the release administrators for the vault reference. Whoever holds it is who can deploy production, which is the point. ## One-time setup The deploy workflows need this in place before they can run: -* Create the `playground` and `production` GitHub Environments. -* Configure each environment with the deployment credentials its jobs expect. The required names are declared at the top of the deploy workflows, and the values are held by the team that administers releases. -* Add required reviewers to `production`. That is the approval gate. +* Create the `playground` GitHub Environment and give it the playground deployment credential. The name the jobs look for is declared at the top of each deploy workflow. +* Restrict that environment's deployment branches to `main`, so a job on some other branch cannot claim the credential. +* Create the `production` environment but leave it without a key, which is what keeps the production job inert. If production deploys are ever moved into CI, that environment needs required reviewers and the same branch restriction first. * Fix the playground `derivationOrigin` so Internet Identity login works there, ideally by making it come from an env var. * Stand up a persistent test station so backend wasms published to the playground registry can be exercised by a real self-upgrade before production. From dd3454d7ebd44eea35d0f21413650aabfa1a0b7a Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Thu, 3 Sep 2026 15:50:40 +0200 Subject: [PATCH 04/15] docs(release): flag the orbit-cli name collision and list the secrets The table proposed renaming dfx-orbit to orbit-cli while the text below explained orbit-cli is a different, internal tool, so the doc contradicted itself. Say plainly that this rename requires renaming the internal tool too, unlike every other row. Also cover the prerelease bump modes and name the per-environment secrets in the setup list. --- RELEASE.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index ca294bba9..9e216763c 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -18,7 +18,7 @@ The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the a | `station` | `station` | Backend | Per-wallet backend, one deployed per org. Wasm to the control-panel registry, stations self-upgrade. | Yes | | `upgrader` | `upgrader` | Backend | Per-station helper that performs safe upgrades, paired one-to-one with a station. Wasm to the registry. | Yes | | `control-panel` | `control-panel` | Backend | The single global registry and directory. Deploys stations. Wasm, deployed as the control-panel canister. | Yes | -| `dfx-orbit` | `orbit-cli` | CLI | The CLI we ship to users. Git tag and GitHub release, users install it themselves. | Yes | +| `dfx-orbit` | `orbit-cli`, but see below | CLI | The CLI we ship to users. Git tag and GitHub release, users install it themselves. | Yes | | `*-api`, `orbit-essentials` | (unchanged) | Crates | Shared Candid and types. No artifact, deploys nowhere. | Bumped automatically | Things worth stating plainly, because they are the usual source of confusion: @@ -26,14 +26,14 @@ Things worth stating plainly, because they are the usual source of confusion: * The three frontends are separate projects with separate versions and separate asset canisters. They are not one "wallet dapp" bundle. * Only the Control Panel is a singleton. There is one global instance. Station and Upgrader are multi-instance: the Control Panel deploys a fresh Station per org, and each Station comes paired with its own Upgrader. Station and Upgrader deploy and control each other, which is what makes a station upgrade safe. * The `station-api` / `upgrader-api` / `control-panel-api` crates are the contract, just the Candid interface and shared types. The bare name (`station`) is the canister that runs; the `-api` crate compiles to no canister. Bumping an api crate cascades a bump into whatever depends on it, which is why one small change can move several version numbers at once. -* `dfx-orbit` and `orbit-cli` are not the same tool. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. +* `dfx-orbit` and `orbit-cli` are not the same tool today. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. Which is why the rename in the table above has a catch: giving the user-facing CLI the name `orbit-cli` means renaming the internal one in the same change, or the name refers to two different tools. Every other row in that table is a straight rename; this one is the exception. ## Phase 1: cut a release Actions tab, run the **Cut release** workflow. The form: * **one checkbox per project**: tick `wallet-dapp`, `station`, and so on. Tick nothing and it releases everything that changed since the last release, which nx works out from the commits. This is where you pick the whole batch or a subset. -* **version_specifier**: `auto` lets the conventional commits decide the bump. Override with `patch` / `minor` / `major` if you need to. +* **version_specifier**: `auto` lets the conventional commits decide the bump. Override with `patch` / `minor` / `major`, or with `prepatch` / `preminor` / `premajor` / `prerelease` to move onto a pre-release version. * **pre_release**: `none`, or `alpha` / `beta` / `rc` to cut something like `0.8.0-rc.0` instead of `0.8.0`. Only valid with `auto` or `prerelease`. * **dry_run**: computes the versions and changelogs and opens nothing, so you can preview. @@ -92,8 +92,8 @@ Ask the release administrators for the vault reference. Whoever holds it is who The deploy workflows need this in place before they can run: -* Create the `playground` GitHub Environment and give it the playground deployment credential. The name the jobs look for is declared at the top of each deploy workflow. +* Create the `playground` GitHub Environment and add `DEPLOY_STAGING_IDENTITY_PEM` (frontends) and `BACKEND_STAGING_IDENTITY_PEM` (backends) to it. * Restrict that environment's deployment branches to `main`, so a job on some other branch cannot claim the credential. -* Create the `production` environment but leave it without a key, which is what keeps the production job inert. If production deploys are ever moved into CI, that environment needs required reviewers and the same branch restriction first. +* Create the `production` environment but leave it without a key, which is what keeps the production job inert. If production deploys are ever moved into CI, that environment needs `DEPLOY_PRODUCTION_IDENTITY_PEM` and `BACKEND_PRODUCTION_IDENTITY_PEM`, plus required reviewers and the same branch restriction, first. * Fix the playground `derivationOrigin` so Internet Identity login works there, ideally by making it come from an env var. * Stand up a persistent test station so backend wasms published to the playground registry can be exercised by a real self-upgrade before production. From 54971b9f52b83b2f1c498396ee209e032ec802bc Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 09:46:51 +0200 Subject: [PATCH 05/15] docs(release): note that latest skips pre-releases --- RELEASE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASE.md b/RELEASE.md index 9e216763c..0fa3d19f0 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -84,6 +84,8 @@ Backends. One target per run, and `station` publishes `upgrader` with it: ./scripts/deploy-backend --target station --network production --op "op:////identity.pem" ``` +Both resolve to the newest stable release and skip pre-releases, so an rc sitting at the top of the list will not be picked up by accident. To deploy one on purpose, pass the tag: `deploy-app --tag @orbit/wallet-dapp-v0.8.0-rc.0`. + Both print what they are about to do and ask for confirmation. Both verify the artifact's published checksum before shipping it. `deploy-backend` also refuses to run if your checkout is not the release you are deploying, because the registry labels the entry with the version from your working tree rather than from the artifact, so a stale checkout would publish the right wasm under the wrong version. If it stops for that reason, check out the tag it names and run it again. Ask the release administrators for the vault reference. Whoever holds it is who can deploy production, which is the point. From 12e13eca5bf5001a0208b56133917835ad7a9eae Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 09:41:14 +0200 Subject: [PATCH 06/15] Update RELEASE.md Co-authored-by: Arshavir Ter-Gabrielyan --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 0fa3d19f0..03027ce29 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -12,7 +12,7 @@ The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the a | Current name | Proposed name | Type | Role and where it deploys | Ships alone | | --- | --- | --- | --- | --- | -| `wallet-dapp` | `wallet-app` | Frontend | The wallet UI users log into. Asset tarball to the wallet canister (`5fu67`, app.orbit.global). | Yes | +| `wallet-dapp` | `station-frontend` | Frontend | The wallet UI users log into. Asset tarball to the wallet canister (`5fu67`, app.orbit.global). | Yes | | `marketing-dapp` | `landing-page` | Frontend | The public marketing site. Asset tarball to the marketing canister (orbit.global). | Yes | | `docs-portal` | `docs-site` | Frontend | The documentation site. Asset tarball to the docs canister (docs.orbit.global). | Yes | | `station` | `station` | Backend | Per-wallet backend, one deployed per org. Wasm to the control-panel registry, stations self-upgrade. | Yes | From f5451626f2a7d1848f2c3b384d167961dc14e8b6 Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 09:41:25 +0200 Subject: [PATCH 07/15] Update RELEASE.md Co-authored-by: Arshavir Ter-Gabrielyan --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 03027ce29..008966c44 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -14,7 +14,7 @@ The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the a | --- | --- | --- | --- | --- | | `wallet-dapp` | `station-frontend` | Frontend | The wallet UI users log into. Asset tarball to the wallet canister (`5fu67`, app.orbit.global). | Yes | | `marketing-dapp` | `landing-page` | Frontend | The public marketing site. Asset tarball to the marketing canister (orbit.global). | Yes | -| `docs-portal` | `docs-site` | Frontend | The documentation site. Asset tarball to the docs canister (docs.orbit.global). | Yes | +| `docs-portal` | `docs-portal` | Frontend | The documentation site. Asset tarball to the docs canister (docs.orbit.global). | Yes | | `station` | `station` | Backend | Per-wallet backend, one deployed per org. Wasm to the control-panel registry, stations self-upgrade. | Yes | | `upgrader` | `upgrader` | Backend | Per-station helper that performs safe upgrades, paired one-to-one with a station. Wasm to the registry. | Yes | | `control-panel` | `control-panel` | Backend | The single global registry and directory. Deploys stations. Wasm, deployed as the control-panel canister. | Yes | From 0a3c1f64a484417264d75f5d3763f42c701d30cd Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 10:03:43 +0200 Subject: [PATCH 08/15] docs(release): say which apps actually have a playground canister Only the wallet does. Also clarify that the one-time setup is GitHub Actions plumbing, not standing up a playground, which already exists. --- RELEASE.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 008966c44..726c75b3d 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -57,7 +57,9 @@ Both halves run the same two scripts, `scripts/deploy-app` and `scripts/deploy-b ### Frontends to playground -Actions tab, run **Deploy frontend**. Tick the apps you want (wallet on by default, marketing and docs off) and run it. It builds each app for playground and uploads it. Go test at the playground URL. +Actions tab, run **Deploy frontend**. Tick **wallet** and run it. It builds the wallet for playground and uploads it to `bxkhk-6yaaa-aaaal-ai6va-cai`. Go test at https://playground.orbitwallet.io. + +Only the wallet has a playground canister. `marketing-dapp` and `docs-portal` exist on production only, so ticking them here fails on purpose, with a message telling you to deploy them to production instead. The backends are unaffected: all three targets work on playground, since the registry publish path needs only the control-panel and the wasm chunk store, both of which exist there. Leave **promote_to_production** unchecked. It is off by default and only does anything if a production key has been put on the environment, which is not how this is set up. @@ -92,9 +94,9 @@ Ask the release administrators for the vault reference. Whoever holds it is who ## One-time setup -The deploy workflows need this in place before they can run: +The playground network, its canisters and the live site all exist already. What is missing is the GitHub Actions plumbing to reach them: -* Create the `playground` GitHub Environment and add `DEPLOY_STAGING_IDENTITY_PEM` (frontends) and `BACKEND_STAGING_IDENTITY_PEM` (backends) to it. +* Create the `playground` GitHub Environment and add `DEPLOY_PLAYGROUND_IDENTITY_PEM` (frontends) and `BACKEND_PLAYGROUND_IDENTITY_PEM` (backends) to it. * Restrict that environment's deployment branches to `main`, so a job on some other branch cannot claim the credential. * Create the `production` environment but leave it without a key, which is what keeps the production job inert. If production deploys are ever moved into CI, that environment needs `DEPLOY_PRODUCTION_IDENTITY_PEM` and `BACKEND_PRODUCTION_IDENTITY_PEM`, plus required reviewers and the same branch restriction, first. * Fix the playground `derivationOrigin` so Internet Identity login works there, ideally by making it come from an env var. From 67874e1345900398f9318cc5f18005082f5ce897 Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 10:08:35 +0200 Subject: [PATCH 09/15] docs(release): warn against reusing the production identity for CI The identity that deploys today controls the production canisters as well as the playground ones, so putting it on the playground environment would hand CI production access. --- RELEASE.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 726c75b3d..f6e4ef57e 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -96,7 +96,9 @@ Ask the release administrators for the vault reference. Whoever holds it is who The playground network, its canisters and the live site all exist already. What is missing is the GitHub Actions plumbing to reach them: -* Create the `playground` GitHub Environment and add `DEPLOY_PLAYGROUND_IDENTITY_PEM` (frontends) and `BACKEND_PLAYGROUND_IDENTITY_PEM` (backends) to it. +* Mint an identity for CI that can reach playground and nothing else, then create the `playground` GitHub Environment and add it as `DEPLOY_PLAYGROUND_IDENTITY_PEM` (frontends) and `BACKEND_PLAYGROUND_IDENTITY_PEM` (backends). + + Do not reuse the identity that deploys today. It controls the production canisters as well as the playground ones, so putting it here would give CI production access and undo the reason production is deployed by hand. The playground canisters already trust several principals that production does not, so a playground-only controller is a shape they already support. The new identity needs to be a controller of the playground canisters, authorized on the playground asset canister, and a registry admin on the playground control-panel. * Restrict that environment's deployment branches to `main`, so a job on some other branch cannot claim the credential. * Create the `production` environment but leave it without a key, which is what keeps the production job inert. If production deploys are ever moved into CI, that environment needs `DEPLOY_PRODUCTION_IDENTITY_PEM` and `BACKEND_PRODUCTION_IDENTITY_PEM`, plus required reviewers and the same branch restriction, first. * Fix the playground `derivationOrigin` so Internet Identity login works there, ideally by making it come from an env var. From 9ae93b08fe6bacf477e7abaf0ea7100276b3fb3c Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 11:48:27 +0200 Subject: [PATCH 10/15] docs(release): say station instead of wallet Per Arshavir's review. Identifiers keep the wallet name since they are literal tags, inputs and canister_ids.json keys; the doc now says so. --- RELEASE.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index f6e4ef57e..746eeef80 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -10,12 +10,14 @@ There is no single "Orbit release". There are independently versioned projects, The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the artifact name, and the build target, so renaming it is a real change, not a label. The proposed name is the clearer one we would move to in a separate PR if we decide to. +Prose here says station, not wallet. Identifiers still say wallet, because that is what they literally are: the `wallet-dapp` project, the `wallet` checkbox on the deploy form, `--app wallet`, the `app_wallet` key in `canister_ids.json`. Changing those is the rename PR, not a wording fix. + | Current name | Proposed name | Type | Role and where it deploys | Ships alone | | --- | --- | --- | --- | --- | -| `wallet-dapp` | `station-frontend` | Frontend | The wallet UI users log into. Asset tarball to the wallet canister (`5fu67`, app.orbit.global). | Yes | +| `wallet-dapp` | `station-frontend` | Frontend | The station UI users log into. Asset tarball to its asset canister (`5fu67`, app.orbit.global). | Yes | | `marketing-dapp` | `landing-page` | Frontend | The public marketing site. Asset tarball to the marketing canister (orbit.global). | Yes | | `docs-portal` | `docs-portal` | Frontend | The documentation site. Asset tarball to the docs canister (docs.orbit.global). | Yes | -| `station` | `station` | Backend | Per-wallet backend, one deployed per org. Wasm to the control-panel registry, stations self-upgrade. | Yes | +| `station` | `station` | Backend | The backend, one instance deployed per org. Wasm to the control-panel registry, stations self-upgrade. | Yes | | `upgrader` | `upgrader` | Backend | Per-station helper that performs safe upgrades, paired one-to-one with a station. Wasm to the registry. | Yes | | `control-panel` | `control-panel` | Backend | The single global registry and directory. Deploys stations. Wasm, deployed as the control-panel canister. | Yes | | `dfx-orbit` | `orbit-cli`, but see below | CLI | The CLI we ship to users. Git tag and GitHub release, users install it themselves. | Yes | @@ -23,7 +25,7 @@ The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the a Things worth stating plainly, because they are the usual source of confusion: -* The three frontends are separate projects with separate versions and separate asset canisters. They are not one "wallet dapp" bundle. +* The three frontends are separate projects with separate versions and separate asset canisters. They are not a single bundle. * Only the Control Panel is a singleton. There is one global instance. Station and Upgrader are multi-instance: the Control Panel deploys a fresh Station per org, and each Station comes paired with its own Upgrader. Station and Upgrader deploy and control each other, which is what makes a station upgrade safe. * The `station-api` / `upgrader-api` / `control-panel-api` crates are the contract, just the Candid interface and shared types. The bare name (`station`) is the canister that runs; the `-api` crate compiles to no canister. Bumping an api crate cascades a bump into whatever depends on it, which is why one small change can move several version numbers at once. * `dfx-orbit` and `orbit-cli` are not the same tool today. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. Which is why the rename in the table above has a catch: giving the user-facing CLI the name `orbit-cli` means renaming the internal one in the same change, or the name refers to two different tools. Every other row in that table is a straight rename; this one is the exception. @@ -57,9 +59,9 @@ Both halves run the same two scripts, `scripts/deploy-app` and `scripts/deploy-b ### Frontends to playground -Actions tab, run **Deploy frontend**. Tick **wallet** and run it. It builds the wallet for playground and uploads it to `bxkhk-6yaaa-aaaal-ai6va-cai`. Go test at https://playground.orbitwallet.io. +Actions tab, run **Deploy frontend**. Tick **wallet** and run it. It builds the station frontend for playground and uploads it to `bxkhk-6yaaa-aaaal-ai6va-cai`. Go test at https://playground.orbitwallet.io. -Only the wallet has a playground canister. `marketing-dapp` and `docs-portal` exist on production only, so ticking them here fails on purpose, with a message telling you to deploy them to production instead. The backends are unaffected: all three targets work on playground, since the registry publish path needs only the control-panel and the wasm chunk store, both of which exist there. +Only the station frontend has a playground canister. `marketing-dapp` and `docs-portal` exist on production only, so ticking them here fails on purpose, with a message telling you to deploy them to production instead. The backends are unaffected: all three targets work on playground, since the registry publish path needs only the control-panel and the wasm chunk store, both of which exist there. Leave **promote_to_production** unchecked. It is off by default and only does anything if a production key has been put on the environment, which is not how this is set up. @@ -68,7 +70,7 @@ Leave **promote_to_production** unchecked. It is off by default and only does an Actions tab, run **Deploy backend**. Tick station, upgrader, or control-panel and run it. Same as above: leave promote unchecked. The two backend types deploy differently: * **station / upgrader**: `orbit-cli registry publish` loads the wasm into the control-panel registry. This only makes the version available. Each production station still upgrades itself, or its upgrader, only when that station's own admins submit and approve the request (finance being 2-of-N). Publishing station also publishes upgrader, its dependency. -* **control-panel**: a direct `dfx canister install --mode upgrade` of the one canister. There is no registry and no per-wallet buffer, so nothing stands between this and every wallet. Handle with care. +* **control-panel**: a direct `dfx canister install --mode upgrade` of the one canister. There is no registry and no per-station buffer, so nothing stands between this and every station. Handle with care. ### Production From 0c468b3a1a901a5635c30091c5939db52ee3bb0a Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 13:07:39 +0200 Subject: [PATCH 11/15] docs(release): tighten the prose Cut the line narrating the document, replace the two scene-setting lead-ins, and give the reason for deploying production by hand instead of labelling it blast radius. Split the sentence that carried the confirmation prompt, the checksum check and the stale-checkout guard into separate claims. Say that the rename and the production key are undecided and unset rather than gesturing at it. --- RELEASE.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 746eeef80..fd2b86bf4 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,6 +1,6 @@ # Orbit release process -A release has three phases: cut, publish, deploy. Cutting and publishing are one flow that ends in a GitHub release with the built artifact attached. Deploying is what puts that artifact on the live canisters. Everything up to and including a playground deploy runs from the Actions tab; production is a command an operator runs. This is the guide to both. +A release has three phases: cut, publish, deploy. Cutting and publishing are one flow that ends in a GitHub release with the built artifact attached. Deploying is what puts that artifact on the live canisters. Everything up to and including a playground deploy runs from the Actions tab. Production is a command an operator runs. Most of this used to be manual. It is now three workflows: **Cut release**, **Deploy frontend**, **Deploy backend**. Publishing was already automated and has not changed. @@ -8,7 +8,7 @@ Most of this used to be manual. It is now three workflows: **Cut release**, **De There is no single "Orbit release". There are independently versioned projects, and nx bumps each one on its own from the conventional commits that touched it. Six produce a deployable artifact. The rest are internal crates that only exist to cascade a version bump. -The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the artifact name, and the build target, so renaming it is a real change, not a label. The proposed name is the clearer one we would move to in a separate PR if we decide to. +The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the artifact name, and the build target, so renaming it is a real change, not a label. The proposed name is what we would rename it to in a separate PR. That rename has not been decided yet. Prose here says station, not wallet. Identifiers still say wallet, because that is what they literally are: the `wallet-dapp` project, the `wallet` checkbox on the deploy form, `--app wallet`, the `app_wallet` key in `canister_ids.json`. Changing those is the rename PR, not a wording fix. @@ -23,12 +23,12 @@ Prose here says station, not wallet. Identifiers still say wallet, because that | `dfx-orbit` | `orbit-cli`, but see below | CLI | The CLI we ship to users. Git tag and GitHub release, users install it themselves. | Yes | | `*-api`, `orbit-essentials` | (unchanged) | Crates | Shared Candid and types. No artifact, deploys nowhere. | Bumped automatically | -Things worth stating plainly, because they are the usual source of confusion: +The usual points of confusion: * The three frontends are separate projects with separate versions and separate asset canisters. They are not a single bundle. * Only the Control Panel is a singleton. There is one global instance. Station and Upgrader are multi-instance: the Control Panel deploys a fresh Station per org, and each Station comes paired with its own Upgrader. Station and Upgrader deploy and control each other, which is what makes a station upgrade safe. * The `station-api` / `upgrader-api` / `control-panel-api` crates are the contract, just the Candid interface and shared types. The bare name (`station`) is the canister that runs; the `-api` crate compiles to no canister. Bumping an api crate cascades a bump into whatever depends on it, which is why one small change can move several version numbers at once. -* `dfx-orbit` and `orbit-cli` are not the same tool today. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. Which is why the rename in the table above has a catch: giving the user-facing CLI the name `orbit-cli` means renaming the internal one in the same change, or the name refers to two different tools. Every other row in that table is a straight rename; this one is the exception. +* `dfx-orbit` and `orbit-cli` are not the same tool today. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. So the rename in the table has a catch: giving the user-facing CLI the name `orbit-cli` means renaming the internal one in the same change, or the name means two different tools. Every other row is a straight rename. ## Phase 1: cut a release @@ -51,9 +51,9 @@ This stops at the GitHub release. Nothing is on a live canister yet. That is pha Playground and production are deployed differently on purpose. -**Playground is a workflow.** Two of them, same shape: tick what you want, run it, done. No gate, because nothing user-facing is behind it. +**Playground is a workflow.** **Deploy frontend** and **Deploy backend** both work the same way: tick what you want and run it. Neither asks for approval, because no user sees playground. -**Production is a command you run.** The key that signs a production deploy is not a repo secret, so there is no button for it. You run one script from a machine that can read the key. The reason is blast radius: a production frontend sync is live to every user the moment it finishes, and a control-panel upgrade has no buffer either, so we would rather the credential not sit somewhere a merged pull request can reach it. +**Production is a command you run.** The key that signs a production deploy is not a repo secret, so there is no button for it. You run one script from a machine that can read the key. A production frontend sync reaches every user the moment it finishes, and a control-panel upgrade reaches every station, so the key that does either should not sit where a merged pull request can read it. Both halves run the same two scripts, `scripts/deploy-app` and `scripts/deploy-backend`. The workflows are wrappers around them, so CI and a laptop do the same thing. @@ -61,9 +61,9 @@ Both halves run the same two scripts, `scripts/deploy-app` and `scripts/deploy-b Actions tab, run **Deploy frontend**. Tick **wallet** and run it. It builds the station frontend for playground and uploads it to `bxkhk-6yaaa-aaaal-ai6va-cai`. Go test at https://playground.orbitwallet.io. -Only the station frontend has a playground canister. `marketing-dapp` and `docs-portal` exist on production only, so ticking them here fails on purpose, with a message telling you to deploy them to production instead. The backends are unaffected: all three targets work on playground, since the registry publish path needs only the control-panel and the wasm chunk store, both of which exist there. +Only the station frontend has a playground canister. `marketing-dapp` and `docs-portal` exist on production only, so ticking them here fails on purpose, with a message telling you to deploy them to production instead. All three backend targets do work on playground. Publishing to the registry needs only the control-panel and the wasm chunk store, and both exist there. -Leave **promote_to_production** unchecked. It is off by default and only does anything if a production key has been put on the environment, which is not how this is set up. +Leave **promote_to_production** unchecked. It is off by default, and the `production` environment holds no key, so ticking it just fails the second job. ### Backends to playground @@ -90,18 +90,20 @@ Backends. One target per run, and `station` publishes `upgrader` with it: Both resolve to the newest stable release and skip pre-releases, so an rc sitting at the top of the list will not be picked up by accident. To deploy one on purpose, pass the tag: `deploy-app --tag @orbit/wallet-dapp-v0.8.0-rc.0`. -Both print what they are about to do and ask for confirmation. Both verify the artifact's published checksum before shipping it. `deploy-backend` also refuses to run if your checkout is not the release you are deploying, because the registry labels the entry with the version from your working tree rather than from the artifact, so a stale checkout would publish the right wasm under the wrong version. If it stops for that reason, check out the tag it names and run it again. +Both print what they are about to do and wait for you to confirm, and both check the artifact against the checksum published beside it. -Ask the release administrators for the vault reference. Whoever holds it is who can deploy production, which is the point. +`deploy-backend` also stops if your checkout is not the release you are deploying. The registry takes the version label from your working tree instead of from the artifact, so a stale checkout would publish the right wasm under the wrong version. Check out the tag it names and run it again. + +Ask the release administrators for the vault reference. Whoever holds it can deploy production, and nobody else can. ## One-time setup -The playground network, its canisters and the live site all exist already. What is missing is the GitHub Actions plumbing to reach them: +The playground network, its canisters and the live site all exist already. What is missing is the GitHub Actions configuration to reach them: * Mint an identity for CI that can reach playground and nothing else, then create the `playground` GitHub Environment and add it as `DEPLOY_PLAYGROUND_IDENTITY_PEM` (frontends) and `BACKEND_PLAYGROUND_IDENTITY_PEM` (backends). - Do not reuse the identity that deploys today. It controls the production canisters as well as the playground ones, so putting it here would give CI production access and undo the reason production is deployed by hand. The playground canisters already trust several principals that production does not, so a playground-only controller is a shape they already support. The new identity needs to be a controller of the playground canisters, authorized on the playground asset canister, and a registry admin on the playground control-panel. + Do not reuse the identity that deploys today. It controls the production canisters as well as the playground ones, so putting it here would hand CI production access and cancel out the reason production is deployed by hand. The playground canisters already trust several principals that production does not, so this is nothing new for them. The new identity needs to be a controller of the playground canisters, authorized on the playground asset canister, and a registry admin on the playground control-panel. * Restrict that environment's deployment branches to `main`, so a job on some other branch cannot claim the credential. * Create the `production` environment but leave it without a key, which is what keeps the production job inert. If production deploys are ever moved into CI, that environment needs `DEPLOY_PRODUCTION_IDENTITY_PEM` and `BACKEND_PRODUCTION_IDENTITY_PEM`, plus required reviewers and the same branch restriction, first. * Fix the playground `derivationOrigin` so Internet Identity login works there, ideally by making it come from an env var. -* Stand up a persistent test station so backend wasms published to the playground registry can be exercised by a real self-upgrade before production. +* Stand up a test station that stays up, so someone can run a real self-upgrade against a wasm in the playground registry before it goes to production. From 932d8b9c28031073652128fdae6e3ac78b4c7c7d Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 13:34:15 +0200 Subject: [PATCH 12/15] docs(release): say why the wallet identifiers are hard to rename They keep the old name for historical reasons, not because wallet is the right word. Give the actual cost: renaming splits the release tag series, so the scripts resolving latest would have to know both names. --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index fd2b86bf4..539a11a93 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -10,7 +10,7 @@ There is no single "Orbit release". There are independently versioned projects, The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the artifact name, and the build target, so renaming it is a real change, not a label. The proposed name is what we would rename it to in a separate PR. That rename has not been decided yet. -Prose here says station, not wallet. Identifiers still say wallet, because that is what they literally are: the `wallet-dapp` project, the `wallet` checkbox on the deploy form, `--app wallet`, the `app_wallet` key in `canister_ids.json`. Changing those is the rename PR, not a wording fix. +Prose here says station. The identifiers still say wallet for historical reasons: the `wallet-dapp` project, the `wallet` checkbox on the deploy form, `--app wallet`, the `app_wallet` key in `canister_ids.json`. Renaming those is a lot of work for a wording change. It splits the release tag series in two, so the scripts that resolve `latest` have to know both names, and every published release keeps the old one. It needs its own PR. | Current name | Proposed name | Type | Role and where it deploys | Ships alone | | --- | --- | --- | --- | --- | From 848e5327bb0eb0e514b0ee490e8830cb2c852513 Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 14:56:26 +0200 Subject: [PATCH 13/15] Update RELEASE.md Co-authored-by: Arshavir Ter-Gabrielyan --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 539a11a93..ef2b615fc 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -26,7 +26,7 @@ Prose here says station. The identifiers still say wallet for historical reasons The usual points of confusion: * The three frontends are separate projects with separate versions and separate asset canisters. They are not a single bundle. -* Only the Control Panel is a singleton. There is one global instance. Station and Upgrader are multi-instance: the Control Panel deploys a fresh Station per org, and each Station comes paired with its own Upgrader. Station and Upgrader deploy and control each other, which is what makes a station upgrade safe. +* Apart from the three frontends, only the Control Panel is a singleton. There is one global instance. Station and Upgrader are multi-instance: the Control Panel deploys a fresh Station per org, and each Station comes paired with its own Upgrader. Station and Upgrader deploy and control each other, which is what makes a station upgrade safe. * The `station-api` / `upgrader-api` / `control-panel-api` crates are the contract, just the Candid interface and shared types. The bare name (`station`) is the canister that runs; the `-api` crate compiles to no canister. Bumping an api crate cascades a bump into whatever depends on it, which is why one small change can move several version numbers at once. * `dfx-orbit` and `orbit-cli` are not the same tool today. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. So the rename in the table has a catch: giving the user-facing CLI the name `orbit-cli` means renaming the internal one in the same change, or the name means two different tools. Every other row is a straight rename. From 9d81f7ebd534c63b23426d3626d47de0aec0e0b4 Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 14:59:41 +0200 Subject: [PATCH 14/15] docs(release): rename the internal CLI to orbit-release-cli in the table Per Arshavir's review. The internal tool moves out of the way, which frees orbit-cli for the CLI users install, so the dfx-orbit row is a straight rename like the others. The internal tool now has its own row, since the doc refers to it and it was not listed anywhere. --- RELEASE.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index ef2b615fc..cae22fbe9 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -6,7 +6,7 @@ Most of this used to be manual. It is now three workflows: **Cut release**, **De ## Components -There is no single "Orbit release". There are independently versioned projects, and nx bumps each one on its own from the conventional commits that touched it. Six produce a deployable artifact. The rest are internal crates that only exist to cascade a version bump. +There is no single "Orbit release". There are independently versioned projects, and nx bumps each one on its own from the conventional commits that touched it. Six produce a deployable artifact. The rest are internal: shared crates that exist only to cascade a version bump, and the release tooling itself. The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the artifact name, and the build target, so renaming it is a real change, not a label. The proposed name is what we would rename it to in a separate PR. That rename has not been decided yet. @@ -20,7 +20,8 @@ Prose here says station. The identifiers still say wallet for historical reasons | `station` | `station` | Backend | The backend, one instance deployed per org. Wasm to the control-panel registry, stations self-upgrade. | Yes | | `upgrader` | `upgrader` | Backend | Per-station helper that performs safe upgrades, paired one-to-one with a station. Wasm to the registry. | Yes | | `control-panel` | `control-panel` | Backend | The single global registry and directory. Deploys stations. Wasm, deployed as the control-panel canister. | Yes | -| `dfx-orbit` | `orbit-cli`, but see below | CLI | The CLI we ship to users. Git tag and GitHub release, users install it themselves. | Yes | +| `dfx-orbit` | `orbit-cli` | CLI | The CLI we ship to users. Git tag and GitHub release, users install it themselves. | Yes | +| `orbit-cli` (internal) | `orbit-release-cli` | Tooling | Drives the release: `release prepare`, `release publish`, `registry publish`. | Not released | | `*-api`, `orbit-essentials` | (unchanged) | Crates | Shared Candid and types. No artifact, deploys nowhere. | Bumped automatically | The usual points of confusion: @@ -28,7 +29,7 @@ The usual points of confusion: * The three frontends are separate projects with separate versions and separate asset canisters. They are not a single bundle. * Apart from the three frontends, only the Control Panel is a singleton. There is one global instance. Station and Upgrader are multi-instance: the Control Panel deploys a fresh Station per org, and each Station comes paired with its own Upgrader. Station and Upgrader deploy and control each other, which is what makes a station upgrade safe. * The `station-api` / `upgrader-api` / `control-panel-api` crates are the contract, just the Candid interface and shared types. The bare name (`station`) is the canister that runs; the `-api` crate compiles to no canister. Bumping an api crate cascades a bump into whatever depends on it, which is why one small change can move several version numbers at once. -* `dfx-orbit` and `orbit-cli` are not the same tool today. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. So the rename in the table has a catch: giving the user-facing CLI the name `orbit-cli` means renaming the internal one in the same change, or the name means two different tools. Every other row is a straight rename. +* `dfx-orbit` and `orbit-cli` are not the same tool today. `dfx-orbit` is the CLI we ship to users. `orbit-cli` is our internal tool that drives the release (`release prepare`, `release publish`, `registry publish`). Only `dfx-orbit` is a release target. The rename settles this by moving the internal tool out of the way: it becomes `orbit-release-cli`, which frees `orbit-cli` for the CLI users install. ## Phase 1: cut a release From 047fbd536674d6fff31b407c7202ac63294c5ed2 Mon Sep 17 00:00:00 2001 From: Mario Ruci Date: Fri, 4 Sep 2026 15:01:24 +0200 Subject: [PATCH 15/15] docs(release): state the naming convention and stop hardcoding wallet-dapp Per Arshavir's review. Backticked names are the current ones so they match the repo and the workflow forms, and the table maps them to the proposed names. The Phase 1 bullet points at the table rather than naming a project that the rename will change, and the deploy section says the form still calls the station frontend wallet. --- RELEASE.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index cae22fbe9..f99aa4244 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -12,6 +12,8 @@ The current name is fixed. It is the git tag (`@orbit/{name}-v{version}`), the a Prose here says station. The identifiers still say wallet for historical reasons: the `wallet-dapp` project, the `wallet` checkbox on the deploy form, `--app wallet`, the `app_wallet` key in `canister_ids.json`. Renaming those is a lot of work for a wording change. It splits the release tag series in two, so the scripts that resolve `latest` have to know both names, and every published release keeps the old one. It needs its own PR. +So backticked names below are the current ones, matching what you see in the repo and on the workflow forms. The table above maps each to its proposed name. + | Current name | Proposed name | Type | Role and where it deploys | Ships alone | | --- | --- | --- | --- | --- | | `wallet-dapp` | `station-frontend` | Frontend | The station UI users log into. Asset tarball to its asset canister (`5fu67`, app.orbit.global). | Yes | @@ -35,7 +37,7 @@ The usual points of confusion: Actions tab, run the **Cut release** workflow. The form: -* **one checkbox per project**: tick `wallet-dapp`, `station`, and so on. Tick nothing and it releases everything that changed since the last release, which nx works out from the commits. This is where you pick the whole batch or a subset. +* **one checkbox per project**, named as in the table above. Tick nothing and it releases everything that changed since the last release, which nx works out from the commits. This is where you pick the whole batch or a subset. * **version_specifier**: `auto` lets the conventional commits decide the bump. Override with `patch` / `minor` / `major`, or with `prepatch` / `preminor` / `premajor` / `prerelease` to move onto a pre-release version. * **pre_release**: `none`, or `alpha` / `beta` / `rc` to cut something like `0.8.0-rc.0` instead of `0.8.0`. Only valid with `auto` or `prerelease`. * **dry_run**: computes the versions and changelogs and opens nothing, so you can preview. @@ -60,7 +62,7 @@ Both halves run the same two scripts, `scripts/deploy-app` and `scripts/deploy-b ### Frontends to playground -Actions tab, run **Deploy frontend**. Tick **wallet** and run it. It builds the station frontend for playground and uploads it to `bxkhk-6yaaa-aaaal-ai6va-cai`. Go test at https://playground.orbitwallet.io. +Actions tab, run **Deploy frontend**. Tick the station frontend, which the form still calls **wallet**, and run it. It builds for playground and uploads to `bxkhk-6yaaa-aaaal-ai6va-cai`. Go test at https://playground.orbitwallet.io. Only the station frontend has a playground canister. `marketing-dapp` and `docs-portal` exist on production only, so ticking them here fails on purpose, with a message telling you to deploy them to production instead. All three backend targets do work on playground. Publishing to the registry needs only the control-panel and the wasm chunk store, and both exist there.