UNPKG

gcbuild

Version:

An API and CLI for building docker containers with Google Cloud Build.

127 lines (120 loc) 3.91 kB
#!/usr/bin/env node import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import util from 'node:util'; import chalk from 'chalk'; import meow from 'meow'; import ora from 'ora'; import updateNotifier from 'update-notifier'; import { Builder, ProgressEvent } from './index.js'; const package_ = JSON.parse(fs.readFileSync(new URL('../../package.json', import.meta.url), 'utf8')); updateNotifier({ pkg: package_ }).notify(); const cli = meow(` Usage $ gcb [SOURCE] [--flags] Positional arguments SOURCE Path to the location of the sources to be deployed. Will default to CWD if not otherwise specified. Flags --config=CONFIG The YAML or JSON file to use as the build configuration file. Defaults to 'cloudbuild.yaml' if not specified. --tag=TAG The tag to use with a "docker build" image creation. Examples $ gcb $ gcb --config ../perfect.yaml --tag ohai123 $ gcp containers/web `, { importMeta: import.meta, flags: { config: { type: 'string' }, tag: { type: 'string' }, }, }); async function main() { if (cli.input.length > 1) { cli.showHelp(); return; } const start = Date.now(); const options = cli.flags; options.sourcePath = cli.input.length > 0 ? cli.input[0] : process.cwd(); if (!path.isAbsolute(options.sourcePath)) { options.sourcePath = path.join(process.cwd(), options.sourcePath); } const hasIgnore = await hasIgnoreFile(options.sourcePath); if (!hasIgnore) { await generateIgnoreFile(options.sourcePath); } const spinny = ora('Initializing build...').start(); const builder = new Builder(options); builder .on(ProgressEvent.CREATING_BUCKET, (bucket) => { spinny.stopAndPersist({ symbol: '🌧', text: `Bucket '${bucket}' created.`, }); spinny.start('Packing and uploading sources...'); }) .on(ProgressEvent.UPLOADING, () => { spinny.stopAndPersist({ symbol: '📦', text: 'Source code packaged.' }); spinny.start('Uploading source...'); }) .on(ProgressEvent.BUILDING, () => { spinny.stopAndPersist({ symbol: '🛸', text: 'Source uploaded to cloud.', }); spinny.start('Building container...'); }) .on(ProgressEvent.LOG, (data) => { console.error(`\n\n${chalk.gray(data)}`); }) .on(ProgressEvent.COMPLETE, () => { const seconds = (Date.now() - start) / 1000; spinny.stopAndPersist({ symbol: '🚀', text: `Container built in ${seconds} seconds.`, }); }); try { await builder.build(); } catch (error) { const error_ = error; console.error(error_); spinny.fail(error_.message); process.exit(1); } } async function generateIgnoreFile(targetDirectory) { console.log(` 🤖 I generated a '.gcloudignore' file in the target directory. This file contains a list of glob patterns that should be ingored in your build. It works just like a .gitignore file 💜 `); await new Promise((resolve, reject) => { fs.createReadStream(path.join(__dirname, '../../src/.gcloudignore')) .pipe(fs.createWriteStream(path.join(targetDirectory, '.gcloudignore'))) .on('error', reject) .on('close', resolve); }); } /** * Checks to see if a given directory has a `.gcloudignore` file. * @param targetDir The directory with the sources to deploy. */ async function hasIgnoreFile(targetDirectory) { const ignoreFile = path.join(targetDirectory, '.gcloudignore'); try { await util.promisify(fs.stat)(ignoreFile); return true; } catch { return false; } } await main();