package releasekit import ( "context" internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build" "gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate" "gitea.maximumdirect.net/eric/ReleaseKit/internal/publish" ) type PublicationState string const ( // PublicationNotAttempted means no tag push was attempted. PublicationNotAttempted PublicationState = PublicationState(publish.NotAttempted) // PublicationNotPublished means this invocation knows the tag was not published. PublicationNotPublished PublicationState = PublicationState(publish.NotPublished) // PublicationPublished means Git reported a successful push of the intended tag object. PublicationPublished PublicationState = PublicationState(publish.Published) // PublicationConflict means an authoritative branch or tag guard failed. PublicationConflict PublicationState = PublicationState(publish.Conflict) // PublicationUnknown means a tag push failed and its remote outcome is unresolved. PublicationUnknown PublicationState = PublicationState(publish.Unknown) ) type PublicationPhase string const ( // PublicationPreflight identifies local and remote candidate inspection. PublicationPreflight PublicationPhase = PublicationPhase(publish.Preflight) // PublicationValidation identifies the standard suite and additional checks. PublicationValidation PublicationPhase = PublicationPhase(publish.Validation) // PublicationTagCreation identifies creation and inspection of the local annotated tag. PublicationTagCreation PublicationPhase = PublicationPhase(publish.TagCreation) // PublicationPush identifies the remote tag push attempt. PublicationPush PublicationPhase = PublicationPhase(publish.Push) // PublicationReconciliation identifies the single authoritative tag query after a push error. PublicationReconciliation PublicationPhase = PublicationPhase(publish.Reconciliation) // PublicationComplete identifies a successful tag push. PublicationComplete PublicationPhase = PublicationPhase(publish.Complete) ) // PublicationResult describes the publication state reached by this call. type PublicationResult struct { Version string // selected stable version CandidateCommit string // captured main commit Endpoint string // captured effective push URL Phase PublicationPhase // last operation phase reached TagObject string // local annotated tag object ID, when created State PublicationState // publication outcome for this invocation } // Publish always runs the offline Go test suite for the captured candidate, // then calls AdditionalChecks when supplied. It optionally builds selected // targets in temporary storage outside the worktree and pushes the exact // annotated tag object to the selected remote. It returns a result with errors: preflight // failures are not_attempted, failed authoritative guards are conflict, and // errors after local tag creation but before push are not_published. A failed // push gets one bounded authoritative tag query: an exact object match confirms // publication, absence is not_published, a different object is conflict, and // an unreadable result is unknown. A nil error means publication is confirmed // by the successful push or exact remote object match. func Publish(ctx context.Context, request ReleaseRequest) (PublicationResult, error) { var validate func(context.Context, candidate.Candidate) error if request.AdditionalChecks != nil { validate = func(ctx context.Context, captured candidate.Candidate) error { return request.AdditionalChecks(ctx, Candidate{ RepositoryDir: captured.RepositoryDir, Commit: captured.Commit, Version: captured.Version, }) } } result, err := publish.Publish(ctx, publish.Request{ RepositoryDir: request.RepositoryDir, Product: request.Product, Version: request.Version, Remote: request.Remote, AdditionalChecks: validate, AfterValidate: internalbuild.CandidateCallback(internalBuildSpec(request.Build), request.Output), Output: request.Output, }) return PublicationResult{ Version: result.Version, CandidateCommit: result.CandidateCommit, Endpoint: result.Endpoint, Phase: PublicationPhase(result.Phase), TagObject: result.TagObject, State: PublicationState(result.State), }, err }