@interopio/iocd-cli 0.0.39 → 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 (83) hide show
  1. package/README.md +780 -779
  2. package/dist/services/installer/electronForge.js +5 -3
  3. package/dist/services/installer/electronForge.js.map +1 -1
  4. package/dist/services/installer/macOS.helper.js +0 -1
  5. package/dist/services/installer/macOS.helper.js.map +1 -1
  6. package/dist/services/license.service.js +14 -14
  7. package/dist/templates/groups/apps/groups/.gitignore.template +23 -23
  8. package/dist/templates/groups/apps/groups/README.md +15 -15
  9. package/dist/templates/groups/apps/groups/config/web-group-dev.json +12 -12
  10. package/dist/templates/groups/apps/groups/index.html +17 -17
  11. package/dist/templates/groups/apps/groups/iocd.app.json +19 -19
  12. package/dist/templates/groups/apps/groups/package.json +25 -25
  13. package/dist/templates/groups/apps/groups/public/manifest.json +24 -24
  14. package/dist/templates/groups/apps/groups/public/robots.txt +3 -3
  15. package/dist/templates/groups/apps/groups/src/App.css +38 -38
  16. package/dist/templates/groups/apps/groups/src/App.tsx +11 -11
  17. package/dist/templates/groups/apps/groups/src/index.css +13 -13
  18. package/dist/templates/groups/apps/groups/src/index.tsx +19 -19
  19. package/dist/templates/groups/apps/groups/vite.config.ts +8 -8
  20. package/dist/templates/groups/template.json +12 -12
  21. package/dist/templates/ioconnect-desktop/.github/actions/setup-smctl/action.yml +121 -121
  22. package/dist/templates/ioconnect-desktop/.github/workflows/build.yml +395 -395
  23. package/dist/templates/ioconnect-desktop/.gitignore.template +15 -15
  24. package/dist/templates/ioconnect-desktop/README.md +780 -779
  25. package/dist/templates/ioconnect-desktop/config/forge.config.js +59 -59
  26. package/dist/templates/ioconnect-desktop/config/iocd.cli.config.json +16 -16
  27. package/dist/templates/ioconnect-desktop/config/mac-build/entitlements.mac.plist +44 -44
  28. package/dist/templates/ioconnect-desktop/config/win-build/template.nuspectemplate +32 -32
  29. package/dist/templates/ioconnect-desktop/modifications/base/iocd/config/system.json.merge +2 -2
  30. package/dist/templates/ioconnect-desktop/modifications/base/iocd/config/system.json.merge-autoUpdate +9 -9
  31. package/dist/templates/ioconnect-desktop/package.json +33 -33
  32. package/dist/templates/ioconnect-desktop/template.json +6 -6
  33. package/dist/templates/launchpad/apps/launchpad/.eslintrc.json +3 -3
  34. package/dist/templates/launchpad/apps/launchpad/.gitignore.template +1 -1
  35. package/dist/templates/launchpad/apps/launchpad/config/iocd.app.def.dev.json +56 -56
  36. package/dist/templates/launchpad/apps/launchpad/config/iocd.system.build.json +2 -2
  37. package/dist/templates/launchpad/apps/launchpad/config/iocd.system.dev.json +2 -2
  38. package/dist/templates/launchpad/apps/launchpad/index.html +16 -16
  39. package/dist/templates/launchpad/apps/launchpad/iocd.app.json +27 -27
  40. package/dist/templates/launchpad/apps/launchpad/package-lock.json +2778 -2778
  41. package/dist/templates/launchpad/apps/launchpad/package.json +21 -21
  42. package/dist/templates/launchpad/apps/launchpad/src/app/app.tsx +41 -41
  43. package/dist/templates/launchpad/apps/launchpad/src/app/constants.ts +27 -27
  44. package/dist/templates/launchpad/apps/launchpad/src/components/logo.tsx +11 -11
  45. package/dist/templates/launchpad/apps/launchpad/src/components/main-context-menu.tsx +161 -161
  46. package/dist/templates/launchpad/apps/launchpad/src/components/notifications-button.tsx +44 -44
  47. package/dist/templates/launchpad/apps/launchpad/src/main.tsx +6 -6
  48. package/dist/templates/launchpad/apps/launchpad/src/styles.css +16 -16
  49. package/dist/templates/launchpad/apps/launchpad/tsconfig.json +10 -10
  50. package/dist/templates/launchpad/apps/launchpad/vite.config.ts +13 -13
  51. package/dist/templates/launchpad/template.json +12 -12
  52. package/dist/templates/splash/apps/splash/assets/styles/style.css +39 -39
  53. package/dist/templates/splash/apps/splash/iocd.app.json +7 -7
  54. package/dist/templates/splash/apps/splash/script.js +53 -53
  55. package/dist/templates/splash/apps/splash/splash.html +25 -25
  56. package/dist/templates/splash/template.json +12 -12
  57. package/dist/templates/tests/template.json +8 -8
  58. package/dist/templates/tests/tests/package-lock.json +7289 -7289
  59. package/dist/templates/tests/tests/package.json +22 -22
  60. package/dist/templates/tests/tests/tests/sample.spec.ts +30 -30
  61. package/dist/templates/tests/tests/tsconfig.json +10 -10
  62. package/dist/templates/tests/tests/wdio.config.ts +32 -32
  63. package/dist/templates/workspaces/apps/workspaces/README.md +15 -15
  64. package/dist/templates/workspaces/apps/workspaces/config/workspaces-dev.json +20 -20
  65. package/dist/templates/workspaces/apps/workspaces/index.html +17 -17
  66. package/dist/templates/workspaces/apps/workspaces/iocd.app.json +19 -19
  67. package/dist/templates/workspaces/apps/workspaces/package.json +29 -29
  68. package/dist/templates/workspaces/apps/workspaces/public/manifest.json +25 -25
  69. package/dist/templates/workspaces/apps/workspaces/public/robots.txt +3 -3
  70. package/dist/templates/workspaces/apps/workspaces/src/App.css +38 -38
  71. package/dist/templates/workspaces/apps/workspaces/src/App.tsx +102 -102
  72. package/dist/templates/workspaces/apps/workspaces/src/index.css +3 -3
  73. package/dist/templates/workspaces/apps/workspaces/src/index.tsx +28 -28
  74. package/dist/templates/workspaces/apps/workspaces/src/logo.svg +7 -7
  75. package/dist/templates/workspaces/apps/workspaces/src/reportWebVitals.ts +15 -15
  76. package/dist/templates/workspaces/apps/workspaces/src/setupTests.ts +5 -5
  77. package/dist/templates/workspaces/apps/workspaces/vite.config.ts +8 -8
  78. package/dist/templates/workspaces/template.json +12 -12
  79. package/package.json +83 -83
  80. package/scripts/copy-assets.js +19 -19
  81. package/scripts/delete-dist.js +12 -12
  82. package/scripts/generate-schema.js +50 -50
  83. package/scripts/handle-gitignore-templates.js +157 -157
package/README.md CHANGED
@@ -1,779 +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
- - [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
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
- npm run components-install <component-name>@<version>
432
- ```
433
- ---
434
-
435
- ## Testing
436
-
437
- 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.
438
-
439
- ### Running Tests
440
-
441
- Tests are written in the `tests/` folder and can be executed using:
442
-
443
- ```bash
444
- # Run all tests
445
- npm test
446
-
447
- # Or using the WebdriverIO CLI directly
448
- npx wdio run ./wdio.config.ts
449
- ```
450
-
451
- ### Writing Tests
452
-
453
- Tests are written using WebdriverIO syntax with the io.Connect Desktop service handling application lifecycle. Example test structure:
454
-
455
- ```javascript
456
- describe('io.Connect Desktop Application', () => {
457
- it('should launch successfully', async () => {
458
- // Your test logic here
459
- // The @interopio/wdio-iocd-service handles starting/stopping io.Connect Desktop
460
- });
461
- });
462
- ```
463
-
464
- Add your test files to the `tests/` directory. They'll run automatically in CI/CD pipelines.
465
-
466
- ---
467
-
468
- ## Building for Production
469
-
470
- The build process creates production-ready installers for distribution. It orchestrates multiple steps to produce signed, optimized packages ready for deployment.
471
-
472
- **What happens during build:**
473
-
474
- 1. **Build all applications** - Executes build scripts for each app in production mode
475
- 2. **Reinstall components** - Downloads and installs fresh component versions
476
- 3. **Apply all modifications** - Copies base and build-specific modifications to components
477
- 4. **Code sign binaries** - Signs executables and libraries (if configured)
478
- 5. **Create build artifacts** - Generates installers (`.exe` setup on Windows, `.dmg` on macOS, `.zip` archives)
479
- 6. **Publish to release server** - Uploads artifacts for auto-updates (if configured)
480
-
481
- **Build System:**
482
-
483
- 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.
484
-
485
- ### Build Commands
486
-
487
- ```bash
488
- # Build installer
489
- iocd build
490
-
491
- # Or using npm script
492
- npm run build
493
-
494
- # Build options
495
- iocd build --output custom/path # Custom output directory
496
- iocd build --publish-only # Skip build, only publish
497
- iocd build --skip-install # Skip component installation
498
- ```
499
-
500
- ### Build Output
501
-
502
- Depending on OS you can configure Electron Forge makers to produce different types of artifacts. We have tested the following configurations:
503
-
504
- For **Windows**:
505
- - **Artifact Types**:
506
- - Squirrel.Windows installer (`.exe` setup)
507
- - Portable ZIP archive
508
-
509
- For **macOS**:
510
- - **Artifact Types**:
511
- - DMG disk image
512
- - ZIP archive
513
-
514
- The full list of makers is available in the [Electron Forge documentation](https://www.electronforge.io/config/makers).
515
-
516
- ### Code Signing
517
-
518
- 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.
519
-
520
- #### Windows Code Signing
521
-
522
- ##### Option 1: PFX Certificate File
523
-
524
- ```json
525
- {
526
- "win": {
527
- "codeSign": {
528
- "type": "signtool",
529
- "pfxPath": "path/to/certificate.pfx",
530
- "pfxPassword": "${WIN_PFX_PASS}"
531
- }
532
- }
533
- }
534
- ```
535
-
536
- ##### Option 2: Certificate Store (e.g., DigiCert KeyLocker)
537
-
538
- ```json
539
- {
540
- "win": {
541
- "codeSign": {
542
- "type": "signtool",
543
- "certificateSha1": "${WIN_CERT_SHA1}"
544
- }
545
- }
546
- }
547
- ```
548
-
549
- **Important**:
550
- - If using DigiCert KeyLocker, run `smctl windows certsync` before building to sync certificates to Windows store
551
- - Either `pfxPath` or `certificateSha1` must be provided (not both)
552
- - Set type to `"off"` to disable code signing
553
-
554
- ##### Option 3: Custom Script
555
-
556
- For advanced signing scenarios, you can provide a custom signing script:
557
-
558
- ```json
559
- {
560
- "win": {
561
- "codeSign": {
562
- "type": "custom",
563
- "customCodeSignScriptPath": "path/to/custom-sign.js"
564
- }
565
- }
566
- }
567
- ```
568
-
569
- Your custom script should export a function that receives the binary path and config:
570
-
571
- ```javascript
572
- // custom-sign.js
573
- module.exports = async function(binaryPath, config) {
574
- // Your custom signing logic here
575
- console.log(`Signing ${binaryPath}`);
576
- // Use any signing tool or API you need
577
- };
578
- ```
579
-
580
- #### macOS Code Signing
581
-
582
- ##### Code Signing Configuration
583
-
584
- ```json
585
- {
586
- "mac": {
587
- "codeSign": {
588
- "type": "keychain",
589
- "identity": "Developer ID Application: Your Company (TEAM_ID)"
590
- }
591
- }
592
- }
593
- ```
594
-
595
- **Options**:
596
- - `type`: `"keychain"` (use keychain certificate), `"certificate"` (use .p12 file), `"custom"` (custom script), or `"off"` (no signing)
597
- - `identity`: Developer ID Application identity or SHA-1 hash (optional - auto-selected if not specified)
598
- - `keychain`: Keychain name or path (optional - uses default keychain if not specified)
599
-
600
- **Custom Script Option:**
601
-
602
- For advanced signing scenarios, you can provide a custom signing script:
603
-
604
- ```json
605
- {
606
- "mac": {
607
- "codeSign": {
608
- "type": "custom",
609
- "customCodeSignScriptPath": "path/to/custom-sign.js"
610
- }
611
- }
612
- }
613
- ```
614
-
615
- Your custom script should export a function that receives the app bundle path and config:
616
-
617
- ```javascript
618
- // custom-sign.js
619
- module.exports = async function(appBundlePath, config) {
620
- // Your custom signing logic here
621
- console.log(`Signing ${appBundlePath}`);
622
- // Use any signing tool or API you need
623
- };
624
- ```
625
-
626
- ##### Notarization Configuration
627
-
628
- ```json
629
- {
630
- "mac": {
631
- "notarization": {
632
- "type": "notarytool",
633
- "appleId": "${MAC_NOTARIZATION_APPLE_ID}",
634
- "appleIdPassword": "${MAC_NOTARIZATION_APPLE_ID_PASSWORD}",
635
- "appleTeamId": "${MAC_NOTARIZATION_APPLE_TEAM_ID}"
636
- }
637
- }
638
- }
639
- ```
640
-
641
- **Important**:
642
- - Notarization is required for distribution outside Mac App Store
643
- - Use app-specific password (not your regular Apple ID password)
644
- - Generate app-specific password at appleid.apple.com
645
- - Set type to `"off"` to skip notarization (for development builds)
646
-
647
- **Custom Script Option:**
648
-
649
- For advanced notarization scenarios, you can provide a custom notarization script:
650
-
651
- ```json
652
- {
653
- "mac": {
654
- "notarization": {
655
- "type": "custom",
656
- "customNotarizationScriptPath": "path/to/custom-notarize.js"
657
- }
658
- }
659
- }
660
- ```
661
-
662
- Your custom script should export a function that receives the app bundle path and config:
663
-
664
- ```javascript
665
- // custom-notarize.js
666
- module.exports = async function(appBundlePath, config) {
667
- // Your custom notarization logic here
668
- console.log(`Notarizing ${appBundlePath}`);
669
- // Use any notarization tool or API you need
670
- };
671
- ```
672
-
673
- ### CI/CD Integration
674
-
675
- 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.
676
-
677
- ### Auto-Updates
678
-
679
- Setting up auto-updates allows your users to automatically receive new versions of your application.
680
-
681
- **Requirements:**
682
-
683
- Auto-updates are supported for specific build artifact types:
684
- - **Windows**: Squirrel.Windows installers (`.exe` setup files)
685
- - **macOS**: ZIP archives
686
-
687
- Other build outputs (portable ZIP on Windows, DMG on macOS) do not support automatic updates.
688
-
689
- **Setup Steps:**
690
-
691
- **1. Set up a release server**
692
-
693
- You can use existing solutions or build your own:
694
- - **Existing services**: Nucleus, Hazel, or other update servers (see [Electron update services](https://www.electronjs.org/docs/latest/tutorial/updates#using-other-update-services))
695
- - **Custom solution**: Build your own update server following Squirrel protocols
696
-
697
- **2. Configure io.Connect Desktop to check the update server**
698
-
699
- Create or modify `modifications/base/iocd/config/system.json.merge`:
700
-
701
- ```json
702
- {
703
- "autoUpdater": {
704
- "enabled": true,
705
- "updateSource": {
706
- "type": "Service",
707
- "baseUrl": "https://updates.yourcompany.com"
708
- },
709
- "interval": 60
710
- }
711
- }
712
- ```
713
-
714
- **3. Publish updates**
715
-
716
- Choose one of the following approaches:
717
-
718
- **Option A: Automatic publishing during build** - Configure publishers in `config/forge.config.js`:
719
-
720
- ```javascript
721
- publishers: [
722
- {
723
- name: '@electron-forge/publisher-electron-release-server',
724
- config: {
725
- baseUrl: 'https://updates.yourcompany.com',
726
- username: process.env.RELEASE_SERVER_USERNAME,
727
- password: process.env.RELEASE_SERVER_PASSWORD
728
- }
729
- }
730
- ]
731
- ```
732
-
733
- **Option B: Manual upload** - After building, manually upload the installer artifacts to your release server.
734
-
735
- **4. Test auto-updates**
736
-
737
- - Install your application using the signed installer
738
- - Publish a new version to your update server
739
- - Launch the application and verify it detects and installs the update
740
-
741
- ---
742
-
743
- ## Troubleshooting
744
-
745
- ### Common Issues
746
-
747
- **Build fails with "License not found"**
748
- - Ensure `IOCD_LICENSE_KEY` environment variable is set
749
- - Or create `config/iocd.license.key` file with your license key
750
-
751
- **Code signing fails on Windows**
752
- - Verify certificate is valid and not expired
753
- - Check that `pfxPassword` is correct
754
- - For certificate store signing: Ensure `smctl windows certsync` was run first
755
- - Verify exactly one of `pfxPath` or `certificateSha1` is configured (not both)
756
-
757
- **macOS notarization fails**
758
- - Use app-specific password, not regular Apple ID password
759
- - Generate app-specific password at appleid.apple.com
760
- - Verify Apple Developer Program membership is active
761
- - Check that `appleTeamId` matches your Developer Team ID
762
-
763
- **Application won't start in dev mode**
764
- - Run `iocd setup` to verify component installation
765
- - Check that `components/iocd` directory exists
766
- - Review logs in system temp directory
767
-
768
- **Components not downloading**
769
- - Verify network connectivity
770
- - Check component store configuration in `config/iocd.cli.config.json`
771
- - For GitHub store: Ensure repository access and credentials are correct
772
-
773
- ### Getting Help
774
-
775
- - 📚 [Documentation](https://docs.interop.io/desktop)
776
- - 💬 [Community Forum](https://community.interop.io)
777
- - 📧 [Support Portal](https://support.interop.io)
778
-
779
- ---
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
+ ---