diff --git a/scripts/build-image.js b/scripts/build-image.js old mode 100644 new mode 100755 index c76876e..6665e5a --- a/scripts/build-image.js +++ b/scripts/build-image.js @@ -2,6 +2,7 @@ const { execSync } = require('child_process'); const fs = require('fs'); +const { parseArgs } = require('util'); function execCommand(command, description) { try { @@ -46,11 +47,77 @@ function getVersion() { return { version: `${packageJson.version}-dev`, isRelease: false }; } +function getHostArchitecture() { + // Map Node.js architecture names to container architecture names + const archMap = { + 'arm64': 'arm64', + 'arm': 'arm64', + 'x64': 'amd64' + }; + return archMap[process.arch] || 'arm64'; +} + +function showHelp() { + const hostArch = getHostArchitecture(); + console.log(`Build multi-architecture container images for JMESPath Playground + +Usage: + build-image.js [OPTIONS] + +Options: + --all-arch Build for both arm64 and amd64 (default: build for host architecture only) + --arch Target architecture (arm64 or amd64). Can be specified multiple times. + --help, -h Show this help message and exit + +Examples: + build-image.js # Builds for ${hostArch} only (host architecture) + build-image.js --all-arch # Builds for both arm64 and amd64 + build-image.js --arch arm64 # Builds for arm64 only + build-image.js --arch arm64 --arch amd64 # Explicitly specify both + build-image.js -h # Show help`); +} + function main() { + const { values } = parseArgs({ + options: { + help: { + type: 'boolean', + short: 'h', + description: 'Show help' + }, + 'all-arch': { + type: 'boolean', + description: 'Build for both arm64 and amd64' + }, + arch: { + type: 'string', + multiple: true, + description: 'Target architecture (arm64 or amd64)' + } + }, + strict: true, + allowPositionals: false + }); + + if (values.help) { + showHelp(); + process.exit(0); + } + const containerTool = getContainerTool(); const { version, isRelease } = getVersion(); + + let architectures; + if (values['all-arch']) { + architectures = ['arm64', 'amd64']; + } else if (values.arch && values.arch.length > 0) { + architectures = values.arch; + } else { + architectures = [getHostArchitecture()]; + } console.log(`Building ${isRelease ? 'release' : 'development'} version: ${version}`); + console.log(`Target architectures: ${architectures.join(', ')}`); // Build container image const tags = isRelease @@ -63,16 +130,24 @@ function main() { `-t skoszewski/jmespath-playground:latest` ].join(' '); - const buildCommand = `${containerTool} build --build-arg VERSION="${version}" --build-arg IS_RELEASE="${isRelease}" ${tags} .`; + const archFlags = architectures.map(arch => `--arch ${arch}`).join(' '); + + const buildCommand = `${containerTool} build ${archFlags} --build-arg VERSION="${version}" --build-arg IS_RELEASE="${isRelease}" ${tags} .`; execCommand(buildCommand, 'Building container image'); console.log('Container image build completed successfully!'); // Show usage instructions + console.log(`\nUsage examples:`); + console.log(` build-image.js # Builds for host architecture only`); + console.log(` build-image.js --all-arch # Builds for both arm64 and amd64`); + console.log(` build-image.js --arch arm64 # Builds for arm64 only`); + console.log(` build-image.js --arch arm64 --arch amd64 # Explicitly specify both`); + if (isRelease) { console.log(`\nTo run the container:`); - console.log(` ${containerTool} run --name jmespathpg -p 3000:3000 skoszewski/jmespath-playground:${version}`); + console.log(` ${containerTool} run --arch arm64 --name jmespathpg -p 3000:3000 skoszewski/jmespath-playground:${version}`); if (containerTool === 'docker') { console.log(`\nTo push to Docker Hub:`); console.log(` docker push skoszewski/jmespath-playground:${version}`); @@ -80,7 +155,7 @@ function main() { } } else { console.log(`\nTo run the container:`); - console.log(` ${containerTool} run --name jmespathpg -p 3000:3000 skoszewski/jmespath-playground:dev`); + console.log(` ${containerTool} run --arch arm64 --name jmespathpg -p 3000:3000 skoszewski/jmespath-playground:dev`); } }