@interopio/iocd-cli 0.0.38 → 0.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +780 -758
  2. package/dist/cli.js +0 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/setup.command.js +1 -7
  5. package/dist/commands/setup.command.js.map +1 -1
  6. package/dist/services/installer/electronForge.js +5 -3
  7. package/dist/services/installer/electronForge.js.map +1 -1
  8. package/dist/services/installer/macOS.helper.js +0 -1
  9. package/dist/services/installer/macOS.helper.js.map +1 -1
  10. package/dist/services/license.service.js +14 -14
  11. package/dist/templates/groups/apps/groups/.gitignore.template +23 -23
  12. package/dist/templates/groups/apps/groups/README.md +15 -15
  13. package/dist/templates/groups/apps/groups/config/web-group-dev.json +12 -12
  14. package/dist/templates/groups/apps/groups/index.html +17 -17
  15. package/dist/templates/groups/apps/groups/iocd.app.json +19 -19
  16. package/dist/templates/groups/apps/groups/package.json +25 -25
  17. package/dist/templates/groups/apps/groups/public/manifest.json +24 -24
  18. package/dist/templates/groups/apps/groups/public/robots.txt +3 -3
  19. package/dist/templates/groups/apps/groups/src/App.css +38 -38
  20. package/dist/templates/groups/apps/groups/src/App.tsx +11 -11
  21. package/dist/templates/groups/apps/groups/src/index.css +13 -13
  22. package/dist/templates/groups/apps/groups/src/index.tsx +19 -19
  23. package/dist/templates/groups/apps/groups/vite.config.ts +8 -8
  24. package/dist/templates/groups/template.json +12 -12
  25. package/dist/templates/ioconnect-desktop/.github/actions/setup-smctl/action.yml +121 -121
  26. package/dist/templates/ioconnect-desktop/.github/workflows/build.yml +395 -395
  27. package/dist/templates/ioconnect-desktop/.gitignore.template +15 -15
  28. package/dist/templates/ioconnect-desktop/README.md +780 -758
  29. package/dist/templates/ioconnect-desktop/config/forge.config.js +59 -59
  30. package/dist/templates/ioconnect-desktop/config/iocd.cli.config.json +16 -16
  31. package/dist/templates/ioconnect-desktop/config/mac-build/entitlements.mac.plist +44 -44
  32. package/dist/templates/ioconnect-desktop/config/win-build/template.nuspectemplate +32 -32
  33. package/dist/templates/ioconnect-desktop/modifications/base/iocd/config/system.json.merge +2 -2
  34. package/dist/templates/ioconnect-desktop/modifications/base/iocd/config/system.json.merge-autoUpdate +9 -9
  35. package/dist/templates/ioconnect-desktop/package.json +33 -32
  36. package/dist/templates/ioconnect-desktop/template.json +6 -6
  37. package/dist/templates/launchpad/apps/launchpad/.eslintrc.json +3 -3
  38. package/dist/templates/launchpad/apps/launchpad/.gitignore.template +1 -1
  39. package/dist/templates/launchpad/apps/launchpad/config/iocd.app.def.dev.json +56 -56
  40. package/dist/templates/launchpad/apps/launchpad/config/iocd.system.build.json +2 -2
  41. package/dist/templates/launchpad/apps/launchpad/config/iocd.system.dev.json +2 -2
  42. package/dist/templates/launchpad/apps/launchpad/index.html +16 -16
  43. package/dist/templates/launchpad/apps/launchpad/iocd.app.json +27 -27
  44. package/dist/templates/launchpad/apps/launchpad/package-lock.json +2778 -2778
  45. package/dist/templates/launchpad/apps/launchpad/package.json +21 -21
  46. package/dist/templates/launchpad/apps/launchpad/src/app/app.tsx +41 -41
  47. package/dist/templates/launchpad/apps/launchpad/src/app/constants.ts +27 -27
  48. package/dist/templates/launchpad/apps/launchpad/src/components/logo.tsx +11 -11
  49. package/dist/templates/launchpad/apps/launchpad/src/components/main-context-menu.tsx +161 -161
  50. package/dist/templates/launchpad/apps/launchpad/src/components/notifications-button.tsx +44 -44
  51. package/dist/templates/launchpad/apps/launchpad/src/main.tsx +6 -6
  52. package/dist/templates/launchpad/apps/launchpad/src/styles.css +16 -16
  53. package/dist/templates/launchpad/apps/launchpad/tsconfig.json +10 -10
  54. package/dist/templates/launchpad/apps/launchpad/vite.config.ts +13 -13
  55. package/dist/templates/launchpad/template.json +12 -12
  56. package/dist/templates/splash/apps/splash/assets/styles/style.css +39 -39
  57. package/dist/templates/splash/apps/splash/iocd.app.json +7 -7
  58. package/dist/templates/splash/apps/splash/script.js +53 -53
  59. package/dist/templates/splash/apps/splash/splash.html +25 -25
  60. package/dist/templates/splash/template.json +12 -12
  61. package/dist/templates/tests/template.json +8 -8
  62. package/dist/templates/tests/tests/package-lock.json +7289 -7289
  63. package/dist/templates/tests/tests/package.json +22 -22
  64. package/dist/templates/tests/tests/tests/sample.spec.ts +30 -30
  65. package/dist/templates/tests/tests/tsconfig.json +10 -10
  66. package/dist/templates/tests/tests/wdio.config.ts +32 -32
  67. package/dist/templates/workspaces/apps/workspaces/README.md +15 -15
  68. package/dist/templates/workspaces/apps/workspaces/config/workspaces-dev.json +20 -20
  69. package/dist/templates/workspaces/apps/workspaces/index.html +17 -17
  70. package/dist/templates/workspaces/apps/workspaces/iocd.app.json +19 -19
  71. package/dist/templates/workspaces/apps/workspaces/package.json +29 -29
  72. package/dist/templates/workspaces/apps/workspaces/public/manifest.json +25 -25
  73. package/dist/templates/workspaces/apps/workspaces/public/robots.txt +3 -3
  74. package/dist/templates/workspaces/apps/workspaces/src/App.css +38 -38
  75. package/dist/templates/workspaces/apps/workspaces/src/App.tsx +102 -102
  76. package/dist/templates/workspaces/apps/workspaces/src/index.css +3 -3
  77. package/dist/templates/workspaces/apps/workspaces/src/index.tsx +28 -28
  78. package/dist/templates/workspaces/apps/workspaces/src/logo.svg +7 -7
  79. package/dist/templates/workspaces/apps/workspaces/src/reportWebVitals.ts +15 -15
  80. package/dist/templates/workspaces/apps/workspaces/src/setupTests.ts +5 -5
  81. package/dist/templates/workspaces/apps/workspaces/vite.config.ts +8 -8
  82. package/dist/templates/workspaces/template.json +12 -12
  83. package/package.json +83 -83
  84. package/scripts/copy-assets.js +19 -19
  85. package/scripts/delete-dist.js +12 -12
  86. package/scripts/generate-schema.js +50 -50
  87. package/scripts/handle-gitignore-templates.js +157 -157
package/README.md CHANGED
@@ -1,758 +1,780 @@
1
- # io.Connect Desktop Seed Project
2
-
3
- > A seed project for developing and building io.Connect Desktop based products
4
-
5
- - [io.Connect Desktop Seed Project](#ioconnect-desktop-seed-project)
6
- - [Overview](#overview)
7
- - [Quick Start](#quick-start)
8
- - [Prerequisites](#prerequisites)
9
- - [Creating Your Project](#creating-your-project)
10
- - [Installation](#installation)
11
- - [Running in Development Mode](#running-in-development-mode)
12
- - [Building for Production](#building-for-production)
13
- - [Project Structure](#project-structure)
14
- - [Configuration](#configuration)
15
- - [Basic Settings](#basic-settings)
16
- - [License Key](#license-key)
17
- - [Customization](#customization)
18
- - [Applying Modifications](#applying-modifications)
19
- - [Changing io.CD System Config](#changing-iocd-system-config)
20
- - [Changing the Logo](#changing-the-logo)
21
- - [Custom Applications](#custom-applications)
22
- - [Using Template Applications](#using-template-applications)
23
- - [Creating Custom Applications](#creating-custom-applications)
24
- - [Managing Applications](#managing-applications)
25
- - [Development](#development)
26
- - [Testing](#testing)
27
- - [Running Tests](#running-tests)
28
- - [Writing Tests](#writing-tests)
29
- - [Building for Production](#building-for-production-1)
30
- - [Build Commands](#build-commands)
31
- - [Build Output](#build-output)
32
- - [Code Signing](#code-signing)
33
- - [Windows Code Signing](#windows-code-signing)
34
- - [Option 1: PFX Certificate File](#option-1-pfx-certificate-file)
35
- - [Option 2: Certificate Store (e.g., DigiCert KeyLocker)](#option-2-certificate-store-eg-digicert-keylocker)
36
- - [Option 3: Custom Script](#option-3-custom-script)
37
- - [macOS Code Signing](#macos-code-signing)
38
- - [Code Signing Configuration](#code-signing-configuration)
39
- - [Notarization Configuration](#notarization-configuration)
40
- - [CI/CD Integration](#cicd-integration)
41
- - [Auto-Updates](#auto-updates)
42
- - [Troubleshooting](#troubleshooting)
43
- - [Common Issues](#common-issues)
44
- - [Getting Help](#getting-help)
45
-
46
- ---
47
-
48
- ## Overview
49
-
50
- This seed project provides everything needed to build, test, and deploy your branded version of io.Connect Desktop distribution. It includes pre-configured components, build scripts, and CI/CD integration examples.
51
-
52
- **What's Included:**
53
- - ✅ Licensed io.Connect Desktop components
54
- - ✅ Build and packaging scripts
55
- - ✅ Configuration templates
56
- - ✅ Automated testing framework
57
- - ✅ CI/CD pipeline examples
58
- - ✅ Code signing setup guides
59
-
60
- ---
61
-
62
- ## Quick Start
63
-
64
- ### Prerequisites
65
-
66
- - **Node.js**: v22 or higher
67
- - **npm**: v9 or higher
68
- - **Operating System**: Windows 10+ or macOS 11+
69
- - **License**: This seed project requires a valid io.Connect Desktop license to use the included components. For licensing questions, contact sales@interop.io
70
-
71
- ### Creating Your Project
72
-
73
- ```bash
74
- npx @interopio/iocd-cli create # Follow prompts to set up your project
75
- ```
76
-
77
- ### Installation
78
-
79
- ```bash
80
- cd your-project-name
81
-
82
- # Install dependencies
83
- npm install
84
-
85
- # Install components
86
- npm run setup
87
- ```
88
-
89
- ### Running in Development Mode
90
-
91
- ```bash
92
- # Start io.Connect Desktop in dev mode
93
- npm run dev
94
- ```
95
-
96
- ### Building for Production
97
-
98
- ```bash
99
- # Build production installer
100
- npm run build
101
- ```
102
-
103
- ---
104
-
105
- ## Project Structure
106
-
107
- ```
108
- .
109
- ├── apps/ # Custom applications (add your own)
110
- ├── components/ # Downloaded io.Connect Desktop components
111
- ├── iocd/ # Main io.Connect Desktop component (required)
112
- └── [other-components]/ # Additional licensed components (devTools, demos, etc.)
113
- ├── config/ # Configuration files
114
- ├── forge.config.js # Electron Forge configuration
115
- │ ├── iocd.cli.config.json # CLI configuration
116
- └── iocd.license.key # License key file (optional)
117
- ├── modifications/ # Customizations and overrides
118
- ├── base/ # Applied in all modes (dev/build)
119
- │ ├── dev/ # Applied only in development mode
120
- └── build/ # Applied only during production builds
121
- ├── tests/ # Automated tests
122
- │ └── basic.test.js # Example Playwright test suite
123
- ├── .github/workflows/ # CI/CD pipeline examples
124
- ├── package.json
125
- └── README.md
126
- ```
127
-
128
- ---
129
-
130
- ## Configuration
131
-
132
- ### Basic Settings
133
-
134
- Edit `config/iocd.cli.config.json`:
135
-
136
- ```json
137
- {
138
- "productName": "Your Product Name",
139
- "productSlug": "your-product-slug",
140
- "company": "Your Company",
141
- "version": "1.0.0",
142
- "win": {
143
- "exe": {
144
- "exeName": "your-product.exe",
145
- "exeIconPath": "path/to/icon.ico"
146
- },
147
- "codeSign": {
148
- "type": "pfx",
149
- "pfxPath": "path/to/certificate.pfx"
150
- }
151
- },
152
- "mac": {
153
- "appBundleName": "Your Product.app",
154
- "appBundleId": "com.yourcompany.product"
155
- }
156
- }
157
- ```
158
-
159
- ### License Key
160
-
161
- Set your license key using:
162
- - **Environment variable**: `IOCD_LICENSE_KEY`
163
- - **Config file**: `config/iocd.license.key`
164
-
165
- ---
166
-
167
- ## Customization
168
-
169
- ### Applying Modifications
170
-
171
- Modifications are the recommended way to customize io.Connect Desktop components without directly editing component files. They allow you to change configurations, add applications, modify assets, and override default behavior while preserving your changes across component updates.
172
-
173
- **Key Concepts:**
174
-
175
- - **Modifications are stored separately** from components in the `modifications/` folder
176
- - **Changes persist** when components are updated or reinstalled
177
- - **Mode-specific modifications** allow different behavior in dev vs. build mode
178
- - **Files are copied or merged** into components when running `iocd dev` or `iocd build`
179
-
180
- **Directory Structure:**
181
-
182
- ```
183
- modifications/
184
- ├── base/ # Applied in all modes
185
- │ └── iocd/
186
- ├── config/
187
- │ ├── assets/
188
- └── apps/
189
- ├── dev/ # Applied only in dev mode
190
- │ └── iocd/
191
- └── config/
192
- └── build/ # Applied only in build mode
193
- └── iocd/
194
- └── config/
195
- ```
196
-
197
- **Processing Order:**
198
-
199
- 1. **Base modifications** (`modifications/base/`) are applied first
200
- 2. **Mode-specific modifications** (`modifications/dev/` or `modifications/build/`) are applied second, overriding base when needed
201
-
202
- **Common Use Cases:**
203
-
204
- - Replace logos and icons in `modifications/base/iocd/assets/`
205
- - Configure system settings in `modifications/base/iocd/config/`
206
- - Add application definitions in `modifications/base/iocd/apps/`
207
- - Use different URLs for dev (localhost) vs. build (file://) in mode-specific folders
208
-
209
- **Special File Types:**
210
-
211
- - **`.json.merge`** - Deep merges with existing JSON instead of replacing
212
- - **`.delete`** - Removes the corresponding file
213
- - **`.replace`** marker - Replaces entire directory (place in directory to replace)
214
-
215
- ### Changing io.CD System Config
216
-
217
- The io.Connect Desktop system configuration (`system.json`) controls platform-wide settings like auto-updates, logging, and feature flags. To customize these settings, create modification files that merge with the default configuration.
218
-
219
- **Location:**
220
- ```
221
- modifications/base/iocd/config/system.json.merge
222
- ```
223
-
224
- **Example - Enable Auto-Updates:**
225
-
226
- ```json
227
- {
228
- "autoUpdater": {
229
- "enabled": true,
230
- "updateSource": {
231
- "type": "Service",
232
- "baseUrl": "https://updates.yourcompany.com"
233
- },
234
- "interval": 60
235
- }
236
- }
237
- ```
238
-
239
- **Example - Configure Logging:**
240
-
241
- ```json
242
- {
243
- "logging": {
244
- "level": "info",
245
- "appender": "default"
246
- }
247
- }
248
- ```
249
-
250
- **Mode-Specific Configuration:**
251
-
252
- Use different settings for dev vs. build mode:
253
-
254
- **Dev mode** (`modifications/dev/iocd/config/system.json.merge`):
255
- ```json
256
- {
257
- "logging": {
258
- "level": "debug"
259
- },
260
- "features": {
261
- "devTools": true
262
- }
263
- }
264
- ```
265
-
266
- **Build mode** (`modifications/build/iocd/config/system.json.merge`):
267
- ```json
268
- {
269
- "logging": {
270
- "level": "error"
271
- },
272
- "features": {
273
- "telemetry": true
274
- }
275
- }
276
- ```
277
-
278
- **Important Notes:**
279
-
280
- - Use `.merge` extension to deep merge with existing configuration
281
- - Without `.merge`, the file completely replaces the original
282
- - Changes are applied when running `iocd dev` or `iocd build`
283
- - Environment variables like `${PRODUCT_VERSION}` are automatically expanded
284
-
285
- ### Changing the Logo
286
-
287
- Replace the default logo files in `modifications/base/iocd/assets/images/`:
288
-
289
- ```bash
290
- modifications/base/iocd/assets/
291
- └── images/
292
- ├── logo.ico # Windows executable icon (multiple resolutions)
293
- ├── logo.icns # macOS app bundle icon (multiple resolutions)
294
- └── logo.png # Application icon (used in UI)
295
- ```
296
-
297
- **Requirements:**
298
- - **logo.ico**: Windows icon file with multiple sizes (16x16, 32x32, 48x48, 256x256)
299
- - **logo.icns**: macOS icon file with multiple sizes (use Icon Composer or iconutil)
300
- - **logo.png**: PNG file, recommended size 512x512
301
-
302
- ### Custom Applications
303
-
304
- io.Connect Desktop includes several built-in applications that you can replace with your own custom versions:
305
-
306
- - **Workspaces** - Workspace management UI
307
- - **Groups** - Window grouping UI
308
- - **Splash Screen** - Application splash screen
309
- - **Launchpad** - Application launcher
310
- - **Notifications** - Notification center
311
-
312
- Applications in the `apps/` folder allow you to customize these built-in apps or add entirely new functionality. This approach keeps your core platform applications in the same repository, eliminating the need to manage them across multiple repositories and simplifying version control, deployment, and coordination.
313
-
314
- #### Using Template Applications
315
-
316
- Template applications can be selected during project creation or added later:
317
-
318
- ```bash
319
- # Add template application
320
- iocd apps add workspaces
321
-
322
- # List available templates
323
- iocd apps list --available
324
- ```
325
-
326
- **Available templates:**
327
- - `workspaces` - Workspace management
328
- - `groups` - Window grouping
329
- - `splash-screen` - Loading screen
330
- - `launchpad` - Application launcher
331
-
332
- Once added, build your implementation on top of the template in the `apps/` folder.
333
-
334
- #### Creating Custom Applications
335
-
336
- For custom applications, create a folder in `apps/` with an `iocd.app.json` file:
337
-
338
- ```
339
- apps/
340
- └── my-custom-app/
341
- ├── iocd.app.json # Defines modifications and build behavior
342
- ├── package.json
343
- └── src/
344
- ```
345
-
346
- **Example `iocd.app.json`:**
347
-
348
- In this example:
349
- - **Dev mode** (triggered by `iocd dev` or `npm run dev`): Executes a `start` script (typically starts a dev server with hot-reload) and copies the development app configuration so the app definition points to the dev server
350
- - **Build mode** (triggered by `iocd build` or `npm run build`): Executes a `build` script (typically builds optimized production assets) and copies the final built assets to the modifications folder
351
-
352
- ```json
353
- {
354
- "dev": {
355
- "script": "start",
356
- "modifications": [
357
- {
358
- "source": "/config/my-app-dev.json",
359
- "destination": "/modifications/dev/iocd/config/apps/my-app.json"
360
- }
361
- ]
362
- },
363
- "build": {
364
- "script": "build",
365
- "modifications": [
366
- {
367
- "source": "/dist/",
368
- "destination": "/modifications/build/iocd/assets/my-app"
369
- }
370
- ]
371
- }
372
- }
373
- ```
374
-
375
- The `iocd.app.json` file defines:
376
- - **base**: Array of modifications applied in all modes
377
- - **dev**: Object with optional `script` (npm script name) and `modifications` array
378
- - **build**: Object with optional `script` (npm script name) and `modifications` array
379
-
380
- #### Managing Applications
381
-
382
- ```bash
383
- # Install application dependencies
384
- iocd apps install
385
-
386
- # Start applications in dev mode
387
- iocd apps dev
388
-
389
- # Build applications for production
390
- iocd apps build
391
- ```
392
-
393
- ---
394
-
395
- ## Development
396
-
397
- Development mode allows you to quickly start io.Connect Desktop with all your configured changes and applications, enabling rapid iteration and testing during development.
398
-
399
- When you run dev mode, the CLI will:
400
- 1. **Apply all relevant modifications** - Base modifications and dev-specific modifications are copied to components
401
- 2. **Start all applications** - Runs the dev script for each app (typically starting dev servers with hot-reload)
402
- 3. **Launch io.Connect Desktop** - Starts the platform with all changes applied
403
-
404
- ```bash
405
- # Start io.Connect Desktop in dev mode
406
- iocd dev
407
-
408
- # Or using npm script
409
- npm run dev
410
- ```
411
-
412
- ---
413
-
414
- ## Testing
415
-
416
- Testing is based on **WebdriverIO** and depends on the `@interopio/wdio-iocd-service` package, which enables starting and controlling io.Connect Desktop from WebDriver. This allows you to create and run comprehensive end-to-end (E2E) tests for your io.Connect Desktop application.
417
-
418
- ### Running Tests
419
-
420
- Tests are written in the `tests/` folder and can be executed using:
421
-
422
- ```bash
423
- # Run all tests
424
- npm test
425
-
426
- # Or using the WebdriverIO CLI directly
427
- npx wdio run ./wdio.config.ts
428
- ```
429
-
430
- ### Writing Tests
431
-
432
- Tests are written using WebdriverIO syntax with the io.Connect Desktop service handling application lifecycle. Example test structure:
433
-
434
- ```javascript
435
- describe('io.Connect Desktop Application', () => {
436
- it('should launch successfully', async () => {
437
- // Your test logic here
438
- // The @interopio/wdio-iocd-service handles starting/stopping io.Connect Desktop
439
- });
440
- });
441
- ```
442
-
443
- Add your test files to the `tests/` directory. They'll run automatically in CI/CD pipelines.
444
-
445
- ---
446
-
447
- ## Building for Production
448
-
449
- The build process creates production-ready installers for distribution. It orchestrates multiple steps to produce signed, optimized packages ready for deployment.
450
-
451
- **What happens during build:**
452
-
453
- 1. **Build all applications** - Executes build scripts for each app in production mode
454
- 2. **Reinstall components** - Downloads and installs fresh component versions
455
- 3. **Apply all modifications** - Copies base and build-specific modifications to components
456
- 4. **Code sign binaries** - Signs executables and libraries (if configured)
457
- 5. **Create build artifacts** - Generates installers (`.exe` setup on Windows, `.dmg` on macOS, `.zip` archives)
458
- 6. **Publish to release server** - Uploads artifacts for auto-updates (if configured)
459
-
460
- **Build System:**
461
-
462
- The build process is based on [Electron Forge](https://www.electronforge.io/), a complete toolchain for building and packaging Electron applications. The main configuration is located in `config/forge.config.js`, where you can customize makers, publishers, and build behavior.
463
-
464
- ### Build Commands
465
-
466
- ```bash
467
- # Build installer
468
- iocd build
469
-
470
- # Or using npm script
471
- npm run build
472
-
473
- # Build options
474
- iocd build --output custom/path # Custom output directory
475
- iocd build --publish-only # Skip build, only publish
476
- iocd build --skip-install # Skip component installation
477
- ```
478
-
479
- ### Build Output
480
-
481
- Depending on OS you can configure Electron Forge makers to produce different types of artifacts. We have tested the following configurations:
482
-
483
- For **Windows**:
484
- - **Artifact Types**:
485
- - Squirrel.Windows installer (`.exe` setup)
486
- - Portable ZIP archive
487
-
488
- For **macOS**:
489
- - **Artifact Types**:
490
- - DMG disk image
491
- - ZIP archive
492
-
493
- The full list of makers is available in the [Electron Forge documentation](https://www.electronforge.io/config/makers).
494
-
495
- ### Code Signing
496
-
497
- Code signing ensures that your application is trusted by operating systems and users can verify it hasn't been tampered with. Both Windows and macOS require code signing for distribution.
498
-
499
- #### Windows Code Signing
500
-
501
- ##### Option 1: PFX Certificate File
502
-
503
- ```json
504
- {
505
- "win": {
506
- "codeSign": {
507
- "type": "signtool",
508
- "pfxPath": "path/to/certificate.pfx",
509
- "pfxPassword": "${WIN_PFX_PASS}"
510
- }
511
- }
512
- }
513
- ```
514
-
515
- ##### Option 2: Certificate Store (e.g., DigiCert KeyLocker)
516
-
517
- ```json
518
- {
519
- "win": {
520
- "codeSign": {
521
- "type": "signtool",
522
- "certificateSha1": "${WIN_CERT_SHA1}"
523
- }
524
- }
525
- }
526
- ```
527
-
528
- **Important**:
529
- - If using DigiCert KeyLocker, run `smctl windows certsync` before building to sync certificates to Windows store
530
- - Either `pfxPath` or `certificateSha1` must be provided (not both)
531
- - Set type to `"off"` to disable code signing
532
-
533
- ##### Option 3: Custom Script
534
-
535
- For advanced signing scenarios, you can provide a custom signing script:
536
-
537
- ```json
538
- {
539
- "win": {
540
- "codeSign": {
541
- "type": "custom",
542
- "customCodeSignScriptPath": "path/to/custom-sign.js"
543
- }
544
- }
545
- }
546
- ```
547
-
548
- Your custom script should export a function that receives the binary path and config:
549
-
550
- ```javascript
551
- // custom-sign.js
552
- module.exports = async function(binaryPath, config) {
553
- // Your custom signing logic here
554
- console.log(`Signing ${binaryPath}`);
555
- // Use any signing tool or API you need
556
- };
557
- ```
558
-
559
- #### macOS Code Signing
560
-
561
- ##### Code Signing Configuration
562
-
563
- ```json
564
- {
565
- "mac": {
566
- "codeSign": {
567
- "type": "keychain",
568
- "identity": "Developer ID Application: Your Company (TEAM_ID)"
569
- }
570
- }
571
- }
572
- ```
573
-
574
- **Options**:
575
- - `type`: `"keychain"` (use keychain certificate), `"certificate"` (use .p12 file), `"custom"` (custom script), or `"off"` (no signing)
576
- - `identity`: Developer ID Application identity or SHA-1 hash (optional - auto-selected if not specified)
577
- - `keychain`: Keychain name or path (optional - uses default keychain if not specified)
578
-
579
- **Custom Script Option:**
580
-
581
- For advanced signing scenarios, you can provide a custom signing script:
582
-
583
- ```json
584
- {
585
- "mac": {
586
- "codeSign": {
587
- "type": "custom",
588
- "customCodeSignScriptPath": "path/to/custom-sign.js"
589
- }
590
- }
591
- }
592
- ```
593
-
594
- Your custom script should export a function that receives the app bundle path and config:
595
-
596
- ```javascript
597
- // custom-sign.js
598
- module.exports = async function(appBundlePath, config) {
599
- // Your custom signing logic here
600
- console.log(`Signing ${appBundlePath}`);
601
- // Use any signing tool or API you need
602
- };
603
- ```
604
-
605
- ##### Notarization Configuration
606
-
607
- ```json
608
- {
609
- "mac": {
610
- "notarization": {
611
- "type": "notarytool",
612
- "appleId": "${MAC_NOTARIZATION_APPLE_ID}",
613
- "appleIdPassword": "${MAC_NOTARIZATION_APPLE_ID_PASSWORD}",
614
- "appleTeamId": "${MAC_NOTARIZATION_APPLE_TEAM_ID}"
615
- }
616
- }
617
- }
618
- ```
619
-
620
- **Important**:
621
- - Notarization is required for distribution outside Mac App Store
622
- - Use app-specific password (not your regular Apple ID password)
623
- - Generate app-specific password at appleid.apple.com
624
- - Set type to `"off"` to skip notarization (for development builds)
625
-
626
- **Custom Script Option:**
627
-
628
- For advanced notarization scenarios, you can provide a custom notarization script:
629
-
630
- ```json
631
- {
632
- "mac": {
633
- "notarization": {
634
- "type": "custom",
635
- "customNotarizationScriptPath": "path/to/custom-notarize.js"
636
- }
637
- }
638
- }
639
- ```
640
-
641
- Your custom script should export a function that receives the app bundle path and config:
642
-
643
- ```javascript
644
- // custom-notarize.js
645
- module.exports = async function(appBundlePath, config) {
646
- // Your custom notarization logic here
647
- console.log(`Notarizing ${appBundlePath}`);
648
- // Use any notarization tool or API you need
649
- };
650
- ```
651
-
652
- ### CI/CD Integration
653
-
654
- Continuous Integration and Continuous Deployment (CI/CD) automates building, testing, and publishing your io.Connect Desktop application. The seed project includes an GitHub Actions workflow located in `.github/workflows/build.yml`. It produces signed installers and can publish them to a release server.
655
-
656
- ### Auto-Updates
657
-
658
- Setting up auto-updates allows your users to automatically receive new versions of your application.
659
-
660
- **Requirements:**
661
-
662
- Auto-updates are supported for specific build artifact types:
663
- - **Windows**: Squirrel.Windows installers (`.exe` setup files)
664
- - **macOS**: ZIP archives
665
-
666
- Other build outputs (portable ZIP on Windows, DMG on macOS) do not support automatic updates.
667
-
668
- **Setup Steps:**
669
-
670
- **1. Set up a release server**
671
-
672
- You can use existing solutions or build your own:
673
- - **Existing services**: Nucleus, Hazel, or other update servers (see [Electron update services](https://www.electronjs.org/docs/latest/tutorial/updates#using-other-update-services))
674
- - **Custom solution**: Build your own update server following Squirrel protocols
675
-
676
- **2. Configure io.Connect Desktop to check the update server**
677
-
678
- Create or modify `modifications/base/iocd/config/system.json.merge`:
679
-
680
- ```json
681
- {
682
- "autoUpdater": {
683
- "enabled": true,
684
- "updateSource": {
685
- "type": "Service",
686
- "baseUrl": "https://updates.yourcompany.com"
687
- },
688
- "interval": 60
689
- }
690
- }
691
- ```
692
-
693
- **3. Publish updates**
694
-
695
- Choose one of the following approaches:
696
-
697
- **Option A: Automatic publishing during build** - Configure publishers in `config/forge.config.js`:
698
-
699
- ```javascript
700
- publishers: [
701
- {
702
- name: '@electron-forge/publisher-electron-release-server',
703
- config: {
704
- baseUrl: 'https://updates.yourcompany.com',
705
- username: process.env.RELEASE_SERVER_USERNAME,
706
- password: process.env.RELEASE_SERVER_PASSWORD
707
- }
708
- }
709
- ]
710
- ```
711
-
712
- **Option B: Manual upload** - After building, manually upload the installer artifacts to your release server.
713
-
714
- **4. Test auto-updates**
715
-
716
- - Install your application using the signed installer
717
- - Publish a new version to your update server
718
- - Launch the application and verify it detects and installs the update
719
-
720
- ---
721
-
722
- ## Troubleshooting
723
-
724
- ### Common Issues
725
-
726
- **Build fails with "License not found"**
727
- - Ensure `IOCD_LICENSE_KEY` environment variable is set
728
- - Or create `config/iocd.license.key` file with your license key
729
-
730
- **Code signing fails on Windows**
731
- - Verify certificate is valid and not expired
732
- - Check that `pfxPassword` is correct
733
- - For certificate store signing: Ensure `smctl windows certsync` was run first
734
- - Verify exactly one of `pfxPath` or `certificateSha1` is configured (not both)
735
-
736
- **macOS notarization fails**
737
- - Use app-specific password, not regular Apple ID password
738
- - Generate app-specific password at appleid.apple.com
739
- - Verify Apple Developer Program membership is active
740
- - Check that `appleTeamId` matches your Developer Team ID
741
-
742
- **Application won't start in dev mode**
743
- - Run `iocd setup` to verify component installation
744
- - Check that `components/iocd` directory exists
745
- - Review logs in system temp directory
746
-
747
- **Components not downloading**
748
- - Verify network connectivity
749
- - Check component store configuration in `config/iocd.cli.config.json`
750
- - For GitHub store: Ensure repository access and credentials are correct
751
-
752
- ### Getting Help
753
-
754
- - 📚 [Documentation](https://docs.interop.io/desktop)
755
- - 💬 [Community Forum](https://community.interop.io)
756
- - 📧 [Support Portal](https://support.interop.io)
757
-
758
- ---
1
+ # io.Connect Desktop Seed Project
2
+
3
+ > A seed project for developing and building io.Connect Desktop based products
4
+
5
+ - [io.Connect Desktop Seed Project](#ioconnect-desktop-seed-project)
6
+ - [Overview](#overview)
7
+ - [Quick Start](#quick-start)
8
+ - [Prerequisites](#prerequisites)
9
+ - [Creating Your Project](#creating-your-project)
10
+ - [Installation](#installation)
11
+ - [Running in Development Mode](#running-in-development-mode)
12
+ - [Building for Production](#building-for-production)
13
+ - [Project Structure](#project-structure)
14
+ - [Configuration](#configuration)
15
+ - [Basic Settings](#basic-settings)
16
+ - [License Key](#license-key)
17
+ - [Customization](#customization)
18
+ - [Applying Modifications](#applying-modifications)
19
+ - [Changing io.CD System Config](#changing-iocd-system-config)
20
+ - [Changing the Logo](#changing-the-logo)
21
+ - [Custom Applications](#custom-applications)
22
+ - [Using Template Applications](#using-template-applications)
23
+ - [Creating Custom Applications](#creating-custom-applications)
24
+ - [Managing Applications](#managing-applications)
25
+ - [Development](#development)
26
+ - [Installing or Updating components during development](#installing-or-updating-components-during-development)
27
+ - [Testing](#testing)
28
+ - [Running Tests](#running-tests)
29
+ - [Writing Tests](#writing-tests)
30
+ - [Building for Production](#building-for-production-1)
31
+ - [Build Commands](#build-commands)
32
+ - [Build Output](#build-output)
33
+ - [Code Signing](#code-signing)
34
+ - [Windows Code Signing](#windows-code-signing)
35
+ - [Option 1: PFX Certificate File](#option-1-pfx-certificate-file)
36
+ - [Option 2: Certificate Store (e.g., DigiCert KeyLocker)](#option-2-certificate-store-eg-digicert-keylocker)
37
+ - [Option 3: Custom Script](#option-3-custom-script)
38
+ - [macOS Code Signing](#macos-code-signing)
39
+ - [Code Signing Configuration](#code-signing-configuration)
40
+ - [Notarization Configuration](#notarization-configuration)
41
+ - [CI/CD Integration](#cicd-integration)
42
+ - [Auto-Updates](#auto-updates)
43
+ - [Troubleshooting](#troubleshooting)
44
+ - [Common Issues](#common-issues)
45
+ - [Getting Help](#getting-help)
46
+
47
+ ---
48
+
49
+ ## Overview
50
+
51
+ This seed project provides everything needed to build, test, and deploy your branded version of io.Connect Desktop distribution. It includes pre-configured components, build scripts, and CI/CD integration examples.
52
+
53
+ **What's Included:**
54
+ - ✅ Licensed io.Connect Desktop components
55
+ - ✅ Build and packaging scripts
56
+ - ✅ Configuration templates
57
+ - ✅ Automated testing framework
58
+ - ✅ CI/CD pipeline examples
59
+ - ✅ Code signing setup guides
60
+
61
+ ---
62
+
63
+ ## Quick Start
64
+
65
+ ### Prerequisites
66
+
67
+ - **Node.js**: v22 or higher
68
+ - **npm**: v9 or higher
69
+ - **Operating System**: Windows 10+ or macOS 11+
70
+ - **License**: This seed project requires a valid io.Connect Desktop license to use the included components. For licensing questions, contact sales@interop.io
71
+
72
+ ### Creating Your Project
73
+
74
+ ```bash
75
+ npx @interopio/iocd-cli@latest create # Follow prompts to set up your project
76
+ ```
77
+
78
+ ### Installation
79
+
80
+ ```bash
81
+ cd your-project-name
82
+
83
+ # Install dependencies
84
+ npm install
85
+
86
+ # Install components
87
+ npm run setup
88
+ ```
89
+
90
+ ### Running in Development Mode
91
+
92
+ ```bash
93
+ # Start io.Connect Desktop in dev mode
94
+ npm run dev
95
+ ```
96
+
97
+ ### Building for Production
98
+
99
+ ```bash
100
+ # Build production installer
101
+ npm run build
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Project Structure
107
+
108
+ ```
109
+ .
110
+ ├── apps/ # Custom applications (add your own)
111
+ ├── components/ # Downloaded io.Connect Desktop components
112
+ ├── iocd/ # Main io.Connect Desktop component (required)
113
+ │ └── [other-components]/ # Additional licensed components (devTools, demos, etc.)
114
+ ├── config/ # Configuration files
115
+ │ ├── forge.config.js # Electron Forge configuration
116
+ ├── iocd.cli.config.json # CLI configuration
117
+ │ └── iocd.license.key # License key file (optional)
118
+ ├── modifications/ # Customizations and overrides
119
+ │ ├── base/ # Applied in all modes (dev/build)
120
+ ├── dev/ # Applied only in development mode
121
+ │ └── build/ # Applied only during production builds
122
+ ├── tests/ # Automated tests
123
+ │ └── basic.test.js # Example Playwright test suite
124
+ ├── .github/workflows/ # CI/CD pipeline examples
125
+ ├── package.json
126
+ └── README.md
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Configuration
132
+
133
+ ### Basic Settings
134
+
135
+ Edit `config/iocd.cli.config.json`:
136
+
137
+ ```json
138
+ {
139
+ "productName": "Your Product Name",
140
+ "productSlug": "your-product-slug",
141
+ "company": "Your Company",
142
+ "version": "1.0.0",
143
+ "win": {
144
+ "exe": {
145
+ "exeName": "your-product.exe",
146
+ "exeIconPath": "path/to/icon.ico"
147
+ },
148
+ "codeSign": {
149
+ "type": "pfx",
150
+ "pfxPath": "path/to/certificate.pfx"
151
+ }
152
+ },
153
+ "mac": {
154
+ "appBundleName": "Your Product.app",
155
+ "appBundleId": "com.yourcompany.product"
156
+ }
157
+ }
158
+ ```
159
+
160
+ ### License Key
161
+
162
+ Set your license key using:
163
+ - **Environment variable**: `IOCD_LICENSE_KEY`
164
+ - **Config file**: `config/iocd.license.key`
165
+
166
+ ---
167
+
168
+ ## Customization
169
+
170
+ ### Applying Modifications
171
+
172
+ Modifications are the recommended way to customize io.Connect Desktop components without directly editing component files. They allow you to change configurations, add applications, modify assets, and override default behavior while preserving your changes across component updates.
173
+
174
+ **Key Concepts:**
175
+
176
+ - **Modifications are stored separately** from components in the `modifications/` folder
177
+ - **Changes persist** when components are updated or reinstalled
178
+ - **Mode-specific modifications** allow different behavior in dev vs. build mode
179
+ - **Files are copied or merged** into components when running `iocd dev` or `iocd build`
180
+
181
+ **Directory Structure:**
182
+
183
+ ```
184
+ modifications/
185
+ ├── base/ # Applied in all modes
186
+ └── iocd/
187
+ │ ├── config/
188
+ ├── assets/
189
+ │ └── apps/
190
+ ├── dev/ # Applied only in dev mode
191
+ └── iocd/
192
+ └── config/
193
+ └── build/ # Applied only in build mode
194
+ └── iocd/
195
+ └── config/
196
+ ```
197
+
198
+ **Processing Order:**
199
+
200
+ 1. **Base modifications** (`modifications/base/`) are applied first
201
+ 2. **Mode-specific modifications** (`modifications/dev/` or `modifications/build/`) are applied second, overriding base when needed
202
+
203
+ **Common Use Cases:**
204
+
205
+ - Replace logos and icons in `modifications/base/iocd/assets/`
206
+ - Configure system settings in `modifications/base/iocd/config/`
207
+ - Add application definitions in `modifications/base/iocd/apps/`
208
+ - Use different URLs for dev (localhost) vs. build (file://) in mode-specific folders
209
+
210
+ **Special File Types:**
211
+
212
+ - **`.json.merge`** - Deep merges with existing JSON instead of replacing
213
+ - **`.delete`** - Removes the corresponding file
214
+ - **`.replace`** marker - Replaces entire directory (place in directory to replace)
215
+
216
+ ### Changing io.CD System Config
217
+
218
+ The io.Connect Desktop system configuration (`system.json`) controls platform-wide settings like auto-updates, logging, and feature flags. To customize these settings, create modification files that merge with the default configuration.
219
+
220
+ **Location:**
221
+ ```
222
+ modifications/base/iocd/config/system.json.merge
223
+ ```
224
+
225
+ **Example - Enable Auto-Updates:**
226
+
227
+ ```json
228
+ {
229
+ "autoUpdater": {
230
+ "enabled": true,
231
+ "updateSource": {
232
+ "type": "Service",
233
+ "baseUrl": "https://updates.yourcompany.com"
234
+ },
235
+ "interval": 60
236
+ }
237
+ }
238
+ ```
239
+
240
+ **Example - Configure Logging:**
241
+
242
+ ```json
243
+ {
244
+ "logging": {
245
+ "level": "info",
246
+ "appender": "default"
247
+ }
248
+ }
249
+ ```
250
+
251
+ **Mode-Specific Configuration:**
252
+
253
+ Use different settings for dev vs. build mode:
254
+
255
+ **Dev mode** (`modifications/dev/iocd/config/system.json.merge`):
256
+ ```json
257
+ {
258
+ "logging": {
259
+ "level": "debug"
260
+ },
261
+ "features": {
262
+ "devTools": true
263
+ }
264
+ }
265
+ ```
266
+
267
+ **Build mode** (`modifications/build/iocd/config/system.json.merge`):
268
+ ```json
269
+ {
270
+ "logging": {
271
+ "level": "error"
272
+ },
273
+ "features": {
274
+ "telemetry": true
275
+ }
276
+ }
277
+ ```
278
+
279
+ **Important Notes:**
280
+
281
+ - Use `.merge` extension to deep merge with existing configuration
282
+ - Without `.merge`, the file completely replaces the original
283
+ - Changes are applied when running `iocd dev` or `iocd build`
284
+ - Environment variables like `${PRODUCT_VERSION}` are automatically expanded
285
+
286
+ ### Changing the Logo
287
+
288
+ Replace the default logo files in `modifications/base/iocd/assets/images/`:
289
+
290
+ ```bash
291
+ modifications/base/iocd/assets/
292
+ └── images/
293
+ ├── logo.ico # Windows executable icon (multiple resolutions)
294
+ ├── logo.icns # macOS app bundle icon (multiple resolutions)
295
+ └── logo.png # Application icon (used in UI)
296
+ ```
297
+
298
+ **Requirements:**
299
+ - **logo.ico**: Windows icon file with multiple sizes (16x16, 32x32, 48x48, 256x256)
300
+ - **logo.icns**: macOS icon file with multiple sizes (use Icon Composer or iconutil)
301
+ - **logo.png**: PNG file, recommended size 512x512
302
+
303
+ ### Custom Applications
304
+
305
+ io.Connect Desktop includes several built-in applications that you can replace with your own custom versions:
306
+
307
+ - **Workspaces** - Workspace management UI
308
+ - **Groups** - Window grouping UI
309
+ - **Splash Screen** - Application splash screen
310
+ - **Launchpad** - Application launcher
311
+ - **Notifications** - Notification center
312
+
313
+ Applications in the `apps/` folder allow you to customize these built-in apps or add entirely new functionality. This approach keeps your core platform applications in the same repository, eliminating the need to manage them across multiple repositories and simplifying version control, deployment, and coordination.
314
+
315
+ #### Using Template Applications
316
+
317
+ Template applications can be selected during project creation or added later:
318
+
319
+ ```bash
320
+ # Add template application
321
+ iocd apps add workspaces
322
+
323
+ # List available templates
324
+ iocd apps list --available
325
+ ```
326
+
327
+ **Available templates:**
328
+ - `workspaces` - Workspace management
329
+ - `groups` - Window grouping
330
+ - `splash-screen` - Loading screen
331
+ - `launchpad` - Application launcher
332
+
333
+ Once added, build your implementation on top of the template in the `apps/` folder.
334
+
335
+ #### Creating Custom Applications
336
+
337
+ For custom applications, create a folder in `apps/` with an `iocd.app.json` file:
338
+
339
+ ```
340
+ apps/
341
+ └── my-custom-app/
342
+ ├── iocd.app.json # Defines modifications and build behavior
343
+ ├── package.json
344
+ └── src/
345
+ ```
346
+
347
+ **Example `iocd.app.json`:**
348
+
349
+ In this example:
350
+ - **Dev mode** (triggered by `iocd dev` or `npm run dev`): Executes a `start` script (typically starts a dev server with hot-reload) and copies the development app configuration so the app definition points to the dev server
351
+ - **Build mode** (triggered by `iocd build` or `npm run build`): Executes a `build` script (typically builds optimized production assets) and copies the final built assets to the modifications folder
352
+
353
+ ```json
354
+ {
355
+ "dev": {
356
+ "script": "start",
357
+ "modifications": [
358
+ {
359
+ "source": "/config/my-app-dev.json",
360
+ "destination": "/modifications/dev/iocd/config/apps/my-app.json"
361
+ }
362
+ ]
363
+ },
364
+ "build": {
365
+ "script": "build",
366
+ "modifications": [
367
+ {
368
+ "source": "/dist/",
369
+ "destination": "/modifications/build/iocd/assets/my-app"
370
+ }
371
+ ]
372
+ }
373
+ }
374
+ ```
375
+
376
+ The `iocd.app.json` file defines:
377
+ - **base**: Array of modifications applied in all modes
378
+ - **dev**: Object with optional `script` (npm script name) and `modifications` array
379
+ - **build**: Object with optional `script` (npm script name) and `modifications` array
380
+
381
+ #### Managing Applications
382
+
383
+ ```bash
384
+ # Install application dependencies
385
+ iocd apps install
386
+
387
+ # Start applications in dev mode
388
+ iocd apps dev
389
+
390
+ # Build applications for production
391
+ iocd apps build
392
+ ```
393
+
394
+ ---
395
+
396
+ ## Development
397
+
398
+ Development mode allows you to quickly start io.Connect Desktop with all your configured changes and applications, enabling rapid iteration and testing during development.
399
+
400
+ When you run dev mode, the CLI will:
401
+ 1. **Apply all relevant modifications** - Base modifications and dev-specific modifications are copied to components
402
+ 2. **Start all applications** - Runs the dev script for each app (typically starting dev servers with hot-reload)
403
+ 3. **Launch io.Connect Desktop** - Starts the platform with all changes applied
404
+
405
+ ```bash
406
+ # Start io.Connect Desktop in dev mode
407
+ iocd dev
408
+
409
+ # Or using npm script
410
+ npm run dev
411
+ ```
412
+
413
+ ### Installing or Updating components during development
414
+ To install a component or update existing component while in development mode, use the following command:
415
+
416
+ ```bash
417
+ # Update components
418
+ iocd components install <component-name>
419
+
420
+ # Or using npm script (note the -- before the component name)
421
+ npm run components-install -- <component-name>
422
+ ```
423
+
424
+ This command will download and install the latest version of the specified component.
425
+
426
+ If you want to install a specific version, use:
427
+
428
+ ```bash
429
+ iocd components install <component-name>@<version>
430
+
431
+ # Or using npm script (note the -- before the component name)
432
+ npm run components-install -- <component-name>@<version>
433
+ ```
434
+ ---
435
+
436
+ ## Testing
437
+
438
+ Testing is based on **WebdriverIO** and depends on the `@interopio/wdio-iocd-service` package, which enables starting and controlling io.Connect Desktop from WebDriver. This allows you to create and run comprehensive end-to-end (E2E) tests for your io.Connect Desktop application.
439
+
440
+ ### Running Tests
441
+
442
+ Tests are written in the `tests/` folder and can be executed using:
443
+
444
+ ```bash
445
+ # Run all tests
446
+ npm test
447
+
448
+ # Or using the WebdriverIO CLI directly
449
+ npx wdio run ./wdio.config.ts
450
+ ```
451
+
452
+ ### Writing Tests
453
+
454
+ Tests are written using WebdriverIO syntax with the io.Connect Desktop service handling application lifecycle. Example test structure:
455
+
456
+ ```javascript
457
+ describe('io.Connect Desktop Application', () => {
458
+ it('should launch successfully', async () => {
459
+ // Your test logic here
460
+ // The @interopio/wdio-iocd-service handles starting/stopping io.Connect Desktop
461
+ });
462
+ });
463
+ ```
464
+
465
+ Add your test files to the `tests/` directory. They'll run automatically in CI/CD pipelines.
466
+
467
+ ---
468
+
469
+ ## Building for Production
470
+
471
+ The build process creates production-ready installers for distribution. It orchestrates multiple steps to produce signed, optimized packages ready for deployment.
472
+
473
+ **What happens during build:**
474
+
475
+ 1. **Build all applications** - Executes build scripts for each app in production mode
476
+ 2. **Reinstall components** - Downloads and installs fresh component versions
477
+ 3. **Apply all modifications** - Copies base and build-specific modifications to components
478
+ 4. **Code sign binaries** - Signs executables and libraries (if configured)
479
+ 5. **Create build artifacts** - Generates installers (`.exe` setup on Windows, `.dmg` on macOS, `.zip` archives)
480
+ 6. **Publish to release server** - Uploads artifacts for auto-updates (if configured)
481
+
482
+ **Build System:**
483
+
484
+ The build process is based on [Electron Forge](https://www.electronforge.io/), a complete toolchain for building and packaging Electron applications. The main configuration is located in `config/forge.config.js`, where you can customize makers, publishers, and build behavior.
485
+
486
+ ### Build Commands
487
+
488
+ ```bash
489
+ # Build installer
490
+ iocd build
491
+
492
+ # Or using npm script
493
+ npm run build
494
+
495
+ # Build options
496
+ iocd build --output custom/path # Custom output directory
497
+ iocd build --publish-only # Skip build, only publish
498
+ iocd build --skip-install # Skip component installation
499
+ ```
500
+
501
+ ### Build Output
502
+
503
+ Depending on OS you can configure Electron Forge makers to produce different types of artifacts. We have tested the following configurations:
504
+
505
+ For **Windows**:
506
+ - **Artifact Types**:
507
+ - Squirrel.Windows installer (`.exe` setup)
508
+ - Portable ZIP archive
509
+
510
+ For **macOS**:
511
+ - **Artifact Types**:
512
+ - DMG disk image
513
+ - ZIP archive
514
+
515
+ The full list of makers is available in the [Electron Forge documentation](https://www.electronforge.io/config/makers).
516
+
517
+ ### Code Signing
518
+
519
+ Code signing ensures that your application is trusted by operating systems and users can verify it hasn't been tampered with. Both Windows and macOS require code signing for distribution.
520
+
521
+ #### Windows Code Signing
522
+
523
+ ##### Option 1: PFX Certificate File
524
+
525
+ ```json
526
+ {
527
+ "win": {
528
+ "codeSign": {
529
+ "type": "signtool",
530
+ "pfxPath": "path/to/certificate.pfx",
531
+ "pfxPassword": "${WIN_PFX_PASS}"
532
+ }
533
+ }
534
+ }
535
+ ```
536
+
537
+ ##### Option 2: Certificate Store (e.g., DigiCert KeyLocker)
538
+
539
+ ```json
540
+ {
541
+ "win": {
542
+ "codeSign": {
543
+ "type": "signtool",
544
+ "certificateSha1": "${WIN_CERT_SHA1}"
545
+ }
546
+ }
547
+ }
548
+ ```
549
+
550
+ **Important**:
551
+ - If using DigiCert KeyLocker, run `smctl windows certsync` before building to sync certificates to Windows store
552
+ - Either `pfxPath` or `certificateSha1` must be provided (not both)
553
+ - Set type to `"off"` to disable code signing
554
+
555
+ ##### Option 3: Custom Script
556
+
557
+ For advanced signing scenarios, you can provide a custom signing script:
558
+
559
+ ```json
560
+ {
561
+ "win": {
562
+ "codeSign": {
563
+ "type": "custom",
564
+ "customCodeSignScriptPath": "path/to/custom-sign.js"
565
+ }
566
+ }
567
+ }
568
+ ```
569
+
570
+ Your custom script should export a function that receives the binary path and config:
571
+
572
+ ```javascript
573
+ // custom-sign.js
574
+ module.exports = async function(binaryPath, config) {
575
+ // Your custom signing logic here
576
+ console.log(`Signing ${binaryPath}`);
577
+ // Use any signing tool or API you need
578
+ };
579
+ ```
580
+
581
+ #### macOS Code Signing
582
+
583
+ ##### Code Signing Configuration
584
+
585
+ ```json
586
+ {
587
+ "mac": {
588
+ "codeSign": {
589
+ "type": "keychain",
590
+ "identity": "Developer ID Application: Your Company (TEAM_ID)"
591
+ }
592
+ }
593
+ }
594
+ ```
595
+
596
+ **Options**:
597
+ - `type`: `"keychain"` (use keychain certificate), `"certificate"` (use .p12 file), `"custom"` (custom script), or `"off"` (no signing)
598
+ - `identity`: Developer ID Application identity or SHA-1 hash (optional - auto-selected if not specified)
599
+ - `keychain`: Keychain name or path (optional - uses default keychain if not specified)
600
+
601
+ **Custom Script Option:**
602
+
603
+ For advanced signing scenarios, you can provide a custom signing script:
604
+
605
+ ```json
606
+ {
607
+ "mac": {
608
+ "codeSign": {
609
+ "type": "custom",
610
+ "customCodeSignScriptPath": "path/to/custom-sign.js"
611
+ }
612
+ }
613
+ }
614
+ ```
615
+
616
+ Your custom script should export a function that receives the app bundle path and config:
617
+
618
+ ```javascript
619
+ // custom-sign.js
620
+ module.exports = async function(appBundlePath, config) {
621
+ // Your custom signing logic here
622
+ console.log(`Signing ${appBundlePath}`);
623
+ // Use any signing tool or API you need
624
+ };
625
+ ```
626
+
627
+ ##### Notarization Configuration
628
+
629
+ ```json
630
+ {
631
+ "mac": {
632
+ "notarization": {
633
+ "type": "notarytool",
634
+ "appleId": "${MAC_NOTARIZATION_APPLE_ID}",
635
+ "appleIdPassword": "${MAC_NOTARIZATION_APPLE_ID_PASSWORD}",
636
+ "appleTeamId": "${MAC_NOTARIZATION_APPLE_TEAM_ID}"
637
+ }
638
+ }
639
+ }
640
+ ```
641
+
642
+ **Important**:
643
+ - Notarization is required for distribution outside Mac App Store
644
+ - Use app-specific password (not your regular Apple ID password)
645
+ - Generate app-specific password at appleid.apple.com
646
+ - Set type to `"off"` to skip notarization (for development builds)
647
+
648
+ **Custom Script Option:**
649
+
650
+ For advanced notarization scenarios, you can provide a custom notarization script:
651
+
652
+ ```json
653
+ {
654
+ "mac": {
655
+ "notarization": {
656
+ "type": "custom",
657
+ "customNotarizationScriptPath": "path/to/custom-notarize.js"
658
+ }
659
+ }
660
+ }
661
+ ```
662
+
663
+ Your custom script should export a function that receives the app bundle path and config:
664
+
665
+ ```javascript
666
+ // custom-notarize.js
667
+ module.exports = async function(appBundlePath, config) {
668
+ // Your custom notarization logic here
669
+ console.log(`Notarizing ${appBundlePath}`);
670
+ // Use any notarization tool or API you need
671
+ };
672
+ ```
673
+
674
+ ### CI/CD Integration
675
+
676
+ Continuous Integration and Continuous Deployment (CI/CD) automates building, testing, and publishing your io.Connect Desktop application. The seed project includes an GitHub Actions workflow located in `.github/workflows/build.yml`. It produces signed installers and can publish them to a release server.
677
+
678
+ ### Auto-Updates
679
+
680
+ Setting up auto-updates allows your users to automatically receive new versions of your application.
681
+
682
+ **Requirements:**
683
+
684
+ Auto-updates are supported for specific build artifact types:
685
+ - **Windows**: Squirrel.Windows installers (`.exe` setup files)
686
+ - **macOS**: ZIP archives
687
+
688
+ Other build outputs (portable ZIP on Windows, DMG on macOS) do not support automatic updates.
689
+
690
+ **Setup Steps:**
691
+
692
+ **1. Set up a release server**
693
+
694
+ You can use existing solutions or build your own:
695
+ - **Existing services**: Nucleus, Hazel, or other update servers (see [Electron update services](https://www.electronjs.org/docs/latest/tutorial/updates#using-other-update-services))
696
+ - **Custom solution**: Build your own update server following Squirrel protocols
697
+
698
+ **2. Configure io.Connect Desktop to check the update server**
699
+
700
+ Create or modify `modifications/base/iocd/config/system.json.merge`:
701
+
702
+ ```json
703
+ {
704
+ "autoUpdater": {
705
+ "enabled": true,
706
+ "updateSource": {
707
+ "type": "Service",
708
+ "baseUrl": "https://updates.yourcompany.com"
709
+ },
710
+ "interval": 60
711
+ }
712
+ }
713
+ ```
714
+
715
+ **3. Publish updates**
716
+
717
+ Choose one of the following approaches:
718
+
719
+ **Option A: Automatic publishing during build** - Configure publishers in `config/forge.config.js`:
720
+
721
+ ```javascript
722
+ publishers: [
723
+ {
724
+ name: '@electron-forge/publisher-electron-release-server',
725
+ config: {
726
+ baseUrl: 'https://updates.yourcompany.com',
727
+ username: process.env.RELEASE_SERVER_USERNAME,
728
+ password: process.env.RELEASE_SERVER_PASSWORD
729
+ }
730
+ }
731
+ ]
732
+ ```
733
+
734
+ **Option B: Manual upload** - After building, manually upload the installer artifacts to your release server.
735
+
736
+ **4. Test auto-updates**
737
+
738
+ - Install your application using the signed installer
739
+ - Publish a new version to your update server
740
+ - Launch the application and verify it detects and installs the update
741
+
742
+ ---
743
+
744
+ ## Troubleshooting
745
+
746
+ ### Common Issues
747
+
748
+ **Build fails with "License not found"**
749
+ - Ensure `IOCD_LICENSE_KEY` environment variable is set
750
+ - Or create `config/iocd.license.key` file with your license key
751
+
752
+ **Code signing fails on Windows**
753
+ - Verify certificate is valid and not expired
754
+ - Check that `pfxPassword` is correct
755
+ - For certificate store signing: Ensure `smctl windows certsync` was run first
756
+ - Verify exactly one of `pfxPath` or `certificateSha1` is configured (not both)
757
+
758
+ **macOS notarization fails**
759
+ - Use app-specific password, not regular Apple ID password
760
+ - Generate app-specific password at appleid.apple.com
761
+ - Verify Apple Developer Program membership is active
762
+ - Check that `appleTeamId` matches your Developer Team ID
763
+
764
+ **Application won't start in dev mode**
765
+ - Run `iocd setup` to verify component installation
766
+ - Check that `components/iocd` directory exists
767
+ - Review logs in system temp directory
768
+
769
+ **Components not downloading**
770
+ - Verify network connectivity
771
+ - Check component store configuration in `config/iocd.cli.config.json`
772
+ - For GitHub store: Ensure repository access and credentials are correct
773
+
774
+ ### Getting Help
775
+
776
+ - 📚 [Documentation](https://docs.interop.io/desktop)
777
+ - 💬 [Community Forum](https://community.interop.io)
778
+ - 📧 [Support Portal](https://support.interop.io)
779
+
780
+ ---