| ... | @@ -253,6 +253,28 @@ function resolveAppRoot(): string { | ... | @@ -253,6 +253,28 @@ function resolveAppRoot(): string { |
| 253 | return app.getAppPath(); | 253 | return app.getAppPath(); |
| 254 | } | 254 | } |
| 255 | | 255 | |
| | 256 | /** Read the baked-in app-update.yml config (if applicable). */ |
| | 257 | function readAppUpdateYml(): Record<string, string> | null { |
| | 258 | try { |
| | 259 | // electron-updater reads from process.resourcesPath in packaged builds, |
| | 260 | // or dev-app-update.yml via app.getAppPath() in dev. |
| | 261 | const ymlPath = app.isPackaged |
| | 262 | ? Path.join(process.resourcesPath, "app-update.yml") |
| | 263 | : Path.join(app.getAppPath(), "dev-app-update.yml"); |
| | 264 | const raw = FS.readFileSync(ymlPath, "utf-8"); |
| | 265 | // The YAML is simple key-value pairs — avoid pulling in a YAML parser by |
| | 266 | // doing a line-based parse (fields: provider, owner, repo, releaseType, …). |
| | 267 | const entries: Record<string, string> = {}; |
| | 268 | for (const line of raw.split("\n")) { |
| | 269 | const match = line.match(/^(\w+):\s*(.+)$/); |
| | 270 | if (match?.[1] && match[2]) entries[match[1]] = match[2].trim(); |
| | 271 | } |
| | 272 | return entries.provider ? entries : null; |
| | 273 | } catch { |
| | 274 | return null; |
| | 275 | } |
| | 276 | } |
| | 277 | |
| 256 | function normalizeCommitHash(value: unknown): string | null { | 278 | function normalizeCommitHash(value: unknown): string | null { |
| 257 | if (typeof value !== "string") { | 279 | if (typeof value !== "string") { |
| 258 | return null; | 280 | return null; |
| ... | @@ -687,10 +709,18 @@ function configureAutoUpdater(): void { | ... | @@ -687,10 +709,18 @@ function configureAutoUpdater(): void { |
| 687 | process.env.GH_TOKEN?.trim() || | 709 | process.env.GH_TOKEN?.trim() || |
| 688 | ""; | 710 | ""; |
| 689 | if (githubToken) { | 711 | if (githubToken) { |
| 690 | autoUpdater.requestHeaders = { | 712 | // When a token is provided, re-configure the feed with `private: true` so |
| 691 | ...autoUpdater.requestHeaders, | 713 | // electron-updater uses the GitHub API (api.github.com) instead of the |
| 692 | Authorization: `Bearer ${githubToken}`, | 714 | // public Atom feed (github.com/…/releases.atom) which rejects Bearer auth. |
| 693 | }; | 715 | const appUpdateYml = readAppUpdateYml(); |
| | 716 | if (appUpdateYml?.provider === "github") { |
| | 717 | autoUpdater.setFeedURL({ |
| | 718 | ...appUpdateYml, |
| | 719 | provider: "github" as const, |
| | 720 | private: true, |
| | 721 | token: githubToken, |
| | 722 | }); |
| | 723 | } |
| 694 | } | 724 | } |
| 695 | | 725 | |
| 696 | autoUpdater.autoDownload = false; | 726 | autoUpdater.autoDownload = false; |