build: replace npx with lockfile-pinned binaries (#50717)

build: replace npx with lockfile-pinned binaries (#50598)

* build: replace npx with lockfile-pinned binaries

- nan-spec-runner: reorder yarn install first, invoke nan node-gyp bin directly
- publish-to-npm: use host npm with E404 try/catch (closes existing TODO)
- upload-symbols: add @sentry/cli devDep, invoke from node_modules/.bin
- remove script/lib/npx.py (dead since #48243)

* build: bump @sentry/cli to 1.70.0 for arm support

* build: bump @sentry/cli to 1.72.0, skip CDN download on test jobs

@sentry/cli fetches its platform binary from Sentry CDN at postinstall.
Only upload-symbols.py (release pipeline) needs the binary; set
SENTRYCLI_SKIP_DOWNLOAD=1 in the two test-segment workflows that
call install-dependencies. The 64k variant uses pre-built artifacts
and does not install deps.
This commit is contained in:
Samuel Attard
2026-04-06 16:07:36 -04:00
committed by GitHub
parent eb871f7eee
commit 218544d32e
8 changed files with 191 additions and 72 deletions

View File

@@ -43,6 +43,8 @@ env:
ELECTRON_OUT_DIR: Default
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
# @sentry/cli is only needed by release upload-symbols.py; skip the ~17MB CDN download on test jobs
SENTRYCLI_SKIP_DOWNLOAD: 1
jobs:
test:

View File

@@ -36,6 +36,8 @@ env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
ELECTRON_OUT_DIR: Default
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
# @sentry/cli is only needed by release upload-symbols.py; skip the ~17MB CDN download on test jobs
SENTRYCLI_SKIP_DOWNLOAD: 1
jobs:
node-tests:

View File

@@ -14,6 +14,7 @@
"@electron/typescript-definitions": "^9.1.5",
"@octokit/rest": "^20.1.2",
"@primer/octicons": "^10.0.0",
"@sentry/cli": "1.72.0",
"@types/minimist": "^1.2.5",
"@types/node": "^24.9.0",
"@types/semver": "^7.5.8",
@@ -150,6 +151,9 @@
"spec/fixtures/native-addon/*"
],
"dependenciesMeta": {
"@sentry/cli": {
"built": true
},
"abstract-socket": {
"built": true
}

View File

@@ -1,21 +0,0 @@
import os
import subprocess
import sys
def npx(*npx_args):
npx_env = os.environ.copy()
npx_env['npm_config_yes'] = 'true'
call_args = [__get_executable_name()] + list(npx_args)
subprocess.check_call(call_args, env=npx_env)
def __get_executable_name():
executable = 'npx'
if sys.platform == 'win32':
executable += '.cmd'
return executable
if __name__ == '__main__':
npx(*sys.argv[1:])

View File

@@ -6,7 +6,7 @@ const path = require('node:path');
const BASE = path.resolve(__dirname, '../..');
const NAN_DIR = path.resolve(BASE, 'third_party', 'nan');
const NPX_CMD = process.platform === 'win32' ? 'npx.cmd' : 'npx';
const NODE_GYP_BIN = path.join(NAN_DIR, 'node_modules', 'node-gyp', 'bin', 'node-gyp.js');
const utils = require('./lib/utils');
const { YARN_SCRIPT_PATH } = require('./yarn');
@@ -19,14 +19,6 @@ const args = minimist(process.argv.slice(2), {
string: ['only']
});
const getNodeGypVersion = () => {
const nanPackageJSONPath = path.join(NAN_DIR, 'package.json');
const nanPackageJSON = JSON.parse(fs.readFileSync(nanPackageJSONPath, 'utf8'));
const { devDependencies } = nanPackageJSON;
const nodeGypVersion = devDependencies['node-gyp'];
return nodeGypVersion || 'latest';
};
async function main () {
const outDir = utils.getOutDir({ shouldLog: true });
const nodeDir = path.resolve(BASE, 'out', outDir, 'gen', 'node_headers');
@@ -34,8 +26,7 @@ async function main () {
npm_config_msvs_version: '2022',
...process.env,
npm_config_nodedir: nodeDir,
npm_config_arch: process.env.NPM_CONFIG_ARCH,
npm_config_yes: 'true'
npm_config_arch: process.env.NPM_CONFIG_ARCH
};
const clangDir = path.resolve(BASE, 'third_party', 'llvm-build', 'Release+Asserts', 'bin');
@@ -105,30 +96,26 @@ async function main () {
env.LDFLAGS = ldflags;
}
const nodeGypVersion = getNodeGypVersion();
const { status: buildStatus, signal } = cp.spawnSync(NPX_CMD, [`node-gyp@${nodeGypVersion}`, 'rebuild', '--verbose', '--directory', 'test', '-j', 'max'], {
const { status: installStatus, signal: installSignal } = cp.spawnSync(process.execPath, [YARN_SCRIPT_PATH, 'install'], {
env,
cwd: NAN_DIR,
stdio: 'inherit',
shell: process.platform === 'win32'
stdio: 'inherit'
});
if (installStatus !== 0 || installSignal != null) {
console.error('Failed to install nan node_modules');
return process.exit(installStatus !== 0 ? installStatus : installSignal);
}
const { status: buildStatus, signal } = cp.spawnSync(process.execPath, [NODE_GYP_BIN, 'rebuild', '--verbose', '--directory', 'test', '-j', 'max'], {
env,
cwd: NAN_DIR,
stdio: 'inherit'
});
if (buildStatus !== 0 || signal != null) {
console.error('Failed to build nan test modules');
return process.exit(buildStatus !== 0 ? buildStatus : signal);
}
const { status: installStatus, signal: installSignal } = cp.spawnSync(process.execPath, [YARN_SCRIPT_PATH, 'install'], {
env,
cwd: NAN_DIR,
stdio: 'inherit',
shell: process.platform === 'win32'
});
if (installStatus !== 0 || installSignal != null) {
console.error('Failed to install nan node_modules');
return process.exit(installStatus !== 0 ? installStatus : installSignal);
}
const onlyTests = args.only?.split(',');
const DISABLED_TESTS = new Set([

View File

@@ -212,10 +212,15 @@ new Promise<string>((resolve, reject) => {
});
})
.then((tarballPath) => {
// TODO: Remove NPX
const existingVersionJSON = childProcess.execSync(`npx npm@7 view ${rootPackageJson.name}@${currentElectronVersion} --json`).toString('utf-8');
// It's possible this is a re-run and we already have published the package, if not we just publish like normal
if (!existingVersionJSON) {
let versionAlreadyPublished = false;
try {
childProcess.execSync(`npm view ${rootPackageJson.name}@${currentElectronVersion} --json`, { stdio: 'pipe' });
versionAlreadyPublished = true;
} catch (e: any) {
if (!e.stdout?.toString().includes('E404')) throw e;
}
if (!versionAlreadyPublished) {
childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag} --otp=${process.env.ELECTRON_NPM_OTP}`);
}
})

View File

@@ -31,9 +31,9 @@ PDB_LIST = [
PDB_LIST += glob.glob(os.path.join(RELEASE_DIR, '*.dll.pdb'))
NPX_CMD = "npx"
SENTRY_CLI = os.path.join(ELECTRON_DIR, 'node_modules', '.bin', 'sentry-cli')
if sys.platform == "win32":
NPX_CMD += ".cmd"
SENTRY_CLI += ".cmd"
def main():
@@ -48,11 +48,8 @@ def main():
for symbol_file in files:
print("Generating Sentry src bundle for: " + symbol_file)
npx_env = os.environ.copy()
npx_env['npm_config_yes'] = 'true'
subprocess.check_output([
NPX_CMD, '@sentry/cli@1.62.0', 'difutil', 'bundle-sources',
symbol_file], env=npx_env)
SENTRY_CLI, 'difutil', 'bundle-sources', symbol_file])
files += glob.glob(SYMBOLS_DIR + '/*/*/*.src.zip')

173
yarn.lock
View File

@@ -446,6 +446,7 @@ __metadata:
"@electron/typescript-definitions": "npm:^9.1.5"
"@octokit/rest": "npm:^20.1.2"
"@primer/octicons": "npm:^10.0.0"
"@sentry/cli": "npm:1.72.0"
"@types/minimist": "npm:^1.2.5"
"@types/node": "npm:^24.9.0"
"@types/semver": "npm:^7.5.8"
@@ -492,6 +493,8 @@ __metadata:
wrapper-webpack-plugin: "npm:^2.2.0"
yaml: "npm:^2.8.1"
dependenciesMeta:
"@sentry/cli":
built: true
abstract-socket:
built: true
languageName: unknown
@@ -1503,6 +1506,22 @@ __metadata:
languageName: node
linkType: hard
"@sentry/cli@npm:1.72.0":
version: 1.72.0
resolution: "@sentry/cli@npm:1.72.0"
dependencies:
https-proxy-agent: "npm:^5.0.0"
mkdirp: "npm:^0.5.5"
node-fetch: "npm:^2.6.0"
npmlog: "npm:^4.1.2"
progress: "npm:^2.0.3"
proxy-from-env: "npm:^1.1.0"
bin:
sentry-cli: bin/sentry-cli
checksum: 10c0/ef850dc9938c009dec485224222c272c1765ee59da04ef0c334de214cf79afe49a456671f465f98c9b48ff4dfa8738f92e7d9988dea0df0e318fba6969e4c0a7
languageName: node
linkType: hard
"@sindresorhus/is@npm:^4.0.0":
version: 4.6.0
resolution: "@sindresorhus/is@npm:4.6.0"
@@ -2671,6 +2690,13 @@ __metadata:
languageName: node
linkType: hard
"ansi-regex@npm:^2.0.0":
version: 2.1.1
resolution: "ansi-regex@npm:2.1.1"
checksum: 10c0/78cebaf50bce2cb96341a7230adf28d804611da3ce6bf338efa7b72f06cc6ff648e29f80cd95e582617ba58d5fdbec38abfeed3500a98bce8381a9daec7c548b
languageName: node
linkType: hard
"ansi-regex@npm:^3.0.0":
version: 3.0.1
resolution: "ansi-regex@npm:3.0.1"
@@ -2738,6 +2764,13 @@ __metadata:
languageName: node
linkType: hard
"aproba@npm:^1.0.3":
version: 1.2.0
resolution: "aproba@npm:1.2.0"
checksum: 10c0/2d34f008c9edfa991f42fe4b667d541d38a474a39ae0e24805350486d76744cd91ee45313283c1d39a055b14026dd0fc4d0cbfc13f210855d59d7e8b5a61dc51
languageName: node
linkType: hard
"aproba@npm:^1.0.3 || ^2.0.0":
version: 2.1.0
resolution: "aproba@npm:2.1.0"
@@ -2755,6 +2788,16 @@ __metadata:
languageName: node
linkType: hard
"are-we-there-yet@npm:~1.1.2":
version: 1.1.7
resolution: "are-we-there-yet@npm:1.1.7"
dependencies:
delegates: "npm:^1.0.0"
readable-stream: "npm:^2.0.6"
checksum: 10c0/03cb45f2892767773c86a616205fc67feb8dfdd56685d1b34999cfa6c0d2aebe73ec0e6ba88a406422b998dea24138337fdb9a3f9b172d7c2a7f75d02f3df088
languageName: node
linkType: hard
"argparse@npm:^1.0.7":
version: 1.0.10
resolution: "argparse@npm:1.0.10"
@@ -3822,6 +3865,13 @@ __metadata:
languageName: node
linkType: hard
"code-point-at@npm:^1.0.0":
version: 1.1.0
resolution: "code-point-at@npm:1.1.0"
checksum: 10c0/33f6b234084e46e6e369b6f0b07949392651b4dde70fc6a592a8d3dafa08d5bb32e3981a02f31f6fc323a26bc03a4c063a9d56834848695bda7611c2417ea2e6
languageName: node
linkType: hard
"coffeescript@npm:^2.4.1":
version: 2.7.0
resolution: "coffeescript@npm:2.7.0"
@@ -3981,7 +4031,7 @@ __metadata:
languageName: node
linkType: hard
"console-control-strings@npm:^1.0.0, console-control-strings@npm:^1.1.0":
"console-control-strings@npm:^1.0.0, console-control-strings@npm:^1.1.0, console-control-strings@npm:~1.1.0":
version: 1.1.0
resolution: "console-control-strings@npm:1.1.0"
checksum: 10c0/7ab51d30b52d461412cd467721bb82afe695da78fff8f29fe6f6b9cbaac9a2328e27a22a966014df9532100f6dd85370460be8130b9c677891ba36d96a343f50
@@ -6236,6 +6286,22 @@ __metadata:
languageName: node
linkType: hard
"gauge@npm:~2.7.3":
version: 2.7.4
resolution: "gauge@npm:2.7.4"
dependencies:
aproba: "npm:^1.0.3"
console-control-strings: "npm:^1.0.0"
has-unicode: "npm:^2.0.0"
object-assign: "npm:^4.1.0"
signal-exit: "npm:^3.0.0"
string-width: "npm:^1.0.1"
strip-ansi: "npm:^3.0.1"
wide-align: "npm:^1.1.0"
checksum: 10c0/d606346e2e47829e0bc855d0becb36c4ce492feabd61ae92884b89e07812dd8a67a860ca30ece3a4c2e9f2c73bd68ba2b8e558ed362432ffd86de83c08847f84
languageName: node
linkType: hard
"get-caller-file@npm:^2.0.5":
version: 2.0.5
resolution: "get-caller-file@npm:2.0.5"
@@ -6710,7 +6776,7 @@ __metadata:
languageName: node
linkType: hard
"has-unicode@npm:^2.0.1":
"has-unicode@npm:^2.0.0, has-unicode@npm:^2.0.1":
version: 2.0.1
resolution: "has-unicode@npm:2.0.1"
checksum: 10c0/ebdb2f4895c26bb08a8a100b62d362e49b2190bcfd84b76bc4be1a3bd4d254ec52d0dd9f2fbcc093fc5eb878b20c52146f9dfd33e2686ed28982187be593b47c
@@ -7374,6 +7440,15 @@ __metadata:
languageName: node
linkType: hard
"is-fullwidth-code-point@npm:^1.0.0":
version: 1.0.0
resolution: "is-fullwidth-code-point@npm:1.0.0"
dependencies:
number-is-nan: "npm:^1.0.0"
checksum: 10c0/12acfcf16142f2d431bf6af25d68569d3198e81b9799b4ae41058247aafcc666b0127d64384ea28e67a746372611fcbe9b802f69175287aba466da3eddd5ba0f
languageName: node
linkType: hard
"is-fullwidth-code-point@npm:^3.0.0":
version: 3.0.0
resolution: "is-fullwidth-code-point@npm:3.0.0"
@@ -9308,16 +9383,7 @@ __metadata:
languageName: node
linkType: hard
"mkdirp@npm:^1.0.3":
version: 1.0.4
resolution: "mkdirp@npm:1.0.4"
bin:
mkdirp: bin/cmd.js
checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf
languageName: node
linkType: hard
"mkdirp@npm:~0.5.1":
"mkdirp@npm:^0.5.5, mkdirp@npm:~0.5.1":
version: 0.5.6
resolution: "mkdirp@npm:0.5.6"
dependencies:
@@ -9328,6 +9394,15 @@ __metadata:
languageName: node
linkType: hard
"mkdirp@npm:^1.0.3":
version: 1.0.4
resolution: "mkdirp@npm:1.0.4"
bin:
mkdirp: bin/cmd.js
checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf
languageName: node
linkType: hard
"mocha-junit-reporter@npm:^1.18.0":
version: 1.23.3
resolution: "mocha-junit-reporter@npm:1.23.3"
@@ -9480,6 +9555,20 @@ __metadata:
languageName: node
linkType: hard
"node-fetch@npm:^2.6.0":
version: 2.7.0
resolution: "node-fetch@npm:2.7.0"
dependencies:
whatwg-url: "npm:^5.0.0"
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8
languageName: node
linkType: hard
"node-fetch@npm:^2.6.1":
version: 2.6.8
resolution: "node-fetch@npm:2.6.8"
@@ -9645,6 +9734,18 @@ __metadata:
languageName: node
linkType: hard
"npmlog@npm:^4.1.2":
version: 4.1.2
resolution: "npmlog@npm:4.1.2"
dependencies:
are-we-there-yet: "npm:~1.1.2"
console-control-strings: "npm:~1.1.0"
gauge: "npm:~2.7.3"
set-blocking: "npm:~2.0.0"
checksum: 10c0/d6a26cb362277c65e24a70ebdaff31f81184ceb5415fd748abaaf26417bf0794a17ba849116e4f454a0370b9067ae320834cc78d74527dbeadf6e9d19a959046
languageName: node
linkType: hard
"npmlog@npm:^5.0.1":
version: 5.0.1
resolution: "npmlog@npm:5.0.1"
@@ -9669,7 +9770,14 @@ __metadata:
languageName: node
linkType: hard
"object-assign@npm:^4.1.1":
"number-is-nan@npm:^1.0.0":
version: 1.0.1
resolution: "number-is-nan@npm:1.0.1"
checksum: 10c0/cb97149006acc5cd512c13c1838223abdf202e76ddfa059c5e8e7507aff2c3a78cd19057516885a2f6f5b576543dc4f7b6f3c997cc7df53ae26c260855466df5
languageName: node
linkType: hard
"object-assign@npm:^4.1.0, object-assign@npm:^4.1.1":
version: 4.1.1
resolution: "object-assign@npm:4.1.1"
checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414
@@ -10774,6 +10882,21 @@ __metadata:
languageName: node
linkType: hard
"readable-stream@npm:^2.0.6":
version: 2.3.8
resolution: "readable-stream@npm:2.3.8"
dependencies:
core-util-is: "npm:~1.0.0"
inherits: "npm:~2.0.3"
isarray: "npm:~1.0.0"
process-nextick-args: "npm:~2.0.0"
safe-buffer: "npm:~5.1.1"
string_decoder: "npm:~1.1.1"
util-deprecate: "npm:~1.0.1"
checksum: 10c0/7efdb01f3853bc35ac62ea25493567bf588773213f5f4a79f9c365e1ad13bab845ac0dae7bc946270dc40c3929483228415e92a3fc600cc7e4548992f41ee3fa
languageName: node
linkType: hard
"readable-stream@npm:^3.0.2":
version: 3.6.0
resolution: "readable-stream@npm:3.6.0"
@@ -12102,7 +12225,7 @@ __metadata:
languageName: node
linkType: hard
"set-blocking@npm:^2.0.0":
"set-blocking@npm:^2.0.0, set-blocking@npm:~2.0.0":
version: 2.0.0
resolution: "set-blocking@npm:2.0.0"
checksum: 10c0/9f8c1b2d800800d0b589de1477c753492de5c1548d4ade52f57f1d1f5e04af5481554d75ce5e5c43d4004b80a3eb714398d6907027dc0534177b7539119f4454
@@ -12621,6 +12744,17 @@ __metadata:
languageName: node
linkType: hard
"string-width@npm:^1.0.1":
version: 1.0.2
resolution: "string-width@npm:1.0.2"
dependencies:
code-point-at: "npm:^1.0.0"
is-fullwidth-code-point: "npm:^1.0.0"
strip-ansi: "npm:^3.0.0"
checksum: 10c0/c558438baed23a9ab9370bb6a939acbdb2b2ffc517838d651aad0f5b2b674fb85d460d9b1d0b6a4c210dffd09e3235222d89a5bd4c0c1587f78b2bb7bc00c65e
languageName: node
linkType: hard
"string-width@npm:^4.1.0":
version: 4.2.0
resolution: "string-width@npm:4.2.0"
@@ -12812,6 +12946,15 @@ __metadata:
languageName: node
linkType: hard
"strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1":
version: 3.0.1
resolution: "strip-ansi@npm:3.0.1"
dependencies:
ansi-regex: "npm:^2.0.0"
checksum: 10c0/f6e7fbe8e700105dccf7102eae20e4f03477537c74b286fd22cfc970f139002ed6f0d9c10d0e21aa9ed9245e0fa3c9275930e8795c5b947da136e4ecb644a70f
languageName: node
linkType: hard
"strip-ansi@npm:^4.0.0":
version: 4.0.0
resolution: "strip-ansi@npm:4.0.0"
@@ -14264,7 +14407,7 @@ __metadata:
languageName: node
linkType: hard
"wide-align@npm:^1.1.2":
"wide-align@npm:^1.1.0, wide-align@npm:^1.1.2":
version: 1.1.5
resolution: "wide-align@npm:1.1.5"
dependencies: