Fixes across 25 files addressing 46+ review comments: - pkg/ai/metrics.go: handle error from Close() on writable file handle - pkg/ansible: restore loop vars after loop, restore become settings, fix Upload with become=true and no password (use sudo -n), honour SSH timeout config, use E() helper for contextual errors, quote git refs in checkout commands - pkg/rag: validate chunk config, guard negative-to-uint64 conversion, use E() helper for errors, add context timeout to Ollama HTTP calls - pkg/deploy/python: fix exec.ExitError type assertion (was os.PathError), handle os.UserHomeDir() error - pkg/build/buildcmd: use cmd.Context() instead of context.Background() for proper Ctrl+C cancellation - install.bat: add curl timeouts, CRLF line endings, use --connect-timeout for archive downloads - install.sh: use absolute path for version check in CI mode - tools/rag: fix broken ingest.py function def, escape HTML in query.py, pin qdrant-client version, add markdown code block languages - internal/cmd/rag: add chunk size validation, env override handling Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
111 lines
3.3 KiB
Go
111 lines
3.3 KiB
Go
// cmd_release.go implements the release command: build + archive + publish in one step.
|
|
|
|
package buildcmd
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
|
|
"github.com/host-uk/core/pkg/cli"
|
|
"github.com/host-uk/core/pkg/framework/core"
|
|
"github.com/host-uk/core/pkg/i18n"
|
|
"github.com/host-uk/core/pkg/release"
|
|
)
|
|
|
|
// Flag variables for release command
|
|
var (
|
|
releaseVersion string
|
|
releaseDraft bool
|
|
releasePrerelease bool
|
|
releaseDryRun bool
|
|
)
|
|
|
|
var releaseCmd = &cli.Command{
|
|
Use: "release",
|
|
Short: i18n.T("cmd.build.release.short"),
|
|
Long: i18n.T("cmd.build.release.long"),
|
|
RunE: func(cmd *cli.Command, args []string) error {
|
|
return runRelease(cmd.Context(), releaseDryRun, releaseVersion, releaseDraft, releasePrerelease)
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
releaseCmd.Flags().BoolVar(&releaseDryRun, "dry-run", false, i18n.T("cmd.build.release.flag.dry_run"))
|
|
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"))
|
|
}
|
|
|
|
// AddReleaseCommand adds the release subcommand to the build command.
|
|
func AddReleaseCommand(buildCmd *cli.Command) {
|
|
buildCmd.AddCommand(releaseCmd)
|
|
}
|
|
|
|
// runRelease executes the full release workflow: build + archive + checksum + publish.
|
|
func runRelease(ctx context.Context, dryRun bool, version string, draft, prerelease bool) error {
|
|
// Get current directory
|
|
projectDir, err := os.Getwd()
|
|
if err != nil {
|
|
return core.E("release", "get working directory", err)
|
|
}
|
|
|
|
// 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")))
|
|
return core.E("release", "config not found", nil)
|
|
}
|
|
|
|
// Load configuration
|
|
cfg, err := release.LoadConfig(projectDir)
|
|
if err != nil {
|
|
return core.E("release", "load config", err)
|
|
}
|
|
|
|
// Apply CLI overrides
|
|
if version != "" {
|
|
cfg.SetVersion(version)
|
|
}
|
|
|
|
// 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
|
|
}
|