Skip to content

Instantly share code, notes, and snippets.

@aaronmcadam
Created August 30, 2019 18:24
Show Gist options
  • Save aaronmcadam/79a5f900285de1c6c00cbceca7e944c2 to your computer and use it in GitHub Desktop.
Save aaronmcadam/79a5f900285de1c6c00cbceca7e944c2 to your computer and use it in GitHub Desktop.
A good example of CLI dev in node
const Listr = require('listr');
const chalk = require('chalk');
const clipboardy = require('clipboardy');
const execa = require('execa');
const { name, version } = require('../package.json');
const repoAddress = 'repo-address';
const repoNamespace = 'namespace';
const imageBaseName = name;
const npmToken = process.env.NPM_TOKEN;
function registryImageTag(imageTag) {
return `${repoAddress}/${repoNamespace}/${imageBaseName}:${imageTag}`;
}
function localImageTag(imageTag) {
return `${repoNamespace}/${imageBaseName}:${imageTag}`;
}
async function runTasks() {
const tasks = new Listr([
{
title: 'Sign in to registry',
task: () => {
return execa.shellSync(
'`aws ecr get-login --no-include-email --region eu-west-2`',
);
},
},
{
title: 'Generate image tag',
task: (context) => {
return new Listr([
{
title: 'Get current branch',
task: () => {
return execa
.stdout('git', ['rev-parse', '--abbrev-ref', 'HEAD'])
.then((currentBranch) => {
context.currentBranch = currentBranch;
});
},
},
{
title: 'Get current SHA',
task: (context) => {
return execa
.stdout('git', ['rev-parse', '--short', 'HEAD'])
.then((currentSha) => {
context.imageTag = `${version}-${
context.currentBranch
}-${currentSha}`;
});
},
},
]);
},
},
{
title: 'Build image',
task: (context) => {
const buildLabel = `${repoNamespace}/${imageBaseName}:${
context.imageTag
}`;
return execa('docker', [
'build',
'-t',
buildLabel,
'--build-arg',
`NPM_TOKEN=${npmToken}`,
'--build-arg',
`SERVICE_NAME=${name}`,
'--build-arg',
`SERVICE_VERSION=${version}`,
'--build-arg',
`SERVICE_TAG=${context.imageTag}`,
'.',
]);
},
},
{
title: 'Tag images',
task: () => {
return new Listr(
[
{
title: 'Tag specific image',
task: (context) => {
const source = localImageTag(context.imageTag);
const target = registryImageTag(context.imageTag);
return execa('docker', ['tag', source, target]);
},
},
{
title: 'Tag latest image',
task: (context) => {
const source = localImageTag(context.imageTag);
const target = registryImageTag('latest');
return execa('docker', ['tag', source, target]);
},
},
],
{
concurrent: true,
},
);
},
},
{
title: 'Push images',
task: () => {
return new Listr(
[
{
title: 'Push specific image',
task: (context) => {
const target = registryImageTag(context.imageTag);
return execa('docker', ['push', target]);
},
},
{
title: 'Push latest image',
task: () => {
const target = registryImageTag('latest');
return execa('docker', ['push', target]);
},
},
],
{
concurrent: true,
},
);
},
},
{
title: 'Copy tag to clipboard',
task: (context) => {
return clipboardy.writeSync(context.imageTag);
},
},
]);
try {
const result = await tasks.run();
console.log(chalk.green('Images pushed for:'), chalk.blue(result.imageTag));
} catch (error) {
console.log(chalk.red(error));
}
}
runTasks();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment