release

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2026 License: EUPL-1.2 Imports: 19 Imported by: 0

Documentation

Overview

Package release provides release automation with changelog generation and publishing.

Package release provides release automation with changelog generation and publishing.

Package release provides release automation with changelog generation and publishing. It orchestrates the build system, changelog generation, and publishing to targets like GitHub Releases.

Package release provides release automation with changelog generation and publishing.

Package release provides release automation with changelog generation and publishing.

Index

Examples

Constants

View Source
const ConfigDir = ".core"

ConfigDir is the directory where release configuration is stored.

configPath := ax.Join(projectDir, release.ConfigDir, release.ConfigFileName)

View Source
const ConfigFileName = "release.yaml"

ConfigFileName is the name of the release configuration file.

configPath := ax.Join(projectDir, release.ConfigDir, release.ConfigFileName)

Variables

This section is empty.

Functions

func CompareVersions

func CompareVersions(a, b string) int

CompareVersions compares two semver strings. Returns -1 if a < b, 0 if a == b, 1 if a > b.

result := release.CompareVersions("v1.2.3", "v1.2.4") // → -1

Example
_ = CompareVersions("agent", "agent")
core.Println("CompareVersions")
Output:
CompareVersions

func ConfigExists

func ConfigExists(dir string) bool

ConfigExists checks if a release config file exists in the given directory.

if release.ConfigExists(".") { ... }

Example
_ = ConfigExists(core.Path(core.TempDir(), "go-build-compliance"))
core.Println("ConfigExists")
Output:
ConfigExists

func ConfigPath

func ConfigPath(dir string) string

ConfigPath returns the path to the release config file for a given directory.

path := release.ConfigPath("/home/user/my-project") // → "/home/user/my-project/.core/release.yaml"

Example
_ = ConfigPath(core.Path(core.TempDir(), "go-build-compliance"))
core.Println("ConfigPath")
Output:
ConfigPath

func DetermineVersion

func DetermineVersion(dir string) core.Result

DetermineVersion determines the version for a release. It checks in order:

  1. Git tag on HEAD
  2. Most recent tag + increment patch
  3. Default to v0.0.1 if no tags exist

result := release.DetermineVersion(".") // → "v1.2.4"

Example

--- v0.9.0 generated usage examples ---

_ = DetermineVersion(core.Path(core.TempDir(), "go-build-compliance"))
core.Println("DetermineVersion")
Output:
DetermineVersion

func DetermineVersionWithContext

func DetermineVersionWithContext(ctx context.Context, dir string) core.Result

DetermineVersionWithContext determines the version while honouring caller cancellation. It checks in order:

  1. Git tag on HEAD
  2. Most recent tag + increment patch
  3. Default to v0.0.1 if no tags exist

result := release.DetermineVersionWithContext(ctx, ".") // → "v1.2.4"

Example
ctx, cancel := core.WithCancel(core.Background())
cancel()
_ = DetermineVersionWithContext(ctx, core.Path(core.TempDir(), "go-build-compliance"))
core.Println("DetermineVersionWithContext")
Output:
DetermineVersionWithContext

func Generate

func Generate(dir, fromRef, toRef string) core.Result

Generate generates a markdown changelog from git commits between two refs. If fromRef is empty, it uses the previous tag or initial commit. If toRef is empty, it uses HEAD.

result := release.Generate(".", "v1.2.3", "HEAD")

Example

--- v0.9.0 generated usage examples ---

_ = Generate(core.Path(core.TempDir(), "go-build-compliance"), "agent", "agent")
core.Println("Generate")
Output:
Generate

func GenerateWithConfig

func GenerateWithConfig(dir, fromRef, toRef string, cfg *ChangelogConfig) core.Result

GenerateWithConfig generates a changelog with filtering based on config.

result := release.GenerateWithConfig(".", "v1.2.3", "HEAD", &cfg.Changelog)

Example
_ = GenerateWithConfig(core.Path(core.TempDir(), "go-build-compliance"), "agent", "agent", &ChangelogConfig{})
core.Println("GenerateWithConfig")
Output:
GenerateWithConfig

