@omega.js/desktop 0.50.0 → 0.51.0

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 (267) hide show
  1. package/README.md +1 -1
  2. package/dist/assets/css/tokens/_index.scss +1 -1
  3. package/dist/assets/themes/base/_includes/frontend/sections/account-section-header.html +4 -1
  4. package/dist/assets/themes/base/_includes/frontend/sections/footer.html +13 -6
  5. package/dist/assets/themes/base/_includes/frontend/sections/nav.html +10 -8
  6. package/dist/assets/themes/base/_includes/global/sections/account.html +3 -1
  7. package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +12 -8
  8. package/dist/assets/themes/base/_includes/global/sections/app-topbar.html +10 -6
  9. package/dist/assets/themes/base/_includes/global/sections/page-header.html +8 -4
  10. package/dist/assets/themes/base/_layouts/backend/pages/dashboard/index.html +24 -24
  11. package/dist/assets/themes/base/_layouts/frontend/pages/about.html +10 -10
  12. package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +35 -35
  13. package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +4 -4
  14. package/dist/assets/themes/base/_layouts/frontend/pages/auth/signin.html +1 -1
  15. package/dist/assets/themes/base/_layouts/frontend/pages/auth/signup.html +4 -4
  16. package/dist/assets/themes/base/_layouts/frontend/pages/contact.html +3 -3
  17. package/dist/assets/themes/base/_layouts/frontend/pages/download.html +34 -33
  18. package/dist/assets/themes/base/_layouts/frontend/pages/extension/index.html +11 -11
  19. package/dist/assets/themes/base/_layouts/frontend/pages/legal/document.html +1 -1
  20. package/dist/assets/themes/base/_layouts/frontend/pages/status.html +1 -1
  21. package/dist/assets/themes/base/_layouts/frontend/pages/team/index.html +9 -7
  22. package/dist/assets/themes/base/_layouts/frontend/pages/team/member.html +5 -3
  23. package/dist/assets/themes/base/_sections/about/letter/section.html +1 -1
  24. package/dist/assets/themes/base/_sections/about/letter/section.json5 +4 -4
  25. package/dist/assets/themes/base/_sections/marketing/bento/section.html +1 -1
  26. package/dist/assets/themes/base/_sections/marketing/bento/section.json5 +15 -15
  27. package/dist/assets/themes/base/_sections/marketing/cta/section.json5 +1 -1
  28. package/dist/assets/themes/base/_sections/marketing/hero/section.html +6 -6
  29. package/dist/assets/themes/base/_sections/marketing/hero/section.json5 +10 -10
  30. package/dist/assets/themes/base/_sections/marketing/product-demo/section.html +1 -1
  31. package/dist/assets/themes/base/_sections/marketing/product-demo/section.json5 +2 -2
  32. package/dist/assets/themes/base/_sections/marketing/stats/section.html +1 -1
  33. package/dist/assets/themes/base/_sections/marketing/stats/section.json5 +5 -5
  34. package/dist/assets/themes/base/_sections/marketing/trusted-by/section.html +1 -1
  35. package/dist/assets/themes/base/_sections/marketing/trusted-by/section.json5 +2 -2
  36. package/dist/assets/themes/neobrutalism/_layouts/frontend/pages/index.html +10 -10
  37. package/dist/assets/themes/newsflash/_layouts/frontend/pages/index.html +10 -10
  38. package/dist/assets/themes/newsflash/_sections/marketing/desks/section.html +2 -2
  39. package/dist/assets/themes/newsflash/_sections/marketing/desks/section.json5 +4 -4
  40. package/dist/build.js +69 -28
  41. package/dist/cli-run.js +20 -13
  42. package/dist/cli.js +12 -7
  43. package/dist/commands/build.js +0 -2
  44. package/dist/commands/deploy.js +116 -44
  45. package/dist/commands/finalize-release.js +5 -4
  46. package/dist/commands/launch.js +12 -7
  47. package/dist/commands/lib/deploy-precheck.js +66 -34
  48. package/dist/commands/lib/ensure-target.js +71 -11
  49. package/dist/commands/package.js +0 -1
  50. package/dist/commands/publish.js +11 -4
  51. package/dist/commands/release.js +99 -252
  52. package/dist/commands/runner.js +42 -5
  53. package/dist/commands/sign-windows.js +46 -15
  54. package/dist/commands/test.js +4 -3
  55. package/dist/commands/validate-certs.js +291 -115
  56. package/dist/config/page-template.html +4 -0
  57. package/dist/defaults/.github/workflows/build.yml +144 -64
  58. package/dist/defaults/AGENTS.md +3 -2
  59. package/dist/defaults/_.gitignore +4 -2
  60. package/dist/defaults/config/certs/README.md +25 -45
  61. package/dist/defaults/config/omega.json5 +66 -32
  62. package/dist/defaults/hooks/deploy/pre.js +10 -0
  63. package/dist/defaults/src/assets/scss/main.scss +12 -2
  64. package/dist/defaults/src/integrations/tray/index.js +1 -1
  65. package/dist/gulp/main.js +13 -25
  66. package/dist/gulp/tasks/audit.js +18 -6
  67. package/dist/gulp/tasks/build-config.js +181 -60
  68. package/dist/gulp/tasks/bundle.js +108 -36
  69. package/dist/gulp/tasks/release.js +86 -4
  70. package/dist/gulp/tasks/sass.js +11 -0
  71. package/dist/hooks/lib/notarize-tools.js +137 -0
  72. package/dist/hooks/notarize-artifacts.js +57 -0
  73. package/dist/hooks/notarize.js +59 -8
  74. package/dist/lib/auth-persistence.js +25 -0
  75. package/dist/lib/client-bridge.js +11 -8
  76. package/dist/lib/deep-link.js +15 -8
  77. package/dist/lib/protocol.js +7 -1
  78. package/dist/lib/restart-manager/install.js +6 -3
  79. package/dist/lib/sign-helpers/auto-unlock.js +65 -27
  80. package/dist/lib/sign-helpers/console-lock.js +34 -0
  81. package/dist/lib/sign-helpers/exec-with-limit.js +68 -0
  82. package/dist/lib/sign-helpers/resolve-icons.js +6 -4
  83. package/dist/lib/tray.js +7 -6
  84. package/dist/main.js +16 -0
  85. package/dist/preload.js +8 -0
  86. package/dist/renderer.js +16 -4
  87. package/dist/runner/job-started.js +104 -0
  88. package/dist/test/fixtures/consumer-app/config/omega.json5 +7 -0
  89. package/dist/test/fixtures/consumer-app/package.json +1 -1
  90. package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +7 -1
  91. package/dist/test/harness/main-entry.js +2 -1
  92. package/dist/test/harness/renderer-preload.js +12 -3
  93. package/dist/test/runners/boot.js +101 -11
  94. package/dist/test/runners/electron.js +1 -1
  95. package/dist/test/suites/boot/consumer-app-boots.test.js +54 -0
  96. package/dist/test/suites/build/audit.test.js +45 -6
  97. package/dist/test/suites/build/auth-persistence-resolve.test.js +119 -0
  98. package/dist/test/suites/build/auto-unlock.test.js +105 -0
  99. package/dist/test/suites/build/boot-runner-timeout.test.js +253 -0
  100. package/dist/test/suites/build/brand-scss.test.js +106 -0
  101. package/dist/test/suites/build/build-config.test.js +146 -36
  102. package/dist/test/suites/build/build-json-bake.test.js +245 -0
  103. package/dist/test/suites/build/build-verbs.test.js +48 -15
  104. package/dist/test/suites/build/build-workflow-jobs.test.js +190 -0
  105. package/dist/test/suites/build/cli.test.js +32 -10
  106. package/dist/test/suites/build/config-schema.test.js +4 -4
  107. package/dist/test/suites/build/console-lock.test.js +51 -0
  108. package/dist/test/suites/build/defaults-scaffold.test.js +71 -2
  109. package/dist/test/suites/build/deploy-direct.test.js +241 -0
  110. package/dist/test/suites/build/deploy-dispatch.test.js +287 -0
  111. package/dist/test/suites/build/deploy-hook.test.js +169 -0
  112. package/dist/test/suites/build/ensure-target.test.js +14 -2
  113. package/dist/test/suites/build/env-delivery.test.js +19 -10
  114. package/dist/test/suites/build/env-watch.test.js +18 -7
  115. package/dist/test/suites/build/esm-only-dependency.test.js +127 -0
  116. package/dist/test/suites/build/exec-with-limit.test.js +53 -0
  117. package/dist/test/suites/build/finalize-release.test.js +2 -2
  118. package/dist/test/suites/build/get-config.test.js +120 -8
  119. package/dist/test/suites/build/github-utils.test.js +12 -6
  120. package/dist/test/suites/build/license-stamp.test.js +6 -4
  121. package/dist/test/suites/build/manager.test.js +88 -68
  122. package/dist/test/suites/build/manifest-deps.test.js +116 -0
  123. package/dist/test/suites/build/merge-line-files.test.js +27 -4
  124. package/dist/test/suites/build/notarize-artifacts.test.js +135 -0
  125. package/dist/test/suites/build/notarize-tools.test.js +38 -0
  126. package/dist/test/suites/build/notarize.test.js +207 -0
  127. package/dist/test/suites/build/release-pipeline.test.js +38 -60
  128. package/dist/test/suites/build/release-skipped-upload.test.js +107 -0
  129. package/dist/test/suites/build/resolve-icons.test.js +35 -35
  130. package/dist/test/suites/build/runner-job-guard.test.js +182 -0
  131. package/dist/test/suites/build/runner.test.js +25 -2
  132. package/dist/test/suites/build/sentry.test.js +8 -3
  133. package/dist/test/suites/build/setup-scripts.test.js +3 -0
  134. package/dist/test/suites/build/sign-windows.test.js +92 -8
  135. package/dist/test/suites/build/test-stealth.test.js +17 -11
  136. package/dist/test/suites/build/url-helpers.test.js +37 -17
  137. package/dist/test/suites/build/validate-certs.test.js +428 -55
  138. package/dist/test/suites/build/validate-config.test.js +3 -3
  139. package/dist/test/suites/main/auth-flow.test.js +12 -0
  140. package/dist/test/suites/main/auth-persistence.test.js +14 -17
  141. package/dist/test/suites/main/auto-updater.test.js +2 -2
  142. package/dist/test/suites/main/boot-sequence.test.js +1 -1
  143. package/dist/test/suites/main/client-bridge.integration.test.js +5 -82
  144. package/dist/test/suites/main/client-bridge.test.js +19 -6
  145. package/dist/test/suites/main/deep-link.test.js +54 -0
  146. package/dist/test/suites/main/startup-paths-and-ua.test.js +1 -1
  147. package/dist/test/suites/main/url-helpers.test.js +81 -72
  148. package/dist/test/suites/renderer/cross-context-helpers.test.js +19 -16
  149. package/dist/utils/build-pipeline.js +10 -10
  150. package/dist/utils/github.js +12 -51
  151. package/dist/utils/load-env.js +66 -0
  152. package/dist/utils/mode-helpers.js +43 -111
  153. package/dist/utils/platform.js +37 -0
  154. package/dist/utils/runner-env.js +2 -1
  155. package/dist/utils/runner-job-guard.js +149 -0
  156. package/dist/utils/ship-keys.js +52 -0
  157. package/dist/utils/test-stealth.js +5 -3
  158. package/dist/utils/url-helpers.js +33 -17
  159. package/dist/vendor/config/bundle-id.js +53 -0
  160. package/dist/vendor/config/client-config.js +141 -0
  161. package/dist/vendor/config/company.js +334 -15
  162. package/dist/vendor/config/dev-facts.js +48 -0
  163. package/dist/vendor/config/env-delivery.js +231 -9
  164. package/dist/vendor/config/env-retired.js +137 -0
  165. package/dist/vendor/config/env-rules.js +22 -3
  166. package/dist/vendor/config/env-schema.js +234 -117
  167. package/dist/vendor/config/env.js +55 -26
  168. package/dist/vendor/config/environment.js +189 -0
  169. package/dist/vendor/config/hooks.js +13 -11
  170. package/dist/vendor/config/index.js +121 -44
  171. package/dist/vendor/config/load.js +366 -115
  172. package/dist/vendor/config/merge.js +2 -2
  173. package/dist/vendor/config/order.js +3 -3
  174. package/dist/vendor/config/platforms.js +276 -0
  175. package/dist/vendor/config/repo.js +226 -104
  176. package/dist/vendor/config/retired-keys.js +232 -27
  177. package/dist/vendor/config/schema.js +525 -99
  178. package/dist/vendor/config/site-global.js +63 -53
  179. package/dist/vendor/config/targets.js +187 -0
  180. package/dist/vendor/config/validate.js +119 -59
  181. package/dist/vendor/devkit/argv.js +118 -0
  182. package/dist/vendor/devkit/attach-log-file.js +21 -13
  183. package/dist/vendor/devkit/brand-tokens.js +278 -0
  184. package/dist/vendor/devkit/brand-version.js +264 -0
  185. package/dist/vendor/devkit/build-json.js +91 -0
  186. package/dist/vendor/devkit/bundle.js +48 -0
  187. package/dist/vendor/devkit/certificate-expiry.js +108 -0
  188. package/dist/vendor/devkit/certs.js +16 -194
  189. package/dist/vendor/devkit/ci-workflows.js +124 -8
  190. package/dist/vendor/devkit/cli-router.js +3 -3
  191. package/dist/vendor/devkit/defaults-engine.js +69 -7
  192. package/dist/vendor/devkit/deploy-follow.js +297 -0
  193. package/dist/vendor/devkit/deploy-precheck.js +23 -8
  194. package/dist/vendor/devkit/deploy-record.js +11 -27
  195. package/dist/vendor/devkit/deploy-snapshot.js +661 -0
  196. package/dist/vendor/devkit/deploy.js +445 -75
  197. package/dist/vendor/devkit/git-auth.js +73 -0
  198. package/dist/vendor/devkit/git-remote.js +95 -0
  199. package/dist/vendor/devkit/github-repo.js +290 -0
  200. package/dist/vendor/devkit/local.js +47 -0
  201. package/dist/vendor/devkit/merge-line-files.js +23 -16
  202. package/dist/vendor/devkit/omega-bin.js +18 -3
  203. package/dist/vendor/devkit/pack-local.js +391 -0
  204. package/dist/vendor/devkit/preludes/index.js +120 -0
  205. package/dist/vendor/devkit/preludes/origin-heal.js +156 -0
  206. package/dist/vendor/devkit/service-account.js +43 -0
  207. package/dist/vendor/devkit/ship-plan.js +112 -0
  208. package/dist/vendor/devkit/signing-env.js +180 -0
  209. package/dist/vendor/devkit/signing-tree.js +92 -0
  210. package/dist/vendor/devkit/target-seams.js +142 -0
  211. package/dist/vendor/devkit/target-secrets.js +235 -50
  212. package/dist/vendor/devkit/test/esm-only-fixture.js +48 -0
  213. package/dist/vendor/devkit/test/fixtures/esm-only-package/browser.js +19 -0
  214. package/dist/vendor/devkit/test/fixtures/esm-only-package/index.js +20 -0
  215. package/dist/vendor/devkit/test/fixtures/esm-only-package/package.json +13 -0
  216. package/dist/vendor/monitoring/env.js +20 -10
  217. package/dist/vendor/monitoring/main.js +1 -1
  218. package/dist/vendor/monitoring/preload.js +1 -1
  219. package/dist/vendor/monitoring/renderer.js +1 -1
  220. package/docs/analytics.md +1 -1
  221. package/docs/auto-updater.md +5 -5
  222. package/docs/boot-sequence.md +1 -1
  223. package/docs/build-system.md +15 -7
  224. package/docs/client-bridge.md +9 -7
  225. package/docs/config-schema.md +4 -4
  226. package/docs/css.md +8 -2
  227. package/docs/deep-link.md +12 -4
  228. package/docs/environment-detection.md +32 -24
  229. package/docs/hooks.md +3 -1
  230. package/docs/icons.md +7 -7
  231. package/docs/index.md +61 -23
  232. package/docs/installer-options.md +24 -21
  233. package/docs/logging.md +5 -5
  234. package/docs/releasing.md +25 -17
  235. package/docs/runner.md +40 -5
  236. package/docs/shared/brands.md +12 -6
  237. package/docs/shared/breaking-changes.md +375 -21
  238. package/docs/shared/config.md +757 -199
  239. package/docs/shared/deploys.md +194 -91
  240. package/docs/shared/icons.md +18 -0
  241. package/docs/shared/local-dev.md +24 -6
  242. package/docs/shared/logging.md +9 -6
  243. package/docs/shared/monitoring.md +27 -13
  244. package/docs/shared/publishing.md +3 -3
  245. package/docs/shared/rulings.md +2 -2
  246. package/docs/shared/testing.md +1 -1
  247. package/docs/shared/theming.md +26 -1
  248. package/docs/shared/translation.md +49 -7
  249. package/docs/shared/updates.md +1 -1
  250. package/docs/signing.md +59 -33
  251. package/docs/test-framework.md +10 -5
  252. package/docs/themes.md +15 -1
  253. package/package.json +18 -12
  254. package/bin/omega-desktop +0 -2
  255. package/dist/commands/push-secrets.js +0 -141
  256. package/dist/test/suites/build/deliver-certs.test.js +0 -95
  257. package/dist/test/suites/build/derive-signing-env.test.js +0 -122
  258. package/dist/test/suites/build/push-secrets.test.js +0 -226
  259. package/dist/test/suites/build/resolve-signing-cert.test.js +0 -342
  260. package/dist/utils/deliver-certs.js +0 -69
  261. package/dist/utils/derive-signing-env.js +0 -56
  262. package/dist/utils/resolve-signing-cert.js +0 -175
  263. package/dist/vendor/config/desktop-artifacts.js +0 -110
  264. package/dist/vendor/config/instances.js +0 -208
  265. /package/dist/defaults/config/icons/{macos → mac}/dmg.png +0 -0
  266. /package/dist/defaults/config/icons/{macos → mac}/icon.png +0 -0
  267. /package/dist/defaults/config/icons/{macos → mac}/tray.png +0 -0
