feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
// cmd_release.go implements the release command: build + archive + publish in one step.
|
|
|
|
|
|
|
|
|
|
package buildcmd
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
|
2026-03-26 17:41:53 +00:00
|
|
|
"dappco.re/go/core/build/internal/ax"
|
2026-03-22 01:53:16 +00:00
|
|
|
"dappco.re/go/core/build/pkg/release"
|
|
|
|
|
"dappco.re/go/core/i18n"
|
|
|
|
|
coreerr "dappco.re/go/core/log"
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
"forge.lthn.ai/core/cli/pkg/cli"
|
|
|
|
|
)
|
|
|
|
|
|
2026-03-31 18:37:59 +00:00
|
|
|
// Flag variables for release command.
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
var (
|
2026-04-01 20:09:53 +00:00
|
|
|
releaseVersion string
|
|
|
|
|
releaseDraft bool
|
|
|
|
|
releasePrerelease bool
|
|
|
|
|
releaseLaunchMode bool
|
|
|
|
|
releaseArchiveFormat string
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var releaseCmd = &cli.Command{
|
2026-03-17 02:31:47 +00:00
|
|
|
Use: "release",
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
RunE: func(cmd *cli.Command, args []string) error {
|
2026-04-01 20:09:53 +00:00
|
|
|
return runRelease(cmd.Context(), !releaseLaunchMode, releaseVersion, releaseDraft, releasePrerelease, releaseArchiveFormat)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-17 02:31:47 +00:00
|
|
|
func setReleaseI18n() {
|
|
|
|
|
releaseCmd.Short = i18n.T("cmd.build.release.short")
|
|
|
|
|
releaseCmd.Long = i18n.T("cmd.build.release.long")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func initReleaseFlags() {
|
2026-03-31 18:37:59 +00:00
|
|
|
releaseCmd.Flags().BoolVar(&releaseLaunchMode, "we-are-go-for-launch", false, i18n.T("cmd.build.release.flag.go_for_launch"))
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
releaseCmd.Flags().StringVar(&releaseVersion, "version", "", i18n.T("cmd.build.release.flag.version"))
|
|
|
|
|
releaseCmd.Flags().BoolVar(&releaseDraft, "draft", false, i18n.T("cmd.build.release.flag.draft"))
|
|
|
|
|
releaseCmd.Flags().BoolVar(&releasePrerelease, "prerelease", false, i18n.T("cmd.build.release.flag.prerelease"))
|
2026-04-01 20:09:53 +00:00
|
|
|
releaseCmd.Flags().StringVar(&releaseArchiveFormat, "archive-format", "", i18n.T("cmd.build.flag.archive_format"))
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddReleaseCommand adds the release subcommand to the build command.
|
2026-03-31 18:33:36 +01:00
|
|
|
//
|
|
|
|
|
// buildcmd.AddReleaseCommand(buildCmd)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
func AddReleaseCommand(buildCmd *cli.Command) {
|
2026-03-17 02:31:47 +00:00
|
|
|
setReleaseI18n()
|
|
|
|
|
initReleaseFlags()
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
buildCmd.AddCommand(releaseCmd)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// runRelease executes the full release workflow: build + archive + checksum + publish.
|
2026-04-01 20:09:53 +00:00
|
|
|
func runRelease(ctx context.Context, dryRun bool, version string, draft, prerelease bool, archiveFormat string) error {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
// Get current directory
|
2026-03-26 17:41:53 +00:00
|
|
|
projectDir, err := ax.Getwd()
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
if err != nil {
|
2026-03-22 01:53:16 +00:00
|
|
|
return coreerr.E("release", "get working directory", err)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for release config
|
|
|
|
|
if !release.ConfigExists(projectDir) {
|
|
|
|
|
cli.Print("%s %s\n",
|
|
|
|
|
buildErrorStyle.Render(i18n.Label("error")),
|
|
|
|
|
i18n.T("cmd.build.release.error.no_config"),
|
|
|
|
|
)
|
|
|
|
|
cli.Print(" %s\n", buildDimStyle.Render(i18n.T("cmd.build.release.hint.create_config")))
|
2026-03-22 01:53:16 +00:00
|
|
|
return coreerr.E("release", "config not found", nil)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Load configuration
|
|
|
|
|
cfg, err := release.LoadConfig(projectDir)
|
|
|
|
|
if err != nil {
|
2026-03-22 01:53:16 +00:00
|
|
|
return coreerr.E("release", "load config", err)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Apply CLI overrides
|
|
|
|
|
if version != "" {
|
|
|
|
|
cfg.SetVersion(version)
|
|
|
|
|
}
|
2026-04-01 20:09:53 +00:00
|
|
|
if err := applyReleaseArchiveFormatOverride(cfg, archiveFormat); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
|
|
|
|
|
// Apply draft/prerelease overrides to all publishers
|
|
|
|
|
if draft || prerelease {
|
|
|
|
|
for i := range cfg.Publishers {
|
|
|
|
|
if draft {
|
|
|
|
|
cfg.Publishers[i].Draft = true
|
|
|
|
|
}
|
|
|
|
|
if prerelease {
|
|
|
|
|
cfg.Publishers[i].Prerelease = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Print header
|
|
|
|
|
cli.Print("%s %s\n", buildHeaderStyle.Render(i18n.T("cmd.build.release.label.release")), i18n.T("cmd.build.release.building_and_publishing"))
|
|
|
|
|
if dryRun {
|
|
|
|
|
cli.Print(" %s\n", buildDimStyle.Render(i18n.T("cmd.build.release.dry_run_hint")))
|
|
|
|
|
}
|
|
|
|
|
cli.Blank()
|
|
|
|
|
|
|
|
|
|
// Run full release (build + archive + checksum + publish)
|
|
|
|
|
rel, err := release.Run(ctx, cfg, dryRun)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Print summary
|
|
|
|
|
cli.Blank()
|
|
|
|
|
cli.Print("%s %s\n", buildSuccessStyle.Render(i18n.T("i18n.done.pass")), i18n.T("cmd.build.release.completed"))
|
|
|
|
|
cli.Print(" %s %s\n", i18n.Label("version"), buildTargetStyle.Render(rel.Version))
|
|
|
|
|
cli.Print(" %s %d\n", i18n.T("cmd.build.release.label.artifacts"), len(rel.Artifacts))
|
|
|
|
|
|
|
|
|
|
if !dryRun {
|
|
|
|
|
for _, pub := range cfg.Publishers {
|
|
|
|
|
cli.Print(" %s %s\n", i18n.T("cmd.build.release.label.published"), buildTargetStyle.Render(pub.Type))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2026-04-01 20:09:53 +00:00
|
|
|
|
|
|
|
|
// applyReleaseArchiveFormatOverride applies the archive-format CLI override to the release config.
|
|
|
|
|
//
|
|
|
|
|
// applyReleaseArchiveFormatOverride(cfg, "xz") // cfg.Build.ArchiveFormat = "xz"
|
|
|
|
|
func applyReleaseArchiveFormatOverride(cfg *release.Config, archiveFormat string) error {
|
|
|
|
|
if cfg == nil || archiveFormat == "" {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
formatValue, err := resolveArchiveFormat("", archiveFormat)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg.Build.ArchiveFormat = string(formatValue)
|
|
|
|
|
return nil
|
|
|
|
|
}
|