Skip to content

Commit 2ffe146

Browse files
committed
Leaving this behind for now
1 parent 3ebfafd commit 2ffe146

6 files changed

Lines changed: 237 additions & 71 deletions

File tree

.github/workflows/npm-publish.yml.example

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,11 @@ jobs:
3232
- name: Setup Go
3333
uses: actions/setup-go@v5
3434
with:
35-
go-version: '1.25.0'
35+
go-version: ${{ env.GO_VERSION }}
3636

3737
- name: Build Go binary
3838
run: make build
3939

40-
- name: Setup npm package structure
41-
run: |
42-
# Copy binary to npm-package structure
43-
mkdir -p npm-package/bin
44-
cp ./kosli npm-package/bin/
45-
chmod +x npm-package/bin/kosli
46-
4740
- name: Extract version and update package.json
4841
run: |
4942
# Extract version from kosli binary
@@ -55,15 +48,48 @@ jobs:
5548
npm version "$KOSLI_VERSION" --no-git-tag-version --allow-same-version
5649
echo "Updated package.json to version $KOSLI_VERSION"
5750

58-
- name: Verify package contents
51+
# Store version for later steps
52+
echo "KOSLI_VERSION=$KOSLI_VERSION" >> $GITHUB_ENV
53+
54+
- name: Verify GitHub release exists
55+
run: |
56+
echo "Checking if GitHub release v${{ env.KOSLI_VERSION }} exists..."
57+
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
58+
"https://api.github.com/repos/kosli-dev/cli/releases/tags/v${{ env.KOSLI_VERSION }}")
59+
60+
if [ "$RESPONSE" != "200" ]; then
61+
echo "Error: GitHub release v${{ env.KOSLI_VERSION }} not found!"
62+
echo "The npm package requires binaries to be available in GitHub releases"
63+
exit 1
64+
fi
65+
echo "✓ GitHub release v${{ env.KOSLI_VERSION }} exists"
66+
67+
- name: Test package with binary download
68+
run: |
69+
# Test that the package works with binary download from GitHub
70+
# Copy binary for local test
71+
mkdir -p npm-package/bin
72+
cp ./kosli npm-package/bin/
73+
chmod +x npm-package/bin/kosli
74+
75+
# Run test script
76+
./test-npm-package.sh
77+
78+
# Remove binary after test (it should not be published)
79+
rm -rf npm-package/bin
80+
81+
- name: Verify package contents (no binary)
82+
working-directory: npm-package
5983
run: |
60-
echo "npm-package contents:"
61-
ls -lah npm-package/
62-
echo -e "\nnpm-package/bin/ directory:"
63-
ls -lah npm-package/bin/
84+
echo "Files to be published:"
85+
npm pack --dry-run
6486

65-
- name: Test package locally
66-
run: ./test-npm-package.sh
87+
# Ensure bin directory doesn't exist
88+
if [ -d "bin" ]; then
89+
echo "Error: bin/ directory should not exist for publication"
90+
exit 1
91+
fi
92+
echo "✓ Package will be published without binary (download-based)"
6793

6894
- name: Publish to npm
6995
working-directory: npm-package

.goreleaser.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
version: 2
22
project_name: kosli
3+
version: 2
34
before:
45
hooks:
56
- go mod tidy
@@ -40,7 +41,7 @@ archives:
4041

4142
# docs for nfpm can be found here: https://goreleaser.com/customization/nfpm/
4243
nfpms:
43-
- id: kosli
44+
ids: ['kosli']
4445

4546
# You can change the file name of the package.
4647
#

NPM_RELEASE.md

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ This document describes how to release the Kosli CLI as an npm package.
44

55
## Overview
66

7-
The Kosli CLI is primarily a Go binary, but we also publish it as an npm package for easy installation in JavaScript/TypeScript projects. The npm package downloads the appropriate platform-specific binary during installation.
7+
The Kosli CLI is primarily a Go binary, but we also publish it as an npm package for easy installation in JavaScript/TypeScript projects.
8+
9+
**Important:** The published npm package is small (~5KB) and does NOT include the binary. Instead, it downloads the appropriate platform-specific binary from GitHub releases during installation. This approach:
10+
- ✅ Keeps the package small
11+
- ✅ Works on all platforms (downloads the correct binary for each user)
12+
- ✅ Requires that a GitHub release exists before publishing to npm
813

914
## Package Structure
1015

@@ -19,38 +24,49 @@ All npm packaging files are located in the `npm-package/` directory:
1924

2025
## Release Process
2126

27+
### Prerequisites
28+
29+
**IMPORTANT:** Before publishing to npm, ensure that:
30+
1. A GitHub release exists for the version you want to publish
31+
2. The release includes binaries for all supported platforms (darwin/linux/windows, amd64/arm64)
32+
3. You have publish permissions to the `@kosli` organization on npm
33+
2234
### 1. Test Locally
2335