func GenerateWithConfigWithContext

func GenerateWithConfigWithContext(ctx context.Context, dir, fromRef, toRef string, cfg *ChangelogConfig) core.Result

GenerateWithConfigWithContext generates a filtered changelog while honouring caller cancellation.

result := release.GenerateWithConfigWithContext(ctx, ".", "v1.2.3", "HEAD", &cfg.Changelog)

Example
ctx, cancel := core.WithCancel(core.Background())
cancel()
_ = GenerateWithConfigWithContext(ctx, core.Path(core.TempDir(), "go-build-compliance"), "agent", "agent", &ChangelogConfig{})
core.Println("GenerateWithConfigWithContext")
Output:
GenerateWithConfigWithContext

func GenerateWithContext

func GenerateWithContext(ctx context.Context, dir, fromRef, toRef string) core.Result

GenerateWithContext generates a markdown changelog while honouring caller cancellation. If fromRef is empty, it uses the previous tag or initial commit. If toRef is empty, it uses HEAD.

result := release.GenerateWithContext(ctx, ".", "v1.2.3", "HEAD")

Example
ctx, cancel := core.WithCancel(core.Background())
cancel()
_ = GenerateWithContext(ctx, core.Path(core.TempDir(), "go-build-compliance"), "agent", "agent")
core.Println("GenerateWithContext")
Output:
GenerateWithContext

func IncrementMajor

func IncrementMajor(current string) string

IncrementMajor increments the major version of a semver string.

  • "v1.2.3" → "v2.0.0"
  • "1.2.3" → "v2.0.0"

next := release.IncrementMajor("v1.2.3") // → "v2.0.0"

Example
_ = IncrementMajor("agent")
core.Println("IncrementMajor")
Output:
IncrementMajor

func IncrementMinor

func IncrementMinor(current string) string

IncrementMinor increments the minor version of a semver string.

  • "v1.2.3" → "v1.3.0"
  • "1.2.3" → "v1.3.0"

next := release.IncrementMinor("v1.2.3") // → "v1.3.0"

Example
_ = IncrementMinor("agent")
core.Println("IncrementMinor")
Output:
IncrementMinor

func IncrementVersion

func IncrementVersion(current string) string

IncrementVersion increments the patch version of a semver string.

  • "v1.2.3" → "v1.2.4"
  • "1.2.3" → "v1.2.4"
  • "v1.2.3-alpha" → "v1.2.4" (strips prerelease)

next := release.IncrementVersion("v1.2.3") // → "v1.2.4"

Example
_ = IncrementVersion("agent")
core.Println("IncrementVersion")
Output:
IncrementVersion

func LoadConfig

func LoadConfig(dir string) core.Result

LoadConfig loads release configuration from the .core/release.yaml file in the given directory. If the config file does not exist, it returns DefaultConfig(). Returns an error if the file exists but cannot be parsed.

result := release.LoadConfig(".")

Example
_ = LoadConfig(core.Path(core.TempDir(), "go-build-compliance"))
core.Println("LoadConfig")
Output:
LoadConfig

func LoadConfigAtPath

func LoadConfigAtPath(filesystem coreio.Medium, configPath string) core.Result

LoadConfigAtPath loads release configuration from an explicit path in the provided medium. If the path does not point to a file, it returns DefaultConfig().

result := release.LoadConfigAtPath(io.Local, "/tmp/project/.core/release.yaml")

Example
_ = LoadConfigAtPath(coreio.NewMemoryMedium(), core.Path(core.TempDir(), "go-build-compliance"))
core.Println("LoadConfigAtPath")
Output:
LoadConfigAtPath

func LoadConfigWithMedium

func LoadConfigWithMedium(filesystem coreio.Medium, dir string) core.Result

LoadConfigWithMedium loads release configuration from the provided medium. This mirrors build config loading so callers that virtualise project files via io.Medium can still resolve release settings consistently.

result := release.LoadConfigWithMedium(io.NewMemoryMedium(), "project")

Example
_ = LoadConfigWithMedium(coreio.NewMemoryMedium(), core.Path(core.TempDir(), "go-build-compliance"))
core.Println("LoadConfigWithMedium")
Output:
LoadConfigWithMedium

