docs(deploy): two-phase deploy_component, revert_component, stage/activate CLI (draft) - #599
docs(deploy): two-phase deploy_component, revert_component, stage/activate CLI (draft)#599dawsontoth wants to merge 5 commits into
Conversation
…ivate CLI Document the two-phase deploy behavior and the new surface from HarperFast/harper#1849: - deploy_component: cluster-wide stage -> barrier -> activate; new properties activate:false (stage-and-stop, returns a staged deployment_id), deployment_id (activate a previously-staged deployment), revert_on_failure, two_phase, and the ignore_replication_errors / deployment_timeout knobs. - revert_component: fast cluster-wide rollback to the retained previous version. - Deployment lifecycle: stage/activate phase names, staged/staging/activating/ rolled_back statuses, and staged-build retention (deployment_stagingRetention_maxCount). - CLI: harper stage / activate / revert verbs (aliases + examples). Companion to HarperFast/harper#1849 (still a draft). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request updates the documentation for the CLI and Operations API to reflect the new two-phase deployment process (staging and activation) and the rollback mechanism (revert_component). It introduces new CLI commands, aliases, API parameters, and examples. The review feedback suggests improving consistency by pointing the new CLI operation category links to the main #components section, and enhancing readability in the API documentation by adding clear labels to the multi-step "Stage now, activate later" JSON examples.
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-599 This preview will update automatically when you push new commits. |
…tage/activate example Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-599 This preview will update automatically when you push new commits. |
Conflict in reference/operations-api/operations.md was additive: main added the `credentials` parameter plus its "Deploy credentials" section (#581) where this branch adds the two-phase parameters. Kept both — the parameter list now carries activate/deployment_id/revert_on_failure/ignore_replication_errors/ deployment_timeout/two_phase AND credentials, followed by main's credentials section. main's get_deployment_payload / delete_deployment_payload docs (#600) are untouched.
… values Documents harper-pro#594 and syncs with harper#1849's latest behavior. add_ssh_key `generate: true` (harper-pro#594): - Harper mints the ed25519 keypair on the node and returns only `public_key`, so the private key is never carried in a request body, shell history, or CI log. Includes the response shape and the `harper:<name>` comment. - `key` and `generate` are mutually exclusive; ssh-keygen must be on PATH. - Notes that `public_key` is returned ONLY on the generating call — Harper does not retain it, and update_ssh_key requires a key you supply (it cannot mint one), so the recovery path is delete_ssh_key + add_ssh_key generate again. - CLI example added alongside the deploy/stage/activate/revert examples. Payload retention (harper#1849): - Splits the old one-line aside into its own subsection with a table covering both bounds: payloadRetention_maxSize (10 MiB, bounds a single payload) and the new payloadRetention_maxCount (default 1, bounds how many are kept per project). Explains why the default is conservative, that rows are never deleted, and that a reclaimed payload reports payload_blob_present: false. Also: - revert_on_failure / ignore_replication_errors now note they apply to a `deployment_id` activate too, matching the peer-failure gate added to that path. - list_deployments `status` listed only 5 of 13 real values; replaced with terminal vs in-flight groupings. - New note on restartRequired: deploying a brand-new component without a restart marks one as required (per node), while redeploying a live component does not.
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-599 This preview will update automatically when you push new commits. |
…cument them The SSH rows linked to #certificate-management, but the SSH operations are documented under ## Components — so every one of those seven links landed the reader in the wrong section. Repointed them to #components (the convention the other 15 component rows already use). Auditing the same block turned up the identical defect on the six user/role rows (list_users, add_user, alter_user, drop_user, list_roles, drop_role), which are documented under ## Users & Roles. Repointed those to #users--roles, matching the existing link to that section elsewhere in the docs. The five genuine certificate rows (create_csr, sign_certificate, list_certificates, add_certificate, remove_certificate) were already correct and are unchanged. Category labels updated to match their new targets. Verified every operations.md anchor referenced from this table against the real headings — all 11 resolve.
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-599 This preview will update automatically when you push new commits. |
|
Opened #616 stacked on this branch: docs(deploy): by-reference deploys, sealed credentials, CI token auth. It targets Where the two meet: this PR documents the two-phase deploy and |
| - `urlPath` — override the HTTP URL path the component is mounted at (e.g. `"/api/v2"`) | ||
| - `install_allow_scripts` — set to `true` to allow npm pre/post install scripts (disabled by default) | ||
| - `activate` — set to `false` to **stage only** and stop before go-live. The build is prepared and verified on every node and the response returns a `deployment_id` in a `staged` state; nothing goes live. Activate it later by calling `deploy_component` again with that `deployment_id` (see below). Useful for pre-staging a release and flipping it live in a separate, fast step. | ||
| - `deployment_id` — activate a previously-staged deployment (from an `activate: false` call). No new payload is fetched or installed; the already-staged build is swapped live cluster-wide. `project` is still required. |
There was a problem hiding this comment.
Medium: deployment_id activate doesn't persist root config for a package deploy
In the reference implementation (harper#1849, deployComponentActivateExisting in components/operations.js), writeComponentRootConfig only runs if (req.package). The activation example just below (line 714) omits package — consistent with this bullet's own "no new payload is fetched or installed" framing — so a real activate-by-deployment_id call for a package deploy will not update harperdb-config.yaml's stored package: reference for the component. A node that restarts without ever having this version installed, or a new peer joining the cluster, re-installs from that stale root config — silently reverting to the pre-activation package. Worth a caveat here (or requiring package again on the activate call) so this isn't assumed to be as durable as a normal single-shot deploy.
Suggested fix: add a line such as "Note: for a package deploy, also pass package on this call to durably update harperdb-config.yaml — omitting it activates the build cluster-wide but leaves the stored package reference unchanged, so a future restart or new peer may reinstall the older version."
—
Generated by Barber AI
|
|
||
| ### `revert_component` | ||
|
|
||
| Swaps a component's live version back to its **retained previous version** across the cluster, then restarts. Every `deploy_component` activation retains the version it replaced (one previous version is kept per component), so `revert_component` is a fast rollback that does not re-fetch or re-install. The swap is bidirectional — reverting a revert rolls forward again. |
There was a problem hiding this comment.
Medium: revert_component won't reconverge a new peer to the reverted version
revertApplication only swaps directories on disk — writeComponentRootConfig is called from the deploy/activate paths only, never from revertComponent. Boot-time installApplications installs strictly from root config's package: reference, so a node that joins the cluster (or has its components directory rebuilt) after a revert installs the newer, reverted-away version, not the one every existing node just reverted to. That's a gap in the "across the cluster" framing here — revert is a live-instance swap, not a config-level rollback, and a not-yet-provisioned node won't pick it up.
Suggested fix: add a caveat that a node provisioned after a revert (new peer, rebuilt components dir) installs the current root-config package reference, not the reverted-to version — so revert doesn't durably change what a future node will run.
—
Generated by Barber AI
|
|
||
| Deployment statuses fall into two groups: | ||
|
|
||
| - **Terminal** — `success`, `failed`, `rolled_back`, and `staged` (an `activate: false` stage-and-stop resting until it is activated or ages out of the staging-retention window). |
There was a problem hiding this comment.
Medium: "Terminal" bucket incorrectly includes staged
The implementation's own terminal-status set — TERMINAL_STATUSES in both components/deploymentRecorder.ts and components/deploymentOperations.ts — is {success, failed, rolled_back}; staged is explicitly excluded. That set gates get_deployment_payload ("... is not in a terminal state") and payload-retention pruning eligibility. Listing staged under "Terminal" here contradicts the unchanged get_deployment_payload section a few paragraphs down, which requires success, failed, or rolled_back — not staged.
Suggested fix: give staged its own "resting" bucket (the parenthetical already describes it that way) instead of grouping it with the true terminal statuses.
—
Generated by Barber AI
| | `deployment_id` | Unique identifier (content hash) | | ||
| | `project` | Component project name | | ||
| | `package_identifier` | Package reference or `payload` for tar uploads | | ||
| | `status` | `pending`, `staging`, `staged`, `activating`, `success`, `failed`, or `rolled_back` | |
There was a problem hiding this comment.
Low: status field list is incomplete
The "Deployment statuses" section just above correctly lists all in-flight statuses (pending, extracting, installing, staging, loading, replicating, activating, reverting, restarting), but this field description only picked up staging/staged/activating and still omits extracting, installing, loading, replicating, reverting, and restarting. Someone building tooling against get_deployment's status field (e.g. during a revert) won't find the value documented here.
Suggested fix:
| | `status` | `pending`, `staging`, `staged`, `activating`, `success`, `failed`, or `rolled_back` | | |
| | `status` | `pending`, `extracting`, `installing`, `staging`, `staged`, `loading`, `replicating`, `activating`, `reverting`, `restarting`, `success`, `failed`, or `rolled_back` | |
—
Generated by Barber AI
| { | ||
| "deployment_id": "a3f8c2d1...", | ||
| "message": "Component deployed successfully" | ||
| "message": "Successfully deployed: my-app" |
There was a problem hiding this comment.
Low: example response doesn't match the request's restart: "rolling"
The request right above sets "restart": "rolling", but per deployComponentTwoPhase's rolling-restart branch the response includes a restartJobId and a message ending in , restarting Harper ("Successfully deployed: my-app, restarting Harper"). The plain "Successfully deployed: my-app" shown here is only returned when no restart was requested.
Suggested fix: either drop "restart": "rolling" from the request to match this response, or update the response to include restartJobId and the , restarting Harper suffix.
—
Generated by Barber AI
| **Mint a deploy key for a private repository** (Harper generates the ed25519 keypair server-side and returns only the public half — register it with your git host): | ||
|
|
||
| ```bash | ||
| harper add_ssh_key name=my-key generate=true host=my-key.github.com hostname=github.com |
There was a problem hiding this comment.
Low: add_ssh_key generate documents an untracked cross-repo dependency
This example (and the mirrored section in operations.md) documents generate: true, implemented in HarperFast/harper-pro#594 — a separate, still-open draft PR. This PR's own "hold merge until #1849 lands" note only tracks HarperFast/harper#1849; it doesn't mention harper-pro#594. If #1849 merges (and this docs PR follows) before harper-pro#594 ships, these docs advertise an operation that isn't yet available.
Suggested fix: add harper-pro#594 to the merge-gating note in the PR description, or split this section into a follow-up PR tied to that dependency.
—
Generated by Barber AI
What this documents
The
deploy_componentoperation now runs as a two-phase, cluster-wide deploy, and there are new operator-facing knobs plus a rollback operation. This PR updates the reference docs to match.reference/operations-api/operations.mddeploy_component— documents the internal stage → cluster-wide barrier → activate flow (all-or-nothing at go-live), and the new properties:activate: false— stage-and-stop; returns astageddeployment_id, nothing goes live.deployment_id— activate a previously-staged deployment (no re-fetch/install).revert_on_failure,two_phase,ignore_replication_errors,deployment_timeout.revert_component(new section) — fast cluster-wide rollback to the retained previous version; bidirectional; customer-driven-rollback use case.stage/activate, legacyprepare/replicate), the new statuses (staging/staged/activating/rolled_back), and staged-build retention (deployment_stagingRetention_maxCount, default 5) with the "aged-out deployment_id" caveat.reference/cli/operations-api-commands.mdharper stage,harper activate, andharper revertto the alias table and the aliases list, with examples in Component Operations.Notes for review
v5.2.0as a placeholder — confirm against the actual shipping release before merge.reference_versioned_docs/version-v4/copies (this is a v5 feature).deployment_stagingRetention_maxCount; it's described inline where deployments are documented, matching howdeployment_payloadRetention_maxSizeis currently surfaced. If you'd prefer a dedicated configuration entry, happy to add one.🤖 Generated with Claude Code