@omnidist/omnidist 0.1.16 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +431 -0
- package/package.json +8 -7
package/README.md
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
# omnidist
|
|
2
|
+
|
|
3
|
+
[](https://goreportcard.com/report/github.com/metalagman/omnidist)
|
|
4
|
+
[](https://github.com/metalagman/omnidist/actions/workflows/lint.yml)
|
|
5
|
+
[](https://github.com/metalagman/omnidist/actions/workflows/test.yml)
|
|
6
|
+
[](https://github.com/metalagman/omnidist/blob/master/go.mod)
|
|
7
|
+
[](https://github.com/metalagman/omnidist/releases)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
Run your Go CLI everywhere with `npx` and `uvx`, without requiring Go on end-user machines.
|
|
11
|
+
|
|
12
|
+
`omnidist` turns one Go project into cross-platform npm and uv distributions with prebuilt binaries, then stages, verifies, and publishes them in a deterministic release flow.
|
|
13
|
+
|
|
14
|
+
Release flow: `build -> stage -> verify -> publish` so users can run your tool from JavaScript and Python ecosystems out of the box.
|
|
15
|
+
|
|
16
|
+
## Why
|
|
17
|
+
|
|
18
|
+
- One release system for JavaScript and Python package ecosystems
|
|
19
|
+
- Run Go binaries via `npx`/`uvx` on machines without a Go runtime
|
|
20
|
+
- Install once with npm: `npm i -g <package>`
|
|
21
|
+
- Publish wheel artifacts to PyPI-compatible indexes with uv
|
|
22
|
+
- No install-time download scripts for npm
|
|
23
|
+
- Reproducible, CI-friendly flow from a single config file
|
|
24
|
+
|
|
25
|
+
## How It Works
|
|
26
|
+
|
|
27
|
+
`omnidist` supports two additive backends:
|
|
28
|
+
|
|
29
|
+
- `npm`:
|
|
30
|
+
- meta package (for example `@scope/tool`) with shim and `optionalDependencies`
|
|
31
|
+
- platform packages (for example `@scope/tool-linux-x64`) with prebuilt binaries
|
|
32
|
+
- `uv`:
|
|
33
|
+
- per-target platform wheel artifacts in `.omnidist/uv/dist/`
|
|
34
|
+
- one wheel per configured target with embedded binary in `<pkg>/bin/`
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- Go 1.25+
|
|
39
|
+
- Node.js + npm (for npm distribution commands)
|
|
40
|
+
- `uv` (for uv distribution commands)
|
|
41
|
+
- `git` (when `version.source: git-tag`)
|
|
42
|
+
- `NPM_PUBLISH_TOKEN` for npm publish (unless `--dry-run`)
|
|
43
|
+
- `UV_PUBLISH_TOKEN` (or `--token`) for uv publish (unless `--dry-run`)
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
Run without installation first:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx @omnidist/omnidist --help
|
|
51
|
+
uvx omnidist --help
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Install globally with npm:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm i -g @omnidist/omnidist
|
|
58
|
+
omnidist --help
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Install with Go toolchain:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
go install github.com/metalagman/omnidist/cmd/omnidist@latest
|
|
65
|
+
omnidist --help
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Build locally from source:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
go build -o ./bin/omnidist ./cmd/omnidist
|
|
72
|
+
./bin/omnidist --help
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Or run directly:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
go run ./cmd/omnidist --help
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Quick Start
|
|
82
|
+
|
|
83
|
+
1. Print repo-tailored onboarding/release commands:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
omnidist quickstart
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
2. Initialize config and distribution folder structure:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
omnidist init
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This creates:
|
|
96
|
+
- `.omnidist/omnidist.yaml`
|
|
97
|
+
- `.omnidist/` workspace directories
|
|
98
|
+
- `.omnidist/.gitignore` for generated artifacts
|
|
99
|
+
|
|
100
|
+
3. Build binaries for configured targets:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
omnidist build
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
This also writes the resolved build version to `.omnidist/dist/VERSION`.
|
|
107
|
+
|
|
108
|
+
4. Stage and verify artifacts:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
omnidist stage
|
|
112
|
+
omnidist verify
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`omnidist uv stage` converts the resolved version to PEP 440 and writes
|
|
116
|
+
`.omnidist/uv/pyproject.toml` with that version.
|
|
117
|
+
It also recreates `.omnidist/uv/dist` to prevent stale wheel artifacts from previous runs.
|
|
118
|
+
|
|
119
|
+
5. Publish when verification passes:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
omnidist publish
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
6. Generate tag-triggered release workflow:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
omnidist ci
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Common Commands
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Build binaries for configured targets and persist build version
|
|
135
|
+
omnidist build
|
|
136
|
+
|
|
137
|
+
# Print a quickstart command sequence for this repo
|
|
138
|
+
omnidist quickstart
|
|
139
|
+
|
|
140
|
+
# Show runtime version/build metadata
|
|
141
|
+
omnidist version
|
|
142
|
+
|
|
143
|
+
# Stage and verify both distributions (npm -> uv)
|
|
144
|
+
omnidist stage
|
|
145
|
+
omnidist verify
|
|
146
|
+
|
|
147
|
+
# Stage dev/pre-release artifacts
|
|
148
|
+
omnidist stage --dev
|
|
149
|
+
|
|
150
|
+
# Publish both distributions (fail-fast, npm -> uv)
|
|
151
|
+
omnidist publish
|
|
152
|
+
|
|
153
|
+
# Generate GitHub Actions workflow for tagged releases
|
|
154
|
+
omnidist ci
|
|
155
|
+
|
|
156
|
+
# Limit orchestration to one distribution
|
|
157
|
+
omnidist stage --only npm
|
|
158
|
+
omnidist verify --only uv
|
|
159
|
+
|
|
160
|
+
# Distribution-specific publishing options
|
|
161
|
+
omnidist npm publish --tag next --otp <6-digit-code>
|
|
162
|
+
omnidist uv publish --publish-url https://test.pypi.org/legacy/ --token <pypi-token>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Environment Variables and .env
|
|
166
|
+
|
|
167
|
+
`omnidist` loads `.env` automatically at startup (via `godotenv`) if present.
|
|
168
|
+
|
|
169
|
+
Supported variables:
|
|
170
|
+
|
|
171
|
+
- `OMNIDIST_VERSION`: used when `version.source: env`; also expanded in `build.ldflags` templates (for example `${OMNIDIST_VERSION}`).
|
|
172
|
+
`VERSION` is not used.
|
|
173
|
+
- `OMNIDIST_GIT_COMMIT`: optional ldflags template variable for build metadata; populated automatically by `omnidist build` when git metadata is available.
|
|
174
|
+
- `OMNIDIST_BUILD_DATE`: optional ldflags template variable for build metadata; populated automatically by `omnidist build` as UTC RFC3339.
|
|
175
|
+
- `NPM_PUBLISH_TOKEN`: required for npm publish commands when not using `--dry-run`
|
|
176
|
+
- `UV_PUBLISH_TOKEN`: used by uv publish when `--token` is not provided
|
|
177
|
+
|
|
178
|
+
Example `.env`:
|
|
179
|
+
|
|
180
|
+
```dotenv
|
|
181
|
+
OMNIDIST_VERSION=1.2.3
|
|
182
|
+
NPM_PUBLISH_TOKEN=npm_xxx
|
|
183
|
+
UV_PUBLISH_TOKEN=pypi-xxx
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Configuration
|
|
187
|
+
|
|
188
|
+
`.omnidist/omnidist.yaml`:
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
tool:
|
|
192
|
+
name: omnidist
|
|
193
|
+
main: ./cmd/omnidist
|
|
194
|
+
|
|
195
|
+
version:
|
|
196
|
+
source: git-tag # git-tag | file | env
|
|
197
|
+
|
|
198
|
+
targets:
|
|
199
|
+
- os: darwin
|
|
200
|
+
arch: amd64
|
|
201
|
+
- os: darwin
|
|
202
|
+
arch: arm64
|
|
203
|
+
- os: linux
|
|
204
|
+
arch: amd64
|
|
205
|
+
- os: linux
|
|
206
|
+
arch: arm64
|
|
207
|
+
- os: windows
|
|
208
|
+
arch: amd64
|
|
209
|
+
|
|
210
|
+
build:
|
|
211
|
+
ldflags: -s -w
|
|
212
|
+
tags: []
|
|
213
|
+
cgo: false
|
|
214
|
+
|
|
215
|
+
distributions:
|
|
216
|
+
npm:
|
|
217
|
+
package: "@omnidist/omnidist"
|
|
218
|
+
registry: https://registry.npmjs.org
|
|
219
|
+
access: public # public | restricted
|
|
220
|
+
include-readme: true # include project README.md in staged packages when present
|
|
221
|
+
|
|
222
|
+
uv:
|
|
223
|
+
package: omnidist
|
|
224
|
+
index-url: https://upload.pypi.org/legacy/
|
|
225
|
+
linux-tag: manylinux2014 # manylinux2014 | musllinux_1_2
|
|
226
|
+
include-readme: true # include project README.md in staged wheels when present
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
`targets` use Go values (`GOOS`/`GOARCH`). Distribution workflows map them as needed (for example `windows/amd64` -> npm `win32/x64`).
|
|
230
|
+
|
|
231
|
+
For appkit version injection, configure `build.ldflags` in your project config:
|
|
232
|
+
|
|
233
|
+
```yaml
|
|
234
|
+
build:
|
|
235
|
+
ldflags: -s -w -X github.com/metalagman/appkit/version.version=${OMNIDIST_VERSION} -X github.com/metalagman/appkit/version.gitCommit=${OMNIDIST_GIT_COMMIT} -X github.com/metalagman/appkit/version.buildDate=${OMNIDIST_BUILD_DATE}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
With `version.source: git-tag`, release workflows require `HEAD` to be on an exact SemVer tag (`vX.Y.Z` or `X.Y.Z`).
|
|
239
|
+
|
|
240
|
+
## Command Reference
|
|
241
|
+
|
|
242
|
+
Top-level:
|
|
243
|
+
|
|
244
|
+
- `omnidist init`
|
|
245
|
+
- `omnidist build`
|
|
246
|
+
- `omnidist quickstart`
|
|
247
|
+
- `omnidist version`
|
|
248
|
+
- `omnidist ci [--force]`
|
|
249
|
+
- `omnidist stage [--dev] [--only npm|uv|npm,uv]`
|
|
250
|
+
- `omnidist verify [--only npm|uv|npm,uv]`
|
|
251
|
+
- `omnidist publish [--dry-run] [--only npm|uv|npm,uv]`
|
|
252
|
+
- `omnidist npm`
|
|
253
|
+
- `omnidist uv`
|
|
254
|
+
|
|
255
|
+
NPM subcommands:
|
|
256
|
+
|
|
257
|
+
- `omnidist npm stage [--dev]`
|
|
258
|
+
- `omnidist npm verify`
|
|
259
|
+
- `omnidist npm publish [--dry-run] [--tag <tag>] [--registry <url>] [--otp <code>]`
|
|
260
|
+
|
|
261
|
+
UV subcommands:
|
|
262
|
+
|
|
263
|
+
- `omnidist uv stage [--dev]`
|
|
264
|
+
- `omnidist uv verify`
|
|
265
|
+
- `omnidist uv publish [--dry-run] [--publish-url <url>] [--token <pypi-token>]`
|
|
266
|
+
|
|
267
|
+
## Usage Patterns
|
|
268
|
+
|
|
269
|
+
### Local development loop
|
|
270
|
+
|
|
271
|
+
Use this when iterating on the CLI binary and validating artifact generation locally:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
omnidist build
|
|
275
|
+
omnidist stage
|
|
276
|
+
omnidist verify
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Dev pre-release artifacts
|
|
280
|
+
|
|
281
|
+
Generate prerelease versions from git describe data:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
omnidist stage --dev
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Unified multi-distribution orchestration
|
|
288
|
+
|
|
289
|
+
Top-level `stage`, `verify`, and `publish` run distributions in deterministic order:
|
|
290
|
+
`npm` first, then `uv`, and stop on first failure.
|
|
291
|
+
|
|
292
|
+
Select a subset with `--only`:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
omnidist stage --only uv
|
|
296
|
+
omnidist verify --only npm
|
|
297
|
+
omnidist publish --dry-run --only npm,uv
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### CI bootstrap for tag releases
|
|
301
|
+
|
|
302
|
+
Generate `.github/workflows/omnidist-release.yml`:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
omnidist ci
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The generated workflow triggers on `v*` tag pushes and runs:
|
|
309
|
+
`build -> stage -> verify -> publish`.
|
|
310
|
+
|
|
311
|
+
If workflow already exists:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
omnidist ci --force
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### npm publishing flow with custom options
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
omnidist npm publish --dry-run --tag next --registry https://registry.npmjs.org
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Before npm commands run, omnidist writes `.omnidist/.npmrc` from `distributions.npm.registry` using:
|
|
324
|
+
`//<registry>/:_authToken=${NPM_PUBLISH_TOKEN}`.
|
|
325
|
+
If staged package version contains a `-dev` prerelease and `--tag` is not provided, omnidist auto-publishes with `--tag dev`.
|
|
326
|
+
|
|
327
|
+
If your npm account requires 2FA for publish operations:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
omnidist npm publish --otp <6-digit-code>
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### uv publishing flow with custom index/auth
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
omnidist uv publish --publish-url https://upload.pypi.org/legacy/ --token <pypi-token>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
`omnidist uv publish` uses token authentication.
|
|
340
|
+
Provide token via `--token` or `UV_PUBLISH_TOKEN` (required for non-dry-run).
|
|
341
|
+
`omnidist uv verify` and `omnidist uv publish` use the staged version from
|
|
342
|
+
`.omnidist/uv/pyproject.toml` when present.
|
|
343
|
+
For PyPI/TestPyPI, `omnidist uv verify` fails if the staged version contains local metadata (`+...`), since those indexes reject local versions.
|
|
344
|
+
|
|
345
|
+
TestPyPI dry-run style validation:
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
omnidist uv publish --dry-run --publish-url https://test.pypi.org/legacy/
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Usage Examples
|
|
352
|
+
|
|
353
|
+
### npm release path
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
git tag v1.2.0
|
|
357
|
+
omnidist build
|
|
358
|
+
omnidist npm stage
|
|
359
|
+
omnidist npm verify
|
|
360
|
+
omnidist npm publish
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### uv release path
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
git tag v1.2.0
|
|
367
|
+
omnidist build
|
|
368
|
+
omnidist uv stage
|
|
369
|
+
omnidist uv verify
|
|
370
|
+
omnidist uv publish --publish-url https://upload.pypi.org/legacy/
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### uv dry-run publish
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
omnidist uv publish --dry-run --publish-url https://test.pypi.org/legacy/
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### version from environment
|
|
380
|
+
|
|
381
|
+
```yaml
|
|
382
|
+
version:
|
|
383
|
+
source: env
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
export OMNIDIST_VERSION=2.0.0
|
|
388
|
+
omnidist npm stage
|
|
389
|
+
omnidist uv stage
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Migration Guide (npm -> dual backend)
|
|
393
|
+
|
|
394
|
+
1. Pull latest `omnidist` and run `omnidist init` in a clean branch to get uv defaults in config.
|
|
395
|
+
2. Keep existing `distributions.npm` unchanged.
|
|
396
|
+
3. Add/update `distributions.uv` values:
|
|
397
|
+
- `package` for wheel distribution name
|
|
398
|
+
- `index-url` for target registry
|
|
399
|
+
- `linux-tag` policy (`manylinux2014` default)
|
|
400
|
+
4. Extend CI pipeline with uv stage/verify gates (see next section).
|
|
401
|
+
5. Release both backends in the same version cycle.
|
|
402
|
+
|
|
403
|
+
This is additive: npm support remains first-class and is not deprecated.
|
|
404
|
+
|
|
405
|
+
## CI and Release Flow (Dual Backend)
|
|
406
|
+
|
|
407
|
+
Recommended release sequence:
|
|
408
|
+
|
|
409
|
+
1. `omnidist build`
|
|
410
|
+
2. `omnidist stage`
|
|
411
|
+
3. `omnidist verify`
|
|
412
|
+
4. `omnidist publish`
|
|
413
|
+
|
|
414
|
+
For CI verification-only jobs, run steps 1-3.
|
|
415
|
+
|
|
416
|
+
When you need distribution-specific publish options (`npm --tag/--otp/--registry`, `uv --publish-url/--token`), use `omnidist npm ...` and `omnidist uv ...` subcommands directly.
|
|
417
|
+
|
|
418
|
+
## Project Layout
|
|
419
|
+
|
|
420
|
+
```text
|
|
421
|
+
cmd/omnidist/ CLI entrypoint and commands
|
|
422
|
+
internal/config/ Config model and YAML load/save
|
|
423
|
+
internal/workflow/ build/init/npm/uv workflows
|
|
424
|
+
.omnidist/omnidist.yaml Project configuration
|
|
425
|
+
.omnidist/.gitignore Ignore rules for generated artifacts
|
|
426
|
+
.omnidist/dist/ Built binaries by os/arch
|
|
427
|
+
.omnidist/dist/VERSION Version captured at build time
|
|
428
|
+
.omnidist/npm/ Staged npm packages
|
|
429
|
+
.omnidist/uv/pyproject.toml UV staging project with PEP 440 version
|
|
430
|
+
.omnidist/uv/dist/ Staged wheel artifacts
|
|
431
|
+
```
|
package/package.json
CHANGED
|
@@ -7,15 +7,16 @@
|
|
|
7
7
|
"node": "\u003e=16"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"omnidist.js"
|
|
10
|
+
"omnidist.js",
|
|
11
|
+
"README.md"
|
|
11
12
|
],
|
|
12
13
|
"name": "@omnidist/omnidist",
|
|
13
14
|
"optionalDependencies": {
|
|
14
|
-
"@omnidist/omnidist-darwin-arm64": "0.1.
|
|
15
|
-
"@omnidist/omnidist-darwin-x64": "0.1.
|
|
16
|
-
"@omnidist/omnidist-linux-arm64": "0.1.
|
|
17
|
-
"@omnidist/omnidist-linux-x64": "0.1.
|
|
18
|
-
"@omnidist/omnidist-win32-x64": "0.1.
|
|
15
|
+
"@omnidist/omnidist-darwin-arm64": "0.1.17",
|
|
16
|
+
"@omnidist/omnidist-darwin-x64": "0.1.17",
|
|
17
|
+
"@omnidist/omnidist-linux-arm64": "0.1.17",
|
|
18
|
+
"@omnidist/omnidist-linux-x64": "0.1.17",
|
|
19
|
+
"@omnidist/omnidist-win32-x64": "0.1.17"
|
|
19
20
|
},
|
|
20
|
-
"version": "0.1.
|
|
21
|
+
"version": "0.1.17"
|
|
21
22
|
}
|