func NormalizeVersion added in v0.2.0

func NormalizeVersion(version string) string

normalizeVersion ensures the version starts with 'v'. NormalizeVersion turns a git tag into a version string.

Exported because the same normalisation is needed wherever a tag becomes a version, and having it written twice is how one copy came to be wrong.

release.NormalizeVersion("go/v0.1.1") // "v0.1.1"
release.NormalizeVersion("1.2.3")     // "v1.2.3"

func ParseCommitType

func ParseCommitType(subject string) string

ParseCommitType extracts the type from a conventional commit subject. Returns empty string if not a conventional commit.

t := release.ParseCommitType("feat(build): add linuxkit support") // → "feat"

Example
_ = ParseCommitType("agent")
core.Println("ParseCommitType")
Output:
ParseCommitType

func ParseVersion

func ParseVersion(version string) core.Result

ParseVersion parses a semver string into its components.

result := release.ParseVersion("v1.2.3-alpha+001")

Example
_ = ParseVersion("v1.2.3")
core.Println("ParseVersion")
Output:
ParseVersion

func Publish

func Publish(ctx context.Context, cfg *Config, dryRun bool) core.Result

Publish publishes pre-built artifacts from dist/ to configured targets. Use this after `core build` to separate build and publish concerns.

result := release.Publish(ctx, cfg, false) // dryRun=true to preview

Example

--- v0.9.0 generated usage examples ---

ctx, cancel := core.WithCancel(core.Background())
cancel()
_ = Publish(ctx, &Config{}, true)
core.Println("Publish")
Output:
Publish

func Run

func Run(ctx context.Context, cfg *Config, dryRun bool) core.Result

Run executes the full release process: determine version, build artifacts, generate changelog, and publish to configured targets. For separated concerns, prefer `core build` then `core ci` (Publish).

result := release.Run(ctx, cfg, false) // dryRun=true to preview

Example
ctx, cancel := core.WithCancel(core.Background())
cancel()
_ = Run(ctx, &Config{}, true)
core.Println("Run")
Output:
Run

func RunSDK

func RunSDK(ctx context.Context, cfg *Config, dryRun bool) core.Result

RunSDK executes SDK-only release: diff check + generate.

result := release.RunSDK(ctx, cfg, false) // dryRun=true to preview

Example

--- v0.9.0 generated usage examples ---

ctx, cancel := core.WithCancel(core.Background())
cancel()
_ = RunSDK(ctx, &Config{}, true)
core.Println("RunSDK")
Output:
RunSDK

func ValidateVersion

func ValidateVersion(version string) bool

ValidateVersion checks if a string is a valid semver.

if release.ValidateVersion("v1.2.3") { ... }

Example
_ = ValidateVersion("v1.2.3")
core.Println("ValidateVersion")
Output:
ValidateVersion

func ValidateVersionIdentifier

func ValidateVersionIdentifier(version string) core.Result

ValidateVersionIdentifier reports whether a version override is safe to interpolate into release metadata and command arguments.

This is intentionally looser than semver validation so release automation can accept safe non-semver labels such as "dev" when needed.

Example
_ = ValidateVersionIdentifier("v1.2.3")
core.Println("ValidateVersionIdentifier")
Output:
ValidateVersionIdentifier

func WriteConfig

func WriteConfig(cfg *Config, dir string) core.Result

WriteConfig writes the config to the .core/release.yaml file.

result := release.WriteConfig(cfg, ".")

Example
_ = WriteConfig(&Config{}, core.Path(core.TempDir(), "go-build-compliance"))
core.Println("WriteConfig")
Output:
WriteConfig

Types

type BuildConfig

type BuildConfig struct {
	// Targets defines the build targets.
	Targets []TargetConfig `yaml:"targets"`
	// ArchiveFormat selects the archive compression format for build outputs.
	// Supported values are "gz", "xz", and "zip"; empty uses gzip.
	ArchiveFormat string `yaml:"archive_format,omitempty"`
}

