@hed-hog/cli 0.0.90 ā 0.0.92
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/dist/package.json +1 -1
- package/dist/src/modules/developer/developer.service.d.ts +3 -0
- package/dist/src/modules/developer/developer.service.js +71 -11
- package/dist/src/modules/developer/developer.service.js.map +1 -1
- package/dist/src/modules/hedhog/services/file-system.service.js +4 -1
- package/dist/src/modules/hedhog/services/file-system.service.js.map +1 -1
- package/dist/src/modules/hedhog/services/migration.service.d.ts +4 -0
- package/dist/src/modules/hedhog/services/migration.service.js +101 -51
- package/dist/src/modules/hedhog/services/migration.service.js.map +1 -1
- package/dist/src/templates/deployment/DEPLOYMENT.md.ejs +3 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/package.json
CHANGED
|
@@ -28,8 +28,11 @@ export declare class DeveloperService {
|
|
|
28
28
|
private generateRandomHexSecret;
|
|
29
29
|
private generateRandomBase64Secret;
|
|
30
30
|
private maskDatabaseUrl;
|
|
31
|
+
private extractGithubRepositoryFromValue;
|
|
32
|
+
private detectGithubRepository;
|
|
31
33
|
private resolveGithubRepository;
|
|
32
34
|
private promptForDatabaseUrl;
|
|
35
|
+
private promptForDigitalOceanAccessToken;
|
|
33
36
|
private setGithubSecret;
|
|
34
37
|
private promptToConfigureGithubSecrets;
|
|
35
38
|
private checkHelm;
|
|
@@ -188,7 +188,7 @@ let DeveloperService = class DeveloperService {
|
|
|
188
188
|
spinner.succeed(chalk.green('Deployment configuration completed successfully!'));
|
|
189
189
|
// Display summary
|
|
190
190
|
this.displayDeploymentSummary(config);
|
|
191
|
-
await this.promptToConfigureGithubSecrets(path, repo);
|
|
191
|
+
await this.promptToConfigureGithubSecrets(path, repo, config.provider);
|
|
192
192
|
}
|
|
193
193
|
catch (error) {
|
|
194
194
|
spinner.fail('Failed to configure deployment.');
|
|
@@ -247,20 +247,52 @@ let DeveloperService = class DeveloperService {
|
|
|
247
247
|
maskDatabaseUrl(databaseUrl) {
|
|
248
248
|
return databaseUrl.replace(/:\/\/([^:/?#]+):([^@]*)@/, '://$1:***@');
|
|
249
249
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
250
|
+
extractGithubRepositoryFromValue(value) {
|
|
251
|
+
const normalizedValue = String(value || '').trim();
|
|
252
|
+
if (!normalizedValue) {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
if (/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(normalizedValue)) {
|
|
256
|
+
return normalizedValue;
|
|
253
257
|
}
|
|
258
|
+
const match = normalizedValue.match(/github\.com[:/]([^/\s]+\/[^/\s]+?)(?:\.git)?(?:[/?#].*)?$/i);
|
|
259
|
+
return match?.[1]?.replace(/\.git$/i, '');
|
|
260
|
+
}
|
|
261
|
+
async detectGithubRepository(path) {
|
|
254
262
|
try {
|
|
255
263
|
const result = await this.runner.executeCommand(runner_service_1.ProgramName.GIT, ['remote', 'get-url', 'origin'], { cwd: path }, true);
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return match[1];
|
|
264
|
+
const detectedRepo = this.extractGithubRepositoryFromValue(result.stdout.trim());
|
|
265
|
+
if (detectedRepo) {
|
|
266
|
+
return detectedRepo;
|
|
260
267
|
}
|
|
261
268
|
}
|
|
262
269
|
catch {
|
|
263
|
-
// Fall through to
|
|
270
|
+
// Fall through to local project metadata.
|
|
271
|
+
}
|
|
272
|
+
try {
|
|
273
|
+
const packageJsonPath = pathModule.join(path, 'package.json');
|
|
274
|
+
if (!(0, fs_1.existsSync)(packageJsonPath)) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
const packageJsonRaw = await (0, promises_1.readFile)(packageJsonPath, 'utf8');
|
|
278
|
+
const packageJson = JSON.parse(packageJsonRaw);
|
|
279
|
+
const repositoryValue = typeof packageJson.repository === 'string'
|
|
280
|
+
? packageJson.repository
|
|
281
|
+
: packageJson.repository?.url;
|
|
282
|
+
return this.extractGithubRepositoryFromValue(repositoryValue);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async resolveGithubRepository(path, repo) {
|
|
289
|
+
const explicitRepo = this.extractGithubRepositoryFromValue(repo);
|
|
290
|
+
if (explicitRepo) {
|
|
291
|
+
return explicitRepo;
|
|
292
|
+
}
|
|
293
|
+
const detectedRepo = await this.detectGithubRepository(path);
|
|
294
|
+
if (detectedRepo) {
|
|
295
|
+
return detectedRepo;
|
|
264
296
|
}
|
|
265
297
|
while (true) {
|
|
266
298
|
const answers = await inquirer_1.default.prompt([
|
|
@@ -276,7 +308,7 @@ let DeveloperService = class DeveloperService {
|
|
|
276
308
|
},
|
|
277
309
|
},
|
|
278
310
|
]);
|
|
279
|
-
const resolvedRepo =
|
|
311
|
+
const resolvedRepo = this.extractGithubRepositoryFromValue(answers.repo);
|
|
280
312
|
if (resolvedRepo) {
|
|
281
313
|
return resolvedRepo;
|
|
282
314
|
}
|
|
@@ -299,10 +331,28 @@ let DeveloperService = class DeveloperService {
|
|
|
299
331
|
}
|
|
300
332
|
}
|
|
301
333
|
}
|
|
334
|
+
async promptForDigitalOceanAccessToken() {
|
|
335
|
+
while (true) {
|
|
336
|
+
const answers = await inquirer_1.default.prompt([
|
|
337
|
+
{
|
|
338
|
+
type: 'password',
|
|
339
|
+
name: 'digitaloceanAccessToken',
|
|
340
|
+
message: 'Enter DIGITALOCEAN_ACCESS_TOKEN:',
|
|
341
|
+
mask: '*',
|
|
342
|
+
validate: (input) => String(input || '').trim().length > 0 ||
|
|
343
|
+
'DIGITALOCEAN_ACCESS_TOKEN is required.',
|
|
344
|
+
},
|
|
345
|
+
]);
|
|
346
|
+
const token = String(answers.digitaloceanAccessToken || '').trim();
|
|
347
|
+
if (token) {
|
|
348
|
+
return token;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
302
352
|
async setGithubSecret(secretName, secretValue, repo) {
|
|
303
353
|
await this.runner.executeCommand(runner_service_1.ProgramName.GH, ['secret', 'set', secretName, '--repo', repo, '--body', secretValue], {}, true);
|
|
304
354
|
}
|
|
305
|
-
async promptToConfigureGithubSecrets(path, repo) {
|
|
355
|
+
async promptToConfigureGithubSecrets(path, repo, provider) {
|
|
306
356
|
const { configureSecrets } = await inquirer_1.default.prompt([
|
|
307
357
|
{
|
|
308
358
|
type: 'confirm',
|
|
@@ -317,9 +367,13 @@ let DeveloperService = class DeveloperService {
|
|
|
317
367
|
}
|
|
318
368
|
console.log(chalk.blue.bold('\nš GitHub Secrets Setup\n'));
|
|
319
369
|
await this.ensureGhAuthenticated();
|
|
370
|
+
const requiresDigitalOceanToken = provider === 'digitalocean';
|
|
320
371
|
const resolvedRepo = await this.resolveGithubRepository(path, repo);
|
|
321
372
|
const secretsConfig = {
|
|
322
373
|
databaseUrl: await this.promptForDatabaseUrl(),
|
|
374
|
+
digitaloceanAccessToken: requiresDigitalOceanToken
|
|
375
|
+
? await this.promptForDigitalOceanAccessToken()
|
|
376
|
+
: undefined,
|
|
323
377
|
jwtSecret: this.generateRandomHexSecret(32),
|
|
324
378
|
encryptionSecret: this.generateRandomBase64Secret(32),
|
|
325
379
|
pepper: this.generateRandomBase64Secret(16),
|
|
@@ -327,6 +381,9 @@ let DeveloperService = class DeveloperService {
|
|
|
327
381
|
const maskedDatabaseUrl = this.maskDatabaseUrl(secretsConfig.databaseUrl);
|
|
328
382
|
console.log(chalk.gray(`Repository: ${chalk.cyan(resolvedRepo)}`));
|
|
329
383
|
console.log(chalk.white(`DATABASE_URL: ${maskedDatabaseUrl}`));
|
|
384
|
+
if (secretsConfig.digitaloceanAccessToken) {
|
|
385
|
+
console.log(chalk.white('DIGITALOCEAN_ACCESS_TOKEN: [provided] (hidden for safety)'));
|
|
386
|
+
}
|
|
330
387
|
console.log(chalk.white(`JWT_SECRET: ${secretsConfig.jwtSecret.substring(0, 16)}... (64 chars hex)`));
|
|
331
388
|
console.log(chalk.white(`ENCRYPTION_SECRET: ${secretsConfig.encryptionSecret.substring(0, 16)}... (base64, 32 bytes)`));
|
|
332
389
|
console.log(chalk.white(`PEPPER: ${secretsConfig.pepper.substring(0, 8)}... (base64, 16 bytes)`));
|
|
@@ -349,6 +406,9 @@ let DeveloperService = class DeveloperService {
|
|
|
349
406
|
await this.setGithubSecret('JWT_SECRET', secretsConfig.jwtSecret, resolvedRepo);
|
|
350
407
|
await this.setGithubSecret('ENCRYPTION_SECRET', secretsConfig.encryptionSecret, resolvedRepo);
|
|
351
408
|
await this.setGithubSecret('PEPPER', secretsConfig.pepper, resolvedRepo);
|
|
409
|
+
if (secretsConfig.digitaloceanAccessToken) {
|
|
410
|
+
await this.setGithubSecret('DIGITALOCEAN_ACCESS_TOKEN', secretsConfig.digitaloceanAccessToken, resolvedRepo);
|
|
411
|
+
}
|
|
352
412
|
spinner.succeed(chalk.green(`GitHub secrets configured successfully for ${resolvedRepo}.`));
|
|
353
413
|
console.log(chalk.gray(`Verify with: gh secret list --repo ${resolvedRepo}`));
|
|
354
414
|
console.log('');
|