Skip to content

Commit cbc523a

Browse files
committed
fix(desktop): add idempotent binary setup to fix empty build output
`neu build` requires platform binaries in `bin/`, which are gitignored and absent on fresh clones — producing an empty `dist/` folder. Add [setup-binaries.js](cci:7://file:///c:/personal/personal/dev/forks/markdown-viewer-fork/desktop-app/setup-binaries.js:0:0-0:0) which downloads binaries via `neu update` only when missing or when the pinned version in [neutralino.config.json](cci:7://file:///c:/personal/personal/dev/forks/markdown-viewer-fork/desktop-app/neutralino.config.json:0:0-0:0) changes, tracked by a `bin/.version` marker file. Wire it into the npm script chain via `setup` + `postsetup` hooks so that `npm run dev`, `npm run build`, and `npm run build:all` all ensure binaries exist before proceeding. - Simplify Dockerfile from 3 stages to 2 (setup handled by npm hooks) - Add explicit setup step in GitHub Actions workflow - Update README with setup documentation
1 parent b782511 commit cbc523a

File tree

5 files changed

+88
-17
lines changed

5 files changed

+88
-17
lines changed

.github/workflows/desktop-build.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ jobs:
2121
with:
2222
node-version: "lts/*"
2323

24+
- name: Setup Neutralinojs binaries
25+
working-directory: desktop-app
26+
run: npm run setup
27+
2428
- name: Build all binaries (embedded + portable)
2529
working-directory: desktop-app
2630
run: npm run build:all

desktop-app/Dockerfile

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
1-
# Stage 1: Prepare resources by copying/transforming browser-version files
2-
FROM node:lts-alpine AS prepare
1+
# Build Neutralinojs desktop app binaries
2+
#
3+
# Context: repo root (see docker-compose.yml)
4+
# Output: /output/ contains dist/ artifacts
5+
6+
FROM node:lts-alpine AS build
37

48
WORKDIR /app
59

610
# Copy the entire repo (context is the repo root)
711
COPY . .
812

9-
# Run the prepare script to generate desktop-app resources
10-
RUN node desktop-app/prepare.js
11-
12-
# Stage 2: Build Neutralinojs binaries
13-
FROM node:lts-alpine AS build
14-
1513
WORKDIR /app/desktop-app
1614

17-
# Copy only the desktop-app directory with prepared resources
18-
COPY --from=prepare /app/desktop-app .
19-
20-
# Build both embedded + portable
15+
# Setup (download binaries + prepare resources) and build all variants
2116
RUN npm run build:all
2217

2318
# Final stage: Export the dist artifacts
24-
FROM alpine:lts
19+
FROM alpine:latest
2520

2621
WORKDIR /output
2722

desktop-app/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ This is a desktop app port of [Markdown Viewer](https://github.com/ThisIs-Develo
66

77
The desktop app **shares** its core files (`script.js`, `styles.css`, `assets/`) with the browser version in the repo root. A build script (`prepare.js`) copies these files into `resources/` and injects Neutralinojs-specific additions into `index.html` at build time.
88

9+
Neutralinojs platform binaries are managed by `setup-binaries.js`, which downloads them on first use and caches them in `bin/` (gitignored). The download is version-locked to `cli.binaryVersion` in `neutralino.config.json` and only re-triggered when that version changes.
10+
911
Desktop-only files (not generated):
1012

1113
- `resources/js/main.js` — Neutralinojs lifecycle, tray menu, window events
1214
- `resources/js/neutralino.js` — Neutralinojs client library
1315
- `neutralino.config.json` — App configuration
16+
- `setup-binaries.js` — Idempotent binary setup (downloads on first use)
1417

1518
## Development
1619

@@ -22,13 +25,21 @@ Desktop-only files (not generated):
2225

2326
No installation is required. The app is built and run using `npx` (via npm scripts).
2427

28+
Neutralinojs platform binaries are downloaded automatically on first build or dev run. To manually trigger the download:
29+
30+
```bash
31+
npm run setup
32+
```
33+
34+
Binaries are cached in `bin/` (gitignored) and only re-downloaded when `cli.binaryVersion` in `neutralino.config.json` changes.
35+
2536
### Running the app
2637

2738
```bash
2839
npm run dev
2940
```
3041

31-
This automatically runs `prepare.js` before starting the app. Hot-reload is enabled by default. Enable the browser inspector by setting `"enableInspector": true` in `neutralino.config.json`.
42+
This automatically runs `setup` (downloads binaries if needed and prepares resources) before starting the app. Hot-reload is enabled by default. Enable the browser inspector by setting `"enableInspector": true` in `neutralino.config.json`.
3243

3344
For more information, see the [Neutralinojs documentation](https://neutralino.js.org/docs/cli/neu-cli#installation).
3445

desktop-app/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
"private": true,
55
"description": "Neutralinojs desktop port of Markdown Viewer",
66
"scripts": {
7-
"prepare:resources": "node prepare.js",
8-
"predev": "node prepare.js",
7+
"setup": "node setup-binaries.js",
8+
"postsetup": "node prepare.js",
9+
"predev": "npm run setup",
910
"dev": "npx -y @neutralinojs/neu@11.7.0 run",
10-
"prebuild": "node prepare.js",
11+
"prebuild": "npm run setup",
1112
"build": "npx -y @neutralinojs/neu@11.7.0 build --embed-resources",
1213
"build:portable": "npx -y @neutralinojs/neu@11.7.0 build --release",
1314
"build:all": "npm run build && npm run build:portable"

desktop-app/setup-binaries.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* setup-binaries.js — Idempotent Neutralinojs binary setup.
5+
*
6+
* Ensures the bin/ folder contains platform binaries matching the version
7+
* pinned in neutralino.config.json (cli.binaryVersion). Downloads them
8+
* via `neu update` only when missing or when the pinned version changes.
9+
*
10+
* A version marker (bin/.version) tracks the installed version so that
11+
* repeated builds and dev runs skip the download entirely.
12+
*
13+
* Run from the desktop-app/ directory:
14+
* node setup-binaries.js
15+
*/
16+
17+
const fs = require("fs");
18+
const path = require("path");
19+
const { execSync } = require("child_process");
20+
21+
const CONFIG_FILE = path.resolve(__dirname, "neutralino.config.json");
22+
const BIN_DIR = path.resolve(__dirname, "bin");
23+
const VERSION_MARKER = path.join(BIN_DIR, ".version");
24+
25+
/** Neu CLI package — same version used across all npm scripts */
26+
const NEU_CLI = "@neutralinojs/neu@11.7.0";
27+
28+
const config = JSON.parse(fs.readFileSync(CONFIG_FILE, "utf-8"));
29+
const expectedVersion = config.cli.binaryVersion;
30+
31+
if (!expectedVersion) {
32+
console.error("✗ cli.binaryVersion not set in neutralino.config.json");
33+
process.exit(1);
34+
}
35+
36+
/** Check if binaries are already present and match the expected version */
37+
if (fs.existsSync(VERSION_MARKER)) {
38+
const installed = fs.readFileSync(VERSION_MARKER, "utf-8").trim();
39+
if (installed === expectedVersion) {
40+
console.log(
41+
`✓ Neutralinojs binaries v${expectedVersion} already present — skipping download`,
42+
);
43+
process.exit(0);
44+
}
45+
console.log(
46+
`↻ Version changed (${installed}${expectedVersion}) — re-downloading`,
47+
);
48+
}
49+
50+
/** Download binaries + client library via neu update */
51+
console.log(`⬇ Downloading Neutralinojs v${expectedVersion} binaries...`);
52+
execSync(`npx -y ${NEU_CLI} update`, {
53+
cwd: __dirname,
54+
stdio: "inherit",
55+
});
56+
57+
/** Write version marker so subsequent runs are no-ops */
58+
fs.mkdirSync(BIN_DIR, { recursive: true });
59+
fs.writeFileSync(VERSION_MARKER, expectedVersion, "utf-8");
60+
console.log(`✓ Neutralinojs binaries v${expectedVersion} ready`);

0 commit comments

Comments
 (0)