@akash-chowdhury-24/deployhub 1.0.15 → 2.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.
@@ -4,7 +4,6 @@ import { createEc2Provider } from './providers/ec2.js';
4
4
  import { createAzureVmProvider } from './providers/azure-vm.js';
5
5
  import { createGcpVmProvider } from './providers/gcp-vm.js';
6
6
  import { createKubernetesProvider } from './providers/kubernetes.js';
7
- import { createPlatformProvider } from './providers/platforms/index.js';
8
7
  import { createLogger } from '../logger/index.js';
9
8
 
10
9
  /** @type {Record<string, Function>} */
@@ -17,25 +16,6 @@ const PROVIDER_FACTORIES = {
17
16
  kubernetes: createKubernetesProvider,
18
17
  };
19
18
 
20
- /**
21
- * @param {Record<string, unknown>} environment
22
- * @returns {boolean}
23
- */
24
- function isPlatformDeployment(environment) {
25
- return environment.deploymentType === 'platform';
26
- }
27
-
28
- /**
29
- * @param {Record<string, unknown>} environment
30
- * @returns {boolean}
31
- */
32
- function isHybridEnvironment(environment) {
33
- return (
34
- environment.frontendDeploymentType === 'platform' &&
35
- (environment.backendDeploymentType === 'server' || !!environment.type)
36
- );
37
- }
38
-
39
19
  /**
40
20
  * @param {string} type
41
21
  * @param {import('../core/config.js').DeployHubConfig} config
@@ -48,10 +28,6 @@ export function getDeploymentProvider(type, config, envName, env = process.env)
48
28
  throw new Error(`Environment "${envName}" not found in config`);
49
29
  }
50
30
 
51
- if (isPlatformDeployment(environment)) {
52
- return createPlatformProvider(environment.platform, config, envName, env);
53
- }
54
-
55
31
  const providerType = type || environment.type;
56
32
  const factory = PROVIDER_FACTORIES[providerType];
57
33
  if (!factory) {
@@ -81,34 +57,6 @@ export async function deployToAll(config, artifactDir, envNames) {
81
57
  throw new Error(`Environment "${envName}" not found in config`);
82
58
  }
83
59
 
84
- if (isHybridEnvironment(envConfig)) {
85
- log.info(`Deploying hybrid target ${envName} (platform frontend + server backend)...`);
86
-
87
- const platformProvider = createPlatformProvider(
88
- envConfig.platform,
89
- config,
90
- envName
91
- );
92
- await platformProvider.deploy(artifactDir);
93
- log.success(`Frontend deployed to ${envConfig.platform}`);
94
-
95
- const serverProvider = getDeploymentProvider(envConfig.type, config, envName);
96
- await serverProvider.deploy(artifactDir);
97
- log.success(`Backend deployed via ${envConfig.type}`);
98
-
99
- deployed.push(envName);
100
- continue;
101
- }
102
-
103
- if (isPlatformDeployment(envConfig)) {
104
- const provider = createPlatformProvider(envConfig.platform, config, envName);
105
- log.info(`Deploying to ${envName} (${envConfig.platform})...`);
106
- await provider.deploy(artifactDir);
107
- deployed.push(envName);
108
- log.success(`Deployed to ${envName}`);
109
- continue;
110
- }
111
-
112
60
  const provider = getDeploymentProvider(envConfig.type, config, envName);
113
61
  log.info(`Deploying to ${envName} (${envConfig.type})...`);
114
62
  await provider.deploy(artifactDir);
@@ -128,26 +76,6 @@ export async function rollbackAll(config, artifactDir, envNames) {
128
76
  const targets = envNames || config.deploy || [];
129
77
  for (const envName of targets) {
130
78
  const envConfig = config.environments[envName];
131
-
132
- if (isHybridEnvironment(envConfig)) {
133
- const platformProvider = createPlatformProvider(
134
- envConfig.platform,
135
- config,
136
- envName
137
- );
138
- await platformProvider.rollback(artifactDir);
139
-
140
- const serverProvider = getDeploymentProvider(envConfig.type, config, envName);
141
- await serverProvider.rollback(artifactDir);
142
- continue;
143
- }
144
-
145
- if (isPlatformDeployment(envConfig)) {
146
- const provider = createPlatformProvider(envConfig.platform, config, envName);
147
- await provider.rollback(artifactDir);
148
- continue;
149
- }
150
-
151
79
  const provider = getDeploymentProvider(envConfig.type, config, envName);
152
80
  await provider.rollback(artifactDir);
153
81
  }
@@ -1,5 +1,5 @@
1
1
  import { downloadFromFirst } from '../storage/index.js';
2
- import { createPlatformProvider } from '../deployment/providers/platforms/index.js';
2
+ import { getDeploymentProvider } from '../deployment/index.js';
3
3
  import { extractArtifact } from '../artifact/engine.js';
4
4
  import { createLogger } from '../logger/index.js';
5
5
  import fs from 'fs-extra';
@@ -10,48 +10,15 @@ import path from 'path';
10
10
  * @param {string} artifactDir
11
11
  * @param {string} envName
12
12
  */
