1- import { execSync } from "node:child_process" ;
1+ import { spawn } from "node:child_process" ;
22import { readdirSync , existsSync , readFileSync , mkdirSync , rmSync } from "node:fs" ;
3+ import { availableParallelism } from "node:os" ;
34import { join , relative } from "node:path" ;
45
56const ROOT = process . cwd ( ) ;
67const OUTPUT_DIR = join ( ROOT , "release-artifacts" ) ;
78const SKIPPED_PATH_PREFIXES = [ "demo" , "utils/tests" ] ;
89const SKIPPED_DIR_NAMES = new Set ( [ ".git" , "node_modules" , "dist" , "release-artifacts" ] ) ;
10+ const DEFAULT_CONCURRENCY = Math . max ( 1 , Math . min ( 8 , availableParallelism ( ) ) ) ;
11+ const ZIP_CONCURRENCY = Math . max ( 1 , Number . parseInt ( process . env . ZIP_CONCURRENCY ?? "" , 10 ) || DEFAULT_CONCURRENCY ) ;
912
1013// Clean output directory
1114rmSync ( OUTPUT_DIR , { recursive : true , force : true } ) ;
@@ -54,13 +57,51 @@ function findPackages(dir) {
5457function createZip ( distPath , outputZipPath ) {
5558 console . log ( `📦 Creating ${ outputZipPath } ` ) ;
5659
57- execSync ( `cd "${ distPath } " && zip -r "${ outputZipPath } " .` , {
58- stdio : "inherit" ,
60+ return new Promise ( ( resolve , reject ) => {
61+ const child = spawn ( "zip" , [ "-r" , outputZipPath , "." ] , {
62+ cwd : distPath ,
63+ stdio : "inherit" ,
64+ } ) ;
65+
66+ child . on ( "error" , ( error ) => {
67+ reject ( error ) ;
68+ } ) ;
69+
70+ child . on ( "close" , ( code ) => {
71+ if ( code === 0 ) {
72+ resolve ( ) ;
73+
74+ return ;
75+ }
76+
77+ reject ( new Error ( `zip command failed with exit code ${ code } for ${ outputZipPath } ` ) ) ;
78+ } ) ;
5979 } ) ;
6080}
6181
82+ async function runWithConcurrency ( items , concurrency , worker ) {
83+ let index = 0 ;
84+
85+ async function runWorker ( ) {
86+ while ( true ) {
87+ const currentIndex = index ;
88+
89+ index += 1 ;
90+
91+ if ( currentIndex >= items . length ) {
92+ return ;
93+ }
94+
95+ await worker ( items [ currentIndex ] ) ;
96+ }
97+ }
98+
99+ await Promise . all ( Array . from ( { length : Math . min ( concurrency , items . length ) } , ( ) => runWorker ( ) ) ) ;
100+ }
101+
62102// 🔍 Find all packages in repo
63103const allPackages = findPackages ( ROOT ) ;
104+ const zipJobs = [ ] ;
64105
65106for ( const pkgPath of allPackages ) {
66107 const distPath = join ( pkgPath , "dist" ) ;
@@ -82,7 +123,14 @@ for (const pkgPath of allPackages) {
82123 const zipName = `${ name } -${ version } .zip` ;
83124 const zipPath = join ( OUTPUT_DIR , zipName ) ;
84125
85- createZip ( distPath , zipPath ) ;
126+ zipJobs . push ( {
127+ distPath,
128+ zipPath,
129+ } ) ;
86130}
87131
132+ console . log ( `⚙️ Packaging ${ zipJobs . length } artifacts with concurrency ${ ZIP_CONCURRENCY } ` ) ;
133+
134+ await runWithConcurrency ( zipJobs , ZIP_CONCURRENCY , ( { distPath, zipPath } ) => createZip ( distPath , zipPath ) ) ;
135+
88136console . log ( "✅ All package archives created successfully." ) ;
0 commit comments