@akash-chowdhury-24/deployhub 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +176 -0
  3. package/install.ps1 +55 -0
  4. package/install.sh +99 -0
  5. package/package.json +86 -0
  6. package/src/adapters/dotnet.adapter.js +41 -0
  7. package/src/adapters/go.adapter.js +40 -0
  8. package/src/adapters/index.js +48 -0
  9. package/src/adapters/java.adapter.js +46 -0
  10. package/src/adapters/node.adapter.js +77 -0
  11. package/src/adapters/php.adapter.js +43 -0
  12. package/src/adapters/python.adapter.js +54 -0
  13. package/src/adapters/rails.adapter.js +66 -0
  14. package/src/artifact/engine.js +473 -0
  15. package/src/cli/index.js +45 -0
  16. package/src/commands/artifact.js +88 -0
  17. package/src/commands/build.js +44 -0
  18. package/src/commands/clean.js +50 -0
  19. package/src/commands/deploy.js +82 -0
  20. package/src/commands/doctor.js +630 -0
  21. package/src/commands/init.js +795 -0
  22. package/src/commands/logs.js +33 -0
  23. package/src/commands/rollback.js +50 -0
  24. package/src/commands/storage.js +116 -0
  25. package/src/commands/update.js +63 -0
  26. package/src/commands/verify.js +55 -0
  27. package/src/core/config.js +168 -0
  28. package/src/core/pipeline.js +77 -0
  29. package/src/core/stages.js +210 -0
  30. package/src/deployment/index.js +156 -0
  31. package/src/deployment/providers/azure-vm.js +7 -0
  32. package/src/deployment/providers/docker.js +30 -0
  33. package/src/deployment/providers/ec2.js +7 -0
  34. package/src/deployment/providers/gcp-vm.js +7 -0
  35. package/src/deployment/providers/kubernetes.js +30 -0
  36. package/src/deployment/providers/platforms/_shared.js +167 -0
  37. package/src/deployment/providers/platforms/aws-amplify.js +164 -0
  38. package/src/deployment/providers/platforms/azure-static-web-apps.js +68 -0
  39. package/src/deployment/providers/platforms/cloudflare-pages.js +103 -0
  40. package/src/deployment/providers/platforms/firebase-app-hosting.js +95 -0
  41. package/src/deployment/providers/platforms/firebase-hosting.js +99 -0
  42. package/src/deployment/providers/platforms/index.js +44 -0
  43. package/src/deployment/providers/platforms/netlify.js +102 -0
  44. package/src/deployment/providers/platforms/vercel.js +92 -0
  45. package/src/deployment/providers/ssh.js +365 -0
  46. package/src/detectors/angular.js +23 -0
  47. package/src/detectors/backend.detector.js +304 -0
  48. package/src/detectors/dotnet.js +18 -0
  49. package/src/detectors/frontend.detector.js +219 -0
  50. package/src/detectors/go.js +20 -0
  51. package/src/detectors/index.js +78 -0
  52. package/src/detectors/java.js +24 -0
  53. package/src/detectors/nextjs.js +23 -0
  54. package/src/detectors/node.js +28 -0
  55. package/src/detectors/php.js +17 -0
  56. package/src/detectors/python.js +22 -0
  57. package/src/detectors/react.js +29 -0
  58. package/src/detectors/vue.js +23 -0
  59. package/src/logger/index.js +44 -0
  60. package/src/notifications/email.js +53 -0
  61. package/src/notifications/index.js +34 -0
  62. package/src/notifications/slack.js +18 -0
  63. package/src/notifications/webhook.js +21 -0
  64. package/src/rollback/engine.js +102 -0
  65. package/src/storage/index.js +109 -0
  66. package/src/storage/providers/aws.js +96 -0
  67. package/src/storage/providers/azure.js +45 -0
  68. package/src/storage/providers/dropbox.js +49 -0
  69. package/src/storage/providers/ftp.js +69 -0
  70. package/src/storage/providers/gcp.js +45 -0
  71. package/src/storage/providers/gdrive.js +80 -0
  72. package/src/storage/providers/local.js +61 -0
  73. package/src/utils/author.js +141 -0
  74. package/src/utils/checksums.js +53 -0
  75. package/src/utils/firebase-config-generator.js +35 -0
  76. package/src/utils/github-actions.js +389 -0
  77. package/src/utils/init-platform.js +229 -0
  78. package/src/utils/nginx.js +34 -0
  79. package/src/utils/platform-env.js +132 -0
  80. package/src/utils/version.js +31 -0
