177 lines
4.7 KiB
JavaScript
Executable File
177 lines
4.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Docker Build and Push Script
|
|
*
|
|
* Builds Docker images and pushes them to the local registry.
|
|
* Tags images based on git state:
|
|
* - Tagged commit: versioned tags + latest
|
|
* - Untagged commit: .dev suffix + commit hash
|
|
*/
|
|
|
|
const { execSync, spawn } = require('child_process');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Configuration
|
|
const REGISTRY = 'dhg.lol:5000';
|
|
const IMAGE_NAME = 'euchre-camp';
|
|
const FULL_IMAGE_NAME = `${REGISTRY}/${IMAGE_NAME}`;
|
|
|
|
// Parse command line arguments
|
|
const args = process.argv.slice(2);
|
|
const forceVersion = args[0]; // Optional: force a specific version
|
|
|
|
// Get current version from package.json
|
|
function getCurrentVersion() {
|
|
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
return packageJson.version;
|
|
}
|
|
|
|
// Get git commit hash
|
|
function getGitCommitHash(short = true) {
|
|
const flag = short ? '--short' : '';
|
|
return execSync(`git rev-parse ${flag} HEAD`, { encoding: 'utf8' }).trim();
|
|
}
|
|
|
|
// Get git tag (if any)
|
|
function getGitTag() {
|
|
try {
|
|
const tag = execSync('git describe --tags --exact-match 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
return tag;
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Check if working directory is clean
|
|
function isWorkingDirectoryClean() {
|
|
try {
|
|
const status = execSync('git status --porcelain', { encoding: 'utf8' }).trim();
|
|
return status === '';
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Build Docker image
|
|
async function buildDockerImage(tags, gitCommit) {
|
|
console.log(`🔨 Building Docker image...\n`);
|
|
|
|
const buildArgs = [
|
|
'build',
|
|
'--build-arg', `GIT_COMMIT=${gitCommit}`,
|
|
'-t', `${FULL_IMAGE_NAME}:${tags[0]}`, // Primary tag
|
|
];
|
|
|
|
// Add additional tags
|
|
tags.forEach(tag => {
|
|
buildArgs.push('-t', `${FULL_IMAGE_NAME}:${tag}`);
|
|
});
|
|
|
|
buildArgs.push('.');
|
|
|
|
console.log(`Build command: docker ${buildArgs.join(' ')}\n`);
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const docker = spawn('docker', buildArgs, {
|
|
cwd: path.join(__dirname, '..'),
|
|
stdio: 'inherit'
|
|
});
|
|
|
|
docker.on('close', (code) => {
|
|
if (code === 0) {
|
|
console.log('✅ Docker image built successfully\n');
|
|
resolve();
|
|
} else {
|
|
reject(new Error(`Docker build failed with code ${code}`));
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Push Docker image
|
|
async function pushDockerImage(tags) {
|
|
console.log(`🚀 Pushing Docker images to ${REGISTRY}...\n`);
|
|
|
|
for (const tag of tags) {
|
|
const imageName = `${FULL_IMAGE_NAME}:${tag}`;
|
|
console.log(`Pushing ${imageName}...`);
|
|
|
|
try {
|
|
execSync(`docker push ${imageName}`, { stdio: 'inherit' });
|
|
console.log(`✅ Pushed ${imageName}\n`);
|
|
} catch (error) {
|
|
console.error(`❌ Failed to push ${imageName}:`, error.message);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
console.log('✅ All images pushed successfully\n');
|
|
}
|
|
|
|
// Main function
|
|
async function main() {
|
|
console.log('🐳 Docker Build & Push Tool\n');
|
|
console.log(`Registry: ${REGISTRY}`);
|
|
console.log(`Image: ${IMAGE_NAME}\n`);
|
|
|
|
// Check if working directory is clean
|
|
if (!isWorkingDirectoryClean()) {
|
|
console.log('⚠️ Warning: Working directory is not clean');
|
|
console.log(' Proceeding anyway...\n');
|
|
}
|
|
|
|
// Determine image tags
|
|
const gitCommit = getGitCommitHash();
|
|
const gitTag = getGitTag();
|
|
const version = forceVersion || getCurrentVersion();
|
|
|
|
let tags = [];
|
|
|
|
if (gitTag) {
|
|
// Tagged commit - use version and 'latest'
|
|
const tagWithoutV = gitTag.startsWith('v') ? gitTag.slice(1) : gitTag;
|
|
|
|
if (tagWithoutV !== version) {
|
|
console.log(`⚠️ Warning: Git tag (${gitTag}) doesn't match package.json version (${version})`);
|
|
console.log(' Using package.json version for Docker tags\n');
|
|
}
|
|
|
|
tags = [
|
|
version, // e.g., 0.1.0
|
|
'latest', // Latest stable
|
|
];
|
|
} else {
|
|
// Untagged commit - use version with .dev suffix and commit hash
|
|
tags = [
|
|
`${version}.dev`, // e.g., 0.1.0.dev
|
|
`${version}-sha-${gitCommit}`, // e.g., 0.1.0-sha-abc123
|
|
];
|
|
}
|
|
|
|
console.log(`Git commit: ${gitCommit}`);
|
|
console.log(`Git tag: ${gitTag || '(none)'}`);
|
|
console.log(`Package version: ${version}`);
|
|
console.log(`Docker tags: ${tags.join(', ')}\n`);
|
|
|
|
// Build the image
|
|
await buildDockerImage(tags, gitCommit);
|
|
|
|
// Push the images
|
|
await pushDockerImage(tags);
|
|
|
|
console.log('🎉 Docker build and push complete!\n');
|
|
console.log('Images available at:');
|
|
tags.forEach(tag => {
|
|
console.log(` - ${FULL_IMAGE_NAME}:${tag}`);
|
|
});
|
|
}
|
|
|
|
// Run main function
|
|
main().catch(error => {
|
|
console.error('❌ Error:', error.message);
|
|
process.exit(1);
|
|
});
|