Finish publication recovery workflow

This commit is contained in:
2026-11-02 19:37:29 +00:00
parent 6915a86132
commit 599ad81bec
10 changed files with 697 additions and 76 deletions

View File

@@ -11,12 +11,14 @@ two Go facades and a command-line interface:
- `buildinfo` is the small runtime facade. `Version` reports the injected
application version, the main-module version when available, or `dev`.
- `cmd/releasekit` is the executable interface. Its `version`, `check`,
`publish`, `build`, `deliver`, and `ci-deliver` commands adapt profiles and
command output to the supported library operations.
`publish`, `reconcile`, `publication-attempts`, `build`, `deliver`, and
`ci-deliver` commands adapt profiles and command output to the supported
library operations.
See the [CLI contract](../cli.md), [configuration reference](../config.md),
[candidate check guide](../consumers/check.md),
[source publication guide](../consumers/publish.md),
[publication record format](../integrations/publication-records.md),
[build guide](../consumers/build.md),
[delivery guide](../consumers/delivery.md), and
[runtime version guide](../consumers/runtime-version.md) for task-oriented use.
@@ -49,7 +51,7 @@ reports these implemented packages:
| `internal/preparation` | Coordination for expected-commit tag checkout and Go module dependency preparation. |
| `internal/releaseidentity` | Committed-object and working-tree module selection, declaration reading, and semantic-version-to-tag derivation. |
| `internal/validation` | Shared Go validation with optional race, full-vet, and static package-compilation target selections, formatting, workspace-file and filesystem-replacement checks, per-blob size limits, and selected Markdown destination and fragment checking; `internal/candidate` retains capture, callback sequencing, and local-state rechecks. |
| `internal/publish` | Publication guards, one validation run, annotated tag creation, push, and recovery state. |
| `internal/publish` | Publication guards, one validation run, annotated tag creation, push, pre-push evidence recording, saved-attempt discovery, later observation, and recovery state. |
| `internal/runtimeinfo` | Injected version selection and cached fallback metadata lookup for the runtime facade. |
| `internal/versioncontract` | Shared stable-version rules and linker-symbol identity. |
@@ -75,6 +77,18 @@ it does not consult neighboring files or traverse submodule checkouts.
See the [shared validation guide](validation.md) for checker, Go command, and
candidate-file integration mechanics.
Publication records and recovery follow a separate path from candidate
validation. `internal/publish` captures and saves attempt evidence before the
tag push, lists local records, and observes explicitly selected evidence through
`internal/git`; the root facade owns the reusable Go evidence and result types.
The CLI's `reconcile` and `publication-attempts` commands load, present, and
select records without loading a profile or choosing an attempt automatically.
These operations do not rerun candidate checks or hosted delivery and do not
change local or remote state. The [publication consumer guide](../consumers/publish.md)
owns storage and API use; the [record format guide](../integrations/publication-records.md)
owns the private and CLI JSON formats; the [CLI contract](../cli.md) owns command
semantics and statuses.
The root facade selects the backend explicitly and passes a configured
`internal/forge.Backend` into `internal/delivery`. Delivery performs cheap
request and source checks, then read-only backend preflight before managed
@@ -102,6 +116,7 @@ not a separate release matrix:
| Piped child-process exchanges and cancellation cleanup | `internal/process` | `TestStartPipedExchangesBeforeInputEOFAndPreservesSettings`, `TestStartPipedCancellationAfterReadinessReapsChild`, `TestStartPipedPreservesNonzeroExit` |
| Authoritative endpoint and exact annotated tag publication | `releasekit.Publish`, `internal/publish`, `internal/git` | `TestPublishPushesOnlyTheCapturedAnnotatedTag`, `TestPublishRejectsUnexpectedPushURLBeforeValidation`, `TestPublishComparesExpectedURLWithResolvedInsteadOfDestination`, `TestPublishExpectedPushURLUsesPushURLWhenFetchAndPushDiffer`, `TestCheckIgnoresExpectedPushURL`, `TestResolveUsesPushURLAndQueriesWithoutMutation` |
| Publication partial and uncertain recovery | `internal/publish`, `internal/git` | `TestPublishRejectedPushKeepsLocalTagAndReportsNotPublished`, `TestPublishLostAcknowledgmentConfirmsExactRemoteObject`, `TestPublishLostAcknowledgmentWithChangedEndpointRemainsUnknown`, `TestPublishUnavailableReconciliationRemainsUnknownAndPreservesPushError` |
| Saved attempt recording, discovery, explicit later reconciliation, and read-only recovery | `releasekit`, `internal/publish`, `internal/git`, `cmd/releasekit` | `TestLostPublicationOutputCanBeRecoveredFromExplicitRecords`, `TestBuiltPublishRecoveryCommandSelectsItsRecordAmongOtherAttempts`, `TestRecoveryFacadeLoadsPartialEvidenceAndPreservesCause`, `TestRecoveryFacadeErrorUnwrapsCancellation`, `TestListPublicationAttemptsReadsExplicitExternalStore` |
| Cross-builds, version smoke checks, module paths, empty target sets, and partial outputs | `releasekit.Build`, `internal/build`, `internal/artifact`, `internal/tempdir`, `buildinfo` | `TestBuildCreatesSelectedTargetsAndInjectsVersion`, `TestBuildUsesNestedWorkingTreeModuleAndModuleRelativeOutput`, `TestBuildResolvesDirtyWorkingTreeDeclaration`, `TestBuildWithNoTargetsDoesNotInvokeCompiler`, `TestBuildReturnsPartialArtifactsAfterTargetFailure`, `TestNormalizeSettingsKeepsBuildInputsAndNormalizesTargets`, `TestOutsideFallsBackWhenTemporaryDirectoryIsInsideWorktree` |
| Explicit destination selection, standalone and automatic preflight, and delivery ordering | `releasekit`, `internal/delivery`, `internal/gitea`, CLI | `TestDeliveryForgeSelectionIsExplicit`, `TestPreflightDeliveryChecksAuthenticatedRepositoryWithoutCheckout`, `TestPreflightDeliveryPreservesPublicFailureKindsAndCauses`, `TestAutomaticPreflightFailurePrecedesPrebuiltArtifactHashing`, `TestDeliverUnavailablePreflightStopsBeforeManagedBuild`, `TestCIDeliverUnavailablePreflightStopsBeforeDependencyPreparation`, `TestCIDeliverPageOnlyReportsUnavailablePreflightWithStatusOne` |
| Page-only and managed or prebuilt binary delivery | `releasekit.Deliver`, `internal/delivery`, `internal/gitea`, CLI | `TestDeliverPageOnlySkipsBuildAndHostedAssets`, `TestDeliverUsesCommittedModuleIdentityForSeparatePages`, `TestDeliverRejectsPrebuiltArtifactsForAnotherModuleBeforeHostedRequests`, `TestDeliverManagedBuildUploadsArtifactsAndCleansTemporaryOutput`, `TestDeliverBinaryConsumerWithBuildinfoAndSelectedTargets`, `TestDeliverPrebuiltArtifactsRemainCallerOwned`, `TestDeliverRejectsSameSizePrebuiltTamperingBeforeHostedWrites`, `TestDeliverManagedBuildFailureCleansTemporaryOutputBeforeHostedWrites`, `TestDeliverManagedBuildCancellationCleansTemporaryOutput`, `TestDeliverBuildsTaggedArtifactsAndReusesAssets`, `TestDeliverRejectsTamperedAssetsAndStaleReceiptBeforeRemoteWrites` |