@@ -1,15 +1,22 @@
1
+ # Deliberate deploys (D13): commits never auto-publish, save = commit and
2
+ # publish = an explicit dispatch (`omega deploy`, or a plain HTTP
3
+ # workflow_dispatch call).
4
+ # Regenerated by every verb's ensureTarget: customize via config/omega.json5, not here.
1
5
  name: Build & Release
2
6
 
3
- # Manual-trigger only — releases are intentional, not a side effect of every commit.
4
7
  on:
5
8
  workflow_dispatch:
6
9
  inputs:
7
10
  platforms:
8
- description: 'Platforms to build (comma-separated). Examples: all, windows, mac,linux'
11
+ description: "Platforms to build (comma-separated), in OMEGA's vocabulary. Examples: all, windows, mac,linux"
9
12
  required: false
10
13
  default: 'all'
11
14
  type: string
12
15
 
16
+ concurrency:
17
+ group: ${{ github.ref }}
18
+ cancel-in-progress: true
19
+
13
20
  env:
14
21
  NODE_VERSION: '{{ versions.node }}'
15
22
  OMEGA_BUILD_MODE: 'true'
@@ -24,18 +31,15 @@ env:
24
31
  # restating one. Add a key to the schema, not to this file.
25
32
  {{ githubSecrets }}
26
33
 
27
- concurrency:
28
- group: ${{ github.ref }}
29
- cancel-in-progress: true
30
-
31
34
  jobs:
32
35
  # Resolve which platforms to build from the workflow_dispatch `platforms` input.
33
36
  # Outputs a JSON matrix (consumed by the build job) plus per-platform booleans
34
37
  # (consumed by windows-strategy / windows-sign gating). When `platforms` is
35
- # omitted (older invocations) the input defaults to 'all'.
38
+ # omitted it defaults to 'all'.
36
39
  setup:
37
40
  name: Setup (resolve target platforms)
38
41
  runs-on: ubuntu-latest
42
+ timeout-minutes: 5
39
43
  outputs:
40
44
  matrix: ${{ steps.resolve.outputs.matrix }}
41
45
  mac: ${{ steps.resolve.outputs.mac }}
@@ -47,28 +51,31 @@ jobs:
47
51
  input="${{ github.event.inputs.platforms || 'all' }}"
48
52
  input="$(echo "$input" | tr '[:upper:]' '[:lower:]')"
49
53
 
50
- mac=false; win=false; linux=false
51
- if [[ "$input" == *all* ]]; then mac=true; win=true; linux=true; fi
52
- if [[ "$input" == *mac* ]] || [[ "$input" == *darwin* ]]; then mac=true; fi
53
- if [[ "$input" == *win* ]]; then win=true; fi
54
- if [[ "$input" == *linux* ]] || [[ "$input" == *ubuntu* ]]; then linux=true; fi
54
+ # The input speaks OMEGA's platform vocabulary and nothing else (#867):
55
+ # mac, windows, linux. The runner LABELS below are GitHub's names, the
56
+ # one foreign vocabulary this job translates.
57
+ mac=false; windows=false; linux=false
58
+ if [[ "$input" == *all* ]]; then mac=true; windows=true; linux=true; fi
59
+ if [[ "$input" == *mac* ]]; then mac=true; fi
60
+ if [[ "$input" == *windows* ]]; then windows=true; fi
61
+ if [[ "$input" == *linux* ]]; then linux=true; fi
55
62
 
