package releasekit import ( "context" "fmt" internaldelivery "gitea.maximumdirect.net/eric/ReleaseKit/internal/delivery" "gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea" ) // DeliveryState describes the result of one delivery invocation. type DeliveryState string const ( // DeliveryNotAttempted means this invocation made no remote write. DeliveryNotAttempted DeliveryState = "not_attempted" // DeliveryComplete means the release page and all declared assets match. DeliveryComplete DeliveryState = "complete" // DeliveryPartial means a page or some assets were delivered, with work pending. DeliveryPartial DeliveryState = "partial" // DeliveryConflict means existing hosted content differs from the declaration. DeliveryConflict DeliveryState = "conflict" // DeliveryUnknown means a remote write may have succeeded but could not be resolved. DeliveryUnknown DeliveryState = "unknown" ) // GiteaDestination supplies the hosted repository and explicit access token. type GiteaDestination struct { BaseURL string Owner string Repository string Token string } // DeliveryAsset identifies a hosted asset by filename and SHA-256 digest. type DeliveryAsset struct { Filename string SHA256 string } // DeliveryRequest identifies a local tagged checkout and its explicit Gitea // destination. Build is nil for page-only delivery. type DeliveryRequest struct { RepositoryDir string Product string Version string Destination GiteaDestination Build *BuildResult } // DeliveryResult reports hosted content and the state reached by this // invocation. A partial result may accompany an error. type DeliveryResult struct { Version string CandidateCommit string ReleaseURL string State DeliveryState Matching []DeliveryAsset Uploaded []DeliveryAsset Pending []DeliveryAsset Conflicting []DeliveryAsset Uncertain []DeliveryAsset } // Deliver verifies the selected local tag and hosted source, then creates or // finds its release page and adds any missing declared build assets. func Deliver(ctx context.Context, request DeliveryRequest) (DeliveryResult, error) { result := DeliveryResult{Version: request.Version, State: DeliveryNotAttempted} var build *internaldelivery.BuildIdentity var assets []gitea.ExpectedAsset if request.Build != nil { if len(request.Build.Targets) == 0 { if len(request.Build.Artifacts) != 0 { return result, fmt.Errorf("page-only build result contains artifacts") } } else { var err error assets, err = declaredBuildAssets(*request.Build) if err != nil { return result, err } targets := make([]string, 0, len(request.Build.Targets)) for _, target := range request.Build.Targets { targets = append(targets, target.OS+"/"+target.Arch) } build = &internaldelivery.BuildIdentity{ RepositoryDir: request.Build.RepositoryDir, CandidateCommit: request.Build.CandidateCommit, SourceVerified: request.Build.SourceVerified, Version: request.Build.Version, MainPackage: request.Build.MainPackage, BinaryName: request.Build.BinaryName, Targets: targets, } } } destination := gitea.Destination{ BaseURL: request.Destination.BaseURL, Owner: request.Destination.Owner, Repository: request.Destination.Repository, Token: request.Destination.Token, } internalResult, err := internaldelivery.Deliver(ctx, internaldelivery.Request{ RepositoryDir: request.RepositoryDir, Product: request.Product, Version: request.Version, Destination: destination, Build: build, Assets: assets, }) result.CandidateCommit = internalResult.CandidateCommit result.ReleaseURL = internalResult.ReleaseURL result.State = DeliveryState(internalResult.State) result.Matching = deliveryAssets(internalResult.Matching) result.Uploaded = deliveryAssets(internalResult.Uploaded) result.Pending = deliveryAssets(internalResult.Pending) result.Conflicting = deliveryAssets(internalResult.Conflicting) result.Uncertain = deliveryAssets(internalResult.Uncertain) return result, err } func deliveryAssets(assets []gitea.AssetIdentity) []DeliveryAsset { result := make([]DeliveryAsset, 0, len(assets)) for _, asset := range assets { result = append(result, DeliveryAsset{Filename: asset.Filename, SHA256: asset.SHA256}) } return result }