Files
electron/script/release/uploaders/upload-symbols.py
Samuel Attard 3d743a6ef7 build: replace npx with lockfile-pinned binaries (#50718)
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.
2026-04-06 10:02:18 -04:00

96 lines
2.5 KiB
Python
Executable File

#!/usr/bin/env python3
import glob
import os
import shutil
import subprocess
import sys
import tempfile
def is_fs_case_sensitive():
with tempfile.NamedTemporaryFile(prefix='TmP') as tmp_file:
return(not os.path.exists(tmp_file.name.lower()))
sys.path.append(
os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
from lib.config import PLATFORM
from lib.util import get_electron_branding, execute, store_artifact, \
get_out_dir, ELECTRON_DIR
RELEASE_DIR = get_out_dir()
PROJECT_NAME = get_electron_branding()['project_name']
PRODUCT_NAME = get_electron_branding()['product_name']
SYMBOLS_DIR = os.path.join(RELEASE_DIR, 'breakpad_symbols')
PDB_LIST = [
os.path.join(RELEASE_DIR, f'{PROJECT_NAME}.exe.pdb')
]
PDB_LIST += glob.glob(os.path.join(RELEASE_DIR, '*.dll.pdb'))
SENTRY_CLI = os.path.join(ELECTRON_DIR, 'node_modules', '.bin', 'sentry-cli')
if sys.platform == "win32":
SENTRY_CLI += ".cmd"
def main():
os.chdir(ELECTRON_DIR)
files = []
if PLATFORM == 'win32':
for pdb in PDB_LIST:
run_symstore(pdb, SYMBOLS_DIR, PRODUCT_NAME)
files = glob.glob(SYMBOLS_DIR + '/*.pdb/*/*.pdb')
files += glob.glob(SYMBOLS_DIR + '/*/*/*.sym')
for symbol_file in files:
print("Generating Sentry src bundle for: " + symbol_file)
subprocess.check_output([
SENTRY_CLI, 'difutil', 'bundle-sources', symbol_file])
files += glob.glob(SYMBOLS_DIR + '/*/*/*.src.zip')
# The file upload needs to be symbols/:symbol_name/:hash/:symbol
os.chdir(SYMBOLS_DIR)
files = [os.path.relpath(f, os.getcwd()) for f in files]
# The symbol server needs lowercase paths, it will fail otherwise
# So lowercase all the file paths here
if is_fs_case_sensitive():
for f in files:
lower_f = f.lower()
if lower_f != f:
if os.path.exists(lower_f):
shutil.rmtree(lower_f)
lower_dir = os.path.dirname(lower_f)
if not os.path.exists(lower_dir):
os.makedirs(lower_dir)
shutil.copy2(f, lower_f)
files = [f.lower() for f in files]
for f in files:
assert os.path.exists(f)
upload_symbols(files)
def run_symstore(pdb, dest, product):
for attempt in range(2):
try:
execute(['symstore', 'add', '/r', '/f', pdb, '/s', dest, '/t', product])
break
except Exception as e:
print(f"An error occurred while adding '{pdb}' to SymStore: {str(e)}")
if attempt == 0:
print("Retrying...")
def upload_symbols(files):
store_artifact(SYMBOLS_DIR, 'symbols',
files)
if __name__ == '__main__':
sys.exit(main())