Expose tagged-source delivery through facade and CLI
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
@@ -134,10 +135,140 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
}
|
||||
fmt.Fprintf(stdout, "build receipt: %s\n", receiptPath)
|
||||
return 0
|
||||
case cli.DeliveryAction:
|
||||
return runDelivery(ctx, invocation, stdout, stderr)
|
||||
}
|
||||
return 2
|
||||
}
|
||||
|
||||
func runDelivery(ctx context.Context, invocation cli.Invocation, stdout, stderr io.Writer) int {
|
||||
settings, err := cli.LoadSettings(invocation.Repository, invocation.ConfigPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "load profile: %v\n", err)
|
||||
return 2
|
||||
}
|
||||
delivery := settings.Delivery
|
||||
if delivery == nil || strings.TrimSpace(delivery.BaseURL) == "" || strings.TrimSpace(delivery.Owner) == "" || strings.TrimSpace(delivery.Repository) == "" {
|
||||
fmt.Fprintln(stderr, "deliver requires base_url, owner, and repository in the profile delivery settings")
|
||||
return 2
|
||||
}
|
||||
tokenEnv := delivery.TokenEnv
|
||||
if strings.TrimSpace(tokenEnv) == "" {
|
||||
tokenEnv = "RELEASEKIT_GITEA_TOKEN"
|
||||
}
|
||||
token, ok := os.LookupEnv(tokenEnv)
|
||||
if !ok || strings.TrimSpace(token) == "" {
|
||||
fmt.Fprintf(stderr, "deliver requires a non-empty token in environment variable %s\n", tokenEnv)
|
||||
return 2
|
||||
}
|
||||
|
||||
hasTargets := settings.Build != nil && len(settings.Build.Targets) != 0
|
||||
if invocation.AssetsDir != "" && !hasTargets {
|
||||
fmt.Fprintln(stderr, "--assets requires build targets in the profile")
|
||||
return 2
|
||||
}
|
||||
var build *releasekit.BuildResult
|
||||
var temporaryDir string
|
||||
if hasTargets {
|
||||
if invocation.AssetsDir != "" {
|
||||
assetsDir := invocation.AssetsDir
|
||||
if !filepath.IsAbs(assetsDir) {
|
||||
assetsDir = filepath.Join(invocation.Repository, assetsDir)
|
||||
}
|
||||
receipt, err := cli.LoadBuildReceipt(filepath.Join(assetsDir, cli.BuildReceiptName))
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "load verified build receipt: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
if !receipt.MatchesBuild(invocation.Repository, receipt.CandidateCommit, invocation.Version, *settings.Build) {
|
||||
fmt.Fprintln(stderr, "build receipt does not match the selected repository, version, or build settings")
|
||||
return 1
|
||||
}
|
||||
build = buildResultFromReceipt(receipt)
|
||||
} else {
|
||||
repositoryDir, resolveErr := filepath.Abs(invocation.Repository)
|
||||
if resolveErr != nil {
|
||||
fmt.Fprintf(stderr, "resolve repository directory: %v\n", resolveErr)
|
||||
return 1
|
||||
}
|
||||
temporaryDir, err = os.MkdirTemp(filepath.Dir(repositoryDir), ".releasekit-delivery-")
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "create temporary build directory: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
defer os.RemoveAll(temporaryDir)
|
||||
result, buildErr := releasekit.Build(ctx, releasekit.BuildRequest{
|
||||
RepositoryDir: invocation.Repository,
|
||||
Version: invocation.Version,
|
||||
Spec: *configuredBuildSpec(settings.Build),
|
||||
OutputDir: filepath.Join(temporaryDir, "assets"),
|
||||
Output: stderr,
|
||||
})
|
||||
if buildErr != nil {
|
||||
fmt.Fprintf(stderr, "build tagged-source assets: %v\n", buildErr)
|
||||
return 1
|
||||
}
|
||||
build = &result
|
||||
}
|
||||
}
|
||||
|
||||
result, err := releasekit.Deliver(ctx, releasekit.DeliveryRequest{
|
||||
RepositoryDir: invocation.Repository,
|
||||
Product: settings.Product,
|
||||
Version: invocation.Version,
|
||||
Destination: releasekit.GiteaDestination{
|
||||
BaseURL: delivery.BaseURL, Owner: delivery.Owner, Repository: delivery.Repository, Token: token,
|
||||
},
|
||||
Build: build,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "delivery state=%s version=%s commit=%s url=%s: %v\n", result.State, result.Version, result.CandidateCommit, result.ReleaseURL, err)
|
||||
writeDeliveryAssets(stderr, result)
|
||||
if errors.Is(err, releasekit.ErrInvalidVersion) {
|
||||
return 2
|
||||
}
|
||||
if result.State == releasekit.DeliveryUnknown {
|
||||
return 3
|
||||
}
|
||||
return 1
|
||||
}
|
||||
fmt.Fprintf(stdout, "delivered %s at %s (state %s)\n", result.Version, result.CandidateCommit, result.State)
|
||||
if result.ReleaseURL != "" {
|
||||
fmt.Fprintf(stdout, "release: %s\n", result.ReleaseURL)
|
||||
}
|
||||
writeDeliveryAssets(stdout, result)
|
||||
return 0
|
||||
}
|
||||
|
||||
func writeDeliveryAssets(output io.Writer, result releasekit.DeliveryResult) {
|
||||
for _, group := range []struct {
|
||||
label string
|
||||
assets []releasekit.DeliveryAsset
|
||||
}{{"matching", result.Matching}, {"uploaded", result.Uploaded}, {"pending", result.Pending}, {"conflicting", result.Conflicting}, {"uncertain", result.Uncertain}} {
|
||||
for _, asset := range group.assets {
|
||||
fmt.Fprintf(output, "%s %s %s\n", group.label, asset.Filename, asset.SHA256)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildResultFromReceipt(receipt cli.BuildReceipt) *releasekit.BuildResult {
|
||||
result := &releasekit.BuildResult{
|
||||
RepositoryDir: receipt.RepositoryDir, CandidateCommit: receipt.CandidateCommit,
|
||||
Version: receipt.Version, MainPackage: receipt.MainPackage, BinaryName: receipt.BinaryName,
|
||||
OutputDir: receipt.OutputDir, Compiler: receipt.Compiler,
|
||||
}
|
||||
for _, target := range receipt.Targets {
|
||||
result.Targets = append(result.Targets, releasekit.Target{OS: target.OS, Arch: target.Arch})
|
||||
}
|
||||
for _, artifact := range receipt.Artifacts {
|
||||
result.Artifacts = append(result.Artifacts, releasekit.BuildArtifact{
|
||||
Path: artifact.Path, Filename: artifact.Filename,
|
||||
Target: releasekit.Target{OS: artifact.Target.OS, Arch: artifact.Target.Arch}, SHA256: artifact.SHA256,
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func configuredBuildSpec(settings *cli.BuildSettings) *releasekit.BuildSpec {
|
||||
if settings == nil {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user