@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.
- package/package.json +1 -1
- package/src/adapters/dotnet.adapter.js +12 -5
- package/src/adapters/go.adapter.js +12 -5
- package/src/adapters/java.adapter.js +12 -5
- package/src/adapters/node.adapter.js +10 -3
- package/src/adapters/php.adapter.js +12 -5
- package/src/adapters/python.adapter.js +7 -1
- package/src/adapters/rails.adapter.js +7 -2
- package/src/commands/init.js +25 -8
- package/src/core/stages.js +5 -1
- package/src/deployment/deployment-env.js +106 -14
- package/src/deployment/providers/docker.js +283 -36
- package/src/utils/docker-image.js +181 -0
- package/src/utils/dockerfile.js +98 -0
- package/src/utils/github-actions.js +54 -10
- package/src/utils/scaffold.js +49 -10
|
@@ -3,7 +3,8 @@ import path from 'path';
|
|
|
3
3
|
import { getWorkflowHeaderComment } from './author.js';
|
|
4
4
|
import {
|
|
5
5
|
generateDeploymentEnvSection,
|
|
6
|
-
|
|
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 =
|
|
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
|
-
|
|
455
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
472
|
-
|
|
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(
|
|
519
|
+
return Array.from(byKey.values());
|
|
476
520
|
}
|
|
477
521
|
|
|
478
522
|
/**
|
package/src/utils/scaffold.js
CHANGED
|
@@ -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
|
|
52
|
+
* @returns {Promise<{ generated: boolean }>}
|
|
52
53
|
*/
|
|
53
|
-
export async function
|
|
54
|
-
const
|
|
55
|
-
if (await fs.pathExists(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|