Skip to content

Commit 8076656

Browse files
Update to the app, fix the selection of files, fcs import
1 parent e0acea8 commit 8076656

18 files changed

Lines changed: 615 additions & 162 deletions

‎.github/workflows/build-windows.yml‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ jobs:
110110
111111
# ── CRAN packages ─────────────────────────────────────────────────────
112112
pak::pak(c(
113-
"shiny", "shinydashboard", "shinyFiles", "shinyjs",
113+
"shiny", "shinydashboard", "shinyjs",
114114
"shinycssloaders", "DT", "plotly", "ggplot2", "dplyr",
115115
"tidyr", "colourpicker", "rhandsontable", "openxlsx",
116116
"umap", "Rtsne", "MASS", "fields", "zip", "jsonlite"
@@ -193,6 +193,13 @@ jobs:
193193
env:
194194
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
195195

196+
# ── 8b. Verify packaged payload ─────────────────────────────────────────
197+
# Runs BEFORE artifact upload / release so a broken installer (missing
198+
# R-Portable, CytoExploreR, shiny, or app files) can never be published.
199+
- name: Verify packaged payload
200+
shell: pwsh
201+
run: ./build/verify-package.ps1 -UnpackedDir "dist/win-unpacked"
202+
196203
# ── 9. Show output ───────────────────────────────────────────────────────
197204
- name: List build output
198205
shell: pwsh

‎.gitignore‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# ── Internal / dev-only docs (kept locally, not for the public repo) ──────────
2+
AUDIT_REPORT.md
3+
BUILDING.md
4+
5+
# ── Build outputs & dependencies ─────────────────────────────────────────────
6+
node_modules/
7+
dist/
8+
9+
# ── Bundled R runtime (≈1 GB, produced by the build, never committed) ─────────
10+
R-Portable/
11+
12+
# ── Logs ─────────────────────────────────────────────────────────────────────
13+
*.log
14+
logs/
15+
install_log.txt
16+
17+
# ── OS / editor cruft ────────────────────────────────────────────────────────
18+
Thumbs.db
19+
desktop.ini
20+
.DS_Store
21+
.vscode/
22+
.idea/

‎build/build.bat‎

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,60 @@ for /f "tokens=*" %%v in ('npm --version') do set NPM_VER=%%v
4343
echo npm: %NPM_VER%
4444
echo.
4545

46-
:: Check R-Portable is present before building
47-
if not exist "%ROOT_DIR%\R-Portable" (
48-
echo WARNING: R-Portable folder not found at:
49-
echo %ROOT_DIR%\R-Portable
46+
:: ------------------------------------------------------------
47+
:: HARD GATE: refuse to build without a complete R-Portable.
48+
:: Shipping an installer with a missing/empty R-Portable produces
49+
:: the "R Portable Not Found" failure at launch, so abort instead
50+
:: of offering to "continue anyway".
51+
:: ------------------------------------------------------------
52+
if not exist "%ROOT_DIR%\R-Portable\bin\Rscript.exe" (
53+
echo ERROR: R-Portable is missing or incomplete.
54+
echo Expected: %ROOT_DIR%\R-Portable\bin\Rscript.exe
5055
echo.
51-
echo The installer will be built without R-Portable.
52-
echo Users will need to run install.bat after installation.
56+
goto :r_portable_missing
57+
)
58+
59+
:: A bare R install with no packages would pass the check above but still
60+
:: produce a broken app at runtime. Require a real package marker.
61+
if not exist "%ROOT_DIR%\R-Portable\library\CytoExploreR" (
62+
echo ERROR: R-Portable has R but no packages installed.
63+
echo Expected: %ROOT_DIR%\R-Portable\library\CytoExploreR
5364
echo.
54-
set /p "CONTINUE=Continue build anyway? (Y/N): "
55-
if /i not "!CONTINUE!"=="Y" (
56-
echo Build cancelled.
57-
pause
58-
exit /b 0
59-
)
65+
goto :r_portable_missing
6066
)
6167

68+
goto :r_portable_ok
69+
70+
:r_portable_missing
71+
echo StreamFLOW cannot be built without a complete bundled R runtime.
72+
echo.
73+
echo Produce a working installer one of these two ways:
74+
echo.
75+
echo 1) RECOMMENDED - run the CI workflow
76+
echo .github\workflows\build-windows.yml builds R-Portable
77+
echo (R 4.4 + Bioconductor 3.19 + CytoExploreR) and a full
78+
echo installer automatically. Push to the build branch or run
79+
echo the "Build Windows" workflow via GitHub Actions.
80+
echo.
81+
echo 2) Populate R-Portable locally, then re-run this script:
82+
echo - Install R 4.4.x.
83+
echo - Run scripts\install_packages.R against it with
84+
echo R_LIBS_USER pointed at "%ROOT_DIR%\R-Portable\library":
85+
echo set "R_LIBS_USER=%ROOT_DIR%\R-Portable\library"
86+
echo Rscript scripts\install_packages.R
87+
echo - Copy the R 4.4 installation into "%ROOT_DIR%\R-Portable"
88+
echo so that R-Portable\bin\Rscript.exe exists.
89+
echo - Confirm BOTH of these exist before re-running:
90+
echo R-Portable\bin\Rscript.exe
91+
echo R-Portable\library\CytoExploreR
92+
echo.
93+
pause
94+
exit /b 1
95+
96+
:r_portable_ok
97+
echo R-Portable verified (Rscript.exe + CytoExploreR present).
98+
echo.
99+
62100
:: Step 1: Install npm dependencies
63101
echo [1/3] Installing npm dependencies...
64102
echo.
@@ -117,7 +155,22 @@ if %ERRORLEVEL% NEQ 0 (
117155
exit /b 1
118156
)
119157

120-
:: Step 4: Report output
158+
:: Step 4: Verify the packaged payload before declaring success.
159+
:: This catches a broken installer (missing R-Portable, shiny, or app
160+
:: files) no matter how the build was invoked.
161+
echo.
162+
echo Verifying packaged payload...
163+
powershell -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%verify-package.ps1"
164+
if %ERRORLEVEL% NEQ 0 (
165+
echo.
166+
echo ERROR: package verification failed. See the missing items listed above.
167+
echo The installer in dist\ is incomplete and must NOT be distributed.
168+
pause
169+
exit /b 1
170+
)
171+
echo.
172+
173+
:: Step 5: Report output
121174
echo.
122175
echo [3/3] Build complete!
123176
echo.

‎build/verify-package.ps1‎

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<#
2+
.SYNOPSIS
3+
Post-package safety net for StreamFLOW.
4+
5+
.DESCRIPTION
6+
Inspects electron-builder's unpacked output (dist/win-unpacked by default,
7+
produced before NSIS compression) and asserts that everything the app needs
8+
at runtime is actually present. If anything is missing it lists exactly what
9+
and exits non-zero, so a broken installer can never reach dist/ or be
10+
published by CI.
11+
12+
This is the last line of defence against the "R Portable Not Found" class of
13+
bug regardless of how the build was invoked.
14+
15+
.PARAMETER UnpackedDir
16+
Path to electron-builder's win-unpacked directory. Defaults to
17+
<repo>/dist/win-unpacked relative to this script.
18+
#>
19+
[CmdletBinding()]
20+
param(
21+
[string]$UnpackedDir
22+
)
23+
24+
$ErrorActionPreference = 'Stop'
25+
26+
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
27+
$rootDir = Split-Path -Parent $scriptDir
28+
29+
if (-not $UnpackedDir -or $UnpackedDir.Trim() -eq '') {
30+
$UnpackedDir = Join-Path $rootDir 'dist\win-unpacked'
31+
}
32+
33+
Write-Host ''
34+
Write-Host '== StreamFLOW package verification ==' -ForegroundColor Cyan
35+
Write-Host "Inspecting: $UnpackedDir"
36+
Write-Host ''
37+
38+
$missing = New-Object System.Collections.Generic.List[string]
39+
40+
function Require-File {
41+
param([string]$RelPath, [string]$Label)
42+
$full = Join-Path $UnpackedDir $RelPath
43+
if (Test-Path -LiteralPath $full -PathType Leaf) {
44+
Write-Host " [OK] $Label" -ForegroundColor Green
45+
} else {
46+
Write-Host " [MISSING] $Label" -ForegroundColor Red
47+
$script:missing.Add("$Label -> $RelPath")
48+
}
49+
}
50+
51+
function Require-NonEmptyDir {
52+
param([string]$RelPath, [string]$Label)
53+
$full = Join-Path $UnpackedDir $RelPath
54+
if ((Test-Path -LiteralPath $full -PathType Container) -and
55+
(Get-ChildItem -LiteralPath $full -Force | Select-Object -First 1)) {
56+
Write-Host " [OK] $Label" -ForegroundColor Green
57+
} else {
58+
Write-Host " [MISSING] $Label (directory absent or empty)" -ForegroundColor Red
59+
$script:missing.Add("$Label -> $RelPath")
60+
}
61+
}
62+
63+
if (-not (Test-Path -LiteralPath $UnpackedDir -PathType Container)) {
64+
Write-Host "FATAL: unpacked directory not found: $UnpackedDir" -ForegroundColor Red
65+
Write-Host 'Did electron-builder run? Expected dist\win-unpacked to exist.' -ForegroundColor Red
66+
exit 1
67+
}
68+
69+
# --- Bundled R runtime (extraResources -> resources/) ---
70+
Require-File 'resources\R-Portable\bin\Rscript.exe' 'R-Portable Rscript.exe'
71+
Require-NonEmptyDir 'resources\R-Portable\library\CytoExploreR' 'R-Portable CytoExploreR library'
72+
73+
# --- Shiny app (extraResources -> resources/) ---
74+
Require-File 'resources\shiny\app.R' 'Shiny app.R'
75+
76+
# --- Packaged Electron app (asar by default, or unpacked app/ dir) ---
77+
$asar = Join-Path $UnpackedDir 'resources\app.asar'
78+
$appMainDir = Join-Path $UnpackedDir 'resources\app\electron'
79+
if (Test-Path -LiteralPath $asar -PathType Leaf) {
80+
Write-Host ' [OK] Electron app (resources\app.asar)' -ForegroundColor Green
81+
# Best-effort: confirm the three entry files live inside the asar.
82+
$asarCli = Join-Path $rootDir 'node_modules\.bin\asar.cmd'
83+
if (Test-Path -LiteralPath $asarCli -PathType Leaf) {
84+
try {
85+
$listing = & $asarCli list $asar 2>$null
86+
foreach ($entry in @('/electron/main.js', '/electron/preload.js', '/electron/splash.html')) {
87+
if ($listing -contains $entry) {
88+
Write-Host " [OK] asar:$entry" -ForegroundColor Green
89+
} else {
90+
Write-Host " [MISSING] asar:$entry" -ForegroundColor Red
91+
$missing.Add("asar entry $entry")
92+
}
93+
}
94+
} catch {
95+
Write-Host ' [WARN] could not list app.asar contents; skipping inner check' -ForegroundColor Yellow
96+
}
97+
}
98+
} elseif (Test-Path -LiteralPath $appMainDir -PathType Container) {
99+
Require-File 'resources\app\electron\main.js' 'electron/main.js'
100+
Require-File 'resources\app\electron\preload.js' 'electron/preload.js'
101+
Require-File 'resources\app\electron\splash.html' 'electron/splash.html'
102+
} else {
103+
Write-Host ' [MISSING] Electron app (neither resources\app.asar nor resources\app\electron found)' -ForegroundColor Red
104+
$missing.Add('Electron app payload (app.asar or app/electron)')
105+
}
106+
107+
Write-Host ''
108+
if ($missing.Count -gt 0) {
109+
Write-Host 'VERIFICATION FAILED. The following are missing from the build:' -ForegroundColor Red
110+
foreach ($m in $missing) { Write-Host " - $m" -ForegroundColor Red }
111+
Write-Host ''
112+
Write-Host 'This installer would be broken. Aborting before it can be shipped.' -ForegroundColor Red
113+
exit 1
114+
}
115+
116+
Write-Host 'VERIFICATION PASSED. Installer payload is complete.' -ForegroundColor Green
117+
exit 0

0 commit comments

Comments
 (0)