13
- async function rollbackPlatformTarget(config, artifactDir, envName) {
13
+ async function rollbackTarget(config, artifactDir, envName) {
14
14
  const envConfig = config.environments[envName];
15
15
  if (!envConfig) {
16
16
  throw new Error(`Environment "${envName}" not found in config`);
17
17
  }
18
18
 
19
- const deploymentPath = path.join(artifactDir, 'deployment.json');
20
- if (await fs.pathExists(deploymentPath)) {
21
- const data = await fs.readJson(deploymentPath);
22
- const deployments = data.deployments || data.platformDeployments || [];
23
- const record = deployments.find((d) => d.environmentName === envName) || data.lastDeployment;
24
- if (record?.platform) {
25
- const log = createLogger('rollback');
26
- log.info(
27
- `Rolling back ${envName} on ${record.platform} (deploy ${record.deployId || record.deploymentId || 'previous'})...`
28
- );
29
- }
30
- }
31
-
32
- if (envConfig.deploymentType === 'platform' || envConfig.frontendDeploymentType === 'platform') {
33
- const platform = envConfig.platform;
34
- if (!platform) {
35
- throw new Error(`No platform configured for environment "${envName}"`);
36
- }
37
- const provider = createPlatformProvider(platform, config, envName);
38
- await provider.rollback(artifactDir);
39
- return;
40
- }
41
-
42
- if (
43
- envConfig.frontendDeploymentType === 'platform' &&
44
- (envConfig.backendDeploymentType === 'server' || envConfig.type)
45
- ) {
46
- const platformProvider = createPlatformProvider(envConfig.platform, config, envName);
47
- await platformProvider.rollback(artifactDir);
48
- const { getDeploymentProvider } = await import('../deployment/index.js');
49
- const serverProvider = getDeploymentProvider(envConfig.type, config, envName);
50
- await serverProvider.rollback(artifactDir);
51
- return;
52
- }
19
+ const log = createLogger('rollback');
20
+ log.info(`Rolling back ${envName} (${envConfig.type || 'server'})...`);
53
21
 
54
- const { getDeploymentProvider } = await import('../deployment/index.js');
55
22
  const provider = getDeploymentProvider(envConfig.type, config, envName);
56
23
  await provider.rollback(artifactDir);
57
24
  }
@@ -90,9 +57,9 @@ export async function rollbackToVersion(config, version, cwd = process.cwd()) {
90
57
  return artifactDir;
91
58
  }
92
59
 
93
- log.info('Executing platform-specific rollback from deployment.json...');
60
+ log.info('Redeploying previous artifact to server targets...');
94
61
  for (const envName of targets) {
95
- await rollbackPlatformTarget(config, artifactDir, envName);
62
+ await rollbackTarget(config, artifactDir, envName);
96
63
  }
97
64
 
98
65
  log.success(`Rollback to v${version} complete`);
@@ -1,11 +1,5 @@
1
1
  import fs from 'fs-extra';
2
2
  import path from 'path';
3
- import {
4
- PLATFORM_ENV_MAP,
5
- PLATFORM_CLI_MAP,
6
- PLATFORM_CHOICES,
7
- getPlatformEnvExample,
8
- } from './platform-env.js';
9
3
  import { getWorkflowHeaderComment } from './author.js';
10
4
 
11
5
  /** @typedef {'aws'|'azure'|'gcp'|'gdrive'|'dropbox'|'local'|'ftp'|'ssh'} ProviderEnvKey */
@@ -47,10 +41,6 @@ const PROVIDER_LABELS = {
47
41
  ssh: 'SSH Deployment',
48
42
  };
49
43
 
50
- const PLATFORM_LABELS = Object.fromEntries(
51
- PLATFORM_CHOICES.map(({ name, value }) => [value, name])
52
- );
53
-
54
44
  const ENV_VAR_DEFAULTS = {
55
45
  AWS_REGION: 'us-east-1',
56
46
  FTP_PORT: '21',
@@ -208,54 +198,6 @@ function getBackendSetupSteps(config) {
208
198
  return steps;
209
199
  }
210
200
 
211
- /**
212
- * @param {Record<string, unknown>[]} environments
213
- * @returns {string[]}
214
- */
215
- function getPlatformInstallSteps(environments) {
216
- /** @type {Set<string>} */
217
- const steps = new Set();
218
-
219
- for (const env of environments) {
220
- if (env.deploymentType !== 'platform' && env.frontendDeploymentType !== 'platform') {
221
- continue;
222
- }
223
- const platform = env.platform;
224
- if (!platform) continue;
225
- const cli = PLATFORM_CLI_MAP[platform];
226
- if (cli?.globalInstall) {
227
- steps.add(` - name: Install ${platform} CLI\n run: ${cli.globalInstall}`);
228
- }
229
- }
230
-
231
- return Array.from(steps);
232
- }
233
-
234
- /**
235
- * @param {string[]} deployEnvironments
236
- * @param {Record<string, Record<string, unknown>>} environments
237
- */
238
- function collectPlatformEnvVars(deployEnvironments, environments) {
239
- /** @type {Set<string>} */
240
- const envVars = new Set();
241
-
242
- for (const envName of deployEnvironments) {
243
- const env = environments[envName];
244
- if (!env) continue;
245
-
246
- if (env.deploymentType === 'platform' || env.frontendDeploymentType === 'platform') {
247
- const platform = env.platform;
248
- if (!platform) continue;
249
- const keys = PLATFORM_ENV_MAP[platform] || [];
250
- for (const key of keys) {
251
- envVars.add(`${key}: \${{ secrets.${key} }}`);
252
- }
253
- }
254
- }
255
-
256
- return envVars;
257
- }
258
-
259
201
  /**
260
202
  * @param {string[]} storageProviders
261
203
  * @param {string[]} deployEnvironments
@@ -285,11 +227,9 @@ export function generateWorkflowYaml(
285
227
  const env = environments[envName];
286
228
  if (!env) continue;
287
229
 
288
- if (env.deploymentType !== 'platform') {
289
- const keys = PROVIDER_ENV_MAP[env.type] || [];
290
- for (const key of keys) {
291
- envVars.add(`${key}: \${{ secrets.${key} }}`);
292
- }
230
+ const keys = PROVIDER_ENV_MAP[env.type] || [];
231
+ for (const key of keys) {
232
+ envVars.add(`${key}: \${{ secrets.${key} }}`);
293
233
  }
294
234
 
295
235
  if (env.type === 'ssh' && config) {
@@ -302,10 +242,6 @@ export function generateWorkflowYaml(
302
242
  }
303
243
  }
304
244
 
305
- for (const line of collectPlatformEnvVars(deployEnvironments, environments)) {
306
- envVars.add(line);
307
- }
308
-
309
245
  const envBlock = Array.from(envVars)
310
246
  .map((line) => ` ${line}`)
311
247
  .join('\n');
@@ -317,11 +253,6 @@ export function generateWorkflowYaml(
317
253
  ? `${getGithubGitConfigStep()}\n`
318
254
  : '';
319
255
 
320
- const envList = deployEnvironments
321
- .map((name) => environments[name])
322
- .filter(Boolean);
323
- const platformSteps = getPlatformInstallSteps(envList).join('\n');
324
-
325
256
  const projectType = config?.projectType || 'frontend';
326
257
  const installDepsCommand =
327
258
  projectType === 'backend' || projectType === 'both'
@@ -342,7 +273,7 @@ ${uniqueBackendSteps ? `${uniqueBackendSteps}\n` : ''} - uses: actions/setu
342
273
  node-version: '20'
343
274
  ${githubGitConfigStep} - name: Install project dependencies
344
275
  run: ${installDepsCommand}
345
- ${platformSteps ? `${platformSteps}\n` : ''} - name: Install DeployHub CLI
276
+ - name: Install DeployHub CLI
346
277
  run: npm install ${installSpec} --no-save
347
278
  - run: ${getCliBuildCommand()}
348
279
  env:
@@ -481,16 +412,8 @@ export function getRequiredSecrets(
481
412
  const env = environments[envName];
482
413
  if (!env) continue;
483
414
 
484
- if (env.deploymentType === 'platform' || env.frontendDeploymentType === 'platform') {
485
- const platform = env.platform;
486
- if (platform) {
487
- const keys = PLATFORM_ENV_MAP[platform] || [];
488
- keys.forEach((k) => secrets.add(k));
489
- }
490
- } else {
491
- const keys = PROVIDER_ENV_MAP[env.type] || [];
492
- keys.forEach((k) => secrets.add(k));
493
- }
415
+ const keys = PROVIDER_ENV_MAP[env.type] || [];
416
+ keys.forEach((k) => secrets.add(k));
494
417
 
495
418
  if (env.type === 'ssh' && config) {
496
419
  const projectType = config.projectType || 'frontend';
@@ -560,19 +483,6 @@ export function generateEnvExampleContent(
560
483
  const env = environments[envName];
561
484
  if (!env) continue;
562
485
 
563
- if (env.deploymentType === 'platform' || env.frontendDeploymentType === 'platform') {
564
- const platform = env.platform;
565
- if (platform) {
566
- const examples = getPlatformEnvExample(platform);
567
- addSection(
568
- PLATFORM_LABELS[platform] || platform,
569
- Object.keys(examples),
570
- examples
571
- );
572
- }
573
- continue;
574
- }
575
-
576
486
  const keys = PROVIDER_ENV_MAP[env.type] || [];
577
487
  if (keys.length > 0) {
578
488
  addSection(PROVIDER_LABELS[env.type] || env.type, keys);
@@ -1,167 +0,0 @@
1
- import fs from 'fs-extra';
2
- import path from 'path';
3
- import { execa } from 'execa';
4
-
5
- /**
6
- * @param {import('../../../core/config.js').DeployHubConfig} config
7
- * @returns {string}
8
- */
9
- export function getBuildOutputDir(config) {
10
- if (config.projectType === 'both' && config.frontend?.buildOutput) {
11
- return config.frontend.buildOutput;
12
- }
13
- return config.buildOutput || 'dist';
14
- }
15
-
16
- /**
17
- * @param {import('../../../core/config.js').DeployHubConfig} config
18
- * @param {string} [cwd]
19
- * @returns {string}
20
- */
21
- export function resolveBuildOutputPath(config, cwd = process.cwd()) {
22
- return path.join(cwd, getBuildOutputDir(config));
23
- }
24
-
25
- /**
26
- * @param {string} artifactDir
27
- * @param {Record<string, unknown>} record
28
- * @param {string} [environmentName]
29
- */
30
- export async function saveDeploymentRecord(artifactDir, record, environmentName = '') {
31
- const deploymentPath = path.join(artifactDir, 'deployment.json');
32
- let existing = { targets: [], deployedAt: new Date().toISOString(), deployments: [] };
33
-
34
- if (await fs.pathExists(deploymentPath)) {
35
- existing = await fs.readJson(deploymentPath);
36
- }
37
-
38
- const timestamp = new Date().toISOString();
39
- const envName = record.environmentName || environmentName || record.envName || '';
40
-
41
- /** @type {Record<string, unknown>} */
42
- const entry = {
43
- ...record,
44
- platform: record.platform,
45
- deployId: record.deployId || record.deploymentId || '',
46
- deployUrl: record.deployUrl || record.deploymentUrl || '',
47
- deploymentId: record.deploymentId || record.deployId || '',
48
- deploymentUrl: record.deploymentUrl || record.deployUrl || '',
49
- timestamp,
50
- environmentName: envName,
51
- };
52
-
53
- const deployments = existing.deployments || existing.platformDeployments || [];
54
- deployments.push(entry);
55
-
56
- await fs.writeJson(
57
- deploymentPath,
58
- {
59
- ...existing,
60
- deployments,
61
- platformDeployments: deployments,
62
- lastDeployment: entry,
63
- deployedAt: timestamp,
64
- },
65
- { spaces: 2 }
66
- );
67
- }
68
-
69
- /**
70
- * @param {string} artifactDir
71
- * @returns {Promise<Record<string, unknown>|null>}
72
- */
73
- export async function readLastPlatformDeployment(artifactDir) {
74
- const deploymentPath = path.join(artifactDir, 'deployment.json');
75
- if (!(await fs.pathExists(deploymentPath))) return null;
76
- const data = await fs.readJson(deploymentPath);
77
- const deployments = data.deployments || data.platformDeployments || [];
78
- return data.lastDeployment || deployments.at(-1) || null;
79
- }
80
-
81
- /**
82
- * @param {string} artifactDir
83
- * @returns {Promise<Record<string, unknown>|null>}
84
- */
85
- export async function readPreviousPlatformDeployment(artifactDir) {
86
- const deploymentPath = path.join(artifactDir, 'deployment.json');
87
- if (!(await fs.pathExists(deploymentPath))) return null;
88
- const data = await fs.readJson(deploymentPath);
89
- const deployments = data.deployments || data.platformDeployments || [];
90
- if (deployments.length < 2) return null;
91
- return deployments[deployments.length - 2];
92
- }
93
-
94
- /**
95
- * @param {string} artifactDir
96
- * @param {string} [environmentName]
97
- * @returns {Promise<Record<string, unknown>|null>}
98
- */
99
- export async function readDeploymentForEnvironment(artifactDir, environmentName) {
100
- const deploymentPath = path.join(artifactDir, 'deployment.json');
101
- if (!(await fs.pathExists(deploymentPath))) return null;
102
- const data = await fs.readJson(deploymentPath);
103
- const deployments = data.deployments || data.platformDeployments || [];
104
- if (environmentName) {
105
- const match = deployments.filter((d) => d.environmentName === environmentName);
106
- return match.at(-1) || null;
107
- }
108
- return data.lastDeployment || deployments.at(-1) || null;
109
- }
110
-
111
- /**
112
- * @param {string} command
113
- * @param {string} [cwd]
114
- * @param {Record<string, string>} [env]
115
- */
116
- export async function runCli(command, cwd = process.cwd(), env = process.env) {
117
- const [cmd, ...args] = command.split(' ');
118
- const result = await execa(cmd, args, {
119
- cwd,
120
- env: { ...process.env, ...env },
121
- shell: true,
122
- reject: false,
123
- });
124
- return result;
125
- }
126
-
127
- /**
128
- * @param {string} binary
129
- * @returns {Promise<boolean>}
130
- */
131
- export async function isCliInstalled(binary) {
132
- try {
133
- const result = await execa(binary, ['--version'], { reject: false });
134
- return result.exitCode === 0;
135
- } catch {
136
- return false;
137
- }
138
- }
139
-
140
- /**
141
- * @param {string} url
142
- * @returns {Promise<boolean>}
143
- */
144
- export async function checkUrlHealth(url) {
145
- try {
146
- const axios = (await import('axios')).default;
147
- const response = await axios.get(url, {
148
- timeout: 30000,
149
- validateStatus: () => true,
150
- });
151
- return response.status >= 200 && response.status < 400;
152
- } catch {
153
- return false;
154
- }
155
- }
156
-
157
- export default {
158
- getBuildOutputDir,
159
- resolveBuildOutputPath,
160
- saveDeploymentRecord,
161
- readLastPlatformDeployment,
162
- readPreviousPlatformDeployment,
163
- readDeploymentForEnvironment,
164
- runCli,
165
- isCliInstalled,
166
- checkUrlHealth,
167
- };