@@ -0,0 +1,88 @@
1
+ import chalk from 'chalk';
2
+ import { loadConfig, loadEnv } from '../core/config.js';
3
+ import {
4
+ createArtifact,
5
+ listLocalArtifacts,
6
+ extractArtifact,
7
+ } from '../artifact/engine.js';
8
+ import { downloadFromFirst } from '../storage/index.js';
9
+ import fs from 'fs-extra';
10
+ import path from 'path';
11
+
12
+ /**
13
+ * @param {import('commander').Command} program
14
+ */
15
+ export function registerArtifactCommand(program) {
16
+ const artifact = program
17
+ .command('artifact')
18
+ .description('Manage deployment artifacts');
19
+
20
+ artifact
21
+ .command('create')
22
+ .description('Create artifact from current build output')
23
+ .action(async () => {
24
+ loadEnv();
25
+ const config = await loadConfig();
26
+ const result = await createArtifact(config, [], process.cwd());
27
+ console.log(chalk.green(`Artifact created: ${result.artifactDir}`));
28
+ });
29
+
30
+ artifact
31
+ .command('list')
32
+ .description('List all artifacts')
33
+ .action(async () => {
34
+ loadEnv();
35
+ const artifacts = await listLocalArtifacts();
36
+
37
+ if (artifacts.length === 0) {
38
+ console.log(chalk.yellow('No local artifacts found.'));
39
+ return;
40
+ }
41
+
42
+ console.log(chalk.bold('\nArtifacts:\n'));
43
+ for (const a of artifacts) {
44
+ const sizeMb = (a.size / 1024 / 1024).toFixed(2);
45
+ console.log(
46
+ ` ${chalk.cyan(a.version)} ${a.date} ${a.project} ${sizeMb} MB`
47
+ );
48
+ console.log(chalk.gray(` ${a.path}`));
49
+ }
50
+ console.log('');
51
+ });
52
+
53
+ artifact
54
+ .command('restore <version>')
55
+ .description('Download and extract an artifact by version')
56
+ .action(async (version) => {
57
+ loadEnv();
58
+ const config = await loadConfig();
59
+ const cwd = process.cwd();
60
+
61
+ const local = await listLocalArtifacts(cwd);
62
+ const localMatch = local.find((a) => a.version === version);
63
+
64
+ if (localMatch) {
65
+ const extractTo = path.join(cwd, '.deployhub-restore', `v${version}`);
66
+ await extractArtifact(localMatch.path, extractTo);
67
+ console.log(chalk.green(`Restored to ${extractTo}`));
68
+ return;
69
+ }
70
+
71
+ const remoteKey = `${config.project}/v${version}/artifact.zip`;
72
+ const restoreDir = path.join(cwd, '.deployhub-restore', `v${version}`);
73
+ await fs.ensureDir(restoreDir);
74
+ const zipPath = path.join(restoreDir, 'artifact.zip');
75
+
76
+ console.log(`Downloading v${version} from storage...`);
77
+ const provider = await downloadFromFirst(config.storage, remoteKey, zipPath);
78
+ console.log(chalk.gray(`Downloaded from ${provider}`));
79
+
80
+ const versionDir = path.join(restoreDir, 'artifact');
81
+ await fs.ensureDir(versionDir);
82
+ await fs.move(zipPath, path.join(versionDir, 'artifact.zip'));
83
+ await extractArtifact(versionDir, path.join(restoreDir, 'extracted'));
84
+ console.log(chalk.green(`Restored to ${restoreDir}`));
85
+ });
86
+ }
87
+
88
+ export default { registerArtifactCommand };
@@ -0,0 +1,44 @@
1
+ import chalk from 'chalk';
2
+ import { loadConfig, loadEnv } from '../core/config.js';
3
+ import { runPipeline } from '../core/pipeline.js';
4
+ import { buildPipelineStages } from '../core/stages.js';
5
+
6
+ /**
7
+ * @param {import('commander').Command} program
8
+ */
9
+ export function registerBuildCommand(program) {
10
+ program
11
+ .command('build')
12
+ .description('Run the full build and deploy pipeline')
13
+ .action(async () => {
14
+ loadEnv();
15
+ const cwd = process.cwd();
16
+
17
+ let config;
18
+ try {
19
+ config = await loadConfig(cwd);
20
+ } catch (err) {
21
+ console.error(chalk.red(err instanceof Error ? err.message : String(err)));
22
+ process.exit(1);
23
+ }
24
+
25
+ /** @type {Record<string, unknown>} */
26
+ const state = {};
27
+ const stages = buildPipelineStages(config, cwd, state);
28
+ const { completed, failure } = await runPipeline(stages, {
29
+ config,
30
+ cwd,
31
+ state,
32
+ });
33
+
34
+ if (failure) {
35
+ state.failure = failure.message;
36
+ console.error(chalk.red(`\nBuild failed: ${failure.message}`));
37
+ process.exit(1);
38
+ }
39
+
40
+ console.log(chalk.green(`\nāœ“ Pipeline complete (${completed.length} stages)`));
41
+ });
42
+ }
43
+
44
+ export default { registerBuildCommand };
@@ -0,0 +1,50 @@
1
+ import chalk from 'chalk';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ import { loadConfig } from '../core/config.js';
5
+ import { listLocalArtifacts } from '../artifact/engine.js';
6
+
7
+ /**
8
+ * @param {import('commander').Command} program
9
+ */
10
+ export function registerCleanCommand(program) {
11
+ program
12
+ .command('clean')
13
+ .description('Delete old local artifacts beyond retention count')
14
+ .option('-k, --keep <count>', 'Number of artifacts to keep', '')
15
+ .action(async (options) => {
16
+ const cwd = process.cwd();
17
+ let retention = 10;
18
+
19
+ try {
20
+ const config = await loadConfig(cwd);
21
+ retention = config.artifactRetention || 10;
22
+ } catch {
23
+ // use default
24
+ }
25
+
26
+ if (options.keep) {
27
+ retention = parseInt(options.keep, 10);
28
+ }
29
+
30
+ const artifacts = await listLocalArtifacts(cwd);
31
+ if (artifacts.length <= retention) {
32
+ console.log(
33
+ chalk.gray(`Nothing to clean (${artifacts.length} artifacts, keeping ${retention})`)
34
+ );
35
+ return;
36
+ }
37
+
38
+ const toRemove = artifacts.slice(retention);
39
+ for (const artifact of toRemove) {
40
+ await fs.remove(artifact.path);
41
+ console.log(chalk.gray(`Removed ${artifact.path}`));
42
+ }
43
+
44
+ console.log(
45
+ chalk.green(`āœ“ Cleaned ${toRemove.length} old artifact(s), kept ${retention}`)
46
+ );
47
+ });
48
+ }
49
+
50
+ export default { registerCleanCommand };
@@ -0,0 +1,82 @@
1
+ import chalk from 'chalk';
2
+ import { loadConfig, loadEnv } from '../core/config.js';
3
+ import { runPipeline } from '../core/pipeline.js';
4
+ import { listLocalArtifacts } from '../artifact/engine.js';
5
+ import { deployToAll } from '../deployment/index.js';
6
+ import { sendNotifications } from '../notifications/index.js';
7
+ import axios from 'axios';
8
+
9
+ /**
10
+ * @param {import('commander').Command} program
11
+ */
12
+ export function registerDeployCommand(program) {
13
+ program
14
+ .command('deploy')
15
+ .description('Deploy the latest artifact')
16
+ .action(async () => {
17
+ loadEnv();
18
+ const cwd = process.cwd();
19
+ const config = await loadConfig(cwd);
20
+
21
+ const artifacts = await listLocalArtifacts(cwd);
22
+ if (artifacts.length === 0) {
23
+ console.error(chalk.red('No artifacts found. Run deployhub build first.'));
24
+ process.exit(1);
25
+ }
26
+
27
+ const latest = artifacts[0];
28
+ /** @type {Record<string, unknown>} */
29
+ const state = { artifactDir: latest.path };
30
+
31
+ const stages = [
32
+ {
33
+ name: 'deploy',
34
+ async run(ctx) {
35
+ const deployed = await deployToAll(
36
+ ctx.config,
37
+ /** @type {string} */ (ctx.state.artifactDir)
38
+ );
39
+ ctx.state.deployedTargets = deployed;
40
+ },
41
+ },
42
+ {
43
+ name: 'verify',
44
+ enabled: (ctx) => !!ctx.config.healthCheck?.url,
45
+ async run(ctx) {
46
+ const url = ctx.config.healthCheck.url;
47
+ const timeout = (ctx.config.healthCheck.timeout || 30) * 1000;
48
+ const start = Date.now();
49
+ const response = await axios.get(url, {
50
+ timeout,
51
+ validateStatus: () => true,
52
+ });
53
+ const elapsed = Date.now() - start;
54
+ if (response.status < 200 || response.status >= 400) {
55
+ throw new Error(`Health check failed: HTTP ${response.status}`);
56
+ }
57
+ console.log(chalk.green(`Health check passed: ${response.status} (${elapsed}ms)`));
58
+ },
59
+ },
60
+ {
61
+ name: 'notify',
62
+ enabled: (ctx) => ctx.config.pipeline.notify === true,
63
+ async run(ctx) {
64
+ await sendNotifications(ctx.config, {
65
+ success: true,
66
+ version: latest.version,
67
+ });
68
+ },
69
+ },
70
+ ];
71
+
72
+ const { failure } = await runPipeline(stages, { config, cwd, state });
73
+ if (failure) {
74
+ console.error(chalk.red(`Deploy failed: ${failure.message}`));
75
+ process.exit(1);
76
+ }
77
+
78
+ console.log(chalk.green('āœ“ Deployment complete'));
79
+ });
80
+ }
81
+
82
+ export default { registerDeployCommand };