package releasekit import ( "context" "io" internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build" ) // Target identifies one explicit Go operating-system and architecture pair. type Target struct { OS string // Go operating system name, such as "linux". Arch string // Go architecture name, such as "amd64". } // BuildSpec selects the application package, output name, and target pairs. type BuildSpec struct { MainPackage string // Go package path to build, such as "./cmd/app". BinaryName string // filename component used in output artifacts. Targets []Target // selected target pairs; duplicates are removed in order. } // BuildRequest contains the source and output settings for Build. type BuildRequest struct { RepositoryDir string // source repository whose current HEAD is recorded. Version string // stable vMAJOR.MINOR.PATCH value injected at link time. Spec BuildSpec // application package, artifact name, and targets. OutputDir string // output location; empty selects /dist. Output io.Writer // optional build progress destination. } // BuildArtifact identifies one generated binary and its SHA-256 digest. type BuildArtifact struct { Path string // absolute path to the generated binary. Filename string // generated filename. Target Target // Go target used for this artifact. SHA256 string // lowercase hexadecimal digest of the complete file. } // BuildResult describes the source and artifacts reached by Build. type BuildResult struct { RepositoryDir string // absolute source repository path. CandidateCommit string // Git HEAD observed when the build started. // SourceVerified reports clean source and the same HEAD observed before and // after a completed build. It is required for binary delivery, not an attestation. SourceVerified bool Version string // requested injected version. MainPackage string // Go package path built. BinaryName string // artifact name prefix. OutputDir string // resolved output directory. Targets []Target // normalized target pairs. Artifacts []BuildArtifact // completed output files, including partial success. Compiler string // output of the selected local Go toolchain's version command. } // Build compiles the selected targets with Version injected through buildinfo. // It uses the available compatible local Go toolchain, applies ReleaseKit's // readonly offline build settings, preserves effective cache and tool settings, // and verifies the version command on the Go host before succeeding. An empty // target set records source identity without running the Go toolchain. Errors // return partial build facts in the result. func Build(ctx context.Context, request BuildRequest) (BuildResult, error) { result, err := internalbuild.Build(ctx, internalbuild.Request{ RepositoryDir: request.RepositoryDir, Version: request.Version, Spec: *internalBuildSpec(&request.Spec), OutputDir: request.OutputDir, Output: request.Output, }) public := BuildResult{ RepositoryDir: result.RepositoryDir, CandidateCommit: result.CandidateCommit, SourceVerified: result.SourceVerified, Version: result.Version, MainPackage: result.MainPackage, BinaryName: result.BinaryName, OutputDir: result.OutputDir, Compiler: result.Compiler, Targets: make([]Target, 0, len(result.Targets)), Artifacts: make([]BuildArtifact, 0, len(result.Artifacts)), } for _, target := range result.Targets { public.Targets = append(public.Targets, Target{OS: target.OS, Arch: target.Arch}) } for _, artifact := range result.Artifacts { public.Artifacts = append(public.Artifacts, BuildArtifact{ Path: artifact.Path, Filename: artifact.Filename, Target: Target{OS: artifact.Target.OS, Arch: artifact.Target.Arch}, SHA256: artifact.SHA256, }) } 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 }