@omnidist/omnidist
v0.1.30
Published
Meta package for omnidist
Readme
omnidist
Package and publish a Go CLI as npm and uv installable tools with prebuilt cross-platform binaries.
omnidist gives Go CLI maintainers one repeatable release flow:
build -> stage -> verify -> publishThe generated npm packages use platform-specific optional dependencies, so users
can run your CLI with npx without install-time downloader scripts. The uv
distribution stages wheel artifacts so users can run the same CLI from Python
tooling with uvx.
Requirements
- Go 1.25+
- Node.js and npm for npm staging, verification, and publishing
uvfor uv staging, verification, and publishinggitwhenversion.source: git-tagNPM_PUBLISH_TOKENfor npm token publishing, unless using--dry-runor trusted publishingUV_PUBLISH_TOKENoromnidist uv publish --tokenfor uv publishing, unless using--dry-run
Install
Run without installing:
npx -y @omnidist/omnidist@latest --help
uvx omnidist --helpInstall with npm:
npm i -g @omnidist/omnidist
omnidist --helpInstall with Go:
go install github.com/metalagman/omnidist/cmd/omnidist@latest
omnidist --helpRun from a checkout:
go run ./cmd/omnidist --helpQuick Start
Initialize an existing Go CLI repository:
omnidist initThis creates .omnidist/omnidist.yaml and initial workspace directories under
.omnidist/default/. The generated config uses profiles.default.
Edit the generated config before building:
$EDITOR .omnidist/omnidist.yamlAt minimum, check these fields:
tool.name: the binary name users will run.tool.main: the Go main package, for example./cmd/mytool.distributions.npm.package: the npm package, for example@my-org/mytool.distributions.uv.package: the uv/PyPI package, for examplemytool.version.source: usuallygit-tag,file,env, orfixed.
Then run the local release pipeline:
omnidist build
omnidist stage
omnidist verifyPublish only after verification passes:
omnidist publishGenerate a GitHub Actions release workflow:
omnidist ciThe generated workflow is written to .github/workflows/omnidist-release.yml.
It runs on v* tag pushes, builds once, stages and verifies artifacts, publishes
npm and uv distributions, then uploads the built binaries and checksums.txt to
the GitHub release.
Configuration
omnidist init writes profiles-mode config by default:
profiles:
default:
tool:
name: mytool
main: ./cmd/mytool
version:
source: git-tag # git-tag | file | env | fixed
file: VERSION # used only when source is file
fixed: 1.2.3 # required only when source is fixed
targets:
- os: darwin
arch: amd64
- os: darwin
arch: arm64
- os: linux
arch: amd64
- os: linux
arch: arm64
- os: windows
arch: amd64
build:
ldflags: -s -w
tags: []
cgo: false
distributions:
npm:
package: "@my-org/mytool"
registry: https://registry.npmjs.org
access: public # public | restricted
publish-auth: token # token | trusted
include-readme: true
uv:
package: mytool
index-url: https://upload.pypi.org/legacy/
linux-tag: manylinux2014 # manylinux2014 | musllinux_1_2
include-readme: trueSelect a profile with --profile <name> or OMNIDIST_PROFILE. If profiles
is present and no profile is selected, default is used. Profiles write
artifacts to .omnidist/<profile>/.
Legacy top-level config is still accepted when loading existing config files,
but do not mix top-level runtime fields with a profiles map in the same file.
Targets use Go values: os is GOOS, and arch is GOARCH. Distribution
workflows map them as needed, for example windows/amd64 becomes npm
win32/x64.
Versioning
omnidist build resolves the release version and writes it to
.omnidist/<profile>/dist/VERSION. Stage and publish commands use that build
version so npm and uv artifacts stay in sync.
Supported version sources:
git-tag:HEADmust be on an exact SemVer tag, eithervX.Y.ZorX.Y.Z.file: read the version fromversion.file, defaulting toVERSION.env: readOMNIDIST_VERSION.fixed: readversion.fixed.
For local prerelease staging, use:
omnidist stage --dev--dev generates prerelease artifact versions from git metadata. For npm
publishing, -dev prerelease versions are automatically published with
--tag dev when no tag is supplied.
Environment and Build Variables
omnidist loads .env at startup when the file exists.
Environment variables:
OMNIDIST_VERSION: used only whenversion.source: env.VERSIONis not used.OMNIDIST_CONFIG: config file path, equivalent to--config.OMNIDIST_PROFILE: config profile name, equivalent to--profile.OMNIDIST_OMNIDIST_ROOT: project root directory, equivalent to--omnidist-root.NPM_PUBLISH_TOKEN: npm token fordistributions.npm.publish-auth: token.UV_PUBLISH_TOKEN: uv publish token when--tokenis not provided.
Build ldflags template variables:
OMNIDIST_VERSION: expanded inbuild.ldflagsduringomnidist build.OMNIDIST_GIT_COMMIT: populated byomnidist buildwhen git metadata is available.OMNIDIST_BUILD_DATE: populated byomnidist buildas UTC RFC3339.
Example:
build:
ldflags: >-
-s -w
-X github.com/your-org/mytool/internal/version.version=${OMNIDIST_VERSION}
-X github.com/your-org/mytool/internal/version.gitCommit=${OMNIDIST_GIT_COMMIT}
-X github.com/your-org/mytool/internal/version.buildDate=${OMNIDIST_BUILD_DATE}build.ldflags uses os.ExpandEnv, so both $VAR and ${VAR} are supported.
Unset variables expand to empty strings.
npm Distribution
The npm distribution has two package types:
- Meta package:
distributions.npm.package, with a small Node shim. - Platform packages: one package per target, selected by npm
osandcpuconstraints.
The meta package lists platform packages as optionalDependencies at the same
version. Published packages do not use postinstall scripts or network
downloaders.
Common npm commands:
omnidist npm stage
omnidist npm verify
omnidist npm publish --tag latestToken publishing uses NPM_PUBLISH_TOKEN. omnidist writes a workspace
.omnidist/.npmrc from distributions.npm.registry with npm's token
substitution syntax.
Trusted publishing uses npm OIDC instead of NPM_PUBLISH_TOKEN:
distributions:
npm:
publish-auth: trusted
repository-url: git+https://github.com/your-org/your-repo.gitIn trusted mode:
repository-urlis required and is written to staged package metadata.omnidist npm publishskips token-only auth preflight.- GitHub Actions must grant
id-token: write. - Each npm package, including platform packages, needs a trusted publisher configured on npm.
Print trusted publisher setup commands:
omnidist npm trustApply them directly:
omnidist npm trust --applyUseful trust options:
--workflow-file <name>for a workflow filename other thanomnidist-release.yml.--repo <owner/repo>to overridedistributions.npm.repository-url.--environment <name>for npm trusted publishers restricted to a GitHub Actions environment.--allow-stage-publishto allow npm stage publish.
uv Distribution
The uv distribution stages wheel artifacts under .omnidist/<profile>/uv/dist.
During staging, versions are converted to PEP 440 where needed.
Common uv commands:
omnidist uv stage
omnidist uv verify
omnidist uv publishPublish to a different PyPI-compatible index:
omnidist uv publish --publish-url https://test.pypi.org/legacy/ --token <token>omnidist uv verify rejects versions with local metadata (+...) for
PyPI/TestPyPI publishing, because those indexes reject local versions.
README and License Staging
README source precedence during staging:
distributions.<name>.readme-path -> readme-path -> README.mdIf a configured readme-path is set and cannot be read, staging fails. Set
include-readme: false for a distribution to skip README inclusion.
For npm packages, license can be set explicitly under distributions.npm.
When it is omitted, omnidist includes the project license file when present and
writes package metadata that points to that file.
CI Releases
Generate a release workflow:
omnidist ciOverwrite an existing generated workflow:
omnidist ci --forceThe workflow installs omnidist with npm. When generating this repository's own
release workflow, it uses go run ./cmd/omnidist instead. The workflow also
sets FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true for JavaScript-based GitHub
Actions.
Before the first tag release, configure the required registry credentials:
- npm token mode:
NPM_PUBLISH_TOKENGitHub secret. - npm trusted mode: npm trusted publishers for every staged npm package.
- uv publishing:
UV_PUBLISH_TOKENGitHub secret.
Release by pushing a SemVer tag:
git tag v1.2.3
git push origin v1.2.3Command Reference
Top-level commands:
omnidist init
omnidist quickstart
omnidist build
omnidist stage [--dev] [--only npm|uv|npm,uv]
omnidist verify [--only npm|uv|npm,uv]
omnidist publish [--dry-run] [--only npm|uv|npm,uv]
omnidist ci [--force] [--dry-run]
omnidist versionGlobal flags:
--config <path>
--profile <name>
--omnidist-root <path>npm commands:
omnidist npm stage [--dev]
omnidist npm verify
omnidist npm publish [--dry-run] [--tag <tag>] [--registry <url>] [--otp <code>]
omnidist npm trust [--apply] [--workflow-file <name>] [--repo <owner/repo>] [--environment <name>] [--allow-stage-publish]uv commands:
omnidist uv stage [--dev]
omnidist uv verify
omnidist uv publish [--dry-run] [--publish-url <url>] [--token <token>]Top-level stage, verify, and publish run distributions in deterministic
order: npm first, then uv. Use --only to limit the command to one or more
distributions.
Troubleshooting
omnidist build says no version could be resolved:
Check version.source. For git-tag, HEAD must be exactly on a SemVer tag.
For env, set OMNIDIST_VERSION. For file, create the configured version
file.
omnidist stage says the build version file is missing:
Run omnidist build first. Stage commands use the build version persisted under
.omnidist/<profile>/dist/VERSION.
npm install cannot find a platform package:
Run omnidist npm verify before publishing. It checks package versions,
platform os and cpu fields, required binaries, forbidden postinstall
scripts, repository metadata, and optional dependency parity.
Trusted npm publish fails:
Verify that distributions.npm.repository-url matches the GitHub repository,
the workflow grants id-token: write, and every npm package has a trusted
publisher configured.
uv publish rejects the version:
Restage with a publishable version. PyPI and TestPyPI reject local version
metadata containing +.
Contributing
For repository layout, development workflow, package model details, and migration notes, see CONTRIBUTING.md.
