refactor(cli): separate build and publish concerns
- Move SDK generation to `core build sdk` subcommand - Make `core ci` publish-only (expects artifacts in dist/) - Add release.Publish() for publishing pre-built artifacts - Keep `core sdk diff` and `core sdk validate` for API validation - Update SKILL.md documentation This separation prevents accidental releases - running `core ci` without first building will fail safely. Workflow: core build # Build binaries core build sdk # Build SDKs core ci # Publish what's in dist/ Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
148670fd82
commit
331032cd57
5 changed files with 274 additions and 116 deletions
|
|
@ -25,7 +25,8 @@ The `core` command provides a unified interface for Go/Wails development, multi-
|
|||
| Deploy PHP app | `core php deploy` | Coolify deployment |
|
||||
| Build project | `core build` | Auto-detects project type |
|
||||
| Build for targets | `core build --targets linux/amd64,darwin/arm64` | Cross-compile |
|
||||
| Release | `core ci` | Build + publish to GitHub/npm/Homebrew |
|
||||
| Build SDK | `core build sdk` | Generate API clients from OpenAPI |
|
||||
| Publish release | `core ci` | Publish pre-built artifacts |
|
||||
| Check environment | `core doctor` | Verify tools installed |
|
||||
| Multi-repo status | `core dev health` | Quick summary across repos |
|
||||
| Multi-repo workflow | `core dev work` | Status + commit + push |
|
||||
|
|
@ -35,7 +36,8 @@ The `core` command provides a unified interface for Go/Wails development, multi-
|
|||
| List issues | `core dev issues` | Open issues across repos |
|
||||
| List PRs | `core dev reviews` | PRs needing review |
|
||||
| Check CI | `core dev ci` | GitHub Actions status |
|
||||
| Generate SDK | `core sdk` | Generate API clients from OpenAPI |
|
||||
| Validate OpenAPI | `core sdk validate` | Validate OpenAPI spec |
|
||||
| Check API changes | `core sdk diff` | Detect breaking API changes |
|
||||
| Sync docs | `core docs sync` | Sync docs across repos |
|
||||
| Search packages | `core pkg search <query>` | GitHub search for core-* repos |
|
||||
| Install package | `core pkg install <name>` | Clone and register package |
|
||||
|
|
@ -65,6 +67,31 @@ core build --ci
|
|||
|
||||
**Why:** Handles cross-compilation, code signing, archiving, checksums, and CI output formatting.
|
||||
|
||||
## Releasing
|
||||
|
||||
Build and publish are **separated** to prevent accidental releases:
|
||||
|
||||
```bash
|
||||
# Step 1: Build artifacts (safe - no publishing)
|
||||
core build
|
||||
core build sdk
|
||||
|
||||
# Step 2: Publish to configured targets (requires pre-built artifacts)
|
||||
core ci # Publish what's in dist/
|
||||
core ci --dry-run # Preview what would be published
|
||||
core ci --draft # Create as draft release
|
||||
core ci --prerelease # Mark as prerelease
|
||||
```
|
||||
|
||||
**Why separate?** Running `core ci` without first building will fail safely - no accidental publishes.
|
||||
|
||||
```bash
|
||||
# Release workflow utilities
|
||||
core ci init # Initialize .core/release.yaml
|
||||
core ci changelog # Generate changelog from commits
|
||||
core ci version # Show determined version
|
||||
```
|
||||
|
||||
## Multi-Repo Workflow
|
||||
|
||||
When working across host-uk repositories:
|
||||
|
|
@ -121,14 +148,31 @@ Generate API clients from OpenAPI specs:
|
|||
|
||||
```bash
|
||||
# Generate all configured SDKs
|
||||
core sdk
|
||||
core build sdk
|
||||
|
||||
# Generate specific language
|
||||
core sdk --lang typescript
|
||||
core sdk --lang php
|
||||
core build sdk --lang typescript
|
||||
core build sdk --lang php
|
||||
|
||||
# Specify OpenAPI spec
|
||||
core sdk --spec ./openapi.yaml
|
||||
core build sdk --spec ./openapi.yaml
|
||||
|
||||
# Preview without generating
|
||||
core build sdk --dry-run
|
||||
```
|
||||
|
||||
## SDK Validation
|
||||
|
||||
Validate specs and check for breaking changes:
|
||||
|
||||
```bash
|
||||
# Validate OpenAPI spec
|
||||
core sdk validate
|
||||
core sdk validate --spec ./api.yaml
|
||||
|
||||
# Check for breaking API changes
|
||||
core sdk diff --base v1.0.0
|
||||
core sdk diff --base ./old-api.yaml --spec ./new-api.yaml
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
|
@ -476,7 +520,8 @@ Go project?
|
|||
└── Lint: core go lint
|
||||
└── Tidy modules: core go mod tidy
|
||||
└── Build: core build [--targets <os/arch>]
|
||||
└── Release: core ci
|
||||
└── Build SDK: core build sdk
|
||||
└── Publish: core ci [--dry-run]
|
||||
|
||||
PHP/Laravel project?
|
||||
└── Start dev: core php dev [--https]
|
||||
|
|
@ -526,6 +571,8 @@ Managing packages?
|
|||
| Raw `linuxkit run` | `core vm run` | Unified interface, templates |
|
||||
| `gh repo clone` | `core pkg install` | Auto-detects org, adds to registry |
|
||||
| Manual GitHub search | `core pkg search` | Filtered to org, formatted output |
|
||||
| `core ci` without build | `core build && core ci` | Build first, then publish |
|
||||
| `core sdk generate` | `core build sdk` | SDK generation moved to build |
|
||||
|
||||
## Configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/host-uk/core/pkg/build"
|
||||
"github.com/host-uk/core/pkg/build/builders"
|
||||
"github.com/host-uk/core/pkg/build/signing"
|
||||
"github.com/host-uk/core/pkg/sdk"
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/leaanthony/debme"
|
||||
"github.com/leaanthony/gosod"
|
||||
|
|
@ -125,6 +126,25 @@ func AddBuildCommand(app *clir.Cli) {
|
|||
}
|
||||
return runPwaBuild(pwaURL)
|
||||
})
|
||||
|
||||
// --- `build sdk` command ---
|
||||
sdkBuildCmd := buildCmd.NewSubCommand("sdk", "Generate API SDKs from OpenAPI spec")
|
||||
sdkBuildCmd.LongDescription("Generates typed API clients from OpenAPI specifications.\n" +
|
||||
"Supports TypeScript, Python, Go, and PHP.\n\n" +
|
||||
"Examples:\n" +
|
||||
" core build sdk # Generate all configured SDKs\n" +
|
||||
" core build sdk --lang typescript # Generate only TypeScript SDK\n" +
|
||||
" core build sdk --spec api.yaml # Use specific OpenAPI spec")
|
||||
|
||||
var sdkSpec, sdkLang, sdkVersion string
|
||||
var sdkDryRun bool
|
||||
sdkBuildCmd.StringFlag("spec", "Path to OpenAPI spec file", &sdkSpec)
|
||||
sdkBuildCmd.StringFlag("lang", "Generate only this language (typescript, python, go, php)", &sdkLang)
|
||||
sdkBuildCmd.StringFlag("version", "Version to embed in generated SDKs", &sdkVersion)
|
||||
sdkBuildCmd.BoolFlag("dry-run", "Show what would be generated without writing files", &sdkDryRun)
|
||||
sdkBuildCmd.Action(func() error {
|
||||
return runBuildSDK(sdkSpec, sdkLang, sdkVersion, sdkDryRun)
|
||||
})
|
||||
}
|
||||
|
||||
// runProjectBuild handles the main `core build` command with auto-detection.
|
||||
|
|
@ -516,6 +536,73 @@ func getBuilder(projectType build.ProjectType) (build.Builder, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// --- SDK Build Logic ---
|
||||
|
||||
func runBuildSDK(specPath, lang, version string, dryRun bool) error {
|
||||
ctx := context.Background()
|
||||
|
||||
projectDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get working directory: %w", err)
|
||||
}
|
||||
|
||||
// Load config
|
||||
config := sdk.DefaultConfig()
|
||||
if specPath != "" {
|
||||
config.Spec = specPath
|
||||
}
|
||||
|
||||
s := sdk.New(projectDir, config)
|
||||
if version != "" {
|
||||
s.SetVersion(version)
|
||||
}
|
||||
|
||||
fmt.Printf("%s Generating SDKs\n", buildHeaderStyle.Render("Build SDK:"))
|
||||
if dryRun {
|
||||
fmt.Printf(" %s\n", buildDimStyle.Render("(dry-run mode)"))
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// Detect spec
|
||||
detectedSpec, err := s.DetectSpec()
|
||||
if err != nil {
|
||||
fmt.Printf("%s %v\n", buildErrorStyle.Render("Error:"), err)
|
||||
return err
|
||||
}
|
||||
fmt.Printf(" Spec: %s\n", buildTargetStyle.Render(detectedSpec))
|
||||
|
||||
if dryRun {
|
||||
if lang != "" {
|
||||
fmt.Printf(" Language: %s\n", buildTargetStyle.Render(lang))
|
||||
} else {
|
||||
fmt.Printf(" Languages: %s\n", buildTargetStyle.Render(strings.Join(config.Languages, ", ")))
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Printf("%s Would generate SDKs (dry-run)\n", buildSuccessStyle.Render("OK:"))
|
||||
return nil
|
||||
}
|
||||
|
||||
if lang != "" {
|
||||
// Generate single language
|
||||
if err := s.GenerateLanguage(ctx, lang); err != nil {
|
||||
fmt.Printf("%s %v\n", buildErrorStyle.Render("Error:"), err)
|
||||
return err
|
||||
}
|
||||
fmt.Printf(" Generated: %s\n", buildTargetStyle.Render(lang))
|
||||
} else {
|
||||
// Generate all
|
||||
if err := s.Generate(ctx); err != nil {
|
||||
fmt.Printf("%s %v\n", buildErrorStyle.Render("Error:"), err)
|
||||
return err
|
||||
}
|
||||
fmt.Printf(" Generated: %s\n", buildTargetStyle.Render(strings.Join(config.Languages, ", ")))
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf("%s SDK generation complete\n", buildSuccessStyle.Render("Success:"))
|
||||
return nil
|
||||
}
|
||||
|
||||
// --- PWA Build Logic ---
|
||||
|
||||
func runPwaBuild(pwaURL string) error {
|
||||
|
|
|
|||
|
|
@ -45,20 +45,15 @@ func AddCIReleaseCommand(app *clir.Cli) {
|
|||
var version string
|
||||
var draft bool
|
||||
var prerelease bool
|
||||
var target string
|
||||
|
||||
releaseCmd.BoolFlag("dry-run", "Preview release without publishing", &dryRun)
|
||||
releaseCmd.StringFlag("version", "Version to release (e.g., v1.2.3)", &version)
|
||||
releaseCmd.BoolFlag("draft", "Create release as a draft", &draft)
|
||||
releaseCmd.BoolFlag("prerelease", "Mark release as a prerelease", &prerelease)
|
||||
releaseCmd.StringFlag("target", "CIRelease target (sdk)", &target)
|
||||
|
||||
// Default action for `core release`
|
||||
// Default action for `core ci` - publish only (expects artifacts in dist/)
|
||||
releaseCmd.Action(func() error {
|
||||
if target == "sdk" {
|
||||
return runCIReleaseSDK(dryRun, version)
|
||||
}
|
||||
return runCIRelease(dryRun, version, draft, prerelease)
|
||||
return runCIPublish(dryRun, version, draft, prerelease)
|
||||
})
|
||||
|
||||
// `release init` subcommand
|
||||
|
|
@ -86,8 +81,9 @@ func AddCIReleaseCommand(app *clir.Cli) {
|
|||
})
|
||||
}
|
||||
|
||||
// runCIRelease executes the main release workflow.
|
||||
func runCIRelease(dryRun bool, version string, draft, prerelease bool) error {
|
||||
// runCIPublish publishes pre-built artifacts from dist/.
|
||||
// It does NOT build - use `core build` first.
|
||||
func runCIPublish(dryRun bool, version string, draft, prerelease bool) error {
|
||||
ctx := context.Background()
|
||||
|
||||
// Get current directory
|
||||
|
|
@ -120,14 +116,19 @@ func runCIRelease(dryRun bool, version string, draft, prerelease bool) error {
|
|||
}
|
||||
|
||||
// Print header
|
||||
fmt.Printf("%s Starting release process\n", releaseHeaderStyle.Render("CIRelease:"))
|
||||
fmt.Printf("%s Publishing release\n", releaseHeaderStyle.Render("CI:"))
|
||||
if dryRun {
|
||||
fmt.Printf(" %s\n", releaseDimStyle.Render("(dry-run mode)"))
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// Run the release
|
||||
rel, err := release.Run(ctx, cfg, dryRun)
|
||||
// Check for publishers
|
||||
if len(cfg.Publishers) == 0 {
|
||||
return fmt.Errorf("no publishers configured in .core/release.yaml")
|
||||
}
|
||||
|
||||
// Publish pre-built artifacts
|
||||
rel, err := release.Publish(ctx, cfg, dryRun)
|
||||
if err != nil {
|
||||
fmt.Printf("%s %v\n", releaseErrorStyle.Render("Error:"), err)
|
||||
return err
|
||||
|
|
@ -135,11 +136,11 @@ func runCIRelease(dryRun bool, version string, draft, prerelease bool) error {
|
|||
|
||||
// Print summary
|
||||
fmt.Println()
|
||||
fmt.Printf("%s CIRelease completed!\n", releaseSuccessStyle.Render("Success:"))
|
||||
fmt.Printf("%s Publish completed!\n", releaseSuccessStyle.Render("Success:"))
|
||||
fmt.Printf(" Version: %s\n", releaseValueStyle.Render(rel.Version))
|
||||
fmt.Printf(" Artifacts: %d\n", len(rel.Artifacts))
|
||||
|
||||
if !dryRun && len(cfg.Publishers) > 0 {
|
||||
if !dryRun {
|
||||
for _, pub := range cfg.Publishers {
|
||||
fmt.Printf(" Published: %s\n", releaseValueStyle.Render(pub.Type))
|
||||
}
|
||||
|
|
@ -148,50 +149,6 @@ func runCIRelease(dryRun bool, version string, draft, prerelease bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// runCIReleaseSDK executes SDK-only release.
|
||||
func runCIReleaseSDK(dryRun bool, version string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
projectDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get working directory: %w", err)
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
cfg, err := release.LoadConfig(projectDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load config: %w", err)
|
||||
}
|
||||
|
||||
// Apply CLI overrides
|
||||
if version != "" {
|
||||
cfg.SetVersion(version)
|
||||
}
|
||||
|
||||
// Print header
|
||||
fmt.Printf("%s Generating SDKs\n", releaseHeaderStyle.Render("SDK CIRelease:"))
|
||||
if dryRun {
|
||||
fmt.Printf(" %s\n", releaseDimStyle.Render("(dry-run mode)"))
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// Run SDK release
|
||||
result, err := release.RunSDK(ctx, cfg, dryRun)
|
||||
if err != nil {
|
||||
fmt.Printf("%s %v\n", releaseErrorStyle.Render("Error:"), err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Print summary
|
||||
fmt.Println()
|
||||
fmt.Printf("%s SDK generation complete!\n", releaseSuccessStyle.Render("Success:"))
|
||||
fmt.Printf(" Version: %s\n", releaseValueStyle.Render(result.Version))
|
||||
fmt.Printf(" Languages: %v\n", result.Languages)
|
||||
fmt.Printf(" Output: %s/\n", releaseValueStyle.Render(result.Output))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// runCIReleaseInit creates a release configuration interactively.
|
||||
func runCIReleaseInit() error {
|
||||
projectDir, err := os.Getwd()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -29,22 +28,16 @@ var (
|
|||
|
||||
// AddSDKCommand adds the sdk command and its subcommands.
|
||||
func AddSDKCommand(app *clir.Cli) {
|
||||
sdkCmd := app.NewSubCommand("sdk", "Generate and manage API SDKs")
|
||||
sdkCmd.LongDescription("Generate typed API clients from OpenAPI specs.\n" +
|
||||
"Supports TypeScript, Python, Go, and PHP.")
|
||||
|
||||
// sdk generate
|
||||
genCmd := sdkCmd.NewSubCommand("generate", "Generate SDKs from OpenAPI spec")
|
||||
var specPath, lang string
|
||||
genCmd.StringFlag("spec", "Path to OpenAPI spec file", &specPath)
|
||||
genCmd.StringFlag("lang", "Generate only this language", &lang)
|
||||
genCmd.Action(func() error {
|
||||
return runSDKGenerate(specPath, lang)
|
||||
})
|
||||
sdkCmd := app.NewSubCommand("sdk", "SDK validation and API compatibility tools")
|
||||
sdkCmd.LongDescription("Tools for validating OpenAPI specs and checking API compatibility.\n" +
|
||||
"To generate SDKs, use: core build sdk\n\n" +
|
||||
"Commands:\n" +
|
||||
" diff Check for breaking API changes\n" +
|
||||
" validate Validate OpenAPI spec syntax")
|
||||
|
||||
// sdk diff
|
||||
diffCmd := sdkCmd.NewSubCommand("diff", "Check for breaking API changes")
|
||||
var basePath string
|
||||
var basePath, specPath string
|
||||
diffCmd.StringFlag("base", "Base spec (version tag or file)", &basePath)
|
||||
diffCmd.StringFlag("spec", "Current spec file", &specPath)
|
||||
diffCmd.Action(func() error {
|
||||
|
|
@ -59,42 +52,6 @@ func AddSDKCommand(app *clir.Cli) {
|
|||
})
|
||||
}
|
||||
|
||||
func runSDKGenerate(specPath, lang string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
projectDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get working directory: %w", err)
|
||||
}
|
||||
|
||||
// Load config
|
||||
config := sdk.DefaultConfig()
|
||||
if specPath != "" {
|
||||
config.Spec = specPath
|
||||
}
|
||||
|
||||
s := sdk.New(projectDir, config)
|
||||
|
||||
fmt.Printf("%s Generating SDKs\n", sdkHeaderStyle.Render("SDK:"))
|
||||
|
||||
if lang != "" {
|
||||
// Generate single language
|
||||
if err := s.GenerateLanguage(ctx, lang); err != nil {
|
||||
fmt.Printf("%s %v\n", sdkErrorStyle.Render("Error:"), err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Generate all
|
||||
if err := s.Generate(ctx); err != nil {
|
||||
fmt.Printf("%s %v\n", sdkErrorStyle.Render("Error:"), err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("%s SDK generation complete\n", sdkSuccessStyle.Render("Success:"))
|
||||
return nil
|
||||
}
|
||||
|
||||
func runSDKDiff(basePath, specPath string) error {
|
||||
projectDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ package release
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/host-uk/core/pkg/build"
|
||||
"github.com/host-uk/core/pkg/build/builders"
|
||||
|
|
@ -25,8 +27,116 @@ type Release struct {
|
|||
ProjectDir string
|
||||
}
|
||||
|
||||
// Run executes the release process: determine version, build artifacts,
|
||||
// Publish publishes pre-built artifacts from dist/ to configured targets.
|
||||
// Use this after `core build` to separate build and publish concerns.
|
||||
// If dryRun is true, it will show what would be done without actually publishing.
|
||||
func Publish(ctx context.Context, cfg *Config, dryRun bool) (*Release, error) {
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("release.Publish: config is nil")
|
||||
}
|
||||
|
||||
projectDir := cfg.projectDir
|
||||
if projectDir == "" {
|
||||
projectDir = "."
|
||||
}
|
||||
|
||||
// Resolve to absolute path
|
||||
absProjectDir, err := filepath.Abs(projectDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("release.Publish: failed to resolve project directory: %w", err)
|
||||
}
|
||||
|
||||
// Step 1: Determine version
|
||||
version := cfg.version
|
||||
if version == "" {
|
||||
version, err = DetermineVersion(absProjectDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("release.Publish: failed to determine version: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: Find pre-built artifacts in dist/
|
||||
distDir := filepath.Join(absProjectDir, "dist")
|
||||
artifacts, err := findArtifacts(distDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("release.Publish: %w", err)
|
||||
}
|
||||
|
||||
if len(artifacts) == 0 {
|
||||
return nil, fmt.Errorf("release.Publish: no artifacts found in dist/\nRun 'core build' first to create artifacts")
|
||||
}
|
||||
|
||||
// Step 3: Generate changelog
|
||||
changelog, err := Generate(absProjectDir, "", version)
|
||||
if err != nil {
|
||||
// Non-fatal: continue with empty changelog
|
||||
changelog = fmt.Sprintf("Release %s", version)
|
||||
}
|
||||
|
||||
release := &Release{
|
||||
Version: version,
|
||||
Artifacts: artifacts,
|
||||
Changelog: changelog,
|
||||
ProjectDir: absProjectDir,
|
||||
}
|
||||
|
||||
// Step 4: Publish to configured targets
|
||||
if len(cfg.Publishers) > 0 {
|
||||
pubRelease := publishers.NewRelease(release.Version, release.Artifacts, release.Changelog, release.ProjectDir)
|
||||
|
||||
for _, pubCfg := range cfg.Publishers {
|
||||
publisher, err := getPublisher(pubCfg.Type)
|
||||
if err != nil {
|
||||
return release, fmt.Errorf("release.Publish: %w", err)
|
||||
}
|
||||
|
||||
extendedCfg := buildExtendedConfig(pubCfg)
|
||||
publisherCfg := publishers.NewPublisherConfig(pubCfg.Type, pubCfg.Prerelease, pubCfg.Draft, extendedCfg)
|
||||
if err := publisher.Publish(ctx, pubRelease, publisherCfg, cfg, dryRun); err != nil {
|
||||
return release, fmt.Errorf("release.Publish: publish to %s failed: %w", pubCfg.Type, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
// findArtifacts discovers pre-built artifacts in the dist directory.
|
||||
func findArtifacts(distDir string) ([]build.Artifact, error) {
|
||||
if _, err := os.Stat(distDir); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("dist/ directory not found")
|
||||
}
|
||||
|
||||
var artifacts []build.Artifact
|
||||
|
||||
entries, err := os.ReadDir(distDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read dist/: %w", err)
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
name := entry.Name()
|
||||
path := filepath.Join(distDir, name)
|
||||
|
||||
// Include archives and checksums
|
||||
if strings.HasSuffix(name, ".tar.gz") ||
|
||||
strings.HasSuffix(name, ".zip") ||
|
||||
strings.HasSuffix(name, ".txt") ||
|
||||
strings.HasSuffix(name, ".sig") {
|
||||
artifacts = append(artifacts, build.Artifact{Path: path})
|
||||
}
|
||||
}
|
||||
|
||||
return artifacts, nil
|
||||
}
|
||||
|
||||
// Run executes the full release process: determine version, build artifacts,
|
||||
// generate changelog, and publish to configured targets.
|
||||
// For separated concerns, prefer using `core build` then `core ci` (Publish).
|
||||
// If dryRun is true, it will show what would be done without actually publishing.
|
||||
func Run(ctx context.Context, cfg *Config, dryRun bool) (*Release, error) {
|
||||
if cfg == nil {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue