fix(controlplane): restore PR-mode promotion suppression and auto-repair newest pre-release version

Draft
MI
1mo ago
+245-41

Summary

PR #3289 removed PR mode's incomplete suppression of latest-version promotion. This PR restores that suppression and completes the behavior in the control plane.

refs https://github.com/chainloop-dev/chainloop/issues/3265

Changes

CLI — restore the PR-mode promotion default

  • Restored the PR #3268 rule in app/cli/pkg/action/attestation_init.go: when isPR is true, set opts.MarkAsLatest to &false unless the user explicitly passed --mark-latest=true (via the restored explicitMarkAsLatestTrue helper).
  • Preserves all three observable states: omitted --mark-latest becomes false in PR mode, explicit --mark-latest=false remains false, explicit --mark-latest=true remains the user override. Non-PR mode leaves the pointer untouched so omitted promotion intent reaches the server as nil.
  • Restored the --pr help literal and TestExplicitMarkAsLatestTrue (nil/false/true cases).

Control plane — auto-promote only the newest existing version when intent is omitted

  • Refactored the existing-version branch in WorkflowRunRepo.Create to always re-read the target ProjectVersion with ForUpdate inside the transaction.
  • Explicit states preserved exactly: true promotes (released versions rejected); false (PR sentinel / explicit opt-out) makes no change.
  • New nil path: if the fresh version is active, pre-release, and not already latest, query for any other active version with created_at strictly greater than the target's immutable CreatedAt. If none exists, call promoteVersionToLatestWithTx. A timestamp tie is not "strictly newer", matching the historical ORDER BY project_id, created_at DESC migration.
  • Released versions are never auto-promoted. UseLatestVersion and new-version creation are unchanged.

API contract

  • Updated the mark_as_latest proto comment to describe the completed nil/true/false semantics; regenerated Go, TypeScript, JSON Schema, and CLI reference artifacts via make generate.

Tests

  • Added four integration subtests covering: the repair lifecycle (v1 latest → PR-sim v2 not latest → non-PR v2 repaired to latest with v1 demoted); older version not promoted over newer; explicit-false suppression wins over automatic repair on a newer version; newest released version not auto-promoted.

Verification

  • go test ./app/cli/pkg/action -run 'Test(ExplicitMarkAsLatestTrue|ResolvePRMode)$' — PASS
  • go test ./app/controlplane/pkg/biz -run 'TestWorkflowRunUseCase/TestCreate' — PASS (all 29 subtests)
  • go test ./app/cli/pkg/action/ ./app/controlplane/pkg/data/ ./app/controlplane/pkg/biz/ — PASS
  • make generate — generated artifacts consistent, no hand-authored schema changes
  • gofmt, go vet, buf lint — clean

🤖 Posted by Maximus bot (Claude Code) on behalf of @migmartri