BuildConfig holds build settings for releases.

cfg.Build.Targets = []release.TargetConfig{{OS: "linux", Arch: "amd64"}}

type ChangelogConfig

type ChangelogConfig struct {
	// Use selects the changelog strategy. Conventional commits are the default.
	Use string `yaml:"use,omitempty"`
	// Include specifies commit types to include in the changelog.
	Include []string `yaml:"include"`
	// Exclude specifies commit types to exclude from the changelog.
	Exclude []string `yaml:"exclude"`
}

ChangelogConfig holds changelog generation settings.

cfg.Changelog = release.ChangelogConfig{Include: []string{"feat", "fix"}, Exclude: []string{"chore"}}

type ChecksumConfig

type ChecksumConfig struct {
	// Algorithm selects the checksum algorithm. Currently sha256 is supported.
	Algorithm string `yaml:"algorithm,omitempty"`
	// File is the checksum file path relative to dist/ unless absolute.
	File string `yaml:"file,omitempty"`
}

ChecksumConfig controls release checksum generation.

type Config

type Config struct {
	// Version is the config file format version.
	Version int `yaml:"version"`
	// Project contains project metadata.
	Project ProjectConfig `yaml:"project"`
	// Build contains build settings for the release.
	Build BuildConfig `yaml:"build"`
	// Publishers defines where to publish the release.
	Publishers []PublisherConfig `yaml:"publishers"`
	// Changelog configures changelog generation.
	Changelog ChangelogConfig `yaml:"changelog"`
	// SDK configures SDK generation.
	SDK *SDKConfig `yaml:"sdk,omitempty"`
	// Checksum configures checksum generation for release artifacts.
	Checksum ChecksumConfig `yaml:"checksum,omitempty"`
	// contains filtered or unexported fields
}

Config holds the complete release configuration loaded from .core/release.yaml.

cfg, err := release.LoadConfig(".")

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns sensible defaults for release configuration.

cfg := release.DefaultConfig()

Example
_ = DefaultConfig()
core.Println("DefaultConfig")
Output:
DefaultConfig

func ScaffoldConfig

func ScaffoldConfig() *Config

ScaffoldConfig returns the config shape written by `core ci init`.

cfg := release.ScaffoldConfig()

Example
_ = ScaffoldConfig()
core.Println("ScaffoldConfig")
Output:
ScaffoldConfig

func (*Config) ExpandEnv

func (c *Config) ExpandEnv()

ExpandEnv expands environment variables across the release config.

cfg.ExpandEnv() // expands $REPO, $PACKAGE_NAME, $SDK_SPEC, etc.
Example
subject := &Config{}
subject.ExpandEnv()
core.Println("Config_ExpandEnv")
Output:
Config_ExpandEnv

func (*Config) GetProjectName

func (c *Config) GetProjectName() string

GetProjectName returns the project name from the config.

name := cfg.GetProjectName() // → "core-build"

Example
subject := &Config{}
_ = subject.GetProjectName()
core.Println("Config_GetProjectName")
Output:
Config_GetProjectName

func (*Config) GetRepository

func (c *Config) GetRepository() string

GetRepository returns the repository from the config.

repo := cfg.GetRepository() // → "host-uk/core-build"

Example
subject := &Config{}
_ = subject.GetRepository()
core.Println("Config_GetRepository")
Output:
Config_GetRepository

func (*Config) PublishersIter

func (c *Config) PublishersIter() iter.Seq[PublisherConfig]

PublishersIter returns an iterator for the publishers.

for p := range cfg.PublishersIter() { fmt.Println(p.Type) }

Example

--- v0.9.0 generated usage examples ---

subject := &Config{}
_ = subject.PublishersIter()
core.Println("Config_PublishersIter")
Output:
Config_PublishersIter

func (*Config) SetOutput

func (c *Config) SetOutput(medium coreio.Medium, dir string)

SetOutput configures the medium and root used for release artifacts.

cfg.SetOutput(io.NewMemoryMedium(), "releases")

Example
subject := &Config{}
subject.SetOutput(coreio.NewMemoryMedium(), core.Path(core.TempDir(), "go-build-compliance"))
core.Println("Config_SetOutput")
Output:
Config_SetOutput

