Files
next.js/scripts/pull-turbo-cache.js
Arian Tron 61f56f997c
Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled
first commit
2026-03-10 19:37:31 +03:30

127 lines
3.1 KiB
JavaScript

#!/usr/bin/env node
// @ts-check
const { spawn } = require('child_process')
const MAX_ATTEMPTS = 3
const RETRY_DELAY_MS = 5000
/**
* @param {number} ms
*/
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
/**
* @param {string} command
* @param {{ stdio?: 'pipe' | 'inherit', captureOutput?: boolean }} options
* @returns {Promise<{ code: number | null, signal: string | null, output: string }>}
*/
function runCommand(
command,
{ stdio = 'inherit', captureOutput = false } = {}
) {
return new Promise((resolve) => {
let output = ''
const child = spawn('/bin/bash', ['-c', command], {
stdio: captureOutput ? 'pipe' : stdio,
})
if (captureOutput) {
child.stdout?.on('data', (data) => {
process.stdout.write(data)
output += data.toString()
})
child.stderr?.on('data', (data) => {
process.stderr.write(data)
})
}
child.on('exit', (code, signal) => {
resolve({ code, signal, output })
})
})
}
/**
* @param {string} command
* @param {number} maxAttempts
* @returns {Promise<boolean>}
*/
async function runWithRetry(command, maxAttempts) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
console.log(`Attempt ${attempt}/${maxAttempts}...`)
const { code, signal } = await runCommand(command)
if (!code && !signal) {
return true // success
}
console.warn(
`Attempt ${attempt} failed (exit code ${code}, signal ${signal})`
)
if (attempt < maxAttempts) {
console.log(`Retrying in ${RETRY_DELAY_MS / 1000}s...`)
await sleep(RETRY_DELAY_MS)
}
}
return false // all attempts failed
}
;(async function () {
const target = process.argv[process.argv.length - 1]
const turboCommand = `pnpm dlx turbo@${process.env.TURBO_VERSION || 'latest'}`
// First, do a dry run to check cache status
const { code, signal, output } = await runCommand(
`${turboCommand} run cache-build-native --dry=json -- ${target}`,
{ captureOutput: true }
)
if (code || signal) {
console.warn(
`Dry run failed (exit code ${code}, signal ${signal}). Continuing without cache.`
)
return
}
let turboData
try {
turboData = JSON.parse(output)
} catch (e) {
console.warn(`Failed to parse turbo output: ${e.message}`)
return
}
const task = turboData.tasks.find((t) => t.command !== '<NONEXISTENT>')
if (!task) {
console.warn(`Failed to find related turbo task`, output)
return
}
// Pull cache if it was available
if (task.cache.local || task.cache.remote) {
console.log('Cache Status', task.taskId, task.hash, task.cache)
const success = await runWithRetry(
`${turboCommand} run cache-build-native -- ${target}`,
MAX_ATTEMPTS
)
if (!success) {
// Don't fail the job - the workflow will check if build exists
// and build from source if needed
console.warn(
`Cache restoration failed after ${MAX_ATTEMPTS} attempts. ` +
`Build will proceed from source.`
)
}
} else {
console.warn(`No turbo cache was available, continuing...`)
console.warn(task)
}
})()