@akash-chowdhury-24/deployhub 2.0.5 → 2.0.7

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.
@@ -3,7 +3,8 @@ import path from 'path';
3
3
  import { getWorkflowHeaderComment } from './author.js';
4
4
  import {
5
5
  generateDeploymentEnvSection,
6
- getDeploymentSecretKeys,
6
+ getDeploymentWorkflowSecretKeys,
7
+ getDeploymentSecretChecklistItems,
7
8
  DEPLOYMENT_ENV_KEYS,
8
9
  } from '../deployment/deployment-env.js';
9
10
 
@@ -287,7 +288,7 @@ export function generateWorkflowYaml(
287
288
  const env = environments[envName];
288
289
  if (!env) continue;
289
290
 
290
- const keys = getDeploymentSecretKeys(env.type, config);
291
+ const keys = getDeploymentWorkflowSecretKeys(env.type, config);
291
292
  for (const key of keys) {
292
293
  envVars.add(`${key}: \${{ secrets.${key} }}`);
293
294
  }
@@ -438,10 +439,12 @@ export async function guessCliGithubRepo(cwd = process.cwd()) {
438
439
  }
439
440
 
440
441
  /**
442
+ * Flat list of required secret key names (for callers that only need keys).
441
443
  * @param {string[]} storageProviders
442
444
  * @param {string[]} deployEnvironments
443
445
  * @param {Record<string, { type: string }>} environments
444
446
  * @param {import('../core/config.js').DeployHubConfig} [config]
447
+ * @param {string|null} [cliSource]
445
448
  * @returns {string[]}
446
449
  */
447
450
  export function getRequiredSecrets(
@@ -451,28 +454,69 @@ export function getRequiredSecrets(
451
454
  config = null,
452
455
  cliSource = null
453
456
  ) {
454
- /** @type {Set<string>} */
455
- const secrets = new Set();
457
+ return getGithubSecretsChecklist(
458
+ storageProviders,
459
+ deployEnvironments,
460
+ environments,
461
+ config,
462
+ cliSource
463
+ )
464
+ .filter((item) => item.required)
465
+ .map((item) => item.key);
466
+ }
467
+
468
+ /**
469
+ * Labeled GitHub Secrets checklist (required + optional) for post-init output.
470
+ * @param {string[]} storageProviders
471
+ * @param {string[]} deployEnvironments
472
+ * @param {Record<string, { type: string }>} environments
473
+ * @param {import('../core/config.js').DeployHubConfig} [config]
474
+ * @param {string|null} [cliSource]
475
+ * @returns {import('../deployment/deployment-env.js').SecretChecklistItem[]}
476
+ */
477
+ export function getGithubSecretsChecklist(
478
+ storageProviders,
479
+ deployEnvironments,
480
+ environments,
481
+ config = null,
482
+ cliSource = null
483
+ ) {
484
+ /** @type {Map<string, import('../deployment/deployment-env.js').SecretChecklistItem>} */
485
+ const byKey = new Map();
456
486
 
457
487
  const resolvedCliSource = cliSource || config?.cli?.source;
458
488
  if (isGithubCliSource(resolvedCliSource)) {
459
- secrets.add(GITHUB_CLI_TOKEN_SECRET);
489
+ byKey.set(GITHUB_CLI_TOKEN_SECRET, {
490
+ key: GITHUB_CLI_TOKEN_SECRET,
491
+ required: true,
492
+ note: 'required when installing DeployHub CLI from a private GitHub repo',
493
+ });
460
494
  }
461
495
 
462
496
  for (const provider of storageProviders) {
463
497
  const keys = PROVIDER_ENV_MAP[provider] || [];
464
- keys.forEach((k) => secrets.add(k));
498
+ for (const key of keys) {
499
+ byKey.set(key, { key, required: true });
500
+ }
465
501
  }
466
502
 
467
503
  for (const envName of deployEnvironments) {
468
504
  const env = environments[envName];
469
- if (!env) continue;
505
+ if (!env?.type) continue;
470
506
 
471
- const keys = getDeploymentSecretKeys(env.type, config);
472
- keys.forEach((k) => secrets.add(k));
507
+ for (const item of getDeploymentSecretChecklistItems(env.type, config)) {
508
+ const existing = byKey.get(item.key);
509
+ if (existing) {
510
+ if (item.required && !existing.required) {
511
+ byKey.set(item.key, item);
512
+ }
513
+ continue;
514
+ }
515
+ byKey.set(item.key, item);
516
+ }
473
517
  }
474
518
 
475
- return Array.from(secrets);
519
+ return Array.from(byKey.values());
476
520
  }
477
521
 
478
522
  /**
@@ -3,6 +3,7 @@ import path from 'path';
3
3
  import chalk from 'chalk';
4
4
  import {
5
5
  generateDockerfile,
6
+ generateDockerignore,
6
7
  getDockerfileFrameworkLabel,
7
8
  resolveDockerSettings,
8
9
  } from './dockerfile.js';
@@ -48,11 +49,11 @@ export function needsKubernetesManifests(
48
49
  * @param {string} cwd
49
50
  * @param {import('../core/config.js').DeployHubConfig} config
50
51
  * @param {{ silent?: boolean }} [options]
51
- * @returns {Promise<{ generated: boolean, framework?: string }>}
52
+ * @returns {Promise<{ generated: boolean }>}
52
53
  */
53
- export async function ensureDockerfile(cwd, config, options = {}) {
54
- const dockerfilePath = path.join(cwd, 'Dockerfile');
55
- if (await fs.pathExists(dockerfilePath)) {
54
+ export async function ensureDockerignore(cwd, config, options = {}) {
55
+ const dockerignorePath = path.join(cwd, '.dockerignore');
56
+ if (await fs.pathExists(dockerignorePath)) {
56
57
  return { generated: false };
57
58
  }
58
59
 
@@ -60,20 +61,56 @@ export async function ensureDockerfile(cwd, config, options = {}) {
60
61
  return { generated: false };
61
62
  }
62
63
 
63
- const settings = resolveDockerSettings(config);
64
- const content = generateDockerfile(config);
65
- await fs.writeFile(dockerfilePath, content);
64
+ await fs.writeFile(dockerignorePath, generateDockerignore(config));
66
65
 
67
66
  if (!options.silent) {
68
- const label = getDockerfileFrameworkLabel(settings.framework);
69
67
  console.log(
70
68
  chalk.yellow(
71
- `No Dockerfile found — generated a starter Dockerfile at ./Dockerfile based on your detected ${label}. Review it before deploying, especially the exposed port and start command.`
69
+ 'No .dockerignore found — generated one at ./.dockerignore to keep node_modules and build caches out of the Docker build context.'
72
70
  )
73
71
  );
74
72
  }
75
73
 
76
- return { generated: true, framework: settings.framework };
74
+ return { generated: true };
75
+ }
76
+
77
+ /**
78
+ * @param {string} cwd
79
+ * @param {import('../core/config.js').DeployHubConfig} config
80
+ * @param {{ silent?: boolean }} [options]
81
+ * @returns {Promise<{ generated: boolean, framework?: string, dockerignoreGenerated?: boolean }>}
82
+ */
83
+ export async function ensureDockerfile(cwd, config, options = {}) {
84
+ const dockerfilePath = path.join(cwd, 'Dockerfile');
85
+ let generated = false;
86
+ /** @type {string|undefined} */
87
+ let framework;
88
+
89
+ if (!(await fs.pathExists(dockerfilePath)) && needsDockerfile(config)) {
90
+ const settings = resolveDockerSettings(config);
91
+ const content = generateDockerfile(config);
92
+ await fs.writeFile(dockerfilePath, content);
93
+ generated = true;
94
+ framework = settings.framework;
95
+
96
+ if (!options.silent) {
97
+ const label = getDockerfileFrameworkLabel(settings.framework);
98
+ console.log(
99
+ chalk.yellow(
100
+ `No Dockerfile found — generated a starter Dockerfile at ./Dockerfile based on your detected ${label}. Review it before deploying, especially the exposed port and start command.`
101
+ )
102
+ );
103
+ }
104
+ }
105
+
106
+ // Always pair Dockerfile generation path with .dockerignore (never overwrite existing)
107
+ const dockerignoreResult = await ensureDockerignore(cwd, config, options);
108
+
109
+ return {
110
+ generated,
111
+ framework,
112
+ dockerignoreGenerated: dockerignoreResult.generated,
113
+ };
77
114
  }
78
115
 
79
116
  /**
@@ -133,6 +170,7 @@ export async function ensureDeployScaffold(
133
170
  const k8sResult = await ensureKubernetesManifests(cwd, config, environments, options);
134
171
  return {
135
172
  dockerfile: dockerResult.generated,
173
+ dockerignore: Boolean(dockerResult.dockerignoreGenerated),
136
174
  kubernetes: k8sResult.generated,
137
175
  };
138
176
  }
@@ -183,6 +221,7 @@ export async function copyDeployAssetsToArtifactDir(stagingDir, artifactDir) {
183
221
 
184
222
  export default {
185
223
  ensureDockerfile,
224
+ ensureDockerignore,
186
225
  ensureKubernetesManifests,
187
226
  ensureDeployScaffold,
188
227
  needsDockerfile,