56
63
  entries=()
57
- $mac && entries+=('"macos-latest"')
58
- $win && entries+=('"windows-latest"')
59
- $linux && entries+=('"ubuntu-latest"')
64
+ $mac && entries+=('"macos-latest"')
65
+ $windows && entries+=('"windows-latest"')
66
+ $linux && entries+=('"ubuntu-latest"')
60
67
  if [ ${#entries[@]} -eq 0 ]; then
61
68
  echo "Error: '$input' did not match any platform. Use: all | mac | windows | linux | comma-separated combos." >&2
62
69
  exit 1
63
70
  fi
64
71
 
65
72
  matrix="[$(IFS=,; echo "${entries[*]}")]"
66
- echo "Resolved input='$input' → mac=$mac, win=$win, linux=$linux, matrix=$matrix"
73
+ echo "Resolved input='$input' → mac=$mac, windows=$windows, linux=$linux, matrix=$matrix"
67
74
 
68
- echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
69
- echo "mac=$mac" >> "$GITHUB_OUTPUT"
70
- echo "windows=$win" >> "$GITHUB_OUTPUT"
71
- echo "linux=$linux" >> "$GITHUB_OUTPUT"
75
+ echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
76
+ echo "mac=$mac" >> "$GITHUB_OUTPUT"
77
+ echo "windows=$windows" >> "$GITHUB_OUTPUT"
78
+ echo "linux=$linux" >> "$GITHUB_OUTPUT"
72
79
 
73
80
  build:
74
81
  name: Build (${{ matrix.os }})
@@ -83,49 +90,91 @@ jobs:
83
90
  # The workflow's own token: a checkout never needs the release PAT, and a
84
91
  # bad PAT then fails at the release step with an API error, not here with
85
92
  # git asking for a username.
86
- - uses: actions/checkout@v4
93
+ # Shallow on purpose: nothing in a desktop release reads git HISTORY, and
94
+ # electron-builder publishes over the API rather than over a git push.
95
+ - uses: actions/checkout@v7
87
96
  with:
88
- fetch-depth: 0
97
+ fetch-depth: 1
89
98
 
90
- - uses: actions/setup-node@v4
99
+ - uses: actions/setup-node@v7
91
100
  with:
92
101
  node-version: ${{ env.NODE_VERSION }}
93
102
  cache: npm
94
103
 
95
- - name: Install Socket Firewall
96
- run: npm install -g sfw
104
+ {{ installFirewall }}
97
105
 
98
106
  # On Windows, force cmd for every shell step in this job — the runner's default
99
107
  # is PowerShell 7 which has its own ExecutionPolicy/wrapping quirks that cause
100
108
  # `npm ci` and similar to exit silently with no captured output. cmd has none
101
109
  # of that. mac/linux use their default bash regardless of this flag (per
102
110
  # actions/runner shell-resolution: `cmd` is win-only and ignored elsewhere).
111
+ # `npm.cmd`, not `npm`, on the cmd leg (#872): the firewall spawns the command
112
+ # it is given LITERALLY, with no PATHEXT resolution, and the only `npm` on a
113
+ # Windows runner's PATH is `npm.cmd`. Bare `npm` there is
114
+ # `Command 'npm' not found in PATH`, from sfw rather than from cmd.
103
115
  - if: matrix.os == 'windows-latest'
104
116
  shell: cmd
105
- run: sfw npm ci
117
+ run: sfw npm.cmd ci {{ installWorkspace }}
106
118
  - if: matrix.os != 'windows-latest'
107
- run: sfw npm ci
119
+ run: sfw npm ci {{ installWorkspace }}
120
+
121
+ # No npx on a runner, in any spelling (#877): which package won npm's
122
+ # shared `omega` bin link is an install-order accident, and an `npx omega`
123
+ # that finds nothing linked fetches a stranger's package from the REGISTRY
124
+ # with every secret in the job env. This workflow belongs to exactly one
125
+ # framework, so it runs that framework's own bin FILE. The path is
126
+ # anchored at the workspace root: npm hoists a workspace's dependencies
127
+ # there, where a target-scoped `./node_modules` never sees them (#898).
128
+ # ONE step for all three legs, under an explicit `shell: bash`: bash exists
129
+ # on every hosted runner, and the cmd forcing above is for npm's
130
+ # long-running scripts, while this step only READS versions.
131
+ - name: Log versions
132
+ shell: bash
133
+ run: |
134
+ echo "Node: $(node -v)"
135
+ echo "NPM: $(npm -v)"
136
+ echo "Omega: $(node "${{ github.workspace }}/node_modules/@omega.js/desktop/bin/omega" version)"
108
137
 
109
138
  # macOS — decode signing assets from secrets, then sign + notarize + publish.
110
- # `npx omega push-secrets` uploads .p12 / .p8 files as base64-encoded secrets;
139
+ # `npx omega deploy`'s precheck uploads .p12 / .p8 files as base64-encoded secrets;
111
140
  # the workflow decodes them back to disk for electron-builder + notarytool to read.
141
+ # Each decode is gated on its secret EXISTING (#872): `base64 --decode` of an
142
+ # empty secret writes an empty file, and `security import` of one dies with
143
+ # "parameters not valid".
144
+ # A missing secret EXITS 1 (#891): a mac build this framework ships is
145
+ # signed and notarized, so the leg stops here with the command that fixes
146
+ # it rather than publishing a release Gatekeeper refuses on every Mac.
112
147
  - if: matrix.os == 'macos-latest'
113
148
  run: |
114
149
  mkdir -p config/certs
115
- echo "${{ secrets.CSC_LINK }}" | base64 --decode > config/certs/dev-id.p12
116
- echo "${{ secrets.APPLE_API_KEY }}" | base64 --decode > config/certs/AuthKey.p8
150
+ if [ -n "${{ secrets.CSC_LINK }}" ]; then
151
+ echo "${{ secrets.CSC_LINK }}" | base64 --decode > config/certs/dev-id.p12
152
+ else
153
+ echo "No CSC_LINK secret: run omega deploy from targets/desktop (its precheck pushes them). A mac build must be signed."
154
+ exit 1
155
+ fi
156
+ if [ -n "${{ secrets.APPLE_API_KEY }}" ]; then
157
+ echo "${{ secrets.APPLE_API_KEY }}" | base64 --decode > config/certs/AuthKey.p8
158
+ else
159
+ echo "No APPLE_API_KEY secret: run omega deploy from targets/desktop (its precheck pushes them). A mac build must be notarized."
160
+ exit 1
161
+ fi
117
162
  # The two file-path OVERRIDES of the workflow env: electron-builder and
118
163
  # notarytool read these as paths, and the step above just decoded the
119
164
  # base64 secrets of the same name to disk. Every other credential comes
120
- # from the generated env block.
165
+ # from the generated env block. Each override is set only when its file was
166
+ # written; empty reads as UNSET after the build's sanitize pass, and
167
+ # electron-builder then finds no identity, warns and skips signing (it only
168
+ # fails on a missing identity for MAS or `forceCodeSigning`, neither of
169
+ # which this framework sets).
121
170
  - if: matrix.os == 'macos-latest'
122
171
  env:
123
- CSC_LINK: config/certs/dev-id.p12
124
- APPLE_API_KEY: config/certs/AuthKey.p8
172
+ CSC_LINK: ${{ secrets.CSC_LINK != '' && 'config/certs/dev-id.p12' || '' }}
173
+ APPLE_API_KEY: ${{ secrets.APPLE_API_KEY != '' && 'config/certs/AuthKey.p8' || '' }}
125
174
  run: npm run release:local
126
175
 
127
- # Linux — install snapcraft when (a) the consumer hasn't explicitly disabled snap
128
- # in their config (`platforms.linux.snap.enabled !== false`; default is true) AND
176
+ # Linux: install snapcraft when (a) the brand still SHIPS the snap format
177
+ # (`platforms.linux.formats.snap`, on unless dropped with `false`) AND
129
178
  # (b) SNAPCRAFT_STORE_CREDENTIALS is set as a repo secret. Without the secret we
130
179
  # skip snapcraft install entirely — build-config.js auto-skips the snap target on
131
180
  # the same condition, so the build still produces .deb + .AppImage cleanly with
@@ -133,29 +182,37 @@ jobs:
133
182
  - name: Install Snapcraft (Linux, when snap enabled + creds present)
134
183
  if: matrix.os == 'ubuntu-latest'
135
184
  run: |
136
- # (a) Config check — explicit `enabled: false` opts out; missing/true opts in.
137
- # `@omega.js/desktop/config` is the vendored @omega.js/config loader — resolves
185
+ # (a) The declaration (#867), read through @omega.js/config's own format
186
+ # table so this check can never drift from the build's.
187
+ # `@omega.js/desktop/config` is the vendored loader: it resolves
138
188
  # config/omega.json5 for the desktop target (brand-monorepo aware).
139
- if node -e 'const c = require("@omega.js/desktop/config").loadConfig(process.cwd(), "desktop").config; process.exit(c.platforms?.linux?.snap?.enabled === false ? 1 : 0);'; then
189
+ if node -e 'const o = require("@omega.js/desktop/config"); const c = o.loadConfig(process.cwd(), "desktop").config; process.exit(o.enabledFormats(c, "desktop").some((e) => e.format === "snap") ? 0 : 1);'; then
140
190
  CONFIG_OK=1
141
191
  else
142
192
  CONFIG_OK=0
143
- echo "platforms.linux.snap.enabled === false — skipping snapcraft install."
193
+ echo "platforms.linux.formats.snap is dropped, skipping snapcraft install."
144
194
  fi
145
195
  # (b) Credentials check — empty secret means no publish creds available.
146
196
  if [ -n "$SNAPCRAFT_STORE_CREDENTIALS" ]; then
147
197
  CREDS_OK=1
148
198
  else
149
199
  CREDS_OK=0
150
- echo "SNAPCRAFT_STORE_CREDENTIALS not set — skipping snapcraft install. Run 'snapcraft export-login -' and add the blob to .env, then 'mgr push-secrets'."
200
+ echo "SNAPCRAFT_STORE_CREDENTIALS not set, skipping snapcraft install. Run 'snapcraft export-login -' and add the blob to .env, then 'omega deploy'."
151
201
  fi
152
202
  if [ "$CONFIG_OK" = 1 ] && [ "$CREDS_OK" = 1 ]; then
153
203
  sudo snap install snapcraft --classic
154
204
  echo "Snapcraft installed."
155
205
  fi
156
206
 
157
- # Linux — no signing
207
+ # Linux — no signing. The workflow env carries the mac credentials as the
208
+ # base64 secrets themselves (only the mac job decodes them to disk), and a
209
+ # leg that never signs for mac has no business holding them: empty reads as
210
+ # UNSET after the build's sanitize pass (#872).
158
211
  - if: matrix.os == 'ubuntu-latest'
212
+ env:
213
+ CSC_LINK: ''
214
+ CSC_KEY_PASSWORD: ''
215
+ APPLE_API_KEY: ''
159
216
  run: npm run release:local
160
217
 
161
218
  # Windows — package (build + electron-builder package) unsigned. We do NOT publish
@@ -173,10 +230,13 @@ jobs:
173
230
  # it always did. windows-sign signs separately.
174
231
  CSC_LINK: ''
175
232
  CSC_KEY_PASSWORD: ''
233
+ # Same for the notarization key: base64 in this env, mac-only, and the
234
+ # precheck should never be handed a .p8 on a leg that cannot notarize.
235
+ APPLE_API_KEY: ''
176
236
  run: npm run package
177
237
 
178
238
  - if: matrix.os == 'windows-latest'
179
- uses: actions/upload-artifact@v4
239
+ uses: actions/upload-artifact@v7
180
240
  with:
181
241
  name: windows-unsigned
182
242
  # Capture installer + auto-updater feed + blockmap so windows-sign can re-upload them all.
@@ -193,59 +253,78 @@ jobs:
193
253
  needs: [setup, build]
194
254
  if: needs.setup.outputs.windows == 'true'
195
255
  runs-on: ubuntu-latest
256
+ timeout-minutes: 10
196
257
  outputs:
197
258
  strategy: ${{ steps.resolve.outputs.strategy }}
198
259
  steps:
199
- - uses: actions/checkout@v4
200
- - uses: actions/setup-node@v4
260
+ - uses: actions/checkout@v7
261
+ - uses: actions/setup-node@v7
201
262
  with:
202
263
  node-version: ${{ env.NODE_VERSION }}
203
264
  cache: npm
204
- - run: npm install -g sfw
205
- - run: sfw npm ci
265
+ {{ installFirewall }}
266
+ - run: sfw npm ci {{ installWorkspace }}
206
267
  - id: resolve
207
268
  run: |
208
- STRATEGY=$(node -e "const c=require('@omega.js/desktop/config').loadConfig(process.cwd(),'desktop').config;console.log(c.platforms?.win?.signing?.strategy || 'self-hosted');")
269
+ STRATEGY=$(node -e "const c=require('@omega.js/desktop/config').loadConfig(process.cwd(),'desktop').config;console.log(c.platforms?.windows?.signing?.strategy || 'self-hosted');")
209
270
  echo "strategy=$STRATEGY" >> "$GITHUB_OUTPUT"
210
271
  echo "Resolved Windows signing strategy: $STRATEGY"
211
272
 
212
273
  windows-sign:
213
274
  name: Sign Windows
214
275
  needs: [setup, build, windows-strategy]
215
- # Strategy comes from config platforms.win.signing.strategy (read by windows-strategy job).
276
+ # Strategy comes from config platforms.windows.signing.strategy (read by windows-strategy job).
216
277
  # self-hosted (default) — runs on a self-hosted runner with EV USB token attached
217
278
  # cloud — runs on hosted windows-latest, calls cloud signing provider
218
279
  # local — skip this job; sign locally via `npx omega sign-windows`
219
- if: needs.setup.outputs.windows == 'true' && needs.windows-strategy.outputs.strategy != 'local'
280
+ # The trigger half of the signer guard (#875): only a DISPATCH may reach the
281
+ # box that holds the EV token, so a `pull_request` or `push` trigger added to
282
+ # this file later skips the sign job instead of signing a stray build. A skip,
283
+ # never a failure: `finalize` runs under `always()` and the unsigned Windows
284
+ # artifact the build job uploaded is still there. The box refuses such a job
285
+ # on its own too, through the runner's job-started hook.
286
+ if: needs.setup.outputs.windows == 'true' && needs.windows-strategy.outputs.strategy != 'local' && github.event_name == 'workflow_dispatch'
220
287
  runs-on: ${{ needs.windows-strategy.outputs.strategy == 'cloud' && fromJSON('["windows-latest"]') || fromJSON('["self-hosted","windows","ev-token"]') }}
288
+ # Signing is ~20s per installer. A job still running much later is waiting on
289
+ # something that never comes (a PIN at a locked console); end it instead of
290
+ # holding the self-hosted runner for GitHub's six-hour default.
291
+ timeout-minutes: 30
221
292
  # Use cmd.exe (not PowerShell) on Windows. Self-hosted runners often have PowerShell
222
293
  # ExecutionPolicy set to Restricted, which blocks the Actions-generated wrapper .ps1
223
294
  # scripts that GH spits out for every `run:` step. cmd.exe has no such restriction
224
- # and runs the same `npm ci` / `npx ...` commands fine.
295
+ # and runs the same `npm ci` / `node ...` commands fine.
225
296
  defaults:
226
297
  run:
227
298
  shell: cmd
228
299
  # Signing credentials — self-hosted EV USB token (WIN_EV_TOKEN_PATH,
229
300
  # WIN_CSC_KEY_PASSWORD, SIGNTOOL_PATH) and the cloud providers (only the set
230
- # `platforms.win.signing.cloud.provider` names is consumed) — all arrive
301
+ # `platforms.windows.signing.cloud.provider` names is consumed), all arrive
231
302
  # through the workflow's generated env block. Set them in the brand .env and
232
- # push with `npx omega push-secrets`.
303
+ # pushed by `npx omega deploy`'s precheck.
233
304
  steps:
234
- - uses: actions/checkout@v4
235
- - uses: actions/setup-node@v4
305
+ - uses: actions/checkout@v7
306
+ - uses: actions/setup-node@v7
236
307
  with:
237
308
  node-version: ${{ env.NODE_VERSION }}
238
- - run: npm install -g sfw
239
- - run: sfw npm ci
240
- - uses: actions/download-artifact@v4
309
+ # No firewall on the self-hosted signer, on purpose (#872): this box is the
310
+ # brand owner's own machine and its network does not reach Socket's API
311
+ # (the firewall fails closed on `fetch failed`). The lockfile it installs is
312
+ # the one the hosted build jobs installed through the firewall minutes
313
+ # earlier in this same run, so nothing arrives here unscreened. `npm.cmd`
314
+ # because this whole job runs under cmd (see `defaults` above).
315
+ - run: npm.cmd ci {{ installWorkspace }}
316
+ - uses: actions/download-artifact@v8
241
317
  with:
242
318
  name: windows-unsigned
243
319
  path: release
244
- - run: npx omega sign-windows --in release --out release/signed
320
+ # The framework's own bin FILE (#877): nothing here resolves a bin NAME,
321
+ # so no missing link can make npx fetch a stranger's package with the
322
+ # signing token attached. cmd runs `node` like any other shell.
323
+ - run: node "${{ github.workspace }}/node_modules/@omega.js/desktop/bin/omega" sign-windows --in release --out release/signed
245
324
  # Upload the SIGNED Windows assets to the release the mac/linux electron-builder
246
325
  # publish step already created in the brand's public releases repo. The asset
247
326
  # names carry no version, so nothing is mirrored anywhere.
248
- - run: npx omega finalize-release --signed-dir release/signed
327
+ - run: node "${{ github.workspace }}/node_modules/@omega.js/desktop/bin/omega" finalize-release --signed-dir release/signed
249
328
 
250
329
  finalize:
251
330
  name: Finalize release
@@ -257,20 +336,21 @@ jobs:
257
336
  needs: [setup, build, windows-sign]
258
337
  if: always() && needs.build.result == 'success'
259
338
  runs-on: ubuntu-latest
339
+ timeout-minutes: 15
260
340
  steps:
261
- - uses: actions/checkout@v4
262
- - uses: actions/setup-node@v4
341
+ - uses: actions/checkout@v7
342
+ - uses: actions/setup-node@v7
263
343
  with:
264
344
  node-version: ${{ env.NODE_VERSION }}
265
345
  cache: npm
266
- - run: npm install -g sfw
267
- - run: sfw npm ci
346
+ {{ installFirewall }}
347
+ - run: sfw npm ci {{ installWorkspace }}
268
348
  # Flip the releases-repo release from Draft to Published so electron-updater
269
349
  # can read it. Idempotent — safe to run even if already published. ONLY runs
270
350
  # on all-platforms builds: a partial run (e.g. `--platforms windows`) leaves
271
351
  # the release as a draft, so subsequent runs can fill in the missing platform
272
352
  # assets before electron-updater starts seeing the version.
273
353
  - if: needs.setup.outputs.mac == 'true' && needs.setup.outputs.linux == 'true' && needs.setup.outputs.windows == 'true'
274
- run: npx omega finalize-release --publish
354
+ run: node "${{ github.workspace }}/node_modules/@omega.js/desktop/bin/omega" finalize-release --publish
275
355
  - if: needs.setup.outputs.mac != 'true' || needs.setup.outputs.linux != 'true' || needs.setup.outputs.windows != 'true'
276
356
  run: echo "Partial-platform run (mac=${{ needs.setup.outputs.mac }} linux=${{ needs.setup.outputs.linux }} windows=${{ needs.setup.outputs.windows }}) — leaving release as draft. Run with --platforms all to publish."
@@ -52,6 +52,7 @@ npx omega install live # restore the published @omega.js/desktop from npm
52
52
  ## Where things live
53
53
 
54
54
  - `config/omega.json5`: the single OMEGA config (JSON5), with shared sections (brand, analytics, payment, cloud, monitoring, theme) at the top level; desktop settings (app, platforms, autoUpdate, startup, releases, remoteConfig, restartManager) under `targets.desktop`.
55
+ - What the app SHIPS is one declaration: `platforms.<mac|windows|linux>.formats.<dmg|nsis|deb|appimage|snap>`. Presence = enabled, every platform and format is on by default, and `false` drops one (`snap: false`). Per-format settings live inside the format.
55
56
  - Packaging config: fully generated. @omega.js/desktop produces `dist/electron-builder.yml` from `config/omega.json5` (brand/app/signing) + @omega.js/desktop's opinionated defaults. Consumers never ship an `electron-builder.yml`. Override defaults via the `electronBuilder:` block in `omega.json5` if you genuinely need to.
56
57
  - `hooks/notarize/post.js`: optional post-notarize extension hook (@omega.js/desktop owns the actual `afterSign` notarize step).
57
58
  - `src/main.js`: main-process entry. One-line bootstrap of `@omega.js/desktop/main`.
@@ -62,7 +63,7 @@ npx omega install live # restore the published @omega.js/desktop from npm
62
63
  - `src/views/<window>/index.html`: per-window HTML.
63
64
  - `src/assets/js/components/<window>/index.js`: renderer entry per window.
64
65
  - `src/assets/scss/main.scss`: shared SCSS.
65
- - `config/icons/<platform>/<slot>.png`: optional icon overrides (`macos/icon.png`, `macos/tray.png`, `macos/dmg.png`, `windows/icon.png`, etc.).
66
+ - `config/icons/<platform>/<slot>.png`: optional icon overrides (`mac/icon.png`, `mac/tray.png`, `mac/dmg.png`, `windows/icon.png`, etc.; the platform words are `mac`, `windows`, `linux`).
66
67
  - Ship ONE file per slot at the native (retina) size; @omega.js/desktop auto-downscales @1x variants.
67
68
  - macOS tray must be 32×32 (@omega.js/desktop renames to `trayTemplate.png` in dist for the OS dark-mode magic).
68
69
  - Missing slots fall back to @omega.js/desktop bundled defaults; Linux falls back to Windows resolution.
@@ -85,7 +86,7 @@ new (require('@omega.js/desktop/renderer'))().initialize();
85
86
 
86
87
  In main: `manager.storage`, `manager.ipc`, `manager.windows`, `manager.tray`, `manager.menu`, `manager.contextMenu`, `manager.startup`, `manager.appState`, `manager.deepLink`, `manager.autoUpdater`, `manager.sentry`, `manager.omega`, `manager.context`, `manager.usage`, `manager.remoteConfig`, `manager.analytics`, `manager.restartManager`.
87
88
 
88
- In renderer: `window.desktop.storage`, `window.desktop.ipc`, `window.desktop.logger`, `OMEGA_BUILD_JSON.config`.
89
+ In renderer: `window.desktop.storage`, `window.desktop.ipc`, `window.desktop.logger`, `window.OMEGA_BUILD_JSON.config` (the one `build.js` the view's shell loads).
89
90
 
90
91
  ## Dependency resolution
91
92
 
@@ -11,8 +11,10 @@ node_modules/
11
11
  *.log
12
12
  /logs/
13
13
 
14
- # Apple signing artifacts — never commit these
15
- config/certs/
14
+ # Signing artifacts: never commit these. config/certs/ keeps its README, the one
15
+ # tracked explanation of where the real material lives.
16
+ config/certs/*
17
+ !config/certs/README.md
16
18
  *.p12
17
19
  *.cer
18
20
  *.mobileprovision
@@ -1,60 +1,40 @@
1
- # `config/certs/` — Code-signing certificates and provisioning profiles
1
+ # `config/certs/`: signing material on a RUNNER, and nothing else
2
2
 
3
- **Never commit anything in this directory.** The parent `.gitignore` excludes `*.p12`, `*.cer`, `*.mobileprovision`, `*.p8`, `*.pem` — and the entire `config/certs/` subdirectory is also ignored as a defense-in-depth measure.
3
+ **Never commit anything in this directory.** The target's `.gitignore` ignores everything here except this file, which is tracked so the explanation travels with the repo.
4
4
 
5
- ## File inventory
5
+ ## Locally: nothing lives here
6
6
 
7
- ### macOS (signing + notarization)
7
+ Signing material is READ IN PLACE from the signing tree ([#891](https://github.com/Omega-JS-Stack/omega/issues/891)), never copied into a target:
8
8
 
9
- | File | Source | Used by | Env var pointing at it |
10
- |---|---|---|---|
11
- | `developer-id-application.p12` | Apple Developer → Certificates → "Developer ID Application" | electron-builder for code signing | `CSC_LINK` |
12
- | `developer-id-installer.p12` | Apple Developer → Certificates → "Developer ID Installer" | electron-builder for `.pkg` signing (only if you ship a pkg installer) | `CSC_INSTALLER_LINK` |
13
- | `AuthKey_XXXXXXXXXX.p8` | App Store Connect → Users and Access → Keys | Notarization via notarytool API | `APPLE_API_KEY` (path), `APPLE_API_KEY_ID`, `APPLE_API_ISSUER` |
14
- | `<app-name>.provisionprofile` | Apple Developer → Profiles → Developer ID Provisioning Profile | Required if your app uses entitlements requiring Apple's review (push notifications, in-app purchase, network extensions, etc.) | electron-builder auto-discovers in `build/` |
9
+ ```
10
+ <company root>/company/.omega/certificates/apple/ # first, when the brand names a company
11
+ <brand root>/.omega/certificates/apple/ # second
12
+ ```
15
13
 
16
- You also need (in `.env`, not in this directory):
17
- - `CSC_KEY_PASSWORD` — password for the `.p12` files
18
- - `APPLE_API_KEY_ID` — 10-char Key ID (matches the `XXXXXXXXXX` in the `.p8` filename)
19
- - `APPLE_API_ISSUER` — issuer UUID from App Store Connect
20
- - `APPLE_TEAM_ID` — 10-char team ID from developer.apple.com
14
+ The `omega manage --service certificates` walk produces that tree, and every desktop boot (the CLI and gulp alike) derives the paths into it once, through `@omega.js/devkit/signing-env`:
21
15
 
22
- ### Windows (signing)
16
+ | Env var | Derived from |
17
+ |---|---|
18
+ | `CSC_LINK` | `certificates/DEVELOPER_ID_APPLICATION_G2.p12` in the tree, when `CSC_KEY_PASSWORD` opens it |
19
+ | `APPLE_API_KEY` | `AuthKey_<APPLE_API_KEY_ID>.p8` in the tree |
23
20
 
24
- For self-hosted EV USB token:
25
- | File / value | Source | Env var |
26
- |---|---|---|
27
- | (USB token plugged into self-hosted runner) | Sectigo / DigiCert / etc. EV cert physical token | `WIN_EV_TOKEN_PATH`, `WIN_CSC_KEY_PASSWORD` |
21
+ So the build, `omega validate-certs` and the deploy precheck's secret publish all read one answer. An EXPLICIT `CSC_LINK` or `APPLE_API_KEY` in the env always wins, and with neither set nor derivable, electron-builder falls back to macOS Keychain identity discovery.
28
22
 
29
- For cloud signing (future):
30
- - Azure Trusted Signing — service principal creds in `.env`
31
- - SSL.com eSigner — username + password + credential ID in `.env`
32
- - DigiCert KeyLocker — API token + endpoint in `.env`
23
+ There is no provisioning profile: Developer ID is DIRECT distribution, signed and notarized, and needs none.
33
24
 
34
- No file lives in `config/certs/` for Windows — credentials are env-vars-only.
25
+ ## On the runner: this directory is the decode target
35
26
 
36
- ## Are these per-brand or universal?
27
+ The generated `.github/workflows/build.yml` decodes the pushed base64 secrets back to disk here (`config/certs/dev-id.p12`, `config/certs/AuthKey.p8`) and points `CSC_LINK` / `APPLE_API_KEY` at the decoded files. `omega deploy`'s precheck is what pushes those secrets; a mac leg with either secret missing exits 1 rather than shipping an unsigned app.
37
28
 
38
- **Universal across brands you ship as the same Apple Developer team:**
39
- - `developer-id-application.p12` — one per team, valid for all your apps
40
- - `developer-id-installer.p12` — same
41
- - `AuthKey_*.p8` — one per team, used for notarization across all apps
42
- - Apple Team ID, Apple ID, app-specific password
43
- - Windows EV token (one per team)
29
+ ## The rest of the signing set
44
30
 
45
- **Per-brand / per-app:**
46
- - Provisioning profile (`*.provisionprofile`) — only required if entitlements demand it; tied to a specific bundle ID (`com.itwcw.<app>`)
47
- - Icons (separate concern, live in `build/`, not `config/certs/`)
31
+ These are values, not files, and live in the brand `.env` (never here):
48
32
 
49
- ## Setup walkthrough
33
+ - `CSC_KEY_PASSWORD`: the password for the `.p12`
34
+ - `APPLE_API_KEY_ID`: 10-char Key ID (it also names the `.p8` file in the tree)
35
+ - `APPLE_API_ISSUER`: issuer UUID from App Store Connect
36
+ - `APPLE_TEAM_ID`: 10-char team ID from developer.apple.com
50
37
 
51
- 1. Drop the relevant cert files into this directory.
52
- 2. Edit `.env` at the repo root and point env vars at them (typically just `CSC_LINK=config/certs/developer-id-application.p12`).
53
- 3. Run `npx omega validate-certs` to check the OS sees them and notarization creds are wired.
54
- 4. `npm run release` to do a signed + notarized build.
38
+ Windows keeps no file here at all: the self-hosted EV USB token is addressed by `WIN_EV_TOKEN_PATH` / `WIN_CSC_KEY_PASSWORD`, and each cloud provider by its own env set.
55
39
 
56
- For full details see [`docs/signing.md`](../../docs/signing.md) at the @omega.js/desktop repo root.
57
-
58
- ## CI
59
-
60
- In CI (GitHub Actions), certs are passed via secrets, not files. The workflow base64-decodes secret values into temp files at runtime, points env vars at them, then nukes the files after the build. See `src/defaults/.github/workflows/build.yml` (when added in Pass 3).
40
+ For the whole picture see [`docs/signing.md`](../../docs/signing.md).