genbox 1.0.43 → 1.0.45
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/commands/create.js +99 -43
- package/dist/commands/init.js +10 -0
- package/package.json +1 -1
package/dist/commands/create.js
CHANGED
|
@@ -114,6 +114,27 @@ function getPrivateSshKey() {
|
|
|
114
114
|
}
|
|
115
115
|
return undefined;
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Get local git config for commits on genbox
|
|
119
|
+
*/
|
|
120
|
+
function getGitConfig() {
|
|
121
|
+
const { execSync } = require('child_process');
|
|
122
|
+
let userName;
|
|
123
|
+
let userEmail;
|
|
124
|
+
try {
|
|
125
|
+
userName = execSync('git config --global user.name', { encoding: 'utf-8' }).trim();
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Git config not set
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
userEmail = execSync('git config --global user.email', { encoding: 'utf-8' }).trim();
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Git config not set
|
|
135
|
+
}
|
|
136
|
+
return { userName, userEmail };
|
|
137
|
+
}
|
|
117
138
|
/**
|
|
118
139
|
* Prompt user for environment name
|
|
119
140
|
*/
|
|
@@ -200,9 +221,9 @@ exports.createCommand = new commander_1.Command('create')
|
|
|
200
221
|
.option('--db <mode>', 'Database mode: none, local, copy, remote')
|
|
201
222
|
.option('--db-source <source>', 'Database source: staging, production')
|
|
202
223
|
.option('-s, --size <size>', 'Server size: small, medium, large, xl')
|
|
203
|
-
.option('-b, --branch <branch>', '
|
|
204
|
-
.option('-n, --new-branch <name>', 'Create a new branch with this name')
|
|
205
|
-
.option('-f, --from-branch <branch>', 'Source branch to create new branch from (defaults to
|
|
224
|
+
.option('-b, --branch <branch>', 'Use existing git branch (skips new branch creation)')
|
|
225
|
+
.option('-n, --new-branch <name>', 'Create a new branch with this name (defaults to env name)')
|
|
226
|
+
.option('-f, --from-branch <branch>', 'Source branch to create new branch from (defaults to main)')
|
|
206
227
|
.option('-y, --yes', 'Skip interactive prompts')
|
|
207
228
|
.option('--dry-run', 'Show what would be created without actually creating')
|
|
208
229
|
.action(async (nameArg, options) => {
|
|
@@ -265,19 +286,19 @@ exports.createCommand = new commander_1.Command('create')
|
|
|
265
286
|
}
|
|
266
287
|
// Silently continue for other errors - the create API will validate
|
|
267
288
|
}
|
|
268
|
-
//
|
|
289
|
+
// Determine branch configuration
|
|
290
|
+
// Default: create new branch from 'main' with name = environment name
|
|
291
|
+
let newBranchName = options.newBranch;
|
|
292
|
+
let sourceBranch = options.fromBranch;
|
|
293
|
+
// If -n (--new-branch) is provided without -f (--from-branch), default source to 'main'
|
|
269
294
|
if (options.newBranch && !options.fromBranch) {
|
|
270
|
-
|
|
271
|
-
console.log(chalk_1.default.dim(
|
|
272
|
-
return;
|
|
295
|
+
sourceBranch = 'main';
|
|
296
|
+
console.log(chalk_1.default.dim(` Source branch not specified, using 'main'`));
|
|
273
297
|
}
|
|
274
|
-
//
|
|
275
|
-
let newBranchName = options.newBranch;
|
|
298
|
+
// If -f (--from-branch) is provided without -n (--new-branch), use env name as branch name
|
|
276
299
|
if (options.fromBranch && !options.newBranch) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
newBranchName = `${name}-${timestamp}`;
|
|
280
|
-
console.log(chalk_1.default.dim(` Auto-generated branch name: ${newBranchName}`));
|
|
300
|
+
newBranchName = name;
|
|
301
|
+
console.log(chalk_1.default.dim(` New branch name: ${newBranchName}`));
|
|
281
302
|
}
|
|
282
303
|
// Build create options
|
|
283
304
|
const createOptions = {
|
|
@@ -291,7 +312,7 @@ exports.createCommand = new commander_1.Command('create')
|
|
|
291
312
|
size: options.size,
|
|
292
313
|
branch: options.branch,
|
|
293
314
|
newBranch: newBranchName,
|
|
294
|
-
sourceBranch:
|
|
315
|
+
sourceBranch: sourceBranch,
|
|
295
316
|
yes: options.yes,
|
|
296
317
|
dryRun: options.dryRun,
|
|
297
318
|
};
|
|
@@ -302,7 +323,20 @@ exports.createCommand = new commander_1.Command('create')
|
|
|
302
323
|
// Interactive branch selection if no branch options were specified
|
|
303
324
|
// Skip if: -b (existing branch), -f (new branch from source), -n (explicit new branch name), or -y (skip prompts)
|
|
304
325
|
if (!options.branch && !options.fromBranch && !options.newBranch && !options.yes && resolved.repos.length > 0) {
|
|
305
|
-
resolved = await promptForBranchOptions(resolved, config);
|
|
326
|
+
resolved = await promptForBranchOptions(resolved, config, name);
|
|
327
|
+
}
|
|
328
|
+
// Default behavior when -y (non-interactive) and no branch options: create new branch from main
|
|
329
|
+
if (!options.branch && !options.fromBranch && !options.newBranch && options.yes && resolved.repos.length > 0) {
|
|
330
|
+
resolved = {
|
|
331
|
+
...resolved,
|
|
332
|
+
repos: resolved.repos.map(repo => ({
|
|
333
|
+
...repo,
|
|
334
|
+
branch: name, // Branch name same as environment name
|
|
335
|
+
newBranch: name,
|
|
336
|
+
sourceBranch: 'main',
|
|
337
|
+
})),
|
|
338
|
+
};
|
|
339
|
+
console.log(chalk_1.default.dim(` Creating new branch '${name}' from 'main'`));
|
|
306
340
|
}
|
|
307
341
|
// Display resolved configuration
|
|
308
342
|
displayResolvedConfig(resolved);
|
|
@@ -494,59 +528,51 @@ function displayResolvedConfig(resolved) {
|
|
|
494
528
|
}
|
|
495
529
|
/**
|
|
496
530
|
* Prompt for branch options interactively
|
|
531
|
+
* Default behavior: create new branch from 'main' with branch name = environment name
|
|
497
532
|
*/
|
|
498
|
-
async function promptForBranchOptions(resolved, config) {
|
|
533
|
+
async function promptForBranchOptions(resolved, config, envName) {
|
|
499
534
|
// Get the default branch from config or first repo
|
|
500
535
|
const defaultBranch = config.defaults?.branch || resolved.repos[0]?.branch || 'main';
|
|
501
536
|
console.log(chalk_1.default.blue('=== Branch Configuration ==='));
|
|
502
|
-
console.log(chalk_1.default.dim(`Default branch: ${defaultBranch}`));
|
|
503
537
|
console.log('');
|
|
504
538
|
const branchChoice = await prompts.select({
|
|
505
539
|
message: 'Branch option:',
|
|
506
540
|
choices: [
|
|
507
541
|
{
|
|
508
|
-
name:
|
|
509
|
-
value: '
|
|
542
|
+
name: `${chalk_1.default.green('Create new branch')} '${chalk_1.default.cyan(envName)}' from 'main' ${chalk_1.default.dim('(recommended)')}`,
|
|
543
|
+
value: 'new-from-main',
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
name: `Create new branch from a different source`,
|
|
547
|
+
value: 'new-custom',
|
|
510
548
|
},
|
|
511
549
|
{
|
|
512
|
-
name: 'Use
|
|
550
|
+
name: 'Use an existing branch',
|
|
513
551
|
value: 'existing',
|
|
514
552
|
},
|
|
515
553
|
{
|
|
516
|
-
name:
|
|
517
|
-
value: '
|
|
554
|
+
name: `Use default branch (${defaultBranch}) without creating new branch`,
|
|
555
|
+
value: 'default',
|
|
518
556
|
},
|
|
519
557
|
],
|
|
520
|
-
default: '
|
|
558
|
+
default: 'new-from-main',
|
|
521
559
|
});
|
|
522
|
-
if (branchChoice === '
|
|
523
|
-
//
|
|
524
|
-
return resolved;
|
|
525
|
-
}
|
|
526
|
-
if (branchChoice === 'existing') {
|
|
527
|
-
const branchName = await prompts.input({
|
|
528
|
-
message: 'Enter branch name:',
|
|
529
|
-
default: defaultBranch,
|
|
530
|
-
validate: (value) => {
|
|
531
|
-
if (!value.trim())
|
|
532
|
-
return 'Branch name is required';
|
|
533
|
-
return true;
|
|
534
|
-
},
|
|
535
|
-
});
|
|
536
|
-
// Update all repos with the selected branch
|
|
560
|
+
if (branchChoice === 'new-from-main') {
|
|
561
|
+
// Create new branch from main with name = environment name
|
|
537
562
|
return {
|
|
538
563
|
...resolved,
|
|
539
564
|
repos: resolved.repos.map(repo => ({
|
|
540
565
|
...repo,
|
|
541
|
-
branch:
|
|
542
|
-
newBranch:
|
|
543
|
-
sourceBranch:
|
|
566
|
+
branch: envName,
|
|
567
|
+
newBranch: envName,
|
|
568
|
+
sourceBranch: 'main',
|
|
544
569
|
})),
|
|
545
570
|
};
|
|
546
571
|
}
|
|
547
|
-
if (branchChoice === 'new') {
|
|
572
|
+
if (branchChoice === 'new-custom') {
|
|
548
573
|
const newBranchName = await prompts.input({
|
|
549
574
|
message: 'New branch name:',
|
|
575
|
+
default: envName,
|
|
550
576
|
validate: (value) => {
|
|
551
577
|
if (!value.trim())
|
|
552
578
|
return 'Branch name is required';
|
|
@@ -557,7 +583,7 @@ async function promptForBranchOptions(resolved, config) {
|
|
|
557
583
|
});
|
|
558
584
|
const sourceBranch = await prompts.input({
|
|
559
585
|
message: 'Create from branch:',
|
|
560
|
-
default:
|
|
586
|
+
default: 'main',
|
|
561
587
|
validate: (value) => {
|
|
562
588
|
if (!value.trim())
|
|
563
589
|
return 'Source branch is required';
|
|
@@ -575,6 +601,31 @@ async function promptForBranchOptions(resolved, config) {
|
|
|
575
601
|
})),
|
|
576
602
|
};
|
|
577
603
|
}
|
|
604
|
+
if (branchChoice === 'existing') {
|
|
605
|
+
const branchName = await prompts.input({
|
|
606
|
+
message: 'Enter branch name:',
|
|
607
|
+
default: defaultBranch,
|
|
608
|
+
validate: (value) => {
|
|
609
|
+
if (!value.trim())
|
|
610
|
+
return 'Branch name is required';
|
|
611
|
+
return true;
|
|
612
|
+
},
|
|
613
|
+
});
|
|
614
|
+
// Update all repos with the selected branch
|
|
615
|
+
return {
|
|
616
|
+
...resolved,
|
|
617
|
+
repos: resolved.repos.map(repo => ({
|
|
618
|
+
...repo,
|
|
619
|
+
branch: branchName.trim(),
|
|
620
|
+
newBranch: undefined,
|
|
621
|
+
sourceBranch: undefined,
|
|
622
|
+
})),
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
if (branchChoice === 'default') {
|
|
626
|
+
// Keep resolved repos as-is (no new branch)
|
|
627
|
+
return resolved;
|
|
628
|
+
}
|
|
578
629
|
return resolved;
|
|
579
630
|
}
|
|
580
631
|
/**
|
|
@@ -794,6 +845,8 @@ function buildPayload(resolved, config, publicKey, privateKey, configLoader) {
|
|
|
794
845
|
sourceBranch: repo.sourceBranch,
|
|
795
846
|
};
|
|
796
847
|
}
|
|
848
|
+
// Get local git config for commits
|
|
849
|
+
const gitConfig = getGitConfig();
|
|
797
850
|
return {
|
|
798
851
|
name: resolved.name,
|
|
799
852
|
size: resolved.size,
|
|
@@ -805,6 +858,9 @@ function buildPayload(resolved, config, publicKey, privateKey, configLoader) {
|
|
|
805
858
|
repos,
|
|
806
859
|
privateKey,
|
|
807
860
|
gitToken: envVars.GIT_TOKEN,
|
|
861
|
+
gitUserName: gitConfig.userName,
|
|
862
|
+
gitUserEmail: gitConfig.userEmail,
|
|
863
|
+
installClaudeCode: config.defaults?.install_claude_code,
|
|
808
864
|
envVars: resolved.env,
|
|
809
865
|
apps: resolved.apps.map(a => a.name),
|
|
810
866
|
appConfigs: resolved.apps.map(a => ({
|
package/dist/commands/init.js
CHANGED
|
@@ -665,6 +665,16 @@ exports.initCommand = new commander_1.Command('init')
|
|
|
665
665
|
v4Config.defaults = {};
|
|
666
666
|
}
|
|
667
667
|
v4Config.defaults.size = serverSize;
|
|
668
|
+
// Ask about Claude Code installation
|
|
669
|
+
if (!nonInteractive && !options.fromScan) {
|
|
670
|
+
const installClaudeCode = await prompts.confirm({
|
|
671
|
+
message: 'Install Claude Code CLI on genbox servers?',
|
|
672
|
+
default: true,
|
|
673
|
+
});
|
|
674
|
+
if (installClaudeCode) {
|
|
675
|
+
v4Config.defaults.install_claude_code = true;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
668
678
|
// Get default branch (use detected branch or allow override)
|
|
669
679
|
const detectedBranch = scan.git?.branch || 'main';
|
|
670
680
|
let defaultBranch = detectedBranch;
|