Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/icy-melons-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"cmdly": patch
---

Add postinstall to build for other platforms and arch other than linux-x64
13 changes: 7 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,23 @@ jobs:
uses: ./.github/actions/setup

- name: Build binary
run: pnpm build:sea
run: pnpm build

- name: Archive binary
run: |
mkdir -p release
cp "dist/${{ matrix.target }}/cmdly" "release/cmdly-${{ matrix.target }}"
tar -C release -czf "release/cmdly-${{ matrix.target }}.tar.gz" "cmdly-${{ matrix.target }}"
${{ matrix.checksum_cmd }} "release/cmdly-${{ matrix.target }}.tar.gz" > "release/cmdly-${{ matrix.target }}.tar.gz.sha256"
ASSET_NAME="cmdly-v${{ needs.version.outputs.release_version }}-${{ matrix.target }}"
cp "dist/${{ matrix.target }}/cmdly" "release/${ASSET_NAME}"
tar -C release -czf "release/${ASSET_NAME}.tar.gz" "${ASSET_NAME}"
${{ matrix.checksum_cmd }} "release/${ASSET_NAME}.tar.gz" > "release/${ASSET_NAME}.tar.gz.sha256"

- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: cmdly-${{ matrix.target }}
path: |
release/cmdly-${{ matrix.target }}.tar.gz
release/cmdly-${{ matrix.target }}.tar.gz.sha256
release/cmdly-v${{ needs.version.outputs.release_version }}-${{ matrix.target }}.tar.gz
release/cmdly-v${{ needs.version.outputs.release_version }}-${{ matrix.target }}.tar.gz.sha256

