mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-09 09:54:40 +00:00
feat: add Nix flake with package and NixOS module
Add a Nix flake that builds the Paseo daemon (server + CLI) and provides a NixOS module for declarative deployment. Package (nix/package.nix): - Builds relay, server, and CLI workspaces - Skips onnxruntime-node install script (sandbox-incompatible) - Rebuilds only node-pty for native terminal support - Source filter excludes app/website/desktop workspaces NixOS module (nix/module.nix): - Systemd service with configurable user, port, listen address - allowedHosts for DNS rebinding protection - relay.enable to toggle remote access via app.paseo.sh - inheritUserEnvironment to expose user tools (git, ssh) to agents - openFirewall and extra environment variables ci: add Nix hash maintenance scripts and workflows scripts/fix-lockfile.mjs: Adds missing resolved/integrity fields to package-lock.json for workspace-local overrides. Idempotent, uses `npm view`. scripts/update-nix.sh: Runs fix-lockfile.mjs, prefetches deps, computes NAR hash, and updates npmDepsHash in nix/package.nix. Supports --check for CI. .github/workflows/nix-build.yml: Builds the Nix package on push/PR and verifies the lockfile and hash are up to date. .github/workflows/fix-nix-hash.yml: Auto-fixes lockfile signatures and Nix hash on dependabot PRs. fix: update npmDepsHash after upstream sync nix: allowlist workspace symlinks instead of blocklist Prevents build failures when upstream adds new workspace packages.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env node
|
||||
// Ensure all workspace-local node_modules entries in package-lock.json have
|
||||
// `resolved` and `integrity` fields. npm omits these for workspace-hoisted
|
||||
// overrides, but tools like Nix's offline `npm ci` require them.
|
||||
//
|
||||
// This script is idempotent — running it on an already-complete lockfile
|
||||
// is a no-op. Run it after `npm install` when the lockfile changes.
|
||||
//
|
||||
// Usage:
|
||||
// node scripts/fix-lockfile.mjs
|
||||
// node scripts/fix-lockfile.mjs path/to/package-lock.json
|
||||
|
||||
import fs from "fs";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
const lockPath = process.argv[2] || "package-lock.json";
|
||||
const lock = JSON.parse(fs.readFileSync(lockPath, "utf8"));
|
||||
|
||||
// Collect workspace package roots (local packages, not from npm)
|
||||
const workspaceRoots = new Set();
|
||||
for (const [key, val] of Object.entries(lock.packages || {})) {
|
||||
if (val.link) {
|
||||
workspaceRoots.add(val.resolved || key);
|
||||
}
|
||||
}
|
||||
|
||||
let fixed = 0;
|
||||
|
||||
for (const [key, val] of Object.entries(lock.packages || {})) {
|
||||
if (
|
||||
!key || // root package
|
||||
key.startsWith("node_modules/") || // top-level (already has resolved)
|
||||
val.link || // workspace link entry
|
||||
(val.resolved && val.integrity) || // already complete
|
||||
!val.version || // no version to look up
|
||||
workspaceRoots.has(key) // workspace package root (local, not on npm)
|
||||
)
|
||||
continue;
|
||||
|
||||
const pkgName = key.replace(/.*node_modules\//, "");
|
||||
const version = val.version;
|
||||
|
||||
try {
|
||||
const info = JSON.parse(
|
||||
execSync(`npm view ${pkgName}@${version} --json dist`, {
|
||||
encoding: "utf8",
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
})
|
||||
);
|
||||
if (info.tarball && info.integrity) {
|
||||
val.resolved = info.tarball;
|
||||
val.integrity = info.integrity;
|
||||
fixed++;
|
||||
}
|
||||
} catch {
|
||||
console.error(`Warning: could not fetch info for ${pkgName}@${version}`);
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2) + "\n");
|
||||
|
||||
if (fixed > 0) {
|
||||
console.log(`Fixed ${fixed} lockfile entries with missing resolved/integrity`);
|
||||
} else {
|
||||
console.log("Lockfile is already complete");
|
||||
}
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fix workspace-local lockfile entries and update the Nix dependency hash.
|
||||
# Requires: node, npm, nix (with prefetch-npm-deps from nixpkgs)
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/update-nix.sh # fix lockfile + update hash
|
||||
# ./scripts/update-nix.sh --check # verify everything is up to date (CI mode)
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
LOCK_FILE="$ROOT_DIR/package-lock.json"
|
||||
PACKAGE_NIX="$ROOT_DIR/nix/package.nix"
|
||||
|
||||
CHECK_MODE=false
|
||||
if [[ "${1:-}" == "--check" ]]; then
|
||||
CHECK_MODE=true
|
||||
fi
|
||||
|
||||
# 1. Fix lockfile (add resolved/integrity for workspace-local entries)
|
||||
echo "Fixing lockfile..."
|
||||
node "$SCRIPT_DIR/fix-lockfile.mjs" "$LOCK_FILE"
|
||||
|
||||
# 2. Prefetch deps and compute hash
|
||||
echo "Prefetching npm dependencies..."
|
||||
TMPDIR_DEPS="$(mktemp -d)"
|
||||
trap "rm -rf $TMPDIR_DEPS" EXIT
|
||||
|
||||
prefetch-npm-deps "$LOCK_FILE" "$TMPDIR_DEPS/deps" 2>/dev/null
|
||||
NEW_HASH="$(nix hash path "$TMPDIR_DEPS/deps")"
|
||||
echo "Computed hash: $NEW_HASH"
|
||||
|
||||
# 3. Read current hash
|
||||
CURRENT_HASH="$(grep 'npmDepsHash' "$PACKAGE_NIX" | sed 's/.*"\(.*\)".*/\1/')"
|
||||
|
||||
if [[ "$NEW_HASH" == "$CURRENT_HASH" ]]; then
|
||||
echo "Hash is already up to date."
|
||||
else
|
||||
if $CHECK_MODE; then
|
||||
echo "ERROR: npmDepsHash is stale."
|
||||
echo " current: $CURRENT_HASH"
|
||||
echo " correct: $NEW_HASH"
|
||||
echo "Run ./scripts/update-nix.sh to fix."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Updating npmDepsHash in nix/package.nix..."
|
||||
sed -i.bak "s|npmDepsHash = \".*\"|npmDepsHash = \"$NEW_HASH\"|" "$PACKAGE_NIX"
|
||||
rm -f "$PACKAGE_NIX.bak"
|
||||
echo "Updated: $CURRENT_HASH -> $NEW_HASH"
|
||||
fi
|
||||
Reference in New Issue
Block a user