Skip to content

Commit

Permalink
feat(deploy): add same-commit-policy option
Browse files Browse the repository at this point in the history
  • Loading branch information
aurrelhebert committed Jan 19, 2024
1 parent 1e8e23c commit 76ff6a2
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 30 deletions.
5 changes: 3 additions & 2 deletions bin/clever.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const git = require('../src/models/git.js');
const Parsers = require('../src/parsers.js');
const handleCommandPromise = require('../src/command-promise-handler.js');
const Formatter = require('../src/models/format-string.js');
const { getOutputFormatOption } = require('../src/get-output-format-option.js');
const { AVAILABLE_ZONES } = require('../src/models/application.js');
const { getOutputFormatOption, getSameCommitPolicyOption } = require('../src/command-options.js');

// Exit cleanly if the program we pipe to exits abruptly
process.stdout.on('error', (error) => {
Expand Down Expand Up @@ -216,6 +216,7 @@ function run () {
aliases: ['f'],
description: 'Force deploy even if it\'s not fast-forwardable',
}),
sameCommitPolicy: getSameCommitPolicyOption(),
webhookFormat: cliparse.option('format', {
metavar: 'format',
default: 'raw',
Expand Down Expand Up @@ -642,7 +643,7 @@ function run () {
const deploy = lazyRequirePromiseModule('../src/commands/deploy.js');
const deployCommand = cliparse.command('deploy', {
description: 'Deploy an application',
options: [opts.alias, opts.branch, opts.quiet, opts.forceDeploy, opts.followDeployLogs],
options: [opts.alias, opts.branch, opts.quiet, opts.forceDeploy, opts.followDeployLogs, opts.sameCommitPolicy],
}, deploy('deploy'));

// DIAG COMMAND
Expand Down
42 changes: 42 additions & 0 deletions src/command-options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const cliparse = require('cliparse');

function getOutputFormatOption (formats = []) {
const availableFormats = ['human', 'json', ...formats];
return cliparse.option('format', {
aliases: ['F'],
metavar: 'format',
parser: (format) => {
return availableFormats.includes(format)
? cliparse.parsers.success(format)
: cliparse.parsers.error('The output format must be one of ' + availableFormats.join(', '));
},
default: 'human',
description: `Output format (${availableFormats.join(', ')})`,
complete () {
return cliparse.autocomplete.words(availableFormats);
},
});
}

function getSameCommitPolicyOption () {
const availablePolicies = ['error', 'ignore', 'restart', 'rebuild'];
return cliparse.option('same-commit-policy', {
aliases: ['p'],
metavar: 'same-commit-policy',
parser: (policy) => {
return availablePolicies.includes(policy)
? cliparse.parsers.success(policy)
: cliparse.parsers.error(`The output policy must be one of ${availablePolicies.join(', ')}`);
},
default: 'error',
description: `Which policy to apply when the local commit is the same as the remote one. Available policies are (${availablePolicies.join(', ')})`,
complete () {
return cliparse.autocomplete.words(availablePolicies);
},
});
}

module.exports = {
getOutputFormatOption,
getSameCommitPolicyOption,
};
28 changes: 23 additions & 5 deletions src/commands/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const { sendToApi } = require('../models/send-to-api.js');
// Once the API call to redeploy() has been triggered successfully,
// the rest (waiting for deployment state to evolve and displaying logs) is done with auto retry (resilient to network failures)
async function deploy (params) {
const { alias, branch: branchName, quiet, force, follow } = params.options;
const { alias, branch: branchName, quiet, force, follow, 'same-commit-policy': sameCommitPolicy } = params.options;

const appData = await AppConfig.getAppDetails({ alias });
const { ownerId, appId } = appData;
Expand All @@ -31,11 +31,24 @@ async function deploy (params) {
Logger.println(colors.bold.blue(`Remote application belongs to ${ownerId}`));

if (commitIdToPush === remoteHeadCommitId) {
const upToDateMessage = `The clever-cloud application is up-to-date (${remoteHeadCommitId}). Try this command to restart the application:`;
if (commitIdToPush !== deployedCommitId) {
throw new Error(`${upToDateMessage}\nclever restart --commit ${commitIdToPush}`);
switch (sameCommitPolicy) {
case 'ignore':
Logger.println(`The clever-cloud application is up-to-date (${colors.green(remoteHeadCommitId)})`);
return;
case 'restart':
return restartOnSameCommit(ownerId, appId, commitIdToPush, quiet, follow, false);
case 'rebuild':
return restartOnSameCommit(ownerId, appId, commitIdToPush, quiet, follow, true);
case 'error':
default: {
const upToDateMessage = `The clever-cloud application is up-to-date (${colors.green(remoteHeadCommitId)}).\nYou can set a policy with 'same-commit-policy' to handle differently when remote HEAD has the same commit as the one to push.\nOr try this command to restart the application:`;
if (commitIdToPush !== deployedCommitId) {
const restartWithId = `clever restart --commit ${commitIdToPush}`
throw new Error(`${upToDateMessage}\n${colors.yellow(restartWithId)}`);
}
throw new Error(`${upToDateMessage}\n${colors.yellow('clever restart')}`);
}
}
throw new Error(`${upToDateMessage}\nclever restart`);
}

if (remoteHeadCommitId == null || deployedCommitId == null) {
Expand Down Expand Up @@ -68,4 +81,9 @@ async function deploy (params) {
return Log.watchDeploymentAndDisplayLogs({ ownerId, appId, commitId: commitIdToPush, knownDeployments, quiet, follow });
}

async function restartOnSameCommit (ownerId, appId, commitIdToPush, quiet, follow, withoutCache) {
const restart = await Application.redeploy(ownerId, appId, commitIdToPush, withoutCache);
return Log.watchDeploymentAndDisplayLogs({ ownerId, appId, deploymentId: restart.deploymentId, quiet, follow });
}

module.exports = { deploy };
23 changes: 0 additions & 23 deletions src/get-output-format-option.js

This file was deleted.

0 comments on commit 76ff6a2

Please sign in to comment.