Files
ReleaseKit/publish.go

91 lines
4.5 KiB
Go

package releasekit
import (
"context"
"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
}
// After publication preflight succeeds, Publish runs one offline Go test suite
// for the captured candidate.
// Validation.Go.Race enables the race detector for that suite,
// Validation.Go.FullVet runs go vet afterward instead of test-time vet, and
// Validation.Go.CompileTargets compiles all packages for each selected target
// with cgo disabled after tests and vet. Compilation produces no artifacts and
// does not execute target binaries. ExpectedPushURL, when nonempty, is compared
// exactly with the resolved effective push URL before validation; a mismatch
// returns ErrUnexpectedPushURL. It 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) {
candidateInput := candidateRequest(request)
result, err := publish.Publish(ctx, publish.Request{
RepositoryDir: candidateInput.RepositoryDir,
Product: candidateInput.Product,
Version: candidateInput.Version,
Remote: request.Remote,
ExpectedPushURL: request.ExpectedPushURL,
Validation: candidateInput.Validation,
AdditionalChecks: candidateInput.AdditionalChecks,
AfterValidate: candidateInput.AfterValidate,
Output: candidateInput.Output,
})
return PublicationResult{
Version: result.Version,
CandidateCommit: result.CandidateCommit,
Endpoint: result.Endpoint,
Phase: PublicationPhase(result.Phase),
TagObject: result.TagObject,
State: PublicationState(result.State),
}, convertValidationError(err)
}