@expo/build-tools 1.0.248 → 1.0.250

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -56,6 +56,7 @@ async function restoreCcacheAsync({ logger, workingDirectory, platform, env, sec
56
56
  const checkInstall = await (0, results_1.asyncResult)((0, steps_1.spawnAsync)('command', ['-v', 'ccache'], {
57
57
  env,
58
58
  stdio: 'pipe',
59
+ shell: true,
59
60
  }));
60
61
  if (!checkInstall.ok) {
61
62
  return;
@@ -123,6 +124,7 @@ async function cacheStatsAsync({ logger, env, }) {
123
124
  const checkInstall = await (0, results_1.asyncResult)((0, steps_1.spawnAsync)('command', ['-v', 'ccache'], {
124
125
  env,
125
126
  stdio: 'pipe',
127
+ shell: true,
126
128
  }));
127
129
  if (!checkInstall.ok) {
128
130
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"restoreBuildCache.js","sourceRoot":"","sources":["../../../src/steps/functions/restoreBuildCache.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BuildFunction,\n BuildStepInput,\n BuildStepInputValueTypeName,\n spawnAsync,\n} from '@expo/steps';\nimport { Platform } from '@expo/eas-build-job';\nimport { bunyan } from '@expo/logger';\nimport { asyncResult } from '@expo/results';\nimport nullthrows from 'nullthrows';\n\nimport {\n CACHE_KEY_PREFIX_BY_PLATFORM,\n generateDefaultBuildCacheKeyAsync,\n getCcachePath,\n} from '../../utils/cacheKey';\nimport { TurtleFetchError } from '../../utils/turtleFetch';\n\nimport { downloadCacheAsync, decompressCacheAsync, downloadPublicCacheAsync } from './restoreCache';\n\nexport function createRestoreBuildCacheFunction(): BuildFunction {\n return new BuildFunction({\n namespace: 'eas',\n id: 'restore_build_cache',\n name: 'Restore Cache',\n inputProviders: [\n BuildStepInput.createProvider({\n id: 'platform',\n required: false,\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n ],\n fn: async (stepCtx, { env, inputs }) => {\n const { logger } = stepCtx;\n const workingDirectory = stepCtx.workingDirectory;\n const platform =\n (inputs.platform.value as Platform | undefined) ??\n stepCtx.global.staticContext.job.platform;\n if (!platform || ![Platform.ANDROID, Platform.IOS].includes(platform)) {\n throw new Error(\n `Unsupported platform: ${platform}. Platform must be \"${Platform.ANDROID}\" or \"${Platform.IOS}\"`\n );\n }\n\n await restoreCcacheAsync({\n logger,\n workingDirectory,\n platform,\n env,\n secrets: stepCtx.global.staticContext.job.secrets,\n });\n },\n });\n}\n\nexport async function restoreCcacheAsync({\n logger,\n workingDirectory,\n platform,\n env,\n secrets,\n}: {\n logger: bunyan;\n workingDirectory: string;\n platform: Platform;\n env: Record<string, string | undefined>;\n secrets?: { robotAccessToken?: string };\n}): Promise<void> {\n const enabled =\n env.EAS_RESTORE_CACHE === '1' || (env.EAS_USE_CACHE === '1' && env.EAS_RESTORE_CACHE !== '0');\n\n if (!enabled) {\n return;\n }\n const robotAccessToken = nullthrows(\n secrets?.robotAccessToken,\n 'Robot access token is required for cache operations'\n );\n const expoApiServerURL = nullthrows(env.__API_SERVER_URL, '__API_SERVER_URL is not set');\n const cachePath = getCcachePath(env);\n\n // Check if ccache is installed before proceeding\n const checkInstall = await asyncResult(\n spawnAsync('command', ['-v', 'ccache'], {\n env,\n stdio: 'pipe',\n })\n );\n if (!checkInstall.ok) {\n return;\n }\n\n try {\n // Zero ccache stats for accurate tracking\n await asyncResult(\n spawnAsync('ccache', ['--zero-stats'], {\n env,\n stdio: 'pipe',\n })\n );\n\n const cacheKey = await generateDefaultBuildCacheKeyAsync(workingDirectory, platform);\n logger.info(`Restoring cache key: ${cacheKey}`);\n\n const jobId = nullthrows(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');\n const { archivePath, matchedKey } = await downloadCacheAsync({\n logger,\n jobId,\n expoApiServerURL,\n robotAccessToken,\n paths: [cachePath],\n key: cacheKey,\n keyPrefixes: [CACHE_KEY_PREFIX_BY_PLATFORM[platform]],\n platform,\n });\n\n await decompressCacheAsync({\n archivePath,\n workingDirectory,\n verbose: env.EXPO_DEBUG === '1',\n logger,\n });\n\n logger.info(\n `Cache restored successfully ${matchedKey === cacheKey ? '(direct hit)' : '(prefix match)'}`\n );\n } catch (err: unknown) {\n if (err instanceof TurtleFetchError && err.response?.status === 404) {\n try {\n logger.info('No cache found for this key. Downloading public cache...');\n const { archivePath } = await downloadPublicCacheAsync({\n logger,\n expoApiServerURL,\n robotAccessToken,\n paths: [cachePath],\n platform,\n });\n await decompressCacheAsync({\n archivePath,\n workingDirectory,\n verbose: env.EXPO_DEBUG === '1',\n logger,\n });\n } catch (err: unknown) {\n logger.warn({ err }, 'Failed to download public cache');\n }\n } else {\n logger.warn({ err }, 'Failed to restore cache');\n }\n }\n}\n\nexport async function cacheStatsAsync({\n logger,\n env,\n}: {\n logger: bunyan;\n env: Record<string, string | undefined>;\n}): Promise<void> {\n const enabled =\n env.EAS_RESTORE_CACHE === '1' || (env.EAS_USE_CACHE === '1' && env.EAS_RESTORE_CACHE !== '0');\n\n if (!enabled) {\n return;\n }\n\n // Check if ccache is installed\n const checkInstall = await asyncResult(\n spawnAsync('command', ['-v', 'ccache'], {\n env,\n stdio: 'pipe',\n })\n );\n if (!checkInstall.ok) {\n return;\n }\n\n logger.info('Cache stats:');\n await asyncResult(\n spawnAsync('ccache', ['--show-stats', '-v'], {\n env,\n logger,\n stdio: 'pipe',\n })\n );\n}\n"]}
1
+ {"version":3,"file":"restoreBuildCache.js","sourceRoot":"","sources":["../../../src/steps/functions/restoreBuildCache.ts"],"names":[],"mappings":";;;;;AAoBA,0EAiCC;AAED,gDAgGC;AAED,0CAkCC;AA3LD,uCAKqB;AACrB,uDAA+C;AAE/C,2CAA4C;AAC5C,4DAAoC;AAEpC,mDAI8B;AAC9B,yDAA2D;AAE3D,iDAAoG;AAEpG,SAAgB,+BAA+B;IAC7C,OAAO,IAAI,qBAAa,CAAC;QACvB,SAAS,EAAE,KAAK;QAChB,EAAE,EAAE,qBAAqB;QACzB,IAAI,EAAE,eAAe;QACrB,cAAc,EAAE;YACd,sBAAc,CAAC,cAAc,CAAC;gBAC5B,EAAE,EAAE,UAAU;gBACd,QAAQ,EAAE,KAAK;gBACf,oBAAoB,EAAE,mCAA2B,CAAC,MAAM;aACzD,CAAC;SACH;QACD,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;;YACrC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;YAC3B,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAClD,MAAM,QAAQ,GACZ,MAAC,MAAM,CAAC,QAAQ,CAAC,KAA8B,mCAC/C,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC5C,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,wBAAQ,CAAC,OAAO,EAAE,wBAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtE,MAAM,IAAI,KAAK,CACb,yBAAyB,QAAQ,uBAAuB,wBAAQ,CAAC,OAAO,SAAS,wBAAQ,CAAC,GAAG,GAAG,CACjG,CAAC;YACJ,CAAC;YAED,MAAM,kBAAkB,CAAC;gBACvB,MAAM;gBACN,gBAAgB;gBAChB,QAAQ;gBACR,GAAG;gBACH,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO;aAClD,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,kBAAkB,CAAC,EACvC,MAAM,EACN,gBAAgB,EAChB,QAAQ,EACR,GAAG,EACH,OAAO,GAOR;;IACC,MAAM,OAAO,GACX,GAAG,CAAC,iBAAiB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG,IAAI,GAAG,CAAC,iBAAiB,KAAK,GAAG,CAAC,CAAC;IAEhG,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IACD,MAAM,gBAAgB,GAAG,IAAA,oBAAU,EACjC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,gBAAgB,EACzB,qDAAqD,CACtD,CAAC;IACF,MAAM,gBAAgB,GAAG,IAAA,oBAAU,EAAC,GAAG,CAAC,gBAAgB,EAAE,6BAA6B,CAAC,CAAC;IACzF,MAAM,SAAS,GAAG,IAAA,wBAAa,EAAC,GAAG,CAAC,CAAC;IAErC,iDAAiD;IACjD,MAAM,YAAY,GAAG,MAAM,IAAA,qBAAW,EACpC,IAAA,kBAAU,EAAC,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;QACtC,GAAG;QACH,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,IAAI;KACZ,CAAC,CACH,CAAC;IACF,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,0CAA0C;QAC1C,MAAM,IAAA,qBAAW,EACf,IAAA,kBAAU,EAAC,QAAQ,EAAE,CAAC,cAAc,CAAC,EAAE;YACrC,GAAG;YACH,KAAK,EAAE,MAAM;SACd,CAAC,CACH,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAA,4CAAiC,EAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QACrF,MAAM,CAAC,IAAI,CAAC,wBAAwB,QAAQ,EAAE,CAAC,CAAC;QAEhD,MAAM,KAAK,GAAG,IAAA,oBAAU,EAAC,GAAG,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;QACtE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,IAAA,iCAAkB,EAAC;YAC3D,MAAM;YACN,KAAK;YACL,gBAAgB;YAChB,gBAAgB;YAChB,KAAK,EAAE,CAAC,SAAS,CAAC;YAClB,GAAG,EAAE,QAAQ;YACb,WAAW,EAAE,CAAC,uCAA4B,CAAC,QAAQ,CAAC,CAAC;YACrD,QAAQ;SACT,CAAC,CAAC;QAEH,MAAM,IAAA,mCAAoB,EAAC;YACzB,WAAW;YACX,gBAAgB;YAChB,OAAO,EAAE,GAAG,CAAC,UAAU,KAAK,GAAG;YAC/B,MAAM;SACP,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CACT,+BAA+B,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAC7F,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,8BAAgB,IAAI,CAAA,MAAA,GAAG,CAAC,QAAQ,0CAAE,MAAM,MAAK,GAAG,EAAE,CAAC;YACpE,IAAI,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;gBACxE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAA,uCAAwB,EAAC;oBACrD,MAAM;oBACN,gBAAgB;oBAChB,gBAAgB;oBAChB,KAAK,EAAE,CAAC,SAAS,CAAC;oBAClB,QAAQ;iBACT,CAAC,CAAC;gBACH,MAAM,IAAA,mCAAoB,EAAC;oBACzB,WAAW;oBACX,gBAAgB;oBAChB,OAAO,EAAE,GAAG,CAAC,UAAU,KAAK,GAAG;oBAC/B,MAAM;iBACP,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,iCAAiC,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,yBAAyB,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,EACpC,MAAM,EACN,GAAG,GAIJ;IACC,MAAM,OAAO,GACX,GAAG,CAAC,iBAAiB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG,IAAI,GAAG,CAAC,iBAAiB,KAAK,GAAG,CAAC,CAAC;IAEhG,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,+BAA+B;IAC/B,MAAM,YAAY,GAAG,MAAM,IAAA,qBAAW,EACpC,IAAA,kBAAU,EAAC,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;QACtC,GAAG;QACH,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,IAAI;KACZ,CAAC,CACH,CAAC;IACF,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC5B,MAAM,IAAA,qBAAW,EACf,IAAA,kBAAU,EAAC,QAAQ,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE;QAC3C,GAAG;QACH,MAAM;QACN,KAAK,EAAE,MAAM;KACd,CAAC,CACH,CAAC;AACJ,CAAC","sourcesContent":["import {\n BuildFunction,\n BuildStepInput,\n BuildStepInputValueTypeName,\n spawnAsync,\n} from '@expo/steps';\nimport { Platform } from '@expo/eas-build-job';\nimport { bunyan } from '@expo/logger';\nimport { asyncResult } from '@expo/results';\nimport nullthrows from 'nullthrows';\n\nimport {\n CACHE_KEY_PREFIX_BY_PLATFORM,\n generateDefaultBuildCacheKeyAsync,\n getCcachePath,\n} from '../../utils/cacheKey';\nimport { TurtleFetchError } from '../../utils/turtleFetch';\n\nimport { downloadCacheAsync, decompressCacheAsync, downloadPublicCacheAsync } from './restoreCache';\n\nexport function createRestoreBuildCacheFunction(): BuildFunction {\n return new BuildFunction({\n namespace: 'eas',\n id: 'restore_build_cache',\n name: 'Restore Cache',\n inputProviders: [\n BuildStepInput.createProvider({\n id: 'platform',\n required: false,\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n ],\n fn: async (stepCtx, { env, inputs }) => {\n const { logger } = stepCtx;\n const workingDirectory = stepCtx.workingDirectory;\n const platform =\n (inputs.platform.value as Platform | undefined) ??\n stepCtx.global.staticContext.job.platform;\n if (!platform || ![Platform.ANDROID, Platform.IOS].includes(platform)) {\n throw new Error(\n `Unsupported platform: ${platform}. Platform must be \"${Platform.ANDROID}\" or \"${Platform.IOS}\"`\n );\n }\n\n await restoreCcacheAsync({\n logger,\n workingDirectory,\n platform,\n env,\n secrets: stepCtx.global.staticContext.job.secrets,\n });\n },\n });\n}\n\nexport async function restoreCcacheAsync({\n logger,\n workingDirectory,\n platform,\n env,\n secrets,\n}: {\n logger: bunyan;\n workingDirectory: string;\n platform: Platform;\n env: Record<string, string | undefined>;\n secrets?: { robotAccessToken?: string };\n}): Promise<void> {\n const enabled =\n env.EAS_RESTORE_CACHE === '1' || (env.EAS_USE_CACHE === '1' && env.EAS_RESTORE_CACHE !== '0');\n\n if (!enabled) {\n return;\n }\n const robotAccessToken = nullthrows(\n secrets?.robotAccessToken,\n 'Robot access token is required for cache operations'\n );\n const expoApiServerURL = nullthrows(env.__API_SERVER_URL, '__API_SERVER_URL is not set');\n const cachePath = getCcachePath(env);\n\n // Check if ccache is installed before proceeding\n const checkInstall = await asyncResult(\n spawnAsync('command', ['-v', 'ccache'], {\n env,\n stdio: 'pipe',\n shell: true,\n })\n );\n if (!checkInstall.ok) {\n return;\n }\n\n try {\n // Zero ccache stats for accurate tracking\n await asyncResult(\n spawnAsync('ccache', ['--zero-stats'], {\n env,\n stdio: 'pipe',\n })\n );\n\n const cacheKey = await generateDefaultBuildCacheKeyAsync(workingDirectory, platform);\n logger.info(`Restoring cache key: ${cacheKey}`);\n\n const jobId = nullthrows(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');\n const { archivePath, matchedKey } = await downloadCacheAsync({\n logger,\n jobId,\n expoApiServerURL,\n robotAccessToken,\n paths: [cachePath],\n key: cacheKey,\n keyPrefixes: [CACHE_KEY_PREFIX_BY_PLATFORM[platform]],\n platform,\n });\n\n await decompressCacheAsync({\n archivePath,\n workingDirectory,\n verbose: env.EXPO_DEBUG === '1',\n logger,\n });\n\n logger.info(\n `Cache restored successfully ${matchedKey === cacheKey ? '(direct hit)' : '(prefix match)'}`\n );\n } catch (err: unknown) {\n if (err instanceof TurtleFetchError && err.response?.status === 404) {\n try {\n logger.info('No cache found for this key. Downloading public cache...');\n const { archivePath } = await downloadPublicCacheAsync({\n logger,\n expoApiServerURL,\n robotAccessToken,\n paths: [cachePath],\n platform,\n });\n await decompressCacheAsync({\n archivePath,\n workingDirectory,\n verbose: env.EXPO_DEBUG === '1',\n logger,\n });\n } catch (err: unknown) {\n logger.warn({ err }, 'Failed to download public cache');\n }\n } else {\n logger.warn({ err }, 'Failed to restore cache');\n }\n }\n}\n\nexport async function cacheStatsAsync({\n logger,\n env,\n}: {\n logger: bunyan;\n env: Record<string, string | undefined>;\n}): Promise<void> {\n const enabled =\n env.EAS_RESTORE_CACHE === '1' || (env.EAS_USE_CACHE === '1' && env.EAS_RESTORE_CACHE !== '0');\n\n if (!enabled) {\n return;\n }\n\n // Check if ccache is installed\n const checkInstall = await asyncResult(\n spawnAsync('command', ['-v', 'ccache'], {\n env,\n stdio: 'pipe',\n shell: true,\n })\n );\n if (!checkInstall.ok) {\n return;\n }\n\n logger.info('Cache stats:');\n await asyncResult(\n spawnAsync('ccache', ['--show-stats', '-v'], {\n env,\n logger,\n stdio: 'pipe',\n })\n );\n}\n"]}
@@ -52,6 +52,7 @@ async function saveCcacheAsync({ logger, workingDirectory, platform, evictUsedBe
52
52
  const checkInstall = await (0, results_1.asyncResult)((0, steps_1.spawnAsync)('command', ['-v', 'ccache'], {
53
53
  env,
54
54
  stdio: 'pipe',
55
+ shell: true,
55
56
  }));
56
57
  if (!checkInstall.ok) {
57
58
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"saveBuildCache.js","sourceRoot":"","sources":["../../../src/steps/functions/saveBuildCache.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\n\nimport {\n BuildFunction,\n BuildStepInput,\n BuildStepInputValueTypeName,\n spawnAsync,\n} from '@expo/steps';\nimport { Platform } from '@expo/eas-build-job';\nimport { bunyan } from '@expo/logger';\nimport { asyncResult } from '@expo/results';\nimport nullthrows from 'nullthrows';\n\nimport { generateDefaultBuildCacheKeyAsync, getCcachePath } from '../../utils/cacheKey';\n\nimport { compressCacheAsync, uploadCacheAsync } from './saveCache';\n\nexport function createSaveBuildCacheFunction(evictUsedBefore: Date): BuildFunction {\n return new BuildFunction({\n namespace: 'eas',\n id: 'save_build_cache',\n name: 'Save Cache',\n inputProviders: [\n BuildStepInput.createProvider({\n id: 'platform',\n required: false,\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n ],\n fn: async (stepCtx, { env, inputs }) => {\n const { logger } = stepCtx;\n const workingDirectory = stepCtx.workingDirectory;\n const platform =\n (inputs.platform.value as Platform | undefined) ??\n stepCtx.global.staticContext.job.platform;\n if (!platform || ![Platform.ANDROID, Platform.IOS].includes(platform)) {\n throw new Error(\n `Unsupported platform: ${platform}. Platform must be \"${Platform.ANDROID}\" or \"${Platform.IOS}\"`\n );\n }\n\n await saveCcacheAsync({\n logger,\n workingDirectory,\n platform,\n evictUsedBefore,\n env,\n secrets: stepCtx.global.staticContext.job.secrets,\n });\n },\n });\n}\n\nexport async function saveCcacheAsync({\n logger,\n workingDirectory,\n platform,\n evictUsedBefore,\n env,\n secrets,\n}: {\n logger: bunyan;\n workingDirectory: string;\n platform: Platform;\n evictUsedBefore: Date;\n env: Record<string, string | undefined>;\n secrets?: { robotAccessToken?: string };\n}): Promise<void> {\n const enabled =\n env.EAS_SAVE_CACHE === '1' || (env.EAS_USE_CACHE === '1' && env.EAS_SAVE_CACHE !== '0');\n\n if (!enabled) {\n return;\n }\n\n // Check if ccache is installed before proceeding\n const checkInstall = await asyncResult(\n spawnAsync('command', ['-v', 'ccache'], {\n env,\n stdio: 'pipe',\n })\n );\n if (!checkInstall.ok) {\n return;\n }\n\n try {\n const cacheKey = await generateDefaultBuildCacheKeyAsync(workingDirectory, platform);\n logger.info(`Saving cache key: ${cacheKey}`);\n\n const jobId = nullthrows(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');\n const robotAccessToken = nullthrows(\n secrets?.robotAccessToken,\n 'Robot access token is required for cache operations'\n );\n const expoApiServerURL = nullthrows(env.__API_SERVER_URL, '__API_SERVER_URL is not set');\n const cachePath = getCcachePath(env);\n\n // Cache size can blow up over time over many builds, so evict stale files\n // and only upload what was used within this build's time window\n const evictWindow = Math.floor((Date.now() - evictUsedBefore.getTime()) / 1000);\n logger.info('Pruning cache...');\n await asyncResult(\n spawnAsync('ccache', ['--evict-older-than', evictWindow + 's'], {\n env,\n logger,\n stdio: 'pipe',\n })\n );\n\n logger.info('Preparing cache archive...');\n\n const { archivePath } = await compressCacheAsync({\n paths: [cachePath],\n workingDirectory,\n verbose: env.EXPO_DEBUG === '1',\n logger,\n });\n\n const { size } = await fs.promises.stat(archivePath);\n\n await uploadCacheAsync({\n logger,\n jobId,\n expoApiServerURL,\n robotAccessToken,\n archivePath,\n key: cacheKey,\n paths: [cachePath],\n size,\n platform,\n });\n } catch (err) {\n logger.error({ err }, 'Failed to save cache');\n }\n}\n"]}
1
+ {"version":3,"file":"saveBuildCache.js","sourceRoot":"","sources":["../../../src/steps/functions/saveBuildCache.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\n\nimport {\n BuildFunction,\n BuildStepInput,\n BuildStepInputValueTypeName,\n spawnAsync,\n} from '@expo/steps';\nimport { Platform } from '@expo/eas-build-job';\nimport { bunyan } from '@expo/logger';\nimport { asyncResult } from '@expo/results';\nimport nullthrows from 'nullthrows';\n\nimport { generateDefaultBuildCacheKeyAsync, getCcachePath } from '../../utils/cacheKey';\n\nimport { compressCacheAsync, uploadCacheAsync } from './saveCache';\n\nexport function createSaveBuildCacheFunction(evictUsedBefore: Date): BuildFunction {\n return new BuildFunction({\n namespace: 'eas',\n id: 'save_build_cache',\n name: 'Save Cache',\n inputProviders: [\n BuildStepInput.createProvider({\n id: 'platform',\n required: false,\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n ],\n fn: async (stepCtx, { env, inputs }) => {\n const { logger } = stepCtx;\n const workingDirectory = stepCtx.workingDirectory;\n const platform =\n (inputs.platform.value as Platform | undefined) ??\n stepCtx.global.staticContext.job.platform;\n if (!platform || ![Platform.ANDROID, Platform.IOS].includes(platform)) {\n throw new Error(\n `Unsupported platform: ${platform}. Platform must be \"${Platform.ANDROID}\" or \"${Platform.IOS}\"`\n );\n }\n\n await saveCcacheAsync({\n logger,\n workingDirectory,\n platform,\n evictUsedBefore,\n env,\n secrets: stepCtx.global.staticContext.job.secrets,\n });\n },\n });\n}\n\nexport async function saveCcacheAsync({\n logger,\n workingDirectory,\n platform,\n evictUsedBefore,\n env,\n secrets,\n}: {\n logger: bunyan;\n workingDirectory: string;\n platform: Platform;\n evictUsedBefore: Date;\n env: Record<string, string | undefined>;\n secrets?: { robotAccessToken?: string };\n}): Promise<void> {\n const enabled =\n env.EAS_SAVE_CACHE === '1' || (env.EAS_USE_CACHE === '1' && env.EAS_SAVE_CACHE !== '0');\n\n if (!enabled) {\n return;\n }\n\n // Check if ccache is installed before proceeding\n const checkInstall = await asyncResult(\n spawnAsync('command', ['-v', 'ccache'], {\n env,\n stdio: 'pipe',\n shell: true,\n })\n );\n if (!checkInstall.ok) {\n return;\n }\n\n try {\n const cacheKey = await generateDefaultBuildCacheKeyAsync(workingDirectory, platform);\n logger.info(`Saving cache key: ${cacheKey}`);\n\n const jobId = nullthrows(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');\n const robotAccessToken = nullthrows(\n secrets?.robotAccessToken,\n 'Robot access token is required for cache operations'\n );\n const expoApiServerURL = nullthrows(env.__API_SERVER_URL, '__API_SERVER_URL is not set');\n const cachePath = getCcachePath(env);\n\n // Cache size can blow up over time over many builds, so evict stale files\n // and only upload what was used within this build's time window\n const evictWindow = Math.floor((Date.now() - evictUsedBefore.getTime()) / 1000);\n logger.info('Pruning cache...');\n await asyncResult(\n spawnAsync('ccache', ['--evict-older-than', evictWindow + 's'], {\n env,\n logger,\n stdio: 'pipe',\n })\n );\n\n logger.info('Preparing cache archive...');\n\n const { archivePath } = await compressCacheAsync({\n paths: [cachePath],\n workingDirectory,\n verbose: env.EXPO_DEBUG === '1',\n logger,\n });\n\n const { size } = await fs.promises.stat(archivePath);\n\n await uploadCacheAsync({\n logger,\n jobId,\n expoApiServerURL,\n robotAccessToken,\n archivePath,\n key: cacheKey,\n paths: [cachePath],\n size,\n platform,\n });\n } catch (err) {\n logger.error({ err }, 'Failed to save cache');\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/build-tools",
3
- "version": "1.0.248",
3
+ "version": "1.0.250",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -86,5 +86,5 @@
86
86
  "node": "20.14.0",
87
87
  "yarn": "1.22.21"
88
88
  },
89
- "gitHead": "eb85ee725bbeaf112a4ca22c8ca92575f68bb93b"
89
+ "gitHead": "63cc7d14181445e79b8782cef1eeb1adf616e291"
90
90
  }