Files
skipper/scripts/images.js
2026-04-05 15:28:04 +02:00

130 lines
2.7 KiB
JavaScript

const { spawn } = require('child_process');
const path = require('path');
const rootDir = path.resolve(__dirname, '..');
const config = {
registry: process.env.IMAGE_REGISTRY || 'registry.internal.budgethost.io',
namespace: process.env.IMAGE_NAMESPACE || 'skipper',
tag: process.env.IMAGE_TAG || 'latest',
platform: process.env.IMAGE_PLATFORM || '',
images: [
{
id: 'skipper-api',
context: '.',
dockerfile: 'skipper-api/Dockerfile',
repository: 'skipper-api',
},
{
id: 'skippy-agent',
context: '.',
dockerfile: 'skippy-agent/Dockerfile',
repository: 'skippy-agent',
},
],
};
function getAction() {
const action = process.argv[2] || 'print';
if (!['print', 'build', 'push', 'release'].includes(action)) {
throw new Error(`Unsupported action: ${action}`);
}
return action;
}
function imageRef(image, tag) {
return `${config.registry}/${config.namespace}/${image.repository}:${tag}`;
}
function spawnCommand(command, args) {
return new Promise((resolve, reject) => {
const child = spawn(command, args, {
cwd: rootDir,
stdio: 'inherit',
});
child.on('error', reject);
child.on('close', (code) => {
if (code === 0) {
resolve();
return;
}
reject(new Error(`${command} ${args.join(' ')} failed with exit code ${code}`));
});
});
}
async function buildImage(image) {
const tags = [imageRef(image, config.tag)];
if (config.tag !== 'latest') {
tags.push(imageRef(image, 'latest'));
}
const args = ['build', '-f', image.dockerfile];
if (config.platform) {
args.push('--platform', config.platform);
}
for (const tag of tags) {
args.push('-t', tag);
}
args.push(image.context);
console.log(`Building ${image.id}`);
await spawnCommand('docker', args);
}
async function pushImage(image) {
const tags = [config.tag];
if (config.tag !== 'latest') {
tags.push('latest');
}
for (const tag of tags) {
const ref = imageRef(image, tag);
console.log(`Pushing ${ref}`);
await spawnCommand('docker', ['push', ref]);
}
}
function printPlan() {
for (const image of config.images) {
console.log(`${image.id}: ${imageRef(image, config.tag)}`);
if (config.tag !== 'latest') {
console.log(`${image.id}: ${imageRef(image, 'latest')}`);
}
}
}
async function main() {
const action = getAction();
if (action === 'print') {
printPlan();
return;
}
for (const image of config.images) {
if (action === 'build' || action === 'release') {
await buildImage(image);
}
if (action === 'push' || action === 'release') {
await pushImage(image);
}
}
}
main().catch((error) => {
console.error(error.message);
process.exit(1);
});