Skip to content

Commit 07dfe84

Browse files
authored
Merge pull request #161 from brainlife/hotfix/user-check
Hotfix/user check
2 parents edb8692 + 83c1969 commit 07dfe84

138 files changed

Lines changed: 46180 additions & 21536 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
1-
ui
1+
# This file applies only to Docker builds whose context is the repo root (`context: .`),
2+
# e.g. the api and ui services in docker-compose.yml. (A ui/.dockerignore is not used when
3+
# context is the repo root — only this file is.) Other services (handler, telemetry)
4+
# use their own build directories, so ignoring paths here does not affect those images.
5+
#
6+
# Shared context rules:
7+
# - api/ must NOT be listed — the API Dockerfile copies ./api; hiding it breaks that image.
8+
# - ui/ must NOT be listed — the UI Dockerfile copies ./ui after npm ci.
9+
#
10+
# handler/ is safe to exclude here — the handler image is built with context ./handler, not
11+
# the repo root, so this ignore list does not apply to that build.
12+
#
13+
# electron/: npm workspaces only require electron/package.json in context for the root
14+
# lockfile. Simple patterns like electron/* would also exclude that file. We exclude
15+
# heavy paths only (node_modules, dist, release); other electron sources may still be
16+
# sent in the context but are small compared to those directories.
17+
218
handler
319
workdir
420
test
521
bids-specification
22+
node_modules
23+
ui/node_modules
24+
electron/node_modules
25+
electron/dist
26+
electron/release
27+
.git

