mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
nix: automatic lockfile fixing to keep main building with nix
This commit is contained in:
parent
ab37132e59
commit
6f079933cb
7 changed files with 396 additions and 73 deletions
64
.github/workflows/nix-lockfile-check.yml
vendored
Normal file
64
.github/workflows/nix-lockfile-check.yml
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
name: Nix Lockfile Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'ui-tui/package.json'
|
||||||
|
- 'ui-tui/package-lock.json'
|
||||||
|
- 'web/package.json'
|
||||||
|
- 'web/package-lock.json'
|
||||||
|
- 'nix/tui.nix'
|
||||||
|
- 'nix/web.nix'
|
||||||
|
- 'nix/lib.nix'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: nix-lockfile-check-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 20
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||||
|
|
||||||
|
- uses: nixbuild/nix-quick-install-action@63ca48f939ee3b8d835f4126562537df0fee5b91 # v30
|
||||||
|
|
||||||
|
- name: Check lockfile hashes
|
||||||
|
id: check
|
||||||
|
continue-on-error: true
|
||||||
|
run: nix run .#fix-lockfiles -- --check
|
||||||
|
|
||||||
|
- name: Post sticky PR comment (stale)
|
||||||
|
if: steps.check.outputs.stale == 'true' && github.event_name == 'pull_request'
|
||||||
|
uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
|
||||||
|
with:
|
||||||
|
header: nix-lockfile-check
|
||||||
|
message: |
|
||||||
|
### ⚠️ npm lockfile hash out of date
|
||||||
|
|
||||||
|
The `hash = "sha256-..."` line in these nix files no longer matches the committed `package-lock.json`:
|
||||||
|
|
||||||
|
${{ steps.check.outputs.report }}
|
||||||
|
|
||||||
|
#### Apply the fix
|
||||||
|
|
||||||
|
- [ ] **Apply lockfile fix** — tick to push a commit with the correct hashes to this PR branch
|
||||||
|
- Or [run the Nix Lockfile Fix workflow](${{ github.server_url }}/${{ github.repository }}/actions/workflows/nix-lockfile-fix.yml) manually (pass PR `#${{ github.event.pull_request.number }}`)
|
||||||
|
- Or locally: `nix run .#fix-lockfiles -- --apply` and commit the diff
|
||||||
|
|
||||||
|
- name: Clear sticky PR comment (resolved)
|
||||||
|
if: steps.check.outputs.stale == 'false' && github.event_name == 'pull_request'
|
||||||
|
uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
|
||||||
|
with:
|
||||||
|
header: nix-lockfile-check
|
||||||
|
delete: true
|
||||||
|
|
||||||
|
- name: Fail if stale
|
||||||
|
if: steps.check.outputs.stale == 'true'
|
||||||
|
run: exit 1
|
||||||
126
.github/workflows/nix-lockfile-fix.yml
vendored
Normal file
126
.github/workflows/nix-lockfile-fix.yml
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
name: Nix Lockfile Fix
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
pr_number:
|
||||||
|
description: 'PR number to fix (leave empty to run on the selected branch)'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
issue_comment:
|
||||||
|
types: [edited]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: nix-lockfile-fix-${{ github.event.issue.number || github.event.inputs.pr_number || github.ref }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
fix:
|
||||||
|
# Run on manual dispatch OR when a task-list checkbox in the sticky
|
||||||
|
# lockfile-check comment flips from `[ ]` to `[x]`.
|
||||||
|
if: |
|
||||||
|
github.event_name == 'workflow_dispatch' ||
|
||||||
|
(github.event_name == 'issue_comment'
|
||||||
|
&& github.event.issue.pull_request != null
|
||||||
|
&& contains(github.event.comment.body, '[x] **Apply lockfile fix**')
|
||||||
|
&& !contains(github.event.changes.body.from, '[x] **Apply lockfile fix**'))
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 25
|
||||||
|
steps:
|
||||||
|
- name: Authorize & resolve PR
|
||||||
|
id: resolve
|
||||||
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
// 1. Verify the actor has write access — applies to both checkbox
|
||||||
|
// clicks and manual dispatch.
|
||||||
|
const { data: perm } =
|
||||||
|
await github.rest.repos.getCollaboratorPermissionLevel({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
username: context.actor,
|
||||||
|
});
|
||||||
|
if (!['admin', 'write', 'maintain'].includes(perm.permission)) {
|
||||||
|
core.setFailed(
|
||||||
|
`${context.actor} lacks write access (has: ${perm.permission})`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Resolve which ref to check out.
|
||||||
|
let prNumber = '';
|
||||||
|
if (context.eventName === 'issue_comment') {
|
||||||
|
prNumber = String(context.payload.issue.number);
|
||||||
|
} else if (context.eventName === 'workflow_dispatch') {
|
||||||
|
prNumber = context.payload.inputs.pr_number || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prNumber) {
|
||||||
|
core.setOutput('ref', context.ref.replace(/^refs\/heads\//, ''));
|
||||||
|
core.setOutput('repo', context.repo.repo);
|
||||||
|
core.setOutput('owner', context.repo.owner);
|
||||||
|
core.setOutput('pr', '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: pr } = await github.rest.pulls.get({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
pull_number: Number(prNumber),
|
||||||
|
});
|
||||||
|
core.setOutput('ref', pr.head.ref);
|
||||||
|
core.setOutput('repo', pr.head.repo.name);
|
||||||
|
core.setOutput('owner', pr.head.repo.owner.login);
|
||||||
|
core.setOutput('pr', String(pr.number));
|
||||||
|
|
||||||
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||||
|
with:
|
||||||
|
repository: ${{ steps.resolve.outputs.owner }}/${{ steps.resolve.outputs.repo }}
|
||||||
|
ref: ${{ steps.resolve.outputs.ref }}
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- uses: nixbuild/nix-quick-install-action@63ca48f939ee3b8d835f4126562537df0fee5b91 # v30
|
||||||
|
|
||||||
|
- name: Apply lockfile hashes
|
||||||
|
id: apply
|
||||||
|
run: nix run .#fix-lockfiles -- --apply
|
||||||
|
|
||||||
|
- name: Commit & push
|
||||||
|
if: steps.apply.outputs.changed == 'true'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
git config user.name 'github-actions[bot]'
|
||||||
|
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
||||||
|
git add nix/tui.nix nix/web.nix
|
||||||
|
git commit -m "fix(nix): refresh npm lockfile hashes"
|
||||||
|
git push
|
||||||
|
|
||||||
|
- name: Comment on PR (applied)
|
||||||
|
if: steps.apply.outputs.changed == 'true' && steps.resolve.outputs.pr != ''
|
||||||
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: Number('${{ steps.resolve.outputs.pr }}'),
|
||||||
|
body: 'Pushed a commit refreshing the npm lockfile hashes.',
|
||||||
|
});
|
||||||
|
|
||||||
|
- name: Comment on PR (already current)
|
||||||
|
if: steps.apply.outputs.changed == 'false' && steps.resolve.outputs.pr != ''
|
||||||
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: Number('${{ steps.resolve.outputs.pr }}'),
|
||||||
|
body: 'npm lockfile hashes are already current — nothing to commit.',
|
||||||
|
z });
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
let
|
let
|
||||||
hermes-agent = inputs.self.packages.${system}.default;
|
hermes-agent = inputs.self.packages.${system}.default;
|
||||||
hermes-tui = inputs.self.packages.${system}.tui;
|
hermes-tui = inputs.self.packages.${system}.tui;
|
||||||
packages = [ hermes-agent hermes-tui ];
|
hermes-web = inputs.self.packages.${system}.web;
|
||||||
|
packages = [ hermes-agent hermes-tui hermes-web ];
|
||||||
in {
|
in {
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
inputsFrom = packages;
|
inputsFrom = packages;
|
||||||
|
|
|
||||||
151
nix/lib.nix
Normal file
151
nix/lib.nix
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
# nix/lib.nix — Shared helpers for nix stuff
|
||||||
|
{ pkgs, npm-lockfile-fix }:
|
||||||
|
{
|
||||||
|
# Shell script that refreshes node_modules, fixes the lockfile, and
|
||||||
|
# rewrites the `hash = "sha256-..."` line in the given nix file so
|
||||||
|
# fetchNpmDeps picks up the new package-lock.json.
|
||||||
|
mkUpdateLockfileScript =
|
||||||
|
{
|
||||||
|
name, # script binary name, e.g. "update_tui_lockfile"
|
||||||
|
folder, # repo-relative folder with package.json, e.g. "ui-tui"
|
||||||
|
nixFile, # repo-relative nix file with the hash line, e.g. "nix/tui.nix"
|
||||||
|
attr, # flake package attr to build to cause the failure, e.g. "tui"
|
||||||
|
}:
|
||||||
|
pkgs.writeShellScriptBin name ''
|
||||||
|
set -euox pipefail
|
||||||
|
|
||||||
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
|
cd "$REPO_ROOT/${folder}"
|
||||||
|
rm -rf node_modules/
|
||||||
|
npm cache clean --force
|
||||||
|
CI=true npm install
|
||||||
|
${pkgs.lib.getExe npm-lockfile-fix} ./package-lock.json
|
||||||
|
|
||||||
|
NIX_FILE="$REPO_ROOT/${nixFile}"
|
||||||
|
sed -i "s/hash = \"[^\"]*\";/hash = \"\";/" $NIX_FILE
|
||||||
|
NIX_OUTPUT=$(nix build .#${attr} 2>&1 || true)
|
||||||
|
NEW_HASH=$(echo "$NIX_OUTPUT" | grep 'got:' | awk '{print $2}')
|
||||||
|
echo got new hash $NEW_HASH
|
||||||
|
sed -i "s|hash = \"[^\"]*\";|hash = \"$NEW_HASH\";|" $NIX_FILE
|
||||||
|
nix build .#${attr}
|
||||||
|
echo "Updated npm hash in $NIX_FILE to $NEW_HASH"
|
||||||
|
'';
|
||||||
|
|
||||||
|
# devShell bootstrap snippet: runs `npm install` in the target folder when
|
||||||
|
# package.json or package-lock.json has changed since the last install.
|
||||||
|
# Hashing happens in bash (not nix eval), and the post-install stamp is
|
||||||
|
# recomputed so a lockfile that npm rewrites during install still matches.
|
||||||
|
mkNpmDevShellHook =
|
||||||
|
{
|
||||||
|
name, # project-unique stampfile name, e.g. "hermes-tui"
|
||||||
|
folder, # repo-relative folder with package.json + package-lock.json
|
||||||
|
}:
|
||||||
|
''
|
||||||
|
_hermes_npm_stamp() {
|
||||||
|
sha256sum "${folder}/package.json" "${folder}/package-lock.json" \
|
||||||
|
2>/dev/null | sha256sum | awk '{print $1}'
|
||||||
|
}
|
||||||
|
STAMP=".nix-stamps/${name}"
|
||||||
|
STAMP_VALUE="$(_hermes_npm_stamp)"
|
||||||
|
if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$STAMP_VALUE" ]; then
|
||||||
|
echo "${name}: installing npm dependencies..."
|
||||||
|
( cd ${folder} && CI=true npm install --silent --no-fund --no-audit 2>/dev/null )
|
||||||
|
mkdir -p .nix-stamps
|
||||||
|
_hermes_npm_stamp > "$STAMP"
|
||||||
|
fi
|
||||||
|
unset -f _hermes_npm_stamp
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Aggregate `fix-lockfiles` bin from a list of packages carrying
|
||||||
|
# passthru.npmLockfile = { attr; folder; nixFile; };
|
||||||
|
# Invocations:
|
||||||
|
# fix-lockfiles --check # exit 1 if any hash is stale
|
||||||
|
# fix-lockfiles --apply # rewrite stale hashes in place
|
||||||
|
# Writes machine-readable fields (stale, changed, report) to $GITHUB_OUTPUT
|
||||||
|
# when set, so CI workflows can post a sticky PR comment directly.
|
||||||
|
mkFixLockfiles =
|
||||||
|
{
|
||||||
|
packages, # list of packages with passthru.npmLockfile
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
entries = map (p: p.passthru.npmLockfile) packages;
|
||||||
|
entryArgs = pkgs.lib.concatMapStringsSep " " (
|
||||||
|
e: "\"${e.attr}:${e.folder}:${e.nixFile}\""
|
||||||
|
) entries;
|
||||||
|
in
|
||||||
|
pkgs.writeShellScriptBin "fix-lockfiles" ''
|
||||||
|
set -uo pipefail
|
||||||
|
MODE="''${1:---check}"
|
||||||
|
case "$MODE" in
|
||||||
|
--check|--apply) ;;
|
||||||
|
-h|--help)
|
||||||
|
echo "usage: fix-lockfiles [--check|--apply]"
|
||||||
|
exit 0 ;;
|
||||||
|
*)
|
||||||
|
echo "usage: fix-lockfiles [--check|--apply]" >&2
|
||||||
|
exit 2 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ENTRIES=(${entryArgs})
|
||||||
|
|
||||||
|
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||||
|
cd "$REPO_ROOT"
|
||||||
|
|
||||||
|
STALE=0
|
||||||
|
FIXED=0
|
||||||
|
REPORT=""
|
||||||
|
|
||||||
|
for entry in "''${ENTRIES[@]}"; do
|
||||||
|
IFS=":" read -r ATTR FOLDER NIX_FILE <<< "$entry"
|
||||||
|
echo "==> .#$ATTR ($FOLDER -> $NIX_FILE)"
|
||||||
|
OUTPUT=$(nix build ".#$ATTR.npmDeps" --no-link --print-build-logs 2>&1)
|
||||||
|
STATUS=$?
|
||||||
|
if [ "$STATUS" -eq 0 ]; then
|
||||||
|
echo " ok"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
NEW_HASH=$(echo "$OUTPUT" | awk '/got:/ {print $2; exit}')
|
||||||
|
if [ -z "$NEW_HASH" ]; then
|
||||||
|
echo " build failed with no hash mismatch:" >&2
|
||||||
|
echo "$OUTPUT" | tail -40 >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
OLD_HASH=$(grep -oE 'hash = "sha256-[^"]+"' "$NIX_FILE" | head -1 \
|
||||||
|
| sed -E 's/hash = "(.*)"/\1/')
|
||||||
|
echo " stale: $OLD_HASH -> $NEW_HASH"
|
||||||
|
STALE=1
|
||||||
|
REPORT+="- \`$NIX_FILE\` (\`.#$ATTR\`): \`$OLD_HASH\` -> \`$NEW_HASH\`"$'\n'
|
||||||
|
|
||||||
|
if [ "$MODE" = "--apply" ]; then
|
||||||
|
sed -i "s|hash = \"sha256-[^\"]*\";|hash = \"$NEW_HASH\";|" "$NIX_FILE"
|
||||||
|
nix build ".#$ATTR.npmDeps" --no-link --print-build-logs
|
||||||
|
FIXED=1
|
||||||
|
echo " fixed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "''${GITHUB_OUTPUT:-}" ]; then
|
||||||
|
{
|
||||||
|
[ "$STALE" -eq 1 ] && echo "stale=true" || echo "stale=false"
|
||||||
|
[ "$FIXED" -eq 1 ] && echo "changed=true" || echo "changed=false"
|
||||||
|
if [ -n "$REPORT" ]; then
|
||||||
|
echo "report<<REPORT_EOF"
|
||||||
|
printf "%s" "$REPORT"
|
||||||
|
echo "REPORT_EOF"
|
||||||
|
fi
|
||||||
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$STALE" -eq 1 ] && [ "$MODE" = "--check" ]; then
|
||||||
|
echo
|
||||||
|
echo "Stale lockfile hashes detected. Run:"
|
||||||
|
echo " nix run .#fix-lockfiles -- --apply"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
@ -8,10 +8,14 @@
|
||||||
inherit (inputs) uv2nix pyproject-nix pyproject-build-systems;
|
inherit (inputs) uv2nix pyproject-nix pyproject-build-systems;
|
||||||
};
|
};
|
||||||
|
|
||||||
hermesTui = pkgs.callPackage ./tui.nix {
|
hermesNpmLib = pkgs.callPackage ./lib.nix {
|
||||||
npm-lockfile-fix = inputs'.npm-lockfile-fix.packages.default;
|
npm-lockfile-fix = inputs'.npm-lockfile-fix.packages.default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hermesTui = pkgs.callPackage ./tui.nix {
|
||||||
|
inherit hermesNpmLib;
|
||||||
|
};
|
||||||
|
|
||||||
# Import bundled skills, excluding runtime caches
|
# Import bundled skills, excluding runtime caches
|
||||||
bundledSkills = pkgs.lib.cleanSourceWith {
|
bundledSkills = pkgs.lib.cleanSourceWith {
|
||||||
src = ../skills;
|
src = ../skills;
|
||||||
|
|
@ -19,7 +23,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
hermesWeb = pkgs.callPackage ./web.nix {
|
hermesWeb = pkgs.callPackage ./web.nix {
|
||||||
npm-lockfile-fix = inputs'.npm-lockfile-fix.packages.default;
|
inherit hermesNpmLib;
|
||||||
};
|
};
|
||||||
|
|
||||||
runtimeDeps = with pkgs; [
|
runtimeDeps = with pkgs; [
|
||||||
|
|
@ -111,6 +115,10 @@
|
||||||
|
|
||||||
tui = hermesTui;
|
tui = hermesTui;
|
||||||
web = hermesWeb;
|
web = hermesWeb;
|
||||||
|
|
||||||
|
fix-lockfiles = hermesNpmLib.mkFixLockfiles {
|
||||||
|
packages = [ hermesTui hermesWeb ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
62
nix/tui.nix
62
nix/tui.nix
|
|
@ -1,16 +1,14 @@
|
||||||
# nix/tui.nix — Hermes TUI (Ink/React) compiled with tsc and bundled
|
# nix/tui.nix — Hermes TUI (Ink/React) compiled with tsc and bundled
|
||||||
{ pkgs, npm-lockfile-fix, ... }:
|
{ pkgs, hermesNpmLib, ... }:
|
||||||
let
|
let
|
||||||
src = ../ui-tui;
|
src = ../ui-tui;
|
||||||
npmDeps = pkgs.fetchNpmDeps {
|
npmDeps = pkgs.fetchNpmDeps {
|
||||||
inherit src;
|
inherit src;
|
||||||
hash = "sha256-mG3vpgGi4ljt4X3XIf3I/5mIcm+rVTUAmx2DQ6YVA90=";
|
hash = "sha256-BlxkTyn1x7ZQcj7pcMB5y5C2AyToT/CzxmtacTfEXmY=";
|
||||||
};
|
};
|
||||||
|
|
||||||
packageJson = builtins.fromJSON (builtins.readFile (src + "/package.json"));
|
packageJson = builtins.fromJSON (builtins.readFile (src + "/package.json"));
|
||||||
version = packageJson.version;
|
version = packageJson.version;
|
||||||
|
|
||||||
npmLockHash = builtins.hashString "sha256" (builtins.readFile ../ui-tui/package-lock.json);
|
|
||||||
in
|
in
|
||||||
pkgs.buildNpmPackage {
|
pkgs.buildNpmPackage {
|
||||||
pname = "hermes-tui";
|
pname = "hermes-tui";
|
||||||
|
|
@ -18,6 +16,12 @@ pkgs.buildNpmPackage {
|
||||||
|
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
|
|
||||||
|
patchPhase = ''
|
||||||
|
runHook prePatch
|
||||||
|
sed -i -z 's/\n$//' package-lock.json
|
||||||
|
runHook postPatch
|
||||||
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
runHook preInstall
|
runHook preInstall
|
||||||
|
|
||||||
|
|
@ -39,39 +43,23 @@ pkgs.buildNpmPackage {
|
||||||
'';
|
'';
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
(pkgs.writeShellScriptBin "update_tui_lockfile" ''
|
(hermesNpmLib.mkUpdateLockfileScript {
|
||||||
set -euox pipefail
|
name = "update_tui_lockfile";
|
||||||
|
folder = "ui-tui";
|
||||||
# get root of repo
|
nixFile = "nix/tui.nix";
|
||||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
attr = "tui";
|
||||||
|
})
|
||||||
# cd into ui-tui and reinstall
|
|
||||||
cd "$REPO_ROOT/ui-tui"
|
|
||||||
rm -rf node_modules/
|
|
||||||
npm cache clean --force
|
|
||||||
CI=true npm install # ci env var to suppress annoying unicode install banner lag
|
|
||||||
${pkgs.lib.getExe npm-lockfile-fix} ./package-lock.json
|
|
||||||
|
|
||||||
NIX_FILE="$REPO_ROOT/nix/tui.nix"
|
|
||||||
# compute the new hash
|
|
||||||
sed -i "s/hash = \"[^\"]*\";/hash = \"\";/" $NIX_FILE
|
|
||||||
NIX_OUTPUT=$(nix build .#tui 2>&1 || true)
|
|
||||||
NEW_HASH=$(echo "$NIX_OUTPUT" | grep 'got:' | awk '{print $2}')
|
|
||||||
echo got new hash $NEW_HASH
|
|
||||||
sed -i "s|hash = \"[^\"]*\";|hash = \"$NEW_HASH\";|" $NIX_FILE
|
|
||||||
nix build .#tui
|
|
||||||
echo "Updated npm hash in $NIX_FILE to $NEW_HASH"
|
|
||||||
'')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
passthru.devShellHook = ''
|
passthru = {
|
||||||
STAMP=".nix-stamps/hermes-tui"
|
devShellHook = hermesNpmLib.mkNpmDevShellHook {
|
||||||
STAMP_VALUE="${npmLockHash}"
|
name = "hermes-tui";
|
||||||
if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$STAMP_VALUE" ]; then
|
folder = "ui-tui";
|
||||||
echo "hermes-tui: installing npm dependencies..."
|
};
|
||||||
cd ui-tui && CI=true npm install --silent --no-fund --no-audit 2>/dev/null && cd ..
|
npmLockfile = {
|
||||||
mkdir -p .nix-stamps
|
attr = "tui";
|
||||||
echo "$STAMP_VALUE" > "$STAMP"
|
folder = "ui-tui";
|
||||||
fi
|
nixFile = "nix/tui.nix";
|
||||||
'';
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
51
nix/web.nix
51
nix/web.nix
|
|
@ -1,13 +1,11 @@
|
||||||
# nix/web.nix — Hermes Web Dashboard (Vite/React) frontend build
|
# nix/web.nix — Hermes Web Dashboard (Vite/React) frontend build
|
||||||
{ pkgs, npm-lockfile-fix, ... }:
|
{ pkgs, hermesNpmLib, ... }:
|
||||||
let
|
let
|
||||||
src = ../web;
|
src = ../web;
|
||||||
npmDeps = pkgs.fetchNpmDeps {
|
npmDeps = pkgs.fetchNpmDeps {
|
||||||
inherit src;
|
inherit src;
|
||||||
hash = "sha256-Y0pOzdFG8BLjfvCLmsvqYpjxFjAQabXp1i7X9W/cCU4=";
|
hash = "sha256-Y0pOzdFG8BLjfvCLmsvqYpjxFjAQabXp1i7X9W/cCU4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
npmLockHash = builtins.hashString "sha256" (builtins.readFile ../web/package-lock.json);
|
|
||||||
in
|
in
|
||||||
pkgs.buildNpmPackage {
|
pkgs.buildNpmPackage {
|
||||||
pname = "hermes-web";
|
pname = "hermes-web";
|
||||||
|
|
@ -28,36 +26,23 @@ pkgs.buildNpmPackage {
|
||||||
'';
|
'';
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
(pkgs.writeShellScriptBin "update_web_lockfile" ''
|
(hermesNpmLib.mkUpdateLockfileScript {
|
||||||
set -euox pipefail
|
name = "update_web_lockfile";
|
||||||
|
folder = "web";
|
||||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
nixFile = "nix/web.nix";
|
||||||
|
attr = "web";
|
||||||
cd "$REPO_ROOT/web"
|
})
|
||||||
rm -rf node_modules/
|
|
||||||
npm cache clean --force
|
|
||||||
CI=true npm install
|
|
||||||
${pkgs.lib.getExe npm-lockfile-fix} ./package-lock.json
|
|
||||||
|
|
||||||
NIX_FILE="$REPO_ROOT/nix/web.nix"
|
|
||||||
sed -i "s/hash = \"[^\"]*\";/hash = \"\";/" $NIX_FILE
|
|
||||||
NIX_OUTPUT=$(nix build .#web 2>&1 || true)
|
|
||||||
NEW_HASH=$(echo "$NIX_OUTPUT" | grep 'got:' | awk '{print $2}')
|
|
||||||
echo got new hash $NEW_HASH
|
|
||||||
sed -i "s|hash = \"[^\"]*\";|hash = \"$NEW_HASH\";|" $NIX_FILE
|
|
||||||
nix build .#web
|
|
||||||
echo "Updated npm hash in $NIX_FILE to $NEW_HASH"
|
|
||||||
'')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
passthru.devShellHook = ''
|
passthru = {
|
||||||
STAMP=".nix-stamps/hermes-web"
|
devShellHook = hermesNpmLib.mkNpmDevShellHook {
|
||||||
STAMP_VALUE="${npmLockHash}"
|
name = "hermes-web";
|
||||||
if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$STAMP_VALUE" ]; then
|
folder = "web";
|
||||||
echo "hermes-web: installing npm dependencies..."
|
};
|
||||||
cd web && CI=true npm install --silent --no-fund --no-audit 2>/dev/null && cd ..
|
npmLockfile = {
|
||||||
mkdir -p .nix-stamps
|
attr = "web";
|
||||||
echo "$STAMP_VALUE" > "$STAMP"
|
folder = "web";
|
||||||
fi
|
nixFile = "nix/web.nix";
|
||||||
'';
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue