Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .circleci/src/pipeline/@pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,29 @@ commands:
build-and-persist:
description: Save entire folder as artifact for other jobs to run without reinstalling
steps:
- run:
name: Generate Electron version key
command: node -p "require('./package.json').devDependencies.electron" > electron_version
- restore_cache:
name: Restore Electron download cache
keys:
- v{{ checksum ".circleci/cache-version.txt" }}-{{ checksum "platform_key"
}}-electron-download-cache-{{ checksum "electron_version" }}
- run:
name: Build packages
command: |
source ./scripts/ensure-node.sh
# @packages/electron forwards this to @electron/get, whose default
# cache root is platform-specific — pinning it keeps a single
# save_cache path valid on every executor
export electron_config_cache="$HOME/.electron-cache"
Comment thread
mschile marked this conversation as resolved.
yarn build
- save_cache:
name: Save Electron download cache
key: v{{ checksum ".circleci/cache-version.txt" }}-{{ checksum "platform_key"
}}-electron-download-cache-{{ checksum "electron_version" }}
paths:
- ~/.electron-cache
- run:
name: Sync Cloud Validations
command: |
Expand Down
1 change: 1 addition & 0 deletions packages/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
},
"devDependencies": {
"@electron/fuses": "1.8.0",
"@electron/get": "^4.0.1",
"@electron/packager": "18.3.6",
"@vitest/coverage-v8": "^3.2.4",
"eslint": "^9.31.0",
Expand Down
37 changes: 37 additions & 0 deletions packages/electron/src/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,35 @@ interface PkgElectronAppOptions {
overwrite: boolean
electronVersion: string
icon: string
electronZipDir?: string
}

// @electron/packager would fetch this through @electron/get, which never
// retries and re-fetches SHASUMS256.txt even on cache hits. Calling it here
// lets us retry; electronZipDir then points the packager at the result.
async function downloadElectronZipWithRetries (options: { version: string, platform: string, arch: string }): Promise<string> {
// required dynamically for the same mksnapshot reason as @electron/packager below
const e = 'electron'
const { downloadArtifact } = require(`@${e}/get`)
const retryDelaysMs = [2000, 4000, 8000, 16000, 32000]

// same env var the `electron` package's own installer honors, so CI can point
// both at one cacheable directory. Undefined falls back to the platform default.
const cacheRoot = process.env.electron_config_cache

for (let attempt = 0; ; attempt++) {
try {
return await downloadArtifact({ artifactName: 'electron', cacheRoot, ...options })
} catch (err) {
const delayMs = retryDelaysMs[attempt]

if (delayMs === undefined) throw err

debug('electron zip download failed %o', { attempt, err })
console.log(`Electron download failed (${(err as Error).message}), retrying in ${delayMs / 1000}s (attempt ${attempt + 1} of ${retryDelaysMs.length})`)
await new Promise((resolve) => setTimeout(resolve, delayMs))
}
}
}

async function pkgElectronApp (
Expand Down Expand Up @@ -180,6 +209,14 @@ async function pkgElectronApp (
...options,
}

const zipPath = await downloadElectronZipWithRetries({
version: resolvedOptions.electronVersion,
platform: resolvedOptions.platform,
arch: resolvedOptions.arch,
})

resolvedOptions.electronZipDir = path.dirname(zipPath)

debug('packager options %j', resolvedOptions)
const [appPath] = await pkgr(resolvedOptions)

Expand Down
Loading