# AyaNova v8 release build How a full release is built: tools, folder layout, what `build-release.bat` does, and where version numbers live. Written for .NET 8 (8.2.4); updated for .NET 10 (8.3.0). Releases are built on the workstation; the backup laptop is the fallback. To set up a machine that can run this from scratch, use the tool list and install commands in `DEV-VM-SETUP.md` (the VM itself is deprecated). **Backup laptop: still to bring in line with the workstation** (John's notes, 2026-10-23): - [ ] Install the .NET 10 SDK: `winget install --id Microsoft.DotNet.SDK.10 -e --source winget` (the .NET 8 SDK is no longer needed) - [ ] Replace KeePass and KeeAgent with KeePassXC - [ ] Install rclone and configure the S3 remote - [ ] Copy over the backup batch files - [ ] Uninstall FileZilla - [ ] Fix up TortoiseGit and Git SSH so both work ## What gets built | Project | Framework | Output | |---|---|---| | AyaNova server (`raven/server/AyaNova`) | .NET 10 | Five packages, below | | Launcher (`raven-launcher`) | .NET 10, self-contained, `PublishTrimmed` | Inside the Windows standalone installer | | QBI (`ravenqbi/AyaNovaQBI`) | .NET Framework 4.8 | `ayanova-qbi-setup.exe`, built separately | | Package | Build | |---|---| | `ayanova-subscription-linux-x64-server.zip` | linux-x64, framework-dependent, `SUBSCRIPTION_BUILD=true`, server `config.json` | | `ayanova-linux-x64-server.zip` | linux-x64, framework-dependent, server `config.json` | | `ayanova-linux-x64-desktop.zip` | Same build, desktop `config.json` | | `ayanova-windows-x64-single-setup.exe` | win-x64 self-contained server, launcher, embedded PostgreSQL | | `ayanova-windows-x64-lan-setup.exe` | win-x64 framework-dependent server | ## Tools | Tool | Version | Used for | |---|---|---| | .NET SDK | 10.0.x | Server and launcher | | Node.js | **12.22.9 exactly** | Front end. Newer versions break `fibers` | | Python | 3.11 | MkDocs | | MkDocs + mkdocs-material | current | Customer manual (`pip install mkdocs mkdocs-material`) | | Inno Setup | 6.x | Windows installers | | 7-Zip | current | Linux zips | | Visual Studio | 18 (2026) Community on the dev machine; no VS 2022 installed | QBI only | The scripts hardcode these paths: - `C:\data\code\raven\`, `C:\data\code\raven-client\ayanova\`, `C:\data\code\raven-launcher\`, `C:\data\code\ravenqbi\` - `C:\Program Files\7-Zip\7z.exe` - `C:\Program Files (x86)\Inno Setup 6\ISCC.exe` ## Folder layout ``` C:\data\code\ ├── raven\ │ ├── build-release.bat master build script │ ├── raven.sln │ ├── server\AyaNova\ AyaNova.csproj, wwwroot\ (generated), resource\ │ ├── docs\8.0\ayanova\ customer manual, mkdocs.yml │ ├── docs\8.0\customer\ customer portal docs, mkdocs.yml │ ├── devdocs\ developer docs (this file) │ ├── dist\ │ │ ├── assets\ LICENSE, license.rtf, logo.ico, lan-install-config.json, │ │ │ linux-server\config.json, linux-desktop\config.json │ │ ├── install\windows\x64\ standalone.iss, lan.iss │ │ ├── win-x64\postgres-standalone\ embedded PostgreSQL (maintained by hand) │ │ └── installers\ final packages (generated) │ │ (also generated: linux-x64\, subscription-build-linux-x64\, win-x64\ayanova\..., win-x64\launcher\) │ └── graphics\ ├── raven-client\ayanova\ Vue front end ├── raven-launcher\ raven-launcher.csproj, config.json └── ravenqbi\ AyaNovaQBI\AyaNovaQBI.csproj, install\qbi.iss ``` ## `build-release.bat`, step by step 1. **Clean** `raven\server\AyaNova\wwwroot` and `raven\dist\installers`. 2. **Customer manual**: `mkdocs build` in `docs\8.0\ayanova` and `docs\8.0\customer`. Output goes straight to `wwwroot\docs` (`site_dir` in `mkdocs.yml`). 3. **Front end**: `npm run build` in `raven-client\ayanova`, then `xcopy dist\* ...\raven\server\AyaNova\wwwroot\ /e`. The .NET build does not produce `wwwroot`: whatever is there is what ships. 4. **Subscription Linux**: ```bat dotnet publish --property:PublishDir=C:\data\code\raven\dist\subscription-build-linux-x64\ -c Release -r linux-x64 --no-self-contained -p:SUBSCRIPTION_BUILD=true ``` Zipped with `assets\linux-server\config.json`. 5. **Perpetual Linux**: the same with `-p:SUBSCRIPTION_BUILD=false` into `dist\linux-x64\`. One build, two zips: desktop and server `config.json`. 6. **Windows standalone**: `-r win-x64 --self-contained` into `dist\win-x64\ayanova\standalone\` (includes the .NET runtime, about 150 MB more). 7. **Windows framework-dependent**: `-r win-x64 --no-self-contained` into `dist\win-x64\ayanova\framework-dependent\`. Needs the .NET runtime on the target. 8. **Launcher**: `dotnet publish -c Release -r win-x64 --self-contained` in `raven-launcher` into `dist\win-x64\launcher\`. 9. **Installers**: `ISCC.exe standalone.iss` and `ISCC.exe lan.iss`. `raven-client\ayanova\buildrelease.bat` runs steps 1–3 alone (main manual only, not the customer portal docs). ### Windows installers - **Standalone** (`standalone.iss`): self-contained server, launcher, embedded PostgreSQL, empty database template, desktop shortcut to the launcher. App in `{autopf}\ayanova`; data in `{commonappdata}\ayanova\database`; logs in `{commonappdata}\ayanova\logs`. The launcher starts PostgreSQL, starts the server, opens the browser at the login page and waits. - **LAN** (`lan.iss`): framework-dependent server plus network config. No PostgreSQL. Prompts the user to download the ASP.NET Core Hosting Bundle and PostgreSQL. ### QBI (separate) ```bat cd C:\data\code\ravenqbi\AyaNovaQBI msbuild /p:Configuration=Release cd C:\data\code\ravenqbi\install "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" qbi.iss ``` Output: `ravenqbi\install\output\ayanova-qbi-setup.exe`. Has a pre-build event that runs a timestamp utility. ## Version numbers Set in five places for every release: | File | Setting | At 8.2.4 | |---|---|---| | `raven\server\AyaNova\AyaNova.csproj` | `` | 8.2.4 | | `raven\dist\install\windows\x64\standalone.iss` | `#define MyAppVersion` | 8.2.4 | | `raven\dist\install\windows\x64\lan.iss` | `#define MyAppVersion` | 8.2.4 | | `raven-client\ayanova\package.json` | `"version"` | 8.2.4 | | `ravenqbi\install\qbi.iss` | `#define MyAppVersion` | 8.0.2 (own cycle) | ## Front-end build notes - Install dependencies with `npm ci`, never `npm install`: it installs the exact versions in `package-lock.json`. - Warnings that appear on every build and are harmless: Browserslist "caniuse-lite is outdated"; Dart Sass "Using / for division is deprecated" (from Vuetify); asset size warnings (Monaco's `ts.worker.js` is about 4.5 MB). - Webpack content-hash file names change on every build even when contents do not. Compare file contents, not names. ## Docker builds `raven-client\ayanova\Dockerfile.frontend` and `raven\Dockerfile.docs` build the front end and the manual in containers. A runtime image and compose file for the Linux server are in `raven\dist\docker\linux-x64\`. The Linux server packages and the Windows framework-dependent build could also build in Docker. Windows self-contained builds, Inno Setup, QBI and the embedded PostgreSQL need Windows. ## Troubleshooting - **`fibers` fails to install**: it needs Python, Visual Studio Build Tools, and Node exactly 12.22.9. Last resort: remove `"fibers"` from `package.json` and the `fiber: require("fibers")` line from `webpack.config.js`; the build still works, a little slower. - **Node version errors**: `node -v` must print `v12.22.9`. - **"Module not found"**: delete `node_modules`, then `npm ci`. - **PuppeteerSharp cannot download the browser**: check connectivity, or point the server at an installed browser through its browser-path setting. - **`SUBSCRIPTION_BUILD` not applied**: the flag is `-p:SUBSCRIPTION_BUILD=true` on `dotnet publish`. - **Inno Setup errors**: an earlier step failed, or 7-Zip / Inno Setup are not at the expected paths.