-
Notifications
You must be signed in to change notification settings - Fork 6
Add npm publishing and update documentation #719
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jbrejner
wants to merge
29
commits into
main
Choose a base branch
from
4590_cli-as-npm-package
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
24db015
Changes required by Gorelase version > 2
jbrejner dd7342b
npm-publish script supports conditional publishing.
jbrejner c43ed83
Create npm packages after goreleaser via a hook script
jbrejner 153ff0d
Update documentation with NPM installation instructions
jbrejner a79527b
Switch npm package scope to @kosli
jbrejner 9cd8341
Fix: Add the missing bin/kosli JS Shim
jbrejner 0d56678
Fix: Token Variable Mismatch
jbrejner 110bed9
Fix: Silent Postinstall Failures
jbrejner 0731aaf
Update npm/README.md
jbrejner ceea475
refactor(npm-publish): replace sed/perl with jq and harden publish sc…
jbrejner 3390c14
Fix: Frontmatter formatting
jbrejner 8d539fa
Consistent formatting of package.json files
jbrejner 3121294
Include npm packages in binary provenance processing
jbrejner f0ab843
Add directory and engines specification to packages
jbrejner 5834afb
Documention updates:
jbrejner b09a04a
Fix three issues in npm postinstall and publish script
jbrejner 1a8be2d
Update scripts/npm-publish.sh
jbrejner 3b4efbc
Integrate npm package build and publish into GoReleaser pipeline
jbrejner fd4d77c
Update scripts/npm-publish.sh
jbrejner 7d3eb03
Update scripts/npm-publish.sh
jbrejner 92bc42b
Update scripts/npm-publish.sh
jbrejner a4798c9
Update scripts/npm-publish.sh
jbrejner 9fa3c32
Add --provenance flag to npm publish when running in GitHub Actions
jbrejner a2221b5
Fix temp file leak and add npm provenance in GitHub Actions
jbrejner 119cd7d
Added distribution: goreleaser-pro and GORELEASER_KEY: ${{ secrets.KO…
jbrejner f7866ed
Add npm installation test job to install-script-tests workflow
jbrejner da52c02
Select npm tag snapshot for now
jbrejner dbbefa8
Removed macos-13. macos-13 is the only GitHub-hosted x64 macOS runner…
jbrejner 6c960ed
Refine dry-run condition in npm-publish script for clarity
jbrejner File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,164 @@ | ||||||
| # NPM Packaging | ||||||
|
|
||||||
| This directory contains the npm package structure for distributing the Kosli CLI via npm, following the same pattern used by [esbuild](https://github.com/evanw/esbuild). | ||||||
|
|
||||||
| ## Structure | ||||||
|
|
||||||
| ``` | ||||||
| npm/ | ||||||
| ├── wrapper/ # @kosli/cli — the package users install | ||||||
| │ ├── bin/kosli # JS shim that detects the platform and runs the binary | ||||||
| │ ├── install.js # postinstall script that validates the binary | ||||||
| │ └── package.json # declares optionalDependencies for all platforms | ||||||
| ├── cli-darwin-arm64/ # @kosli/cli-darwin-arm64 | ||||||
| │ ├── bin/kosli # the native binary — see below | ||||||
| │ └── package.json # declares os/cpu fields for platform filtering | ||||||
| ├── cli-darwin-x64/ # @kosli/cli-darwin-x64 | ||||||
| │ ├── bin/kosli # the native binary — see below | ||||||
| │ └── package.json # declares os/cpu fields for platform filtering | ||||||
| ├── cli-linux-arm/ # @kosli/cli-linux-arm | ||||||
| │ ├── bin/kosli # the native binary — see below | ||||||
| │ └── package.json # declares os/cpu fields for platform filtering | ||||||
| ├── cli-linux-arm64/ # @kosli/cli-linux-arm64 | ||||||
| │ ├── bin/kosli # the native binary — see below | ||||||
| │ └── package.json # declares os/cpu fields for platform filtering | ||||||
| ├── cli-linux-x64/ # @kosli/cli-linux-x64 | ||||||
| │ ├── bin/kosli # the native binary — see below | ||||||
| │ └── package.json # declares os/cpu fields for platform filtering | ||||||
| ├── cli-win32-arm64/ # @kosli/cli-win32-arm64 | ||||||
| │ ├── bin/kosli.exe # the native binary — see below | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Tree diagram formatting.
Suggested change
|
||||||
| │ └── package.json # declares os/cpu fields for platform filtering | ||||||
| └── cli-win32-x64/ # @kosli/cli-win32-x64 | ||||||
| ├── bin/kosli.exe # the native binary — see below | ||||||
| └── package.json # declares os/cpu fields for platform filtering | ||||||
| ``` | ||||||
|
|
||||||
| ## How it works | ||||||
|
|
||||||
| Users install a single package: | ||||||
|
|
||||||
| ```sh | ||||||
| npm install @kosli/cli | ||||||
| ``` | ||||||
|
|
||||||
| or if using in continuous integration you can install globally: | ||||||
|
|
||||||
| ```sh | ||||||
| npm install -g @kosli/cli | ||||||
| ``` | ||||||
|
|
||||||
| npm resolves the `optionalDependencies` declared in the wrapper's `package.json` and installs only the platform-specific package that matches the current OS and CPU architecture — all non-matching packages are silently skipped. The wrapper's `bin/kosli` JS shim then locates the binary inside the installed platform package and executes it. | ||||||
|
|
||||||
| > **`npx` is not supported.** `npx @kosli/cli` does not install optional dependencies, so the platform binary is never fetched and the command fails. Always install the package before running it. | ||||||
|
|
||||||
| ## The `bin/` directories are populated by goreleaser | ||||||
|
|
||||||
| The platform package `bin/` directories are **not committed to git**. They are populated automatically during the release process by a post-build hook in [`.goreleaser.yml`](../.goreleaser.yml): | ||||||
|
|
||||||
| ```yaml | ||||||
| hooks: | ||||||
| post: | ||||||
| - cmd: >- | ||||||
| bash -c ' | ||||||
| OS="{{ .Os }}"; | ||||||
| ARCH="{{ .Arch }}"; | ||||||
| [ "$OS" = "windows" ] && OS="win32"; | ||||||
| [ "$ARCH" = "amd64" ] && ARCH="x64"; | ||||||
| EXT=""; | ||||||
| [ "{{ .Os }}" = "windows" ] && EXT=".exe"; | ||||||
| mkdir -p npm/cli-${OS}-${ARCH}/bin && | ||||||
| cp "{{ .Path }}" npm/cli-${OS}-${ARCH}/bin/kosli${EXT} && | ||||||
| chmod +x npm/cli-${OS}-${ARCH}/bin/kosli${EXT}' | ||||||
| ``` | ||||||
|
|
||||||
| This hook runs once per build target immediately after goreleaser compiles the binary. It applies the following naming conventions: | ||||||
|
|
||||||
| | goreleaser | npm package dir | | ||||||
| |------------|-----------------| | ||||||
| | `linux` | `linux` | | ||||||
| | `darwin` | `darwin` | | ||||||
| | `windows` | `win32` | | ||||||
| | `amd64` | `x64` | | ||||||
| | `arm64` | `arm64` | | ||||||
| | `arm` | `arm` | | ||||||
|
|
||||||
| Windows binaries are copied as `kosli.exe`; all others as `kosli`. The `windows/arm` combination is excluded from builds. | ||||||
|
|
||||||
| The `before` hooks in `.goreleaser.yml` clean up stale artifacts before each build run: | ||||||
|
|
||||||
| ```yaml | ||||||
| before: | ||||||
| hooks: | ||||||
| - rm -rf npm/cli-*/bin | ||||||
| - find npm -name "*.tgz" -delete | ||||||
| ``` | ||||||
|
|
||||||
| ## Publishing | ||||||
|
|
||||||
| Packages are published to the [npm public registry](https://registry.npmjs.org). Platform packages must be published before the wrapper, since the wrapper's `optionalDependencies` references them by version. After a goreleaser build has populated the `bin/` directories: | ||||||
|
|
||||||
| ```sh | ||||||
| # Publish platform packages first | ||||||
| (cd npm/cli-linux-x64 && npm publish) | ||||||
| (cd npm/cli-linux-arm64 && npm publish) | ||||||
| (cd npm/cli-linux-arm && npm publish) | ||||||
| (cd npm/cli-darwin-x64 && npm publish) | ||||||
| (cd npm/cli-darwin-arm64 && npm publish) | ||||||
| (cd npm/cli-win32-x64 && npm publish) | ||||||
| (cd npm/cli-win32-arm64 && npm publish) | ||||||
|
|
||||||
| # Then publish the wrapper | ||||||
| (cd npm/wrapper && npm publish) | ||||||
| ``` | ||||||
|
|
||||||
| Each package directory contains an `.npmrc` that sets the auth token: | ||||||
|
|
||||||
| ```text | ||||||
| //registry.npmjs.org/:_authToken=${NPM_TOKEN} | ||||||
| ``` | ||||||
|
|
||||||
| ## Automated Publishing with npm-publish.sh | ||||||
|
|
||||||
| The `scripts/npm-publish.sh` script automates the npm packaging and publishing process. It injects the version into all `package.json` files, packs each package into a `.tgz`, and optionally publishes them. | ||||||
|
|
||||||
| ### Usage | ||||||
|
|
||||||
| ```bash | ||||||
| scripts/npm-publish.sh <version> [--dry-run] | ||||||
| ``` | ||||||
|
|
||||||
| ### Arguments | ||||||
|
|
||||||
| - `<version>`: Required. A SemVer string — either `X.Y.Z` (stable) or `X.Y.Z-TAG` (pre-release). | ||||||
| - `--dry-run` (optional second argument): Pack packages but skip publishing. | ||||||
|
|
||||||
| ### Behavior | ||||||
|
|
||||||
| 1. Injects `<version>` into the `version` field of all `package.json` files. | ||||||
| 2. Updates the `optionalDependencies` version references in `npm/wrapper/package.json` to match. | ||||||
| 3. Runs `npm pack` on each platform package, then on the wrapper. | ||||||
| 4. Unless `--dry-run` is set, runs `npm publish --tag <tag>` on each package. | ||||||
|
|
||||||
| The dist-tag is determined by the version format: | ||||||
|
|
||||||
| | Version format | npm dist-tag | | ||||||
| |----------------|--------------| | ||||||
| | `X.Y.Z` | `latest` | | ||||||
| | `X.Y.Z-*` | `snapshot` | | ||||||
|
|
||||||
| ### Integration with GoReleaser | ||||||
|
|
||||||
| GoReleaser calls this script automatically via the `after` hook once all platform binaries have been built and copied into the `bin/` directories: | ||||||
|
|
||||||
| ```yaml | ||||||
| after: | ||||||
| hooks: | ||||||
| - cmd: bash scripts/npm-publish.sh "{{ .Version }}" ... | ||||||
| output: true | ||||||
| ``` | ||||||
|
|
||||||
| The script output is surfaced in the goreleaser log (`output: true`). | ||||||
|
|
||||||
| ## Versioning | ||||||
|
|
||||||
| All packages share the same version number. When releasing, `npm-publish.sh` updates it automatically in all eight `package.json` files — the seven platform packages and the wrapper — as well as the `optionalDependencies` version pins in `npm/wrapper/package.json`. There is no need to edit these files manually. | ||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| //registry.npmjs.org/:_authToken=${NPM_TOKEN} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # @kosli/cli-darwin-arm64 | ||
|
|
||
| This is the macOS ARM64 platform binary for the Kosli CLI (Apple Silicon). **Do not install this package directly.** | ||
|
|
||
| Install the main package instead, which selects the right binary for your platform automatically: | ||
|
|
||
| ```sh | ||
| npm install -g @kosli/cli | ||
| ``` | ||
|
|
||
| See the [Kosli CLI repository](https://github.com/kosli-dev/cli) for documentation and source code. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.