func (*Config) SetOutputDir

func (c *Config) SetOutputDir(dir string)

SetOutputDir overrides the root directory or key prefix used for release artifacts.

cfg.SetOutputDir("releases")

Example
subject := &Config{}
subject.SetOutputDir(core.Path(core.TempDir(), "go-build-compliance"))
core.Println("Config_SetOutputDir")
Output:
Config_SetOutputDir

func (*Config) SetOutputMedium

func (c *Config) SetOutputMedium(medium coreio.Medium)

SetOutputMedium overrides the medium used for release artifacts.

cfg.SetOutputMedium(io.NewMemoryMedium())

Example
subject := &Config{}
subject.SetOutputMedium(coreio.NewMemoryMedium())
core.Println("Config_SetOutputMedium")
Output:
Config_SetOutputMedium

func (*Config) SetProjectDir

func (c *Config) SetProjectDir(dir string)

SetProjectDir sets the project directory on the config.

cfg.SetProjectDir("/home/user/my-project")

Example
subject := &Config{}
subject.SetProjectDir(core.Path(core.TempDir(), "go-build-compliance"))
core.Println("Config_SetProjectDir")
Output:
Config_SetProjectDir

func (*Config) SetVersion

func (c *Config) SetVersion(version string)

SetVersion sets the version override on the config.

cfg.SetVersion("v1.2.3")

Example
subject := &Config{}
subject.SetVersion("v1.2.3")
core.Println("Config_SetVersion")
Output:
Config_SetVersion

type ConventionalCommit

type ConventionalCommit struct {
	Type        string // feat, fix, etc.
	Scope       string // optional scope in parentheses
	Subject     string // full conventional commit subject without the hash
	Description string // commit description
	Hash        string // short commit hash
	Breaking    bool   // has breaking change indicator
}

ConventionalCommit represents a parsed conventional commit.

commit := release.ConventionalCommit{Type: "feat", Scope: "build", Description: "add linuxkit support"}

type OfficialConfig

type OfficialConfig struct {
	// Enabled determines whether to generate files for official repos.
	Enabled bool `yaml:"enabled"`
	// Output is the directory to write generated files.
	Output string `yaml:"output,omitempty"`
}

OfficialConfig holds configuration for generating files for official repo PRs.

pub.Official = &release.OfficialConfig{Enabled: true, Output: "dist/homebrew"}

type ParsedVersion

type ParsedVersion struct {
	Major      int
	Minor      int
	Patch      int
	Prerelease string
	Build      string
}

ParsedVersion holds the components of a semantic version string.

type ProjectConfig

type ProjectConfig struct {
	// Name is the project name.
	Name string `yaml:"name"`
	// Repository is the GitHub repository in owner/repo format.
	Repository string `yaml:"repository"`
}

ProjectConfig holds project metadata for releases.

cfg.Project = release.ProjectConfig{Name: "core-build", Repository: "host-uk/core-build"}

type PublisherConfig