.eslintrc.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,13 @@
2929
"no-empty": "error",
3030
"no-empty-function": "error",
3131
"no-floating-decimal": "error"
32-
}
32+
},
33+
"overrides": [
34+
{
35+
"files": ["**/*.test.ts"],
36+
"rules": {
37+
"max-nested-callbacks": ["warn", { "max": 8 }]
38+
}
39+
}
40+
]
3341
}
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
name: Build Desktop App
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
create-release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Create release
16+
uses: softprops/action-gh-release@v2
17+
with:
18+
name: ${{ github.ref_name }}
19+
draft: false
20+
prerelease: false
21+
generate_release_notes: true
22+
env:
23+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24+
25+
build:
26+
needs: create-release
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
include:
31+
- os: macos-latest
32+
platform: darwin
33+
arch: arm64
34+
eb_flags: --mac --arm64
35+
- os: windows-latest
36+
platform: windows
37+
arch: amd64
38+
eb_flags: --win --x64
39+
- os: ubuntu-latest
40+
platform: linux
41+
arch: amd64
42+
eb_flags: --linux --x64
43+
44+
runs-on: ${{ matrix.os }}
45+
46+
defaults:
47+
run:
48+
shell: bash
49+
50+
# specify bash for windows
51+
env:
52+
npm_config_script_shell: bash
53+
54+
steps:
55+
- name: Checkout
56+
uses: actions/checkout@v4
57+
with:
58+
submodules: recursive
59+
60+
- name: Setup Node.js
61+
uses: actions/setup-node@v4
62+
with:
63+
node-version: '20'
64+
65+
- name: Install dependencies
66+
run: npm ci
67+
68+
- name: Fetch binaries
69+
run: bash fetch-binaries.sh ${{ matrix.platform }} ${{ matrix.arch }}
70+
env:
71+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
72+
73+
- name: Remove embedded archives / package test fixtures (mac notarization)
74+
if: matrix.platform == 'darwin'
75+
run: |
76+
PY_SITE="handler/bin/python-runtime/venv/lib/python3.8/site-packages"
77+
# Some vendored Python packages ship test fixtures as zip/tar archives (and sometimes odd perms).
78+
# Apple's notarization pipeline can flag these when bundled inside a signed app.
79+
rm -rf "$PY_SITE/joblib/test"
80+
rm -rf "$PY_SITE/pooch/tests"
81+
# remove dcm2niix_binaries to avoid notarization failure. We will point to the bundled dcm2niix in the app.
82+
# Note that we have pinned pypet2bids to 1.4.6 in requirements.txt, and it uses dcm2niix v1.0.20250505.
83+
# in the future, if we want to upgrade pypet2bids, we must make sure that our version of dcm2niix is compatible and vice versa.
84+
rm -rf "$PY_SITE/pypet2bids/dcm2niix_binaries"
85+
86+
- name: Clean dist
87+
run: rm -rf electron/dist
88+
89+
- name: Build JS bundles
90+
working-directory: electron
91+
run: |
92+
npm run build:electron-api
93+
npm run build:electron-handler
94+
npm run build:electron-handler-scripts
95+
96+
- name: Copy Python files, BIDS schema, and templates
97+
working-directory: electron
98+
run: |
99+
npm run build:electron-python
100+
npm run build:electron-bids-spec
101+
npm run build:electron-templates
102+
103+
- name: Build frontend
104+
working-directory: ui
105+
run: npm run build:electron
106+
107+
- name: Transpile main process
108+
working-directory: electron
109+
run: |
110+
npm run build:electron-preload
111+
npm run build:electron-main
112+
113+
- name: Validate Apple signing secrets
114+
if: matrix.platform == 'darwin'
115+
run: |
116+
test -n "${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}"
117+
test -n "${{ secrets.APPLE_CERTIFICATE_PASSWORD }}"
118+
test -n "${{ secrets.APPLE_API_KEY_ID }}"
119+
test -n "${{ secrets.APPLE_API_ISSUER }}"
120+
test -n "${{ secrets.APPLE_API_KEY_P8_BASE64 }}"
121+
122+
- name: Import Apple signing certificate
123+
if: matrix.platform == 'darwin'
124+
uses: apple-actions/import-codesign-certs@v3
125+
with:
126+
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}
127+
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
128+
129+
- name: Create Apple API key file
130+
if: matrix.platform == 'darwin'
131+
run: |
132+
API_KEY_PATH="$RUNNER_TEMP/AuthKey_${APPLE_API_KEY_ID}.p8"
133+
# Support both GNU and BSD base64 flags on GitHub runners.
134+
if ! printf '%s' "$APPLE_API_KEY_P8_BASE64" | base64 --decode > "$API_KEY_PATH" 2>/dev/null; then
135+
printf '%s' "$APPLE_API_KEY_P8_BASE64" | base64 -D > "$API_KEY_PATH"
136+
fi
137+
env:
138+
APPLE_API_KEY_P8_BASE64: ${{ secrets.APPLE_API_KEY_P8_BASE64 }}
139+
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
140+
141+
- name: Package (macOS signed + notarized)
142+
if: matrix.platform == 'darwin'
143+
working-directory: electron
144+
timeout-minutes: 360
145+
run: |
146+
npx electron-builder ${{ matrix.eb_flags }} &
147+
EB_PID=$!
148+
while kill -0 "$EB_PID" 2>/dev/null; do
149+
echo "[heartbeat] electron-builder still running at $(date -u +'%Y-%m-%dT%H:%M:%SZ')"
150+
ps -axo pid,ppid,etime,command | grep -E "electron-builder|app-builder|codesign|notarytool" | grep -v grep || true
151+
sleep 60
152+
done
153+
wait "$EB_PID"
154+
env:
155+
# Verbose logs: builder-util registers `electron-builder`; @electron/notarize registers `electron-notarize`.
156+
DEBUG: 'electron-builder*,electron-notarize*'
157+
APPLE_API_KEY: ${{ runner.temp }}/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8
158+
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
159+
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
160+
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
161+
162+
- name: Package (Windows/Linux)
163+
if: matrix.platform != 'darwin'
164+
working-directory: electron
165+
run: npx electron-builder ${{ matrix.eb_flags }}
166+
167+
- name: Verify macOS code signing and notarization
168+
if: matrix.platform == 'darwin'
169+
working-directory: electron
170+
run: |
171+
# electron-builder puts the .app under release/mac-<arch>/ (not release/*.app).
172+
APP_PATH=$(find release -name '*.app' -type d | head -n 1)
173+
DMG_PATH=$(find release -maxdepth 1 -name '*.dmg' -type f | head -n 1)
174+
if [[ -z "$APP_PATH" || ! -d "$APP_PATH" ]]; then
175+
echo "No .app bundle found under electron/release (expected e.g. release/mac-arm64/*.app):"
176+
find release -maxdepth 4 -type d -print || true
177+
exit 1
178+
fi
179+
if [[ -z "$DMG_PATH" || ! -f "$DMG_PATH" ]]; then
180+
echo "No .dmg found under electron/release:"
181+
ls -la release || true
182+
exit 1
183+
fi
184+
185+
echo "Verifying app signature: $APP_PATH"
186+
codesign --verify --deep --strict --verbose=2 "$APP_PATH"
187+
codesign -dv --verbose=4 "$APP_PATH" 2>&1
188+
189+
# electron-notarize staples the .app; the .dmg is built afterward and usually has no separate ticket.
190+
echo "Validating notarization ticket on app bundle: $APP_PATH"
191+
xcrun stapler validate "$APP_PATH"
192+
193+
echo "Gatekeeper assess app bundle: $APP_PATH"
194+
spctl --assess --verbose=4 "$APP_PATH"
195+
196+
echo "DMG artifact present (notarization ticket is on the .app, not this wrapper): $DMG_PATH"
197+
test -f "$DMG_PATH"
198+
199+
- name: Upload artifacts to release
200+
uses: softprops/action-gh-release@v2
201+
with:
202+
files: |
203+
electron/release/*.dmg
204+
electron/release/*.exe
205+
electron/release/*.AppImage
206+
electron/release/*.deb
207+
env:
208+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/unit-tests.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
name: Jest Unit Tests
3+
4+
on:
5+
push:
6+
branches: [master]
7+
pull_request:
8+
branches: [master]
9+
workflow_dispatch:
10+
11+
jobs:
12+
jest:
13+
name: Run Jest unit tests
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: '20'
24+
cache: npm
25+
26+
- name: Install dependencies
27+
run: npm ci
28+
29+
- name: Run unit tests
30+
run: npm test -- --ci

.gitignore

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,36 @@ api/config.json
2929

3030
handler/container/ROBEXv12.linux64.tar.gz
3131

32-
api/*.pub
33-
api/*.key
34-
api/ezbids.key
35-
api/*.js
36-
api/*.js.map
32+
api/**/*.pub
33+
api/**/*.key
34+
api/**/*.key
35+
api/**/*.js
36+
api/**/*.js.map
37+
api/**/*.cjs
38+
api/**/*.cjs.map
39+
40+
handler/**/*.js
41+
handler/**/*.js.map
42+
handler/**/*.cjs
43+
handler/**/*.cjs.map
44+
handler/bin/*
45+
handler/*.js
46+
handler/*.js.map
47+
handler/*.cjs
48+
handler/*.log
49+
50+
tmp/*
51+
52+
electron/node_modules
53+
electron/dist
54+
electron/dist/*
55+
electron/build
56+
electron/release
57+
electron/**/*.js
58+
electron/dist/*
59+
electron/**/*.js
60+
electron/**/*.js.map
61+
electron/**/*.cjs
62+
electron/**/*.cjs.map
63+
electron/ezbids.key
64+
electron/ezbids.pub

.lintstagedrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"**/*.{js,json,ts,vue}": ["npm run style-check", "npm run lint-check"]
2+
"**/*.{js,json,ts,vue}": ["npm run style-check", "npm run lint-check"],
3+
"**/*.{js,ts,vue}": ["npm run test -- --findRelatedTests --passWithNoTests"]
34
}

.prettierignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
.vscode/settings.json
2+
# Auto-generated by unplugin-vue-components (indent does not match repo Prettier).
3+
ui/components.d.ts
24
node_modules
35
ui/node_modules
46
ui/src/components/modalityForm.vue
57
ui/src/libUnsafe.ts
68
handler/convert.js
79
ui/test/events/*.js
810
api/*.ts
9-
ui/src/Finalize.vue
11+
ui/src/Finalize.vue
12+
bids-specification/*

Dockerfile

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
FROM node:20
22

3-
COPY . /app
4-
53
WORKDIR /app
64

75
RUN npm install -g npm@9.5.1
86

97
RUN npm install -g pm2 typescript tsc-watch
108

11-
RUN npm install
9+
# For npm to work and run npm install with specific workspaces
10+
COPY package.json package-lock.json ./
11+
COPY ui/package.json ./ui/
12+
COPY electron/package.json ./electron/
13+
14+
# API/runtime only: root deps from the lockfile — not ui or electron workspace packages (avoids
15+
# pulling Vite, electron, electron-builder, etc. into this image).
16+
RUN npm ci --workspaces=false
17+
18+
COPY tsconfig.base.json ./
19+
COPY api ./api

0 commit comments

Comments
 (0)