release

package
v0.13.6 Latest Latest
Warning

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

Go to latest
Published: May 9, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package release provides the helper logic the release workflow invokes via cmd/mdsmith-release/. The package was originally a set of bash scripts under scripts/, but JSON/TOML editing in perl regex and indirect testing through `bash <script>` made them brittle. The Go port runs under one toolchain, has direct tests, and reports actionable errors without shelling out.

Production code constructs a Toolkit via New(); tests can substitute a fake FS via NewWithFS to exercise IO error branches the real OS cannot reliably trigger.

Index

Constants

View Source
const DevSentinel = "0.0.0-dev"

DevSentinel is the version every tracked manifest carries between releases. Stamp rewrites it to the cleaned tag during release; Check fails the version-guard CI job when a hand-edit pushes anything else to main.

Variables

View Source
var PlatformPackages = []string{
	"@mdsmith/linux-x64",
	"@mdsmith/linux-arm64",
	"@mdsmith/darwin-x64",
	"@mdsmith/darwin-arm64",
	"@mdsmith/win32-x64",
}

PlatformPackages enumerates the @mdsmith/<platform> optional- dependency keys the npm root must list. Stays in lock-step with the build matrix in .github/workflows/release.yml.

Functions

func BuildNpmPlatforms

func BuildNpmPlatforms(rootDir, artifactsDir, outDir string) error

BuildNpmPlatforms delegates to a default-OS Toolkit (see Stamp).

func BuildWheels

func BuildWheels(rootDir, artifactsDir, outDir string) error

BuildWheels delegates to a default-OS Toolkit (see Stamp).

func Check

func Check(root string) error

Check delegates to a default-OS Toolkit (see Stamp).

func Stamp

func Stamp(root, version string) error

Stamp delegates to a default-OS Toolkit so callers without an explicit Toolkit (for example, the cmd binary) can stay terse. Tests that need fault injection construct a Toolkit via NewWithFS instead.

func ValidateSemver

func ValidateSemver(v string) error

ValidateSemver rejects empty strings, leading-v tags ("v1.2.3"), and any version that isn't conforming SemVer.

Types

type FS

type FS interface {
	// Stat returns the FileInfo for the named file, mirroring
	// os.Stat.
	Stat(name string) (os.FileInfo, error)
	// ReadFile reads the named file, mirroring os.ReadFile.
	ReadFile(name string) ([]byte, error)
	// WriteFile writes data to the named file, mirroring
	// os.WriteFile.
	WriteFile(name string, data []byte, perm fs.FileMode) error
	// ReadDir reads the named directory, mirroring os.ReadDir.
	ReadDir(name string) ([]os.DirEntry, error)
	// MkdirAll creates name and any parents, mirroring
	// os.MkdirAll.
	MkdirAll(path string, perm fs.FileMode) error
	// MkdirTemp creates a new temporary directory, mirroring
	// os.MkdirTemp.
	MkdirTemp(dir, pattern string) (string, error)
	// Rename renames (moves) oldpath to newpath, mirroring
	// os.Rename.
	Rename(oldpath, newpath string) error
	// RemoveAll removes path and any children, mirroring
	// os.RemoveAll.
	RemoveAll(path string) error
}

FS is the small filesystem surface the release toolkit uses. Production paths use osFS (delegating to the real syscalls); tests inject a fault-injecting fake to exercise IO error branches that real filesystems don't reliably trigger (mid-pipeline mkdir failure, rename target on a non-directory, disk-full WriteFile, etc.).

We intentionally keep this independent of stdlib's read-only `io/fs.FS`. The release toolkit needs Mkdir/Write/Rename alongside Read/Stat, and stdlib's interface only covers reads.

type Manifest

type Manifest struct {
	Path         string
	Kind         ManifestKind
	OptionalDeps bool
}

