Move release mechanics behind the public facade
This commit is contained in:
36
build.go
36
build.go
@@ -59,20 +59,12 @@ type BuildResult struct {
|
|||||||
// empty target set records source identity without running the Go toolchain.
|
// empty target set records source identity without running the Go toolchain.
|
||||||
// Errors return partial build facts in the result.
|
// Errors return partial build facts in the result.
|
||||||
func Build(ctx context.Context, request BuildRequest) (BuildResult, error) {
|
func Build(ctx context.Context, request BuildRequest) (BuildResult, error) {
|
||||||
targets := make([]internalbuild.Target, 0, len(request.Spec.Targets))
|
|
||||||
for _, target := range request.Spec.Targets {
|
|
||||||
targets = append(targets, internalbuild.Target{OS: target.OS, Arch: target.Arch})
|
|
||||||
}
|
|
||||||
result, err := internalbuild.Build(ctx, internalbuild.Request{
|
result, err := internalbuild.Build(ctx, internalbuild.Request{
|
||||||
RepositoryDir: request.RepositoryDir,
|
RepositoryDir: request.RepositoryDir,
|
||||||
Version: request.Version,
|
Version: request.Version,
|
||||||
Spec: internalbuild.Spec{
|
Spec: *internalBuildSpec(&request.Spec),
|
||||||
MainPackage: request.Spec.MainPackage,
|
OutputDir: request.OutputDir,
|
||||||
BinaryName: request.Spec.BinaryName,
|
Output: request.Output,
|
||||||
Targets: targets,
|
|
||||||
},
|
|
||||||
OutputDir: request.OutputDir,
|
|
||||||
Output: request.Output,
|
|
||||||
})
|
})
|
||||||
public := BuildResult{
|
public := BuildResult{
|
||||||
RepositoryDir: result.RepositoryDir,
|
RepositoryDir: result.RepositoryDir,
|
||||||
@@ -99,3 +91,25 @@ func Build(ctx context.Context, request BuildRequest) (BuildResult, error) {
|
|||||||
}
|
}
|
||||||
return public, err
|
return public, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func internalBuildSpec(spec *BuildSpec) *internalbuild.Spec {
|
||||||
|
if spec == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
result := &internalbuild.Spec{MainPackage: spec.MainPackage, BinaryName: spec.BinaryName}
|
||||||
|
for _, target := range spec.Targets {
|
||||||
|
result.Targets = append(result.Targets, internalbuild.Target{OS: target.OS, Arch: target.Arch})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func internalBuildResult(result BuildResult) *internalbuild.Result {
|
||||||
|
converted := &internalbuild.Result{RepositoryDir: result.RepositoryDir, CandidateCommit: result.CandidateCommit, SourceVerified: result.SourceVerified, Version: result.Version, MainPackage: result.MainPackage, BinaryName: result.BinaryName, OutputDir: result.OutputDir, Compiler: result.Compiler}
|
||||||
|
for _, target := range result.Targets {
|
||||||
|
converted.Targets = append(converted.Targets, internalbuild.Target{OS: target.OS, Arch: target.Arch})
|
||||||
|
}
|
||||||
|
for _, artifact := range result.Artifacts {
|
||||||
|
converted.Artifacts = append(converted.Artifacts, internalbuild.Artifact{Path: artifact.Path, Filename: artifact.Filename, Target: internalbuild.Target{OS: artifact.Target.OS, Arch: artifact.Target.Arch}, SHA256: artifact.SHA256})
|
||||||
|
}
|
||||||
|
return converted
|
||||||
|
}
|
||||||
|
|||||||
3
check.go
3
check.go
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ func Check(ctx context.Context, request ReleaseRequest) (Candidate, error) {
|
|||||||
Product: request.Product,
|
Product: request.Product,
|
||||||
Version: request.Version,
|
Version: request.Version,
|
||||||
Validate: validate,
|
Validate: validate,
|
||||||
AfterValidate: candidateBuildCallback(request.Build, request.Output),
|
AfterValidate: internalbuild.CandidateCallback(internalBuildSpec(request.Build), request.Output),
|
||||||
Output: request.Output,
|
Output: request.Output,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
31
delivery.go
31
delivery.go
@@ -2,8 +2,8 @@ package releasekit
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
|
internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build"
|
||||||
internaldelivery "gitea.maximumdirect.net/eric/ReleaseKit/internal/delivery"
|
internaldelivery "gitea.maximumdirect.net/eric/ReleaseKit/internal/delivery"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea"
|
||||||
)
|
)
|
||||||
@@ -66,33 +66,9 @@ type DeliveryResult struct {
|
|||||||
// finds its release page and adds any missing declared build assets.
|
// finds its release page and adds any missing declared build assets.
|
||||||
func Deliver(ctx context.Context, request DeliveryRequest) (DeliveryResult, error) {
|
func Deliver(ctx context.Context, request DeliveryRequest) (DeliveryResult, error) {
|
||||||
result := DeliveryResult{Version: request.Version, State: DeliveryNotAttempted}
|
result := DeliveryResult{Version: request.Version, State: DeliveryNotAttempted}
|
||||||
var build *internaldelivery.BuildIdentity
|
var build *internalbuild.Result
|
||||||
var assets []gitea.ExpectedAsset
|
|
||||||
if request.Build != nil {
|
if request.Build != nil {
|
||||||
if len(request.Build.Targets) == 0 {
|
build = internalBuildResult(*request.Build)
|
||||||
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{
|
destination := gitea.Destination{
|
||||||
BaseURL: request.Destination.BaseURL, Owner: request.Destination.Owner,
|
BaseURL: request.Destination.BaseURL, Owner: request.Destination.Owner,
|
||||||
@@ -104,7 +80,6 @@ func Deliver(ctx context.Context, request DeliveryRequest) (DeliveryResult, erro
|
|||||||
Version: request.Version,
|
Version: request.Version,
|
||||||
Destination: destination,
|
Destination: destination,
|
||||||
Build: build,
|
Build: build,
|
||||||
Assets: assets,
|
|
||||||
})
|
})
|
||||||
result.CandidateCommit = internalResult.CandidateCommit
|
result.CandidateCommit = internalResult.CandidateCommit
|
||||||
result.ReleaseURL = internalResult.ReleaseURL
|
result.ReleaseURL = internalResult.ReleaseURL
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ these implemented packages:
|
|||||||
| `cmd/releasekit` | Executable entry point, command routing, output, and exit status. |
|
| `cmd/releasekit` | Executable entry point, command routing, output, and exit status. |
|
||||||
| `cmd/releasekit/internal/cli` | Command parsing, strict JSON profile loading, configured checks, and private build receipts. |
|
| `cmd/releasekit/internal/cli` | Command parsing, strict JSON profile loading, configured checks, and private build receipts. |
|
||||||
| `internal/apicheck` | Compiled-export and import-boundary checks run during development. |
|
| `internal/apicheck` | Compiled-export and import-boundary checks run during development. |
|
||||||
| `internal/build` | Selected Go target compilation, version injection, native smoke check, and artifact digests. |
|
| `internal/build` | Candidate-build coordination, selected Go target compilation, version injection, native smoke check, and artifact digests. |
|
||||||
| `internal/candidate` | Stable-version, note, repository-state, candidate capture, and post-validation checks. |
|
| `internal/candidate` | Stable-version, note, repository-state, candidate capture, and post-validation checks. |
|
||||||
| `internal/delivery` | Tagged-checkout verification and coordination of release pages, assets, and delivery results. |
|
| `internal/delivery` | Tagged-checkout verification, artifact inventory/hash validation, manifest assembly, and coordination of hosted delivery results. |
|
||||||
| `internal/git` | Git command boundary, push-destination resolution, exact ref inspection, and tag operations. |
|
| `internal/git` | Git command boundary, push-destination resolution, exact ref inspection, and tag operations. |
|
||||||
| `internal/gitea` | Gitea API transport, hosted release pages, asset inspection, manifests, and uploads. |
|
| `internal/gitea` | Gitea API transport, hosted release pages, asset inspection, manifests, and uploads. |
|
||||||
| `internal/process` | Cancellable child-process execution with per-command environment overlays. |
|
| `internal/process` | Cancellable child-process execution with per-command environment overlays. |
|
||||||
|
|||||||
@@ -198,11 +198,13 @@ removes the previous receipt. Affected suites pass.
|
|||||||
|
|
||||||
### R5 — Medium: The root facade still owns release mechanics
|
### R5 — Medium: The root facade still owns release mechanics
|
||||||
|
|
||||||
|
Status: Resolved.
|
||||||
|
|
||||||
Category: Architectural ownership gap and maintainability.
|
Category: Architectural ownership gap and maintainability.
|
||||||
|
|
||||||
**Evidence:** [candidate_build.go](../../candidate_build.go) implements temporary
|
**Evidence:** [candidate_build.go](../../internal/build/candidate.go) implements temporary
|
||||||
storage allocation, containment checking, cleanup, and candidate-build
|
storage allocation, containment checking, cleanup, and candidate-build
|
||||||
coordination in the public package. [delivery_assets.go](../../delivery_assets.go)
|
coordination in the public package. [delivery_assets.go](../../internal/delivery/assets.go)
|
||||||
implements artifact inventory validation, file opening/stat/hash checks,
|
implements artifact inventory validation, file opening/stat/hash checks,
|
||||||
filename derivation, and manifest assembly there. These are substantial
|
filename derivation, and manifest assembly there. These are substantial
|
||||||
implementation responsibilities beyond forwarding and type conversion.
|
implementation responsibilities beyond forwarding and type conversion.
|
||||||
@@ -220,11 +222,17 @@ assembly API or generic framework.
|
|||||||
checks remain valid after the move. Confirm filesystem and artifact algorithms
|
checks remain valid after the move. Confirm filesystem and artifact algorithms
|
||||||
are owned internally without introducing inward imports of public facades.
|
are owned internally without introducing inward imports of public facades.
|
||||||
|
|
||||||
|
**Resolution:** Candidate-build coordination now belongs to `internal/build`;
|
||||||
|
artifact inventory, hashing, and manifest assembly belong to `internal/delivery`.
|
||||||
|
The root facade performs conversions and forwarding only. Existing artifact
|
||||||
|
tests moved with their implementation; external API and CLI tests, the complete
|
||||||
|
offline suite, and compiled-export/import checks pass.
|
||||||
|
|
||||||
### R6 — Medium: Builds require a writable parent of the repository
|
### R6 — Medium: Builds require a writable parent of the repository
|
||||||
|
|
||||||
Category: Inadvertently strengthened filesystem prerequisite.
|
Category: Inadvertently strengthened filesystem prerequisite.
|
||||||
|
|
||||||
**Evidence:** [Candidate builds](../../candidate_build.go), around line 21,
|
**Evidence:** [Candidate builds](../../internal/build/candidate.go), around line 21,
|
||||||
and [CLI delivery builds](../../cmd/releasekit/main.go), around line 194,
|
and [CLI delivery builds](../../cmd/releasekit/main.go), around line 194,
|
||||||
allocate temporary storage with `os.MkdirTemp(filepath.Dir(repositoryDir), ...)`.
|
allocate temporary storage with `os.MkdirTemp(filepath.Dir(repositoryDir), ...)`.
|
||||||
The requirement is disposable output outside the worktree, not sibling output.
|
The requirement is disposable output outside the worktree, not sibling output.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package releasekit
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
|
||||||
)
|
)
|
||||||
|
|
||||||
func candidateBuildCallback(spec *BuildSpec, output io.Writer) func(context.Context, candidate.Candidate) error {
|
func CandidateCallback(spec *Spec, output io.Writer) func(context.Context, candidate.Candidate) error {
|
||||||
if spec == nil || len(spec.Targets) == 0 {
|
if spec == nil || len(spec.Targets) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func candidateBuildCallback(spec *BuildSpec, output io.Writer) func(context.Cont
|
|||||||
if relative == "." || relative != ".." && !strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
|
if relative == "." || relative != ".." && !strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
|
||||||
return fmt.Errorf("temporary candidate build output %q is inside the repository", temporaryDir)
|
return fmt.Errorf("temporary candidate build output %q is inside the repository", temporaryDir)
|
||||||
}
|
}
|
||||||
_, err = Build(ctx, BuildRequest{
|
_, err = Build(ctx, Request{
|
||||||
RepositoryDir: captured.RepositoryDir,
|
RepositoryDir: captured.RepositoryDir,
|
||||||
Version: captured.Version,
|
Version: captured.Version,
|
||||||
Spec: selected,
|
Spec: selected,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package releasekit
|
package delivery
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
@@ -9,10 +9,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea"
|
||||||
)
|
)
|
||||||
|
|
||||||
func declaredBuildAssets(result BuildResult) ([]gitea.ExpectedAsset, error) {
|
func declaredBuildAssets(result internalbuild.Result) ([]gitea.ExpectedAsset, error) {
|
||||||
if len(result.Targets) == 0 {
|
if len(result.Targets) == 0 {
|
||||||
if len(result.Artifacts) != 0 {
|
if len(result.Artifacts) != 0 {
|
||||||
return nil, fmt.Errorf("source-only build result contains artifacts")
|
return nil, fmt.Errorf("source-only build result contains artifacts")
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package releasekit
|
package delivery
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,12 +24,12 @@ func TestDeclaredBuildAssetsGenerateManifestFromBuildResult(t *testing.T) {
|
|||||||
if err := os.WriteFile(secondPath, second, 0o600); err != nil {
|
if err := os.WriteFile(secondPath, second, 0o600); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
result, err := declaredBuildAssets(BuildResult{
|
result, err := declaredBuildAssets(internalbuild.Result{
|
||||||
Version: "v1.2.3", BinaryName: "app",
|
Version: "v1.2.3", BinaryName: "app",
|
||||||
Targets: []Target{{OS: "linux", Arch: "amd64"}, {OS: "darwin", Arch: "arm64"}},
|
Targets: []internalbuild.Target{{OS: "linux", Arch: "amd64"}, {OS: "darwin", Arch: "arm64"}},
|
||||||
Artifacts: []BuildArtifact{
|
Artifacts: []internalbuild.Artifact{
|
||||||
{Path: firstPath, Filename: filepath.Base(firstPath), Target: Target{OS: "linux", Arch: "amd64"}, SHA256: assetDigest(first)},
|
{Path: firstPath, Filename: filepath.Base(firstPath), Target: internalbuild.Target{OS: "linux", Arch: "amd64"}, SHA256: assetDigest(first)},
|
||||||
{Path: secondPath, Filename: filepath.Base(secondPath), Target: Target{OS: "darwin", Arch: "arm64"}, SHA256: assetDigest(second)},
|
{Path: secondPath, Filename: filepath.Base(secondPath), Target: internalbuild.Target{OS: "darwin", Arch: "arm64"}, SHA256: assetDigest(second)},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -51,9 +52,9 @@ func TestDeclaredBuildAssetsRejectsTamperedArtifact(t *testing.T) {
|
|||||||
if err := os.WriteFile(path, []byte("changed bytes"), 0o600); err != nil {
|
if err := os.WriteFile(path, []byte("changed bytes"), 0o600); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
_, err := declaredBuildAssets(BuildResult{
|
_, err := declaredBuildAssets(internalbuild.Result{
|
||||||
Version: "v1.2.3", BinaryName: "app", Targets: []Target{{OS: "linux", Arch: "amd64"}},
|
Version: "v1.2.3", BinaryName: "app", Targets: []internalbuild.Target{{OS: "linux", Arch: "amd64"}},
|
||||||
Artifacts: []BuildArtifact{{Path: path, Filename: filepath.Base(path), Target: Target{OS: "linux", Arch: "amd64"}, SHA256: assetDigest([]byte("original bytes"))}},
|
Artifacts: []internalbuild.Artifact{{Path: path, Filename: filepath.Base(path), Target: internalbuild.Target{OS: "linux", Arch: "amd64"}, SHA256: assetDigest([]byte("original bytes"))}},
|
||||||
})
|
})
|
||||||
if err == nil || !strings.Contains(err.Error(), "SHA-256") {
|
if err == nil || !strings.Contains(err.Error(), "SHA-256") {
|
||||||
t.Fatalf("declaredBuildAssets() error = %v, want digest mismatch", err)
|
t.Fatalf("declaredBuildAssets() error = %v, want digest mismatch", err)
|
||||||
@@ -61,7 +62,7 @@ func TestDeclaredBuildAssetsRejectsTamperedArtifact(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDeclaredBuildAssetsKeepsSourceOnlyBuildManifestFree(t *testing.T) {
|
func TestDeclaredBuildAssetsKeepsSourceOnlyBuildManifestFree(t *testing.T) {
|
||||||
assets, err := declaredBuildAssets(BuildResult{})
|
assets, err := declaredBuildAssets(internalbuild.Result{})
|
||||||
if err != nil || len(assets) != 0 {
|
if err != nil || len(assets) != 0 {
|
||||||
t.Fatalf("assets = %#v, error = %v", assets, err)
|
t.Fatalf("assets = %#v, error = %v", assets, err)
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/git"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/git"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea"
|
||||||
@@ -23,23 +24,12 @@ const (
|
|||||||
Unknown State = "unknown"
|
Unknown State = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BuildIdentity struct {
|
|
||||||
RepositoryDir string
|
|
||||||
CandidateCommit string
|
|
||||||
SourceVerified bool
|
|
||||||
Version string
|
|
||||||
MainPackage string
|
|
||||||
BinaryName string
|
|
||||||
Targets []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
RepositoryDir string
|
RepositoryDir string
|
||||||
Product string
|
Product string
|
||||||
Version string
|
Version string
|
||||||
Destination gitea.Destination
|
Destination gitea.Destination
|
||||||
Build *BuildIdentity
|
Build *internalbuild.Result
|
||||||
Assets []gitea.ExpectedAsset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
@@ -76,11 +66,18 @@ func Deliver(ctx context.Context, request Request) (Result, error) {
|
|||||||
if source.Head != source.TagCommit {
|
if source.Head != source.TagCommit {
|
||||||
return result, fmt.Errorf("checkout HEAD %s does not match tag %s commit %s", source.Head, request.Version, source.TagCommit)
|
return result, fmt.Errorf("checkout HEAD %s does not match tag %s commit %s", source.Head, request.Version, source.TagCommit)
|
||||||
}
|
}
|
||||||
if err := validateBuild(repositoryDir, source.TagCommit, request.Version, request.Build, request.Assets); err != nil {
|
var assets []gitea.ExpectedAsset
|
||||||
|
if request.Build != nil {
|
||||||
|
assets, err = declaredBuildAssets(*request.Build)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := validateBuild(repositoryDir, source.TagCommit, request.Version, request.Build, assets); err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
if len(request.Assets) > 0 {
|
if len(assets) > 0 {
|
||||||
if err := gitea.VerifyLocalAssets(request.Assets); err != nil {
|
if err := gitea.VerifyLocalAssets(assets); err != nil {
|
||||||
return result, fmt.Errorf("verify build assets: %w", err)
|
return result, fmt.Errorf("verify build assets: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,17 +101,17 @@ func Deliver(ctx context.Context, request Request) (Result, error) {
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
result.ReleaseURL = releaseResult.Release.URL
|
result.ReleaseURL = releaseResult.Release.URL
|
||||||
if len(request.Assets) == 0 {
|
if len(assets) == 0 {
|
||||||
result.State = Complete
|
result.State = Complete
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
inspection, err := (gitea.Client{}).InspectAssets(ctx, request.Destination, releaseResult.Release.ID, request.Assets)
|
inspection, err := (gitea.Client{}).InspectAssets(ctx, request.Destination, releaseResult.Release.ID, assets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.State = NotAttempted
|
result.State = NotAttempted
|
||||||
if releaseResult.WriteAttempted {
|
if releaseResult.WriteAttempted {
|
||||||
result.State = Partial
|
result.State = Partial
|
||||||
}
|
}
|
||||||
result.Uncertain = assetIdentities(request.Assets)
|
result.Uncertain = assetIdentities(assets)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
uploadResult, uploadErr := (gitea.Client{}).UploadMissing(ctx, request.Destination, releaseResult.Release.ID, inspection)
|
uploadResult, uploadErr := (gitea.Client{}).UploadMissing(ctx, request.Destination, releaseResult.Release.ID, inspection)
|
||||||
@@ -130,7 +127,7 @@ func Deliver(ctx context.Context, request Request) (Result, error) {
|
|||||||
return result, uploadErr
|
return result, uploadErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateBuild(repositoryDir, commit, version string, build *BuildIdentity, assets []gitea.ExpectedAsset) error {
|
func validateBuild(repositoryDir, commit, version string, build *internalbuild.Result, assets []gitea.ExpectedAsset) error {
|
||||||
if build == nil {
|
if build == nil {
|
||||||
if len(assets) != 0 {
|
if len(assets) != 0 {
|
||||||
return errors.New("assets require a build identity")
|
return errors.New("assets require a build identity")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package releasekit
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
|
||||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/publish"
|
"gitea.maximumdirect.net/eric/ReleaseKit/internal/publish"
|
||||||
)
|
)
|
||||||
@@ -75,7 +76,7 @@ func Publish(ctx context.Context, request ReleaseRequest) (PublicationResult, er
|
|||||||
Version: request.Version,
|
Version: request.Version,
|
||||||
Remote: request.Remote,
|
Remote: request.Remote,
|
||||||
Validate: validate,
|
Validate: validate,
|
||||||
AfterValidate: candidateBuildCallback(request.Build, request.Output),
|
AfterValidate: internalbuild.CandidateCallback(internalBuildSpec(request.Build), request.Output),
|
||||||
Output: request.Output,
|
Output: request.Output,
|
||||||
})
|
})
|
||||||
return PublicationResult{
|
return PublicationResult{
|
||||||
|
|||||||
Reference in New Issue
Block a user