type PublisherConfig struct {
	// Type is the publisher type (e.g., "github", "linuxkit", "docker").
	Type string `yaml:"type"`
	// Prerelease marks the release as a prerelease.
	Prerelease bool `yaml:"prerelease"`
	// Draft creates the release as a draft.
	Draft bool `yaml:"draft"`

	// LinuxKit-specific configuration
	// Config is the path to the LinuxKit YAML configuration file.
	Config string `yaml:"config,omitempty"`
	// Formats are the output formats to build (iso, raw, qcow2, vmdk).
	Formats []string `yaml:"formats,omitempty"`
	// Platforms are the target platforms (linux/amd64, linux/arm64).
	Platforms []string `yaml:"platforms,omitempty"`

	// Docker-specific configuration
	// Registry is the container registry (default: ghcr.io).
	Registry string `yaml:"registry,omitempty"`
	// Image is the image name in owner/repo format.
	Image string `yaml:"image,omitempty"`
	// Dockerfile is the path to the Dockerfile (default: Dockerfile).
	Dockerfile string `yaml:"dockerfile,omitempty"`
	// Tags are the image tags to apply.
	Tags []string `yaml:"tags,omitempty"`
	// BuildArgs are additional Docker build arguments.
	BuildArgs map[string]string `yaml:"build_args,omitempty"`

	// npm-specific configuration
	// Package is the npm package name (e.g., "@host-uk/core").
	Package string `yaml:"package,omitempty"`
	// Access is the npm access level: "public" or "restricted".
	Access string `yaml:"access,omitempty"`

	// Homebrew-specific configuration
	// Tap is the Homebrew tap repository (e.g., "host-uk/homebrew-tap").
	Tap string `yaml:"tap,omitempty"`
	// Formula is the formula name (defaults to project name).
	Formula string `yaml:"formula,omitempty"`

	// Scoop-specific configuration
	// Bucket is the Scoop bucket repository (e.g., "host-uk/scoop-bucket").
	Bucket string `yaml:"bucket,omitempty"`

	// AUR-specific configuration
	// Maintainer is the AUR package maintainer (e.g., "Name <email>").
	Maintainer string `yaml:"maintainer,omitempty"`

	// Chocolatey-specific configuration
	// Push determines whether to push to Chocolatey (false = generate only).
	Push bool `yaml:"push,omitempty"`

	// Official repo configuration (for Homebrew, Scoop)
	// When enabled, generates files for PR to official repos.
	Official *OfficialConfig `yaml:"official,omitempty"`
}

PublisherConfig holds configuration for a publisher.

cfg.Publishers = []release.PublisherConfig{{Type: "github", Draft: false}}

type Release

type Release struct {
	// Version is the semantic version string (e.g., "v1.2.3").
	Version string
	// Artifacts are the built release artifacts (archives with checksums).
	Artifacts []build.Artifact
	// Changelog is the generated markdown changelog.
	Changelog string
	// ProjectDir is the root directory of the project.
	ProjectDir string
	// FS is the project filesystem used for local project file access.
	FS storage.Medium
	// ArtifactFS is the medium backing the release artifact paths.
	ArtifactFS storage.Medium
}

Release represents a release with its version, artifacts, and changelog.

result := release.Publish(ctx, cfg, false)

type SDKConfig

type SDKConfig = sdk.Config

SDKConfig holds SDK generation configuration.

cfg.SDK = &release.SDKConfig{Spec: "docs/openapi.yaml", Languages: []string{"typescript", "go"}}

type SDKDiffConfig

type SDKDiffConfig = sdk.DiffConfig

SDKDiffConfig holds diff configuration.

cfg.SDK.Diff = release.SDKDiffConfig{Enabled: true, FailOnBreaking: true}

type SDKPackageConfig

type SDKPackageConfig = sdk.PackageConfig

SDKPackageConfig holds package naming configuration.

cfg.SDK.Package = release.SDKPackageConfig{Name: "@host-uk/api-client", Version: "1.0.0"}

type SDKPublishConfig

type SDKPublishConfig = sdk.PublishConfig

SDKPublishConfig holds monorepo publish configuration.

cfg.SDK.Publish = release.SDKPublishConfig{Repo: "host-uk/ts", Path: "packages/api-client"}

type SDKRelease

type SDKRelease struct {
	// Version is the SDK version.
	Version string
	// Languages that were generated.
	Languages []string
	// Output directory.
	Output string
}

SDKRelease holds the result of an SDK release.

result := release.RunSDK(ctx, cfg, false)

type TargetConfig

type TargetConfig struct {
	// OS is the target operating system (e.g., "linux", "darwin", "windows").
	OS string "yaml:\"os\""
	// Arch is the target architecture (e.g., "amd64", "arm64").
	Arch string `yaml:"arch"`
}

TargetConfig defines a build target.

t := release.TargetConfig{OS: "linux", Arch: "arm64"}

Example
subject := TargetConfig{OS: "linux", Arch: "amd64"}
core.Println(subject.Arch)
Output:
amd64

Directories

Path Synopsis
Package publishers provides release publishing implementations.
Package publishers provides release publishing implementations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL