UNPKG

@nx/docker

Version:

The Nx Plugin for Docker to aid in containerizing projects.

115 lines (114 loc) 4.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LARGE_BUFFER = void 0; exports.default = dockerReleasePublish; const devkit_1 = require("@nx/devkit"); const internal_1 = require("@nx/devkit/internal"); const child_process_1 = require("child_process"); const fs_1 = require("fs"); const version_utils_1 = require("../../release/version-utils"); exports.LARGE_BUFFER = 1024 * 1000000; async function dockerReleasePublish(schema, context) { const projectConfig = context.projectGraph.nodes[context.projectName]; const options = await normalizeOptions(projectConfig, schema); if (!options.dryRun) { const digest = await dockerPush(options.imageReference, options.quiet); devkit_1.logger.log(`Successfully pushed ${options.imageReference}${options.quiet ? `. Digest: ${digest}` : ''}`); } else { devkit_1.logger.log(`Docker Image ${options.imageReference} was not pushed as --dry-run is enabled.`); } return { success: true, }; } async function normalizeOptions(projectConfig, schema) { return { quiet: schema.quiet ?? false, imageReference: await findImageReference(projectConfig, schema), dryRun: process.env.NX_DRY_RUN === 'true' || schema.dryRun || false, }; } async function findImageReference(projectConfig, schema) { let imageRef = readVersionFromFile(projectConfig.data.root); if (imageRef) { if (await checkDockerImageExistsLocally(imageRef)) { return imageRef; } throw new Error(`Could not find Docker Image ${imageRef}. Did you run 'nx release version'?`); } } function readVersionFromFile(projectRoot) { const versionFilePath = (0, version_utils_1.getDockerVersionPath)(devkit_1.workspaceRoot, projectRoot); if (!(0, fs_1.existsSync)(versionFilePath)) { throw new Error(`Could not find ${versionFilePath} file. Did you run 'nx release version'?`); } const version = (0, fs_1.readFileSync)(versionFilePath, { encoding: 'utf8' }); return version.trim(); } async function checkDockerImageExistsLocally(imageRef) { try { return await new Promise((res) => { // If the ref starts with 'docker.io/', then we need to strip it since it is the default value and Docker CLI will not find it. const normalizedImageRef = imageRef.startsWith('docker.io/') ? imageRef.split('docker.io/')[1] : imageRef; const childProcess = (0, child_process_1.exec)(`docker images --filter "reference=${normalizedImageRef}" --quiet`, { encoding: 'utf8', windowsHide: true }); let result = ''; childProcess.stdout?.on('data', (data) => { result += data; }); childProcess.stderr?.on('data', (data) => { console.error(data); }); childProcess.on('error', (error) => { console.error('Docker command failed:', error); res(false); }); childProcess.on('exit', () => { res(result.trim().length > 0); }); }); } catch { return false; } } async function dockerPush(imageReference, quiet) { try { return await new Promise((res, rej) => { const childProcess = (0, child_process_1.exec)(`docker push ${imageReference}${quiet ? ' --quiet' : ''}`, { encoding: 'utf8', maxBuffer: exports.LARGE_BUFFER, windowsHide: true, }); let result = ''; childProcess.stdout?.on('data', (data) => { result += data; if (!quiet) { console.log(data); } }); childProcess.stderr?.on('data', (data) => { console.error(data); }); childProcess.on('error', (error) => { rej(error); }); childProcess.on('exit', (code, signal) => { if (code === null) code = (0, internal_1.signalToCode)(signal); if (code === 0) { res(result.trim()); } else { rej(new Error(`Docker push failed with exit code ${code}`)); } }); }); } catch (e) { devkit_1.logger.error(`Failed to push ${imageReference}`); throw e; } }