From 7a08b10b3f43090674f44be66b40314f2e6cc837 Mon Sep 17 00:00:00 2001 From: eoinjordan Date: Tue, 24 Mar 2026 12:58:04 +0000 Subject: [PATCH 1/6] Add Windows offline installer workflow for linux CLI package --- .github/workflows/build-windows-installer.yml | 103 +++++++++++++++ windows-installer/.gitignore | 2 + windows-installer/installer.nsi | 125 ++++++++++++++++++ windows-installer/stage.ps1 | 106 +++++++++++++++ 4 files changed, 336 insertions(+) create mode 100644 .github/workflows/build-windows-installer.yml create mode 100644 windows-installer/.gitignore create mode 100644 windows-installer/installer.nsi create mode 100644 windows-installer/stage.ps1 diff --git a/.github/workflows/build-windows-installer.yml b/.github/workflows/build-windows-installer.yml new file mode 100644 index 00000000..365c92d3 --- /dev/null +++ b/.github/workflows/build-windows-installer.yml @@ -0,0 +1,103 @@ +name: Build Windows Linux-CLI Installer + +on: + workflow_dispatch: + inputs: + upload_release: + description: 'Upload as a GitHub Release (requires a version tag)' + type: boolean + default: false + push: + branches: + - windows-offline-installer + tags: + - 'linux-cli-v*' + +jobs: + build: + name: Build installer (${{ matrix.arch }}) + strategy: + fail-fast: false + matrix: + include: + - arch: x64 + runner: windows-latest + - arch: arm64 + runner: windows-11-arm + runs-on: ${{ matrix.runner }} + continue-on-error: ${{ matrix.arch == 'arm64' }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + architecture: ${{ matrix.arch }} + + - name: Install dependencies and compile TypeScript + shell: pwsh + run: | + npm ci + npm run build + + - name: Stage installer bundle + shell: pwsh + run: | + & windows-installer/stage.ps1 ` + -Arch "${{ matrix.arch }}" ` + -NodeVersion "22.15.1" + if ($LASTEXITCODE -gt 1) { exit $LASTEXITCODE } + exit 0 + + - name: Install NSIS + shell: pwsh + run: choco install nsis --no-progress -y + + - name: Build NSIS installer + shell: pwsh + run: | + $version = (Get-Content package.json | ConvertFrom-Json).version + Set-Location windows-installer + New-Item -ItemType Directory -Force output | Out-Null + + $makeNsis = $null + $candidates = @( + "$env:ChocolateyInstall\bin\makensis.exe", + "$env:ProgramData\chocolatey\bin\makensis.exe", + "$env:ProgramFiles\NSIS\makensis.exe", + "C:\Program Files (x86)\NSIS\makensis.exe" + ) + + foreach ($candidate in $candidates) { + if (Test-Path $candidate) { + $makeNsis = $candidate + break + } + } + + if (-not $makeNsis) { + $cmd = Get-Command makensis -ErrorAction SilentlyContinue + if ($cmd) { $makeNsis = $cmd.Source } + } + + if (-not $makeNsis) { + throw "makensis.exe not found after NSIS install" + } + + & $makeNsis /DARCH=${{ matrix.arch }} /DPRODUCT_VERSION=$version installer.nsi + + - name: Upload installer artifact + uses: actions/upload-artifact@v4 + with: + name: edge-impulse-linux-cli-windows-${{ matrix.arch }} + path: windows-installer/output/edge-impulse-linux-cli-windows-${{ matrix.arch }}-setup.exe + if-no-files-found: error + + - name: Upload to GitHub Release + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && inputs.upload_release) + uses: softprops/action-gh-release@v2 + with: + files: windows-installer/output/edge-impulse-linux-cli-windows-${{ matrix.arch }}-setup.exe + tag_name: ${{ github.ref_name }} diff --git a/windows-installer/.gitignore b/windows-installer/.gitignore new file mode 100644 index 00000000..15f8d9bf --- /dev/null +++ b/windows-installer/.gitignore @@ -0,0 +1,2 @@ +staging/ +output/ diff --git a/windows-installer/installer.nsi b/windows-installer/installer.nsi new file mode 100644 index 00000000..276b9611 --- /dev/null +++ b/windows-installer/installer.nsi @@ -0,0 +1,125 @@ +; Edge Impulse Linux CLI – Windows Installer + +Unicode true +SetCompressor /SOLID lzma + +!ifndef PRODUCT_VERSION + !define PRODUCT_VERSION "0.0.0" +!endif +!ifndef ARCH + !define ARCH "x64" +!endif + +!define PRODUCT_NAME "Edge Impulse Linux CLI" +!define PRODUCT_PUBLISHER "EdgeImpulse Inc." +!define PRODUCT_URL "https://edgeimpulse.com" +!define UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeImpulseLinuxCLI" +!define STAGING_DIR "staging" +!define OUTPUT_DIR "output" + +!include "MUI2.nsh" +!include "x64.nsh" +!include "WinMessages.nsh" +!include "FileFunc.nsh" + +!define MUI_ABORTWARNING + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "${STAGING_DIR}\LICENSE.txt" +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +!insertmacro MUI_LANGUAGE "English" + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +OutFile "${OUTPUT_DIR}\edge-impulse-linux-cli-windows-${ARCH}-setup.exe" +InstallDir "$PROGRAMFILES64\EdgeImpulse Linux CLI" +InstallDirRegKey HKLM "${UNINSTALL_KEY}" "InstallLocation" +RequestExecutionLevel admin +ShowInstDetails show +ShowUnInstDetails show + +VIProductVersion "${PRODUCT_VERSION}.0" +VIAddVersionKey "ProductName" "${PRODUCT_NAME}" +VIAddVersionKey "CompanyName" "${PRODUCT_PUBLISHER}" +VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}" +VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}" +VIAddVersionKey "FileDescription" "${PRODUCT_NAME} Installer" + +Section "Edge Impulse Linux CLI (required)" SecMain + SectionIn RO + + SetOutPath "$INSTDIR" + File "${STAGING_DIR}\node.exe" + File "${STAGING_DIR}\LICENSE.txt" + File "${STAGING_DIR}\package.json" + File /r "${STAGING_DIR}\build" + File /r "${STAGING_DIR}\node_modules" + + SetOutPath "$INSTDIR\bin" + File "${STAGING_DIR}\bin\edge-impulse-linux.cmd" + File "${STAGING_DIR}\bin\edge-impulse-linux-runner.cmd" + File "${STAGING_DIR}\bin\edge-impulse-camera-debug.cmd" + + FileOpen $R0 "$TEMP\_ei_addpath.ps1" w + FileWrite $R0 "$$binDir = '$INSTDIR\bin'$\r$\n" + FileWrite $R0 "$$key = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'$\r$\n" + FileWrite $R0 "$$cur = (Get-ItemProperty -Path $$key -Name Path).Path$\r$\n" + FileWrite $R0 "$$parts = $$cur -split ';' | Where-Object { $$_ -ne '' }$\r$\n" + FileWrite $R0 "if ($$parts -notcontains $$binDir) {$\r$\n" + FileWrite $R0 " Set-ItemProperty -Path $$key -Name Path -Value (($$parts + $$binDir) -join ';')$\r$\n" + FileWrite $R0 "}$\r$\n" + FileClose $R0 + + nsExec::ExecToLog "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File $\"$TEMP\_ei_addpath.ps1$\"" + Pop $R1 + Delete "$TEMP\_ei_addpath.ps1" + + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + WriteRegStr HKLM "${UNINSTALL_KEY}" "DisplayName" "${PRODUCT_NAME}" + WriteRegStr HKLM "${UNINSTALL_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr HKLM "${UNINSTALL_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" + WriteRegStr HKLM "${UNINSTALL_KEY}" "URLInfoAbout" "${PRODUCT_URL}" + WriteRegStr HKLM "${UNINSTALL_KEY}" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "${UNINSTALL_KEY}" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "${UNINSTALL_KEY}" "NoModify" 1 + WriteRegDWORD HKLM "${UNINSTALL_KEY}" "NoRepair" 1 + + ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 + IntFmt $0 "0x%08X" $0 + WriteRegDWORD HKLM "${UNINSTALL_KEY}" "EstimatedSize" "$0" + + WriteUninstaller "$INSTDIR\uninstall.exe" +SectionEnd + +Section "Uninstall" + FileOpen $R0 "$TEMP\_ei_rmpath.ps1" w + FileWrite $R0 "$$binDir = '$INSTDIR\bin'$\r$\n" + FileWrite $R0 "$$key = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'$\r$\n" + FileWrite $R0 "$$cur = (Get-ItemProperty -Path $$key -Name Path).Path$\r$\n" + FileWrite $R0 "$$parts = $$cur -split ';' | Where-Object { $$_ -ne '' -and $$_ -ne $$binDir }$\r$\n" + FileWrite $R0 "Set-ItemProperty -Path $$key -Name Path -Value ($$parts -join ';')$\r$\n" + FileClose $R0 + + nsExec::ExecToLog "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File $\"$TEMP\_ei_rmpath.ps1$\"" + Pop $R1 + Delete "$TEMP\_ei_rmpath.ps1" + + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + RMDir /r "$INSTDIR\build" + RMDir /r "$INSTDIR\node_modules" + RMDir /r "$INSTDIR\bin" + Delete "$INSTDIR\node.exe" + Delete "$INSTDIR\LICENSE.txt" + Delete "$INSTDIR\package.json" + Delete "$INSTDIR\uninstall.exe" + RMDir "$INSTDIR" + + DeleteRegKey HKLM "${UNINSTALL_KEY}" +SectionEnd diff --git a/windows-installer/stage.ps1 b/windows-installer/stage.ps1 new file mode 100644 index 00000000..402fb426 --- /dev/null +++ b/windows-installer/stage.ps1 @@ -0,0 +1,106 @@ +[CmdletBinding()] +param( + [Parameter(Mandatory)] + [ValidateSet('x64', 'arm64')] + [string]$Arch, + + [Parameter(Mandatory)] + [string]$NodeVersion +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$repoRoot = Resolve-Path "$PSScriptRoot\.." +$stagingDir = Join-Path $PSScriptRoot "staging" +$outputDir = Join-Path $PSScriptRoot "output" + +Write-Host "=========================================================" +Write-Host " Staging Edge Impulse Linux CLI Windows installer" +Write-Host " Arch : $Arch" +Write-Host " Node.js : $NodeVersion" +Write-Host " Staging dir: $stagingDir" +Write-Host "=========================================================" + +foreach ($dir in @($stagingDir, $outputDir, + "$stagingDir\bin", + "$stagingDir\build", + "$stagingDir\node_modules")) { + if (-not (Test-Path $dir)) { + New-Item -ItemType Directory -Path $dir | Out-Null + } +} + +$nodeZipName = "node-v${NodeVersion}-win-${Arch}.zip" +$nodeZipUrl = "https://nodejs.org/dist/v${NodeVersion}/${nodeZipName}" +$nodeZipPath = Join-Path $Env:TEMP $nodeZipName +$nodeExeDest = Join-Path $stagingDir "node.exe" + +if (-not (Test-Path $nodeExeDest)) { + Write-Host "`n--> Downloading $nodeZipUrl" + Invoke-WebRequest -Uri $nodeZipUrl -OutFile $nodeZipPath -UseBasicParsing + + Write-Host "--> Extracting node.exe" + $expandDir = Join-Path $Env:TEMP "node-expand-$Arch" + Expand-Archive -Path $nodeZipPath -DestinationPath $expandDir -Force + + $extractedExe = Get-ChildItem -Path $expandDir -Filter "node.exe" -Recurse | Select-Object -First 1 + if (-not $extractedExe) { + throw "node.exe not found in Node.js archive" + } + Copy-Item -Path $extractedExe.FullName -Destination $nodeExeDest -Force + + Remove-Item $nodeZipPath -Force -ErrorAction SilentlyContinue + Remove-Item $expandDir -Recurse -Force -ErrorAction SilentlyContinue +} + +Write-Host "`n--> Copying build/" +$buildSrc = Join-Path $repoRoot "build" +if (-not (Test-Path $buildSrc)) { throw "build/ not found. Run npm run build first." } +robocopy $buildSrc "$stagingDir\build" /E /NFL /NDL /NJH /NJS | Out-Null +if ($LASTEXITCODE -gt 7) { throw "robocopy build failed with exit code $LASTEXITCODE" } + +Write-Host "--> Copying node_modules/" +$nmSrc = Join-Path $repoRoot "node_modules" +if (-not (Test-Path $nmSrc)) { throw "node_modules/ not found. Run npm ci first." } +robocopy $nmSrc "$stagingDir\node_modules" /E /NFL /NDL /NJH /NJS | Out-Null +if ($LASTEXITCODE -gt 7) { throw "robocopy node_modules failed with exit code $LASTEXITCODE" } + +Write-Host "`n--> Writing .cmd shims" +$binEntries = @{ + 'edge-impulse-linux' = 'build\cli\linux\linux.js' + 'edge-impulse-linux-runner' = 'build\cli\linux\runner.js' + 'edge-impulse-camera-debug' = 'build\cli\linux\camera-debug.js' +} +foreach ($name in $binEntries.Keys) { + $jsPath = $binEntries[$name] + $cmdPath = Join-Path "$stagingDir\bin" "${name}.cmd" + $content = @" +@echo off +"%~dp0..\node.exe" "%~dp0..\$jsPath" %* +"@ + Set-Content -Path $cmdPath -Value $content -Encoding ASCII + Write-Host " $name.cmd" +} + +Write-Host "`n--> Copying LICENSE" +$licenseSrc = Join-Path $repoRoot "LICENSE.3-clause-bsd-clear" +if (Test-Path $licenseSrc) { + Copy-Item -Path $licenseSrc -Destination "$stagingDir\LICENSE.txt" -Force +} +else { + Set-Content -Path "$stagingDir\LICENSE.txt" -Value "BSD-3-Clause-Clear" -Encoding UTF8 +} + +Write-Host "--> Copying package.json" +$packageJsonSrc = Join-Path $repoRoot "package.json" +if (-not (Test-Path $packageJsonSrc)) { throw "package.json not found at $packageJsonSrc" } +Copy-Item -Path $packageJsonSrc -Destination "$stagingDir\package.json" -Force + +Write-Host "`n=========================================================" +Write-Host " Staging complete." +Write-Host " Files in $stagingDir :" +Get-ChildItem $stagingDir | Format-Table Name, Length -AutoSize +Write-Host "=========================================================" + +exit 0 From dad1d8bcf903b66ec7c010e283579f8d26abbc70 Mon Sep 17 00:00:00 2001 From: eoinjordan Date: Tue, 24 Mar 2026 13:00:20 +0000 Subject: [PATCH 2/6] Document Windows offline installer for locked-down environments --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index 68f70e02..378a1eb7 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,42 @@ Add the library to your application via: $ npm install edge-impulse-linux ``` +## Windows offline installer (for locked-down environments) + +For corporate-managed Windows devices where `npm install` is blocked (TLS interception, no build tools, restricted package access), this repo also supports a prebuilt Windows installer artifact via GitHub Actions. + +### What this installer includes + +* Bundled `node.exe` runtime (no separate Node.js install required) +* Prebuilt `node_modules` from CI (no local `node-gyp` / Python toolchain required) +* Installed CLI shims in PATH: + * `edge-impulse-linux` + * `edge-impulse-linux-runner` + * `edge-impulse-camera-debug` + +### End-user requirements + +* Windows 10/11 (`x64` or `arm64` artifact) +* Administrator rights to install (writes to `Program Files` and system PATH) +* No WSL required for installation + +### Important runtime note + +This is still the Linux CLI package, packaged for Windows installation. Some commands or hardware flows that depend on Linux-specific behavior or drivers may still require Linux/WSL at runtime. + +### Build and download installer artifacts + +Use the workflow in this repository: + +* **Actions** → **Build Windows Linux-CLI Installer** + +Artifacts produced: + +* `edge-impulse-linux-cli-windows-x64` +* `edge-impulse-linux-cli-windows-arm64` + +Each artifact zip contains a `.exe` installer. + ## Collecting data Before you can classify data you'll first need to collect it. If you want to collect data from the camera or microphone on your system you can use the Edge Impulse CLI, and if you want to collect data from different sensors (like accelerometers or proprietary control systems) you can do so in a few lines of code. From a49e36ae62798cd3f64b7de2f419bbafc7e3cd22 Mon Sep 17 00:00:00 2001 From: eoinjordan Date: Tue, 24 Mar 2026 13:18:55 +0000 Subject: [PATCH 3/6] Partial alignment: add installer branding pipeline parity --- .github/workflows/build-windows-installer.yml | 8 ++++ windows-installer/.gitignore | 1 + windows-installer/installer.nsi | 6 +++ windows-installer/prepare-branding.ps1 | 45 +++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 windows-installer/prepare-branding.ps1 diff --git a/.github/workflows/build-windows-installer.yml b/.github/workflows/build-windows-installer.yml index 365c92d3..96ce3432 100644 --- a/.github/workflows/build-windows-installer.yml +++ b/.github/workflows/build-windows-installer.yml @@ -55,6 +55,14 @@ jobs: shell: pwsh run: choco install nsis --no-progress -y + - name: Install ImageMagick + shell: pwsh + run: choco install imagemagick --no-progress -y + + - name: Generate installer branding assets + shell: pwsh + run: windows-installer/prepare-branding.ps1 + - name: Build NSIS installer shell: pwsh run: | diff --git a/windows-installer/.gitignore b/windows-installer/.gitignore index 15f8d9bf..fa77c50a 100644 --- a/windows-installer/.gitignore +++ b/windows-installer/.gitignore @@ -1,2 +1,3 @@ staging/ output/ +branding/ diff --git a/windows-installer/installer.nsi b/windows-installer/installer.nsi index 276b9611..538ac297 100644 --- a/windows-installer/installer.nsi +++ b/windows-installer/installer.nsi @@ -16,6 +16,8 @@ SetCompressor /SOLID lzma !define UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeImpulseLinuxCLI" !define STAGING_DIR "staging" !define OUTPUT_DIR "output" +!define BRAND_HEADER_BMP "branding\header.bmp" +!define BRAND_WELCOME_BMP "branding\welcome.bmp" !include "MUI2.nsh" !include "x64.nsh" @@ -23,6 +25,10 @@ SetCompressor /SOLID lzma !include "FileFunc.nsh" !define MUI_ABORTWARNING +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_RIGHT +!define MUI_HEADERIMAGE_BITMAP "${BRAND_HEADER_BMP}" +!define MUI_WELCOMEFINISHPAGE_BITMAP "${BRAND_WELCOME_BMP}" !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "${STAGING_DIR}\LICENSE.txt" diff --git a/windows-installer/prepare-branding.ps1 b/windows-installer/prepare-branding.ps1 new file mode 100644 index 00000000..d059fead --- /dev/null +++ b/windows-installer/prepare-branding.ps1 @@ -0,0 +1,45 @@ +[CmdletBinding()] +param() + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$repoRoot = Resolve-Path "$PSScriptRoot\.." +$sourceImage = Join-Path $repoRoot "img\linux-collection.png" +$brandingDir = Join-Path $PSScriptRoot "branding" +$headerBmp = Join-Path $brandingDir "header.bmp" +$welcomeBmp = Join-Path $brandingDir "welcome.bmp" + +if (-not (Test-Path $sourceImage)) { + throw "Branding source image not found: $sourceImage" +} + +New-Item -ItemType Directory -Force -Path $brandingDir | Out-Null + +$magick = Get-Command magick -ErrorAction SilentlyContinue +if (-not $magick) { + throw "ImageMagick (magick) is required to generate NSIS branding bitmaps" +} + +Write-Host "Generating NSIS branding bitmaps from $sourceImage" + +# NSIS header image: 150x57 +& $magick.Source "$sourceImage" ` + -background white -gravity center ` + -resize 150x57 ` + -extent 150x57 ` + BMP3:"$headerBmp" + +# NSIS welcome/finish side image: 164x314 +& $magick.Source "$sourceImage" ` + -background white -gravity center ` + -resize 164x314 ` + -extent 164x314 ` + BMP3:"$welcomeBmp" + +if (-not (Test-Path $headerBmp) -or -not (Test-Path $welcomeBmp)) { + throw "Failed to generate branding assets" +} + +Write-Host "Branding assets generated:" +Get-ChildItem $brandingDir | Format-Table Name, Length -AutoSize From f6f0a6f9c1f3be09808865f476f2ca64558ac046 Mon Sep 17 00:00:00 2001 From: eoinjordan Date: Tue, 24 Mar 2026 13:20:04 +0000 Subject: [PATCH 4/6] Docs: recommend WSL install for full Windows runtime support --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 378a1eb7..8614e9dc 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,18 @@ For corporate-managed Windows devices where `npm install` is blocked (TLS interc * Windows 10/11 (`x64` or `arm64` artifact) * Administrator rights to install (writes to `Program Files` and system PATH) -* No WSL required for installation +* WSL is not required for installation, but recommended for full Linux CLI behavior ### Important runtime note This is still the Linux CLI package, packaged for Windows installation. Some commands or hardware flows that depend on Linux-specific behavior or drivers may still require Linux/WSL at runtime. +For full functionality, install WSL first from an elevated Command Prompt: + +``` +wsl --install +``` + ### Build and download installer artifacts Use the workflow in this repository: From 0d4019230e94822a5b6f1538b91ac60c2bc5ee78 Mon Sep 17 00:00:00 2001 From: eoinjordan Date: Fri, 8 May 2026 11:06:33 +0100 Subject: [PATCH 5/6] ci: pre-commit branding BMPs, remove broken ImageMagick CI steps Chocolatey ImageMagick on Windows runners lacks PNG codec delegates, causing prepare-branding.ps1 to fail with: magick.exe: no decode delegate for this image format Fix: generate header.bmp (150x57) and welcome.bmp (164x314) on macOS using Homebrew ImageMagick from img/linux-collection.png, commit them to the repo, and remove the Install ImageMagick and Generate installer branding assets CI steps entirely. BMPs will be regenerated locally when the source image changes. --- .github/workflows/build-windows-installer.yml | 8 -------- windows-installer/.gitignore | 3 ++- windows-installer/branding/header.bmp | Bin 0 -> 25818 bytes windows-installer/branding/welcome.bmp | Bin 0 -> 154542 bytes 4 files changed, 2 insertions(+), 9 deletions(-) create mode 100644 windows-installer/branding/header.bmp create mode 100644 windows-installer/branding/welcome.bmp diff --git a/.github/workflows/build-windows-installer.yml b/.github/workflows/build-windows-installer.yml index 96ce3432..365c92d3 100644 --- a/.github/workflows/build-windows-installer.yml +++ b/.github/workflows/build-windows-installer.yml @@ -55,14 +55,6 @@ jobs: shell: pwsh run: choco install nsis --no-progress -y - - name: Install ImageMagick - shell: pwsh - run: choco install imagemagick --no-progress -y - - - name: Generate installer branding assets - shell: pwsh - run: windows-installer/prepare-branding.ps1 - - name: Build NSIS installer shell: pwsh run: | diff --git a/windows-installer/.gitignore b/windows-installer/.gitignore index fa77c50a..7d309a94 100644 --- a/windows-installer/.gitignore +++ b/windows-installer/.gitignore @@ -1,3 +1,4 @@ staging/ output/ -branding/ +# Only ignore generated sub-folder; header.bmp / welcome.bmp are pre-built and committed. +branding/generated/ diff --git a/windows-installer/branding/header.bmp b/windows-installer/branding/header.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4582fcabc61812b52dabe5b1d352032571f9fc93 GIT binary patch literal 25818 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 literal 0 HcmV?d00001 diff --git a/windows-installer/branding/welcome.bmp b/windows-installer/branding/welcome.bmp new file mode 100644 index 0000000000000000000000000000000000000000..614568c5ad9e5ad417b792eecb02d88e594df434 GIT binary patch literal 154542 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

d` z+F)`P?CSC8$3b{opGqucuT^*6t{cLJ)lZH={HpO_j77**nrW<=SuqxWz4wE#E9 zK-MwAe1Yq5!-=WEVOI&z+}2nFtrlEc3)6r*dDzzk*Zl)6WBy8*w{S(;Ld5VG#KNs4 zYjHg$wx5xF{hatU#BliDAbdRosxp2Dsc>OjZ$J{>V8$5YdQ5CTeQh=`zZT%e7y{fF16lKt zTr!5oAQo=Le8u*&%sLEuL29!n@#}eQK!Wm2vge8k-NNnD$8Z5|j3MSLwvja-#wBC; zpNX|3Xm~iU{(A9Z_*47!Z@%!vKSTvk0aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`0 z0aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti` z6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5 zPyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK0 z02M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~ z1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||% zQ~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4L dKm||%Q~(t~1yBK002M$5Pyti`6?nE3`2U^r<4FJj literal 0 HcmV?d00001 From e15d2a152f06eb97b1c4eaa953e9968c239f133c Mon Sep 17 00:00:00 2001 From: eoinjordan Date: Fri, 8 May 2026 13:59:28 +0100 Subject: [PATCH 6/6] installer: fix branding BMPs to use Edge Impulse logo instead of project graph image The previous header.bmp and welcome.bmp were generated from img/linux-collection.png which is a raw sensor data graph screenshot, not the Edge Impulse brand logo. Regenerate from studio/public/themes/default/png/logo.png (same source as the serial-daemon installer). Also update prepare-branding.ps1 to look for img/edge-impulse-logo.png first, falling back to the monorepo logo path. --- windows-installer/branding/header.bmp | Bin 25818 -> 25818 bytes windows-installer/branding/welcome.bmp | Bin 154542 -> 154542 bytes windows-installer/prepare-branding.ps1 | 6 +++++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/windows-installer/branding/header.bmp b/windows-installer/branding/header.bmp index 4582fcabc61812b52dabe5b1d352032571f9fc93..d474802f7ccc7a4e85317dafa8104edbf0337202 100644 GIT binary patch literal 25818 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 diff --git a/windows-installer/branding/welcome.bmp b/windows-installer/branding/welcome.bmp index 614568c5ad9e5ad417b792eecb02d88e594df434..f3122da4bfe4c59599d6f1663238800c0b374c8e 100644 GIT binary patch literal 154542 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 literal 154542 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

d` z+F)`P?CSC8$3b{opGqucuT^*6t{cLJ)lZH={HpO_j77**nrW<=SuqxWz4wE#E9 zK-MwAe1Yq5!-=WEVOI&z+}2nFtrlEc3)6r*dDzzk*Zl)6WBy8*w{S(;Ld5VG#KNs4 zYjHg$wx5xF{hatU#BliDAbdRosxp2Dsc>OjZ$J{>V8$5YdQ5CTeQh=`zZT%e7y{fF16lKt zTr!5oAQo=Le8u*&%sLEuL29!n@#}eQK!Wm2vge8k-NNnD$8Z5|j3MSLwvja-#wBC; zpNX|3Xm~iU{(A9Z_*47!Z@%!vKSTvk0aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`0 z0aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti` z6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5 zPyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK0 z02M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~ z1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4LKm||% zQ~(t~1yBK002M$5Pyti`6+i`00aO4LKm||%Q~(t~1yBK002M$5Pyti`6+i`00aO4L dKm||%Q~(t~1yBK002M$5Pyti`6?nE3`2U^r<4FJj diff --git a/windows-installer/prepare-branding.ps1 b/windows-installer/prepare-branding.ps1 index d059fead..5bebfed7 100644 --- a/windows-installer/prepare-branding.ps1 +++ b/windows-installer/prepare-branding.ps1 @@ -5,7 +5,11 @@ Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $repoRoot = Resolve-Path "$PSScriptRoot\.." -$sourceImage = Join-Path $repoRoot "img\linux-collection.png" +$sourceImage = Join-Path $repoRoot "img\edge-impulse-logo.png" +# Fall back to the monorepo logo if running from within the edgeimpulse monorepo checkout +if (-not (Test-Path $sourceImage)) { + $sourceImage = Join-Path $repoRoot "studio\public\themes\default\png\logo.png" +} $brandingDir = Join-Path $PSScriptRoot "branding" $headerBmp = Join-Path $brandingDir "header.bmp" $welcomeBmp = Join-Path $brandingDir "welcome.bmp"