mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
89 lines
2.8 KiB
JavaScript
89 lines
2.8 KiB
JavaScript
// @ts-check
|
|
const { put } = require('@vercel/blob')
|
|
const fs = require('node:fs/promises')
|
|
const path = require('node:path')
|
|
|
|
/**
|
|
* Yields one entry per package tarball under `tarballDirectory`. Scoped
|
|
* packages are laid out one level deeper (e.g. `@next/env/<name>.tgz`), so the
|
|
* walk descends into any directory whose name starts with `@`.
|
|
*
|
|
* @param {string} tarballDirectory
|
|
* @returns {AsyncGenerator<{ packageName: string, tarballPath: string }>}
|
|
*/
|
|
async function* findTarballs(tarballDirectory) {
|
|
const entries = await fs.readdir(tarballDirectory, { withFileTypes: true })
|
|
for (const entry of entries) {
|
|
if (!entry.isDirectory()) continue
|
|
const entryPath = path.join(tarballDirectory, entry.name)
|
|
if (entry.name.startsWith('@')) {
|
|
const scopeEntries = await fs.readdir(entryPath, { withFileTypes: true })
|
|
for (const scopeEntry of scopeEntries) {
|
|
if (!scopeEntry.isDirectory()) continue
|
|
const tarballPath = await findTarballInDir(
|
|
path.join(entryPath, scopeEntry.name)
|
|
)
|
|
if (tarballPath === null) continue
|
|
yield {
|
|
packageName: `${entry.name}/${scopeEntry.name}`,
|
|
tarballPath,
|
|
}
|
|
}
|
|
} else {
|
|
const tarballPath = await findTarballInDir(entryPath)
|
|
if (tarballPath === null) continue
|
|
yield { packageName: entry.name, tarballPath }
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} dir
|
|
* @returns {Promise<string | null>}
|
|
*/
|
|
async function findTarballInDir(dir) {
|
|
const files = await fs.readdir(dir)
|
|
const tgzFile = files.find((f) => f.endsWith('.tgz'))
|
|
return tgzFile ? path.join(dir, tgzFile) : null
|
|
}
|
|
|
|
async function main() {
|
|
const [githubHeadSha, tarballDirectory] = process.argv.slice(2)
|
|
if (!githubHeadSha || !tarballDirectory) {
|
|
throw new Error(
|
|
'Usage: node scripts/upload-preview-tarballs.js <commitSha> <tarballDirectory>'
|
|
)
|
|
}
|
|
|
|
if (!process.env.BLOB_READ_WRITE_TOKEN) {
|
|
throw new Error('BLOB_READ_WRITE_TOKEN environment variable is required')
|
|
}
|
|
const blobAccess = process.env.BLOB_ACCESS
|
|
if (blobAccess !== 'private' && blobAccess !== 'public') {
|
|
throw new Error(
|
|
`BLOB_ACCESS environment variable can only be "private" or "public" but got "${blobAccess}".`
|
|
)
|
|
}
|
|
|
|
for await (const { packageName, tarballPath } of findTarballs(
|
|
tarballDirectory
|
|
)) {
|
|
const blobPathname = `next/commits/${githubHeadSha}/${packageName}.tgz`
|
|
|
|
const fileBuffer = await fs.readFile(tarballPath)
|
|
const { url } = await put(blobPathname, fileBuffer, {
|
|
access: blobAccess,
|
|
addRandomSuffix: false,
|
|
contentType: 'application/gzip',
|
|
})
|
|
console.info(`Uploaded ${packageName} -> ${url}`)
|
|
}
|
|
|
|
console.info('All tarballs uploaded to Vercel Blob')
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error(err)
|
|
process.exit(1)
|
|
})
|