Manifest is one tracked file. OptionalDeps marks the npm root — only that file carries @mdsmith/* pins.

func TrackedManifests

func TrackedManifests(root string) []Manifest

TrackedManifests is a thin wrapper over the default Toolkit so callers without an explicit Toolkit can still introspect the tracked set.

type ManifestKind

type ManifestKind int

ManifestKind tells the rewrite/check helpers which syntax to expect: JSON for npm package manifests, TOML for pyproject.

const (
	// ManifestJSON marks JSON manifests (npm package.json files).
	ManifestJSON ManifestKind = iota
	// ManifestTOML marks TOML manifests (python pyproject.toml).
	ManifestTOML
)

type Runner

type Runner interface {
	// RunCommand executes name+args in dir, with stdout/stderr
	// inherited from the calling process. Mirrors exec.Cmd.Run
	// semantics: a non-zero exit returns *exec.ExitError; other
	// failures (binary not found, IO) return their underlying
	// error.
	RunCommand(dir, name string, args ...string) error
}

Runner runs an external command. The release toolkit shells out to `python -m build` and `python -m wheel tags` for the PyPI publish path; tests inject a fake Runner to cover those branches without putting python on PATH.

type Toolkit

type Toolkit struct {
	// contains filtered or unexported fields
}

Toolkit owns a configured FS and Runner and exposes the release helpers (Stamp, Check, BuildNpmPlatforms, BuildWheels) as methods. `New()` returns a Toolkit backed by the real OS for both; tests can use `NewWithFS(fakeFS)` or `NewWithDeps` to drive error paths that the OS does not expose.

func New

func New() *Toolkit

New returns a Toolkit backed by the real OS filesystem and command runner.

func NewWithDeps

func NewWithDeps(fsys FS, runner Runner) *Toolkit

NewWithDeps returns a Toolkit with custom FS and Runner. Used by tests that exercise both IO and command-execution faults.

func NewWithFS

func NewWithFS(fsys FS) *Toolkit

NewWithFS returns a Toolkit with a custom FS and the OS-backed Runner. Convenience helper for tests that only need IO faults.

func (*Toolkit) BuildNpmPlatforms

func (t *Toolkit) BuildNpmPlatforms(rootDir, artifactsDir, outDir string) error

BuildNpmPlatforms emits one ready-to-publish npm sub-package directory per supported platform under outDir, copying the matching release artifact from artifactsDir. Stamp must run first because the version is taken from rootDir/npm/mdsmith/package.json.

func (*Toolkit) BuildWheels

func (t *Toolkit) BuildWheels(rootDir, artifactsDir, outDir string) error

BuildWheels builds one platform-tagged wheel per supported host from prebuilt binaries in artifactsDir, writing the wheels to outDir. The python source tree at rootDir/python is staged per build with the matching binary embedded under mdsmith/_bin/, then `python -m build` produces a py3-none-any wheel which `python -m wheel tags` retags to the correct platform tag (in both the filename and the dist-info/WHEEL metadata).

Requires `python -m build`, `python -m wheel`, and the hatchling build backend on PATH. Stamp must run first so pyproject.toml carries the published version.

func (*Toolkit) Check

func (t *Toolkit) Check(root string) error

Check accumulates every problem with the tracked manifests (missing file, missing field, drifted version, missing or drifted @mdsmith/* pin) into one multi-line error. The version-guard CI job uses Check; reporting all problems at once is more useful than failing on the first.

func (*Toolkit) Stamp

func (t *Toolkit) Stamp(root, version string) error

Stamp rewrites every tracked manifest under root from the dev sentinel to version. Idempotent: running with the same version twice produces no further change. A required manifest that's missing a version field — or, for the npm root, missing the @mdsmith/* optionalDependencies block — is a hard error.

func (*Toolkit) TrackedManifests

func (t *Toolkit) TrackedManifests(root string) []Manifest

TrackedManifests returns the set of manifests Stamp rewrites and Check verifies via the Toolkit's FS. The npm/platforms/ directory is not in source control — BuildNpmPlatforms emits the platform sub-packages under its own outDir argument (npm/dist in the release workflow). Anything that has already materialised npm/platforms/<plat>/package.json (a previous local Stamp+BuildNpmPlatforms invocation, a custom staging step) is stamped here too; if the directory is absent the helper just returns the four checked-in manifests.

Jump to

Keyboard shortcuts

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