release:
name: Release assets
Expand Down
19 changes: 14 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
"url": "https://github.com/Armadillidiid/cmdly/issues"
},
"author": "Emmanuel Isenah <emmanuelisenah@gmail.com> (https://emmanuelisenah.com)",
"bin": {
"cmdly": "./bin/cmdly"
},
"files": [
"bin/cmdly",
"dist",
"scripts/postinstall.mjs"
],
Comment thread
Armadillidiid marked this conversation as resolved.
Comment on lines +24 to +31
"repository": {
"type": "git",
"url": "https://github.com/Armadillidiid/cmdly"
Expand All @@ -33,15 +41,16 @@
},
"scripts": {
"dev": "node --import=tsx src/bin.ts --watch",
"build": "pnpm build:sea",
"build:sea": "node scripts/build-sea.mjs",
"verify:sea": "node scripts/verify-sea.mjs",
"build": "node scripts/build-sea.mjs",
"stage:bin": "node scripts/stage-default-bin.mjs",
"build:verify": "node scripts/verify-sea.mjs",
"prepack": "pnpm build && pnpm stage:bin",
Comment thread
Armadillidiid marked this conversation as resolved.
"prepare": "effect-language-service patch",
"clean": "rm -rf dist .sea",
"clean": "rm -rf dist",
"typecheck": "tsc -b tsconfig.json",
"test": "vitest run",
"changeset-version": "changeset version",
"changeset-publish": "pnpm build && pnpm vitest && changeset tag && git push --tags",
"changeset-publish": "node scripts/publish.mjs",
"format": "biome format --write",
"lint": "biome lint --write",
"check": "biome check --write --unsafe"
Expand Down
82 changes: 82 additions & 0 deletions scripts/postinstall.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env node

import {
chmodSync,
copyFileSync,
existsSync,
mkdirSync,
renameSync,
} from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = dirname(fileURLToPath(import.meta.url));
const packageRoot = join(__dirname, "..");
const binDir = join(packageRoot, "bin");
const binPath = join(binDir, "cmdly");
const supportedTargets = ["linux-x64", "linux-arm64", "darwin-arm64"];

const detectTarget = () => {
if (process.platform === "linux" && process.arch === "x64") {
return "linux-x64";
}
if (process.platform === "linux" && process.arch === "arm64") {
return "linux-arm64";
}
if (process.platform === "darwin" && process.arch === "arm64") {
return "darwin-arm64";
}
return null;
};

const installBinary = (sourcePath) => {
if (!existsSync(sourcePath)) {
throw new Error(`missing target binary in package: ${sourcePath}`);
}

mkdirSync(binDir, { recursive: true });
const tempTarget = join(binDir, ".cmdly.tmp");
copyFileSync(sourcePath, tempTarget);
chmodSync(tempTarget, 0o755);
renameSync(tempTarget, binPath);
};

const main = () => {
const target = detectTarget();

if (!target) {
console.warn(
`[postinstall] skipping unsupported target ${process.platform}-${process.arch}; supported: ${supportedTargets.join(", ")}`,
);
return;
}
Comment on lines +47 to +52

if (target === "linux-x64" && existsSync(binPath)) {
// The binary is already included in the package and bin field points to it
// No postinstall setup needed
console.log(
`[postinstall] skipping install for ${target} since binary already exists`,
);
return;
}

const sourcePath = join(packageRoot, "dist", target, "cmdly");
installBinary(sourcePath);
Comment on lines +63 to +64

console.log(`[postinstall] installed ${target} binary`);
};

try {
main();
} catch (error) {
const target = detectTarget();
const message = error instanceof Error ? error.message : String(error);

if (target) {
console.error(`[postinstall] native install failed for ${target}: ${message}`);
process.exit(1);
Comment on lines +63 to +77
}

console.warn(`[postinstall] native install failed on unsupported target: ${message}`);
process.exit(0);
}
62 changes: 62 additions & 0 deletions scripts/publish.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { writeFileSync } from "node:fs";
import { spawnSync } from "node:child_process";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import pkg from "../package.json" with { type: "json" };

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = resolve(__dirname, "..");
const pkgPath = join(rootDir, "package.json");

const run = (cmd, args, opts) => {
const result = spawnSync(cmd, args, {
cwd: rootDir,
stdio: "inherit",
...opts,
});
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
Comment on lines +12 to +20
};

const getNpmVersion = () => {
const result = spawnSync("npm", ["--version"], {
cwd: rootDir,
encoding: "utf8",
stdio: "pipe",
});
return result.stdout.trim();
};

// @changesets/cli currently only supports npm so we need to temporarily change our package manager
const npmVersion = getNpmVersion();
const original = JSON.parse(JSON.stringify(pkg));
const savedPackageManager = pkg.packageManager;
const savedDevEnginesPackageManager = JSON.parse(
JSON.stringify(pkg.devEngines?.packageManager),
);
Comment on lines +36 to +38

original.scripts.postinstall = "node scripts/postinstall.mjs";
original.packageManager = `npm@${npmVersion}`;
if (original.devEngines) {
original.devEngines.packageManager = {
name: "npm",
version: npmVersion,
};
}
writeFileSync(pkgPath, `${JSON.stringify(original, null, "\t")}\n`, "utf8");

run("pnpm", ["build"]);
run("pnpm", ["stage:bin"]);
run("pnpm", ["vitest"]);
run("changeset", ["publish"]);
run("changeset", ["tag"]);
run("git", ["push", "--tags"]);
Comment on lines +40 to +55

delete original.scripts.postinstall;
original.packageManager = savedPackageManager;
if (original.devEngines) {
original.devEngines.packageManager = savedDevEnginesPackageManager;
}
writeFileSync(pkgPath, `${JSON.stringify(original, null, "\t")}\n`, "utf8");
18 changes: 18 additions & 0 deletions scripts/stage-default-bin.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { chmodSync, copyFileSync, mkdirSync, rmSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = resolve(__dirname, "..");

const source = join(rootDir, "dist", "linux-x64", "cmdly");
const targetDir = join(rootDir, "bin");
const target = join(targetDir, "cmdly");

mkdirSync(targetDir, { recursive: true });
rmSync(target, { force: true });
copyFileSync(source, target);
chmodSync(target, 0o755);
Comment on lines +9 to +16

console.log(`[stage:bin] staged ${source} -> ${target}`);
Loading