Skip to content

Deployments: an activated staged release still reads "waiting to be activated" and offers Activate again #1927

Closed

Description

@dawsontoth

Found while hand-testing the release candidate against Harper 5.3.2 on a 2-node cluster. Follows #1874 and #1876.

Problem

  1. Deploy an application with Stage only on. Config → Deployments lists 4ac92da3 hello — Staged, waiting to be activated.
  2. Open it, click Activate and confirm. The progress shows Prepare ✓, Load (a hollow, pending ring), Replicate ✓, Restart ✓, Finish ✓.
  3. A new record 5c12b89e hello — Success — Activation of 4ac92da3 appears.

The original row still reads Staged, waiting to be activated. Its detail still says "Staged: built and installed, but not live. Activating it makes it live with nothing to install." and still offers Activate.

Activating it again isn't harmless. Harper sees that the release is already live, skips the swap, and still restarts every worker on every node.

The Load step also stays a pending ring after the activation has finished, as if it were still to come.

Cause

Harper never changes a staged record after it is written. An activation writes a separate record that points back at it:

  • components/deploymentRecorder.ts:60-63 (v5.3.2): staged is terminal, "activating its artifact is a separate operator action with a row of its own". components/deploymentOperations.ts:16-19 says the same.
  • components/operations.js:725-740: an activation (deploy_component with deployment_id) creates a new recorder row with activated_from: req.deployment_id (line 731). It finishes that row as success (line 1088). Only the recorder writes rows, and each recorder writes only its own.
  • components/Application.ts:4812-4821: activating a release that is already live sets alreadyActive and skips the swap. components/operations.js:956 then restarts every worker (restartScope = '*').
  • Re-activating a release that a later deploy has replaced is a real rollback. The replaced release is kept as a dormant build (components/Application.ts:1691-1736, retainDisplacedRelease) unless deployment_stagingRetention_maxCount has pruned it. In that case Harper answers 404 (components/Application.ts:4970).

Studio decides the label from the record's own status alone:

  • src/features/instance/config/deployments/constants/tableDefinition.tsx: status === 'staged' → "waiting to be activated".
  • src/features/instance/config/deployments/components/DeploymentDetail.tsx: status === 'staged' → the "not live" text and ActivateStagedRelease.

The Load ring is a separate, smaller issue. Harper sends no load phase when it skips the validation load (components/operations.js:467-473 returns before emit('phase', { phase: 'load', … })). It skips it whenever the worker's intrinsics are frozen after boot, and applications.lockdown: freeze-after-load is the default (static/defaultConfig.yaml:29). It also skips it for a release that is already live (no validateCandidate). DeployProgress draws any phase that has no event as pending, even after later phases have finished.

Expected

  • The list shows a staged release that has been activated as activated (for example "Activated by 5c12b89e", with a link to that record), not as waiting.
  • Its detail says it is live and doesn't offer Activate.
  • If a newer release has replaced it, the detail says so and offers going back to it as a rollback, with wording that says so.
  • A phase Harper passed over without reporting (a later phase has already reported) shows as skipped, not pending.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    P2

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions