mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
fix(release): validate minified telemetry and prune target natives first
This commit is contained in:
@@ -266,16 +266,6 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
afterPack: async (context) => {
|
||||
// Why: a Linux runner-image glibc bump silently shipped a node-pty pty.node
|
||||
// requiring GLIBC_2.34, crashing the app on startup on Ubuntu 20.04 (#9902).
|
||||
// Fail packaging if any bundled native binary exceeds the supported floor.
|
||||
if (context.electronPlatformName === 'linux') {
|
||||
// Why the arch is passed: symbol-version checks pass happily on a wrong-architecture binary,
|
||||
// so a cross-built slice could ship the host's pty.node and only fail at runtime.
|
||||
verifyLinuxGlibcFloor(context.appOutDir, {
|
||||
targetArch: { 1: 'x64', 3: 'arm64' }[context.arch]
|
||||
})
|
||||
}
|
||||
const resourcesDir =
|
||||
context.electronPlatformName === 'darwin'
|
||||
? join(
|
||||
@@ -313,6 +303,13 @@ module.exports = {
|
||||
}
|
||||
stampPackagedCliVersion(resourcesDir, context.packager.appInfo.version)
|
||||
prunePackagedRuntimeNodeModules(resourcesDir, context.electronPlatformName, context.arch)
|
||||
// Prune optional native variants before checking the glibc/architecture
|
||||
// floor; cross-builds intentionally install all optional packages.
|
||||
if (context.electronPlatformName === 'linux') {
|
||||
verifyLinuxGlibcFloor(context.appOutDir, {
|
||||
targetArch: { 1: 'x64', 3: 'arm64' }[context.arch]
|
||||
})
|
||||
}
|
||||
verifyPackagedMainRuntimeDeps(resourcesDir)
|
||||
// Why: boot the packaged daemon-entry under plain Node, but only for the
|
||||
// slice matching the packaging host's arch — daemon-entry.js is JS, yet it
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
export const BUILD_IDENTITY_RE = /\b(?:const|let|var)\s+BUILD_IDENTITY\s*=\s*"(rc|stable)"/
|
||||
export const WRITE_KEY_RE = /\b(?:const|let|var)\s+WRITE_KEY\s*=\s*"(phc_[A-Za-z0-9_-]+)"/
|
||||
// The unminified bundle keeps these names. Production minification may rename
|
||||
// them, but the injected identity and key remain adjacent in the declaration.
|
||||
export const BUILD_IDENTITY_RE = /\b(?:const|let|var)\s+BUILD_IDENTITY\s*=\s*["`](rc|stable)["`]/
|
||||
export const WRITE_KEY_RE = /\b(?:const|let|var)\s+WRITE_KEY\s*=\s*["`](phc_[A-Za-z0-9_-]+)["`]/
|
||||
export const MINIFIED_TELEMETRY_RE =
|
||||
/\b(?:const|let|var)\s+[$\w]+\s*=\s*["`](rc|stable)["`]\s*,\s*[$\w]+\s*=\s*["`](phc_[A-Za-z0-9_-]+)["`]/
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { BUILD_IDENTITY_RE, WRITE_KEY_RE } from './telemetry-bundle-constant-patterns.mjs'
|
||||
import {
|
||||
BUILD_IDENTITY_RE,
|
||||
MINIFIED_TELEMETRY_RE,
|
||||
WRITE_KEY_RE
|
||||
} from './telemetry-bundle-constant-patterns.mjs'
|
||||
|
||||
describe('telemetry bundle constant patterns', () => {
|
||||
it.each(['const', 'let', 'var'])('accepts %s declarations', (declaration) => {
|
||||
@@ -13,4 +17,9 @@ describe('telemetry bundle constant patterns', () => {
|
||||
expect('const WRITE_KEY = null').not.toMatch(WRITE_KEY_RE)
|
||||
expect('const WRITE_KEY = "example-key"').not.toMatch(WRITE_KEY_RE)
|
||||
})
|
||||
|
||||
it('accepts minified adjacent declarations', () => {
|
||||
const bundle = 'var dde=`stable`,fde=`phc_example-key_123`,pde=(dde===`stable`)'
|
||||
expect(bundle).toMatch(MINIFIED_TELEMETRY_RE)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -38,7 +38,11 @@ import { join, resolve } from 'node:path'
|
||||
// `node_modules`). If electron-builder ever drops it, promote this to a
|
||||
// direct devDependency in package.json.
|
||||
import { extractFile, listPackage } from '@electron/asar'
|
||||
import { BUILD_IDENTITY_RE, WRITE_KEY_RE } from './telemetry-bundle-constant-patterns.mjs'
|
||||
import {
|
||||
BUILD_IDENTITY_RE,
|
||||
MINIFIED_TELEMETRY_RE,
|
||||
WRITE_KEY_RE
|
||||
} from './telemetry-bundle-constant-patterns.mjs'
|
||||
|
||||
// Why resolve from import.meta.url instead of cwd: a release runner (or a
|
||||
// developer debugging locally) may invoke this script from a non-root cwd.
|
||||
@@ -156,8 +160,14 @@ function verifyAsar(asarPath) {
|
||||
|
||||
const buildIdentityMatch = BUILD_IDENTITY_RE.exec(indexJs)
|
||||
const writeKeyMatch = WRITE_KEY_RE.exec(indexJs)
|
||||
const minifiedTelemetryMatch = MINIFIED_TELEMETRY_RE.exec(indexJs)
|
||||
|
||||
if (!buildIdentityMatch) {
|
||||
// Rolldown renames module-local constants in production output. In that
|
||||
// form, verify the adjacent injected identity/key declaration instead.
|
||||
const verifiedIdentity = buildIdentityMatch?.[1] ?? minifiedTelemetryMatch?.[1]
|
||||
const verifiedWriteKey = writeKeyMatch?.[1] ?? minifiedTelemetryMatch?.[2]
|
||||
|
||||
if (!verifiedIdentity) {
|
||||
console.error(`::error::BUILD_IDENTITY constant missing or unexpected value in ${asarPath}`)
|
||||
const sample = indexJs.match(/.{0,80}BUILD_IDENTITY.{0,80}/g)?.slice(0, 5) ?? []
|
||||
for (const line of sample) {
|
||||
@@ -165,7 +175,7 @@ function verifyAsar(asarPath) {
|
||||
}
|
||||
return null
|
||||
}
|
||||
if (!writeKeyMatch) {
|
||||
if (!verifiedWriteKey) {
|
||||
console.error(`::error::PostHog WRITE_KEY missing from ${asarPath}`)
|
||||
const sample = indexJs.match(/.{0,80}WRITE_KEY.{0,80}/g)?.slice(0, 5) ?? []
|
||||
for (const line of sample) {
|
||||
@@ -174,7 +184,7 @@ function verifyAsar(asarPath) {
|
||||
return null
|
||||
}
|
||||
|
||||
return { asarPath, buildIdentity: buildIdentityMatch[1], writeKey: writeKeyMatch[1] }
|
||||
return { asarPath, buildIdentity: verifiedIdentity, writeKey: verifiedWriteKey }
|
||||
}
|
||||
|
||||
// Why verify every match (not just the first): macOS dual-arch produces one
|
||||
|
||||
Reference in New Issue
Block a user