24-
The test script automatically extracts the version from the kosli binary and updates `package.json`. Before publishing, test the package locally:
36+
Test the package with a bundled binary (for local validation):
2537

2638
```bash
2739
# Run the automated test script
2840
./test-npm-package.sh
2941
```
3042

31-
This script will:
32-
- Build the kosli binary (if not already built)
33-
- Copy the binary to `npm-package/bin/`
34-
- Extract the version from the binary and update `package.json`
35-
- Pack the npm package
36-
- Install it in a temporary directory
37-
- Run tests to verify installation
38-
- Clean up
43+
This script:
44+
- Builds the kosli binary (if not already built)
45+
- **Includes the binary** in the package for testing
46+
- Extracts the version from the binary and updates `package.json`
47+
- Packs and installs the package in a temporary directory
48+
- Runs tests to verify installation
3949

40-
### 2. Publish to npm
50+
**Note:** This test includes the binary, but production publishing should NOT include it.
4151

42-
```bash
43-
# Login to npm (first time only)
44-
npm login
52+
### 2. Publish to npm (Small Package Approach)
4553

46-
# Navigate to npm-package directory
47-
cd npm-package
54+
Use the dedicated publish script that publishes WITHOUT the binary:
4855

49-
# Publish the package (npm will automatically pack it)
50-
npm publish --access public
56+
```bash
57+
# Run the publish script
58+
./npm-publish.sh
5159
```
5260

53-
**Note:** Make sure you have permission to publish to the `@kosli` organization on npm.
61+
This script will:
62+
- Extract the version from the kosli binary
63+
- Update `package.json` version
64+
- Verify that the GitHub release exists
65+
- Show you what will be published
66+
- Prompt for confirmation
67+
- Publish the small package (~5KB) to npm
68+
69+
**Note:** The published package will download binaries from GitHub releases during user installation.
5470

5571
### 3. Automate with GitHub Actions (Recommended)
5672

@@ -98,14 +114,17 @@ npx @kosli/cli version
98114

99115
## How It Works
100116

117+
### For End Users (npm install):
101118
1. When `npm install` runs, the `postinstall` script (`install.js`) executes
102-
2. The script checks if the binary already exists (for local testing)
103-
3. If not present, it detects the platform (OS and architecture)
104-
4. It downloads the appropriate binary from GitHub releases
105-
5. The binary is extracted to the `bin/` directory
106-
6. The `index.js` wrapper script forwards all commands to the binary
119+
2. The script detects the platform (OS and architecture)
120+
3. It downloads the appropriate binary from GitHub releases:
121+
- URL format: `https://github.com/kosli-dev/cli/releases/download/v{version}/kosli_{version}_{os}_{arch}.{tar.gz|zip}`
122+
- Example: `https://github.com/kosli-dev/cli/releases/download/v2.11.43/kosli_2.11.43_linux_amd64.tar.gz`
123+
4. The binary is extracted to the `bin/` directory
124+
5. The `index.js` wrapper script forwards all commands to the binary
107125

108-
**Note:** For local testing, when the binary is already packaged in `npm-package/bin/`, the download step is skipped.
126+
### For Local Testing:
127+
When using `./test-npm-package.sh`, the binary is included in the package, and `install.js` detects it and skips the download step.
109128

110129
## Supported Platforms
111130

@@ -146,34 +165,49 @@ The devcontainer includes Node.js and npm, so you can test the npm package workf
146165
./test-npm-package.sh
147166
```
148167

149-
## Manual Package Creation
168+
## Manual Publishing Steps
150169

151-
If you want to create the package without running tests:
170+
If you prefer to publish manually instead of using `./npm-publish.sh`:
152171

153172
```bash
154-
# Build the binary
173+
# 1. Build the binary to extract version
155174
make build
156175
157-
# Copy to npm-package structure
158-
mkdir -p npm-package/bin
159-
cp ./kosli npm-package/bin/
160-
chmod +x npm-package/bin/kosli
161-
162-
# Extract version and update package.json
176+
# 2. Extract version and update package.json
163177
KOSLI_VERSION=$(./kosli version 2>/dev/null | head -1 | grep -oP 'Version:"v\K[^"]+')
164178
cd npm-package
165179
npm version "$KOSLI_VERSION" --no-git-tag-version --allow-same-version
166180
167-
# Pack the package
168-
npm pack
181+
# 3. Ensure bin/ directory does NOT exist (so binary is not included)
182+
rm -rf bin
183+
184+
# 4. Verify GitHub release exists
185+
curl -f -s "https://github.com/kosli-dev/cli/releases/tag/v${KOSLI_VERSION}" > /dev/null || \
186+
echo "ERROR: GitHub release v${KOSLI_VERSION} does not exist!"
187+
188+
# 5. Preview what will be published
189+
npm pack --dry-run
190+
191+
# 6. Publish to npm
192+
npm publish --access public
169193
```
170194

171-
This creates `kosli-cli-<version>.tgz` in the `npm-package/` directory.
195+
**Important:** The `bin/` directory must NOT exist during publishing, so the package will download binaries from GitHub releases.
196+
197+
## Key Differences: Testing vs Publishing
198+
199+
| Aspect | Local Testing (`./test-npm-package.sh`) | Production Publishing (`./npm-publish.sh`) |
200+
|--------|----------------------------------------|-------------------------------------------|
201+
| Binary included? | ✅ Yes (copied to `npm-package/bin/`) | ❌ No (`bin/` directory removed) |
202+
| Package size | Large (~18 MB) | Small (~5 KB) |
203+
| Platform support | Single platform only | All platforms (downloads correct binary) |
204+
| Purpose | Validate packaging works | Publish for end users |
172205

173206
## Notes
174207

175208
- The npm package version is automatically extracted from the kosli binary
176-
- For published packages, the release must exist on GitHub before users can install it
177-
- Users need internet access during installation to download the binary (unless the binary is pre-packaged)
209+
- **GitHub release must exist BEFORE publishing to npm** (users download binaries from there)
210+
- Users need internet access during installation to download the binary
178211
- Consider caching the binary in CI/CD pipelines to avoid repeated downloads
179212
- All npm packaging is isolated in the `npm-package/` directory to avoid conflicts with other project files
213+
- The published package is platform-independent; the correct binary is downloaded during installation

npm-package/install.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,33 @@ const version = packageJson.version;
1818
const platform = process.platform;
1919
const arch = process.arch;
2020

21-
// Map Node.js platform/arch to Goreleaser naming
21+
// Map Node.js platform/arch to kosli release naming
2222
const platformMap = {
23-
darwin: 'Darwin',
24-
linux: 'Linux',
25-
win32: 'Windows'
23+
darwin: 'darwin',
24+
linux: 'linux',
25+
win32: 'windows'
2626
};
2727

2828
const archMap = {
29-
x64: 'x86_64',
30-
arm64: 'arm64',
31-
arm: 'arm'
29+
x64: 'amd64',
30+
arm64: 'arm64'
3231
};
3332

3433
const mappedPlatform = platformMap[platform];
3534
const mappedArch = archMap[arch];
3635

3736
if (!mappedPlatform || !mappedArch) {
3837
console.error(`Unsupported platform: ${platform} ${arch}`);
38+
console.error('Kosli CLI supports: darwin/linux/windows with amd64/arm64 architectures');
3939
process.exit(1);
4040
}
4141

4242
// Construct download URL
43-
// Format: kosli_<OS>_<ARCH>.tar.gz (for Linux/Darwin)
44-
// Format: kosli_<OS>_<ARCH>.zip (for Windows)
43+
// Format: kosli_<version>_<os>_<arch>.tar.gz (for Linux/Darwin)
44+
// Format: kosli_<version>_<os>_<arch>.zip (for Windows)
45+
// Example: https://github.com/kosli-dev/cli/releases/download/v2.11.43/kosli_2.11.43_linux_amd64.tar.gz
4546
const extension = platform === 'win32' ? 'zip' : 'tar.gz';
46-
const archiveName = `kosli_${mappedPlatform}_${mappedArch}.${extension}`;
47+
const archiveName = `kosli_${version}_${mappedPlatform}_${mappedArch}.${extension}`;
4748
const downloadUrl = `https://github.com/kosli-dev/cli/releases/download/v${version}/${archiveName}`;
4849

4950
console.log(`Downloading Kosli CLI v${version} for ${platform}/${arch}...`);
@@ -91,12 +92,12 @@ function downloadFile(url, dest) {
9192
resolve();
9293
});
9394
}).on('error', (err) => {
94-
fs.unlink(dest, () => {}); // Delete the file on error
95+
fs.unlink(dest, () => { }); // Delete the file on error
9596
reject(err);
9697
});
9798

9899
file.on('error', (err) => {
99-
fs.unlink(dest, () => {}); // Delete the file on error
100+
fs.unlink(dest, () => { }); // Delete the file on error
100101
reject(err);
101102
});
102103
});
@@ -108,9 +109,8 @@ function downloadFile(url, dest) {
108109
function extractArchive() {
109110
try {
110111
if (platform === 'win32') {
111-
// Extract zip file on Windows
112-
// Note: This requires PowerShell or a zip utility
113-
execSync(`tar -xf "${archivePath}" -C "${binDir}"`, { stdio: 'inherit' });
112+
// Extract zip file on Windows using PowerShell
113+
execSync(`powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${binDir}' -Force"`, { stdio: 'inherit' });
114114
} else {
115115
// Extract tar.gz on Unix-like systems
116116
execSync(`tar -xzf "${archivePath}" -C "${binDir}"`, { stdio: 'inherit' });

npm-package/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@kosli/cli",
3-
"version": "2.11.43",
3+
"version": "2.11.2",
44
"description": "Kosli CLI - Record and query software delivery events",
55
"main": "index.js",
66
"bin": {

0 commit comments

Comments
 (0)