Files
deepseek-harness/apps/desktop/scripts/desktop-release-environment.mjs
T

99 lines
4.4 KiB
JavaScript

/** Resolve public release identifiers supplied by the packaging environment. */
/** Environment variable that supplies the Electron application identifier. */
export const DESKTOP_APP_ID_ENV = 'DSH_DESKTOP_APP_ID'
/** Environment variable that supplies electron-builder's macOS certificate qualifier. */
export const MACOS_SIGNING_IDENTITY_ENV = 'DSH_DESKTOP_MACOS_SIGNING_IDENTITY'
/** Environment variable that supplies the expected Apple Developer Team ID. */
export const MACOS_TEAM_ID_ENV = 'DSH_DESKTOP_MACOS_TEAM_ID'
const APPLE_API_KEY_ENV = 'APPLE_API_KEY'
const APPLE_API_KEY_ID_ENV = 'APPLE_API_KEY_ID'
const APPLE_API_ISSUER_ENV = 'APPLE_API_ISSUER'
const APPLE_ID_ENV = 'APPLE_ID'
const APPLE_APP_SPECIFIC_PASSWORD_ENV = 'APPLE_APP_SPECIFIC_PASSWORD'
const APPLE_TEAM_ID_ENV = 'APPLE_TEAM_ID'
const APPLE_KEYCHAIN_ENV = 'APPLE_KEYCHAIN'
const APPLE_KEYCHAIN_PROFILE_ENV = 'APPLE_KEYCHAIN_PROFILE'
/**
* Read one required non-empty environment variable.
* @param {NodeJS.ProcessEnv} env - Packaging environment.
* @param {string} name - Required variable name.
* @returns {string} Trimmed variable value.
*/
function requireEnvironmentValue(env, name) {
const value = env[name]?.trim()
if (value === undefined || value === '') {
throw new Error(`desktop release environment: ${name} must be set to a non-empty value`)
}
return value
}
/**
* Resolve and validate the application identifier shared by every platform target.
* @param {NodeJS.ProcessEnv} env - Packaging environment.
* @returns {string} Reverse-DNS application identifier.
*/
export function resolveDesktopAppId(env) {
const appId = requireEnvironmentValue(env, DESKTOP_APP_ID_ENV)
if (!/^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/u.test(appId)) {
throw new Error(`desktop release environment: ${DESKTOP_APP_ID_ENV} must be a reverse-DNS identifier`)
}
return appId
}
/**
* Resolve and validate the public identity expected on a macOS release.
* @param {NodeJS.ProcessEnv} env - Packaging environment.
* @returns {{ signingIdentity: string, teamId: string }} Expected certificate qualifier and Team ID.
*/
export function resolveMacOSSigningEnvironment(env) {
const signingIdentity = requireEnvironmentValue(env, MACOS_SIGNING_IDENTITY_ENV)
if (signingIdentity.startsWith('Developer ID Application:')) {
throw new Error(`desktop release environment: ${MACOS_SIGNING_IDENTITY_ENV} must omit the "Developer ID Application:" prefix`)
}
const teamId = requireEnvironmentValue(env, MACOS_TEAM_ID_ENV)
if (!/^[A-Z0-9]{10}$/u.test(teamId)) {
throw new Error(`desktop release environment: ${MACOS_TEAM_ID_ENV} must contain 10 uppercase letters or digits`)
}
return { signingIdentity, teamId }
}
/**
* Resolve one complete credential set accepted by Apple's notary service.
* @param {NodeJS.ProcessEnv} env - Packaging environment.
* @returns {{ appleId: string, appleIdPassword: string, teamId: string } | { appleApiKey: string, appleApiKeyId: string, appleApiIssuer: string } | { keychainProfile: string, keychain?: string }} Notary credentials without the submitted artifact path.
*/
export function resolveMacOSNotarizationEnvironment(env) {
const appleIdValues = [env[APPLE_ID_ENV], env[APPLE_APP_SPECIFIC_PASSWORD_ENV], env[APPLE_TEAM_ID_ENV]]
if (appleIdValues.some(value => value !== undefined)) {
return {
appleId: requireEnvironmentValue(env, APPLE_ID_ENV),
appleIdPassword: requireEnvironmentValue(env, APPLE_APP_SPECIFIC_PASSWORD_ENV),
teamId: requireEnvironmentValue(env, APPLE_TEAM_ID_ENV),
}
}
const apiKeyValues = [env[APPLE_API_KEY_ENV], env[APPLE_API_KEY_ID_ENV], env[APPLE_API_ISSUER_ENV]]
if (apiKeyValues.some(value => value !== undefined)) {
return {
appleApiKey: requireEnvironmentValue(env, APPLE_API_KEY_ENV),
appleApiKeyId: requireEnvironmentValue(env, APPLE_API_KEY_ID_ENV),
appleApiIssuer: requireEnvironmentValue(env, APPLE_API_ISSUER_ENV),
}
}
const keychainProfile = env[APPLE_KEYCHAIN_PROFILE_ENV]?.trim()
if (keychainProfile !== undefined && keychainProfile !== '') {
const keychain = env[APPLE_KEYCHAIN_ENV]?.trim()
return keychain === undefined || keychain === ''
? { keychainProfile }
: { keychainProfile, keychain }
}
throw new Error('desktop release environment: macOS packaging requires APPLE_API_KEY, APPLE_API_KEY_ID, and APPLE_API_ISSUER; APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, and APPLE_TEAM_ID; or APPLE_KEYCHAIN_PROFILE')
}