Skip to content

Commit f6ad2a0

Browse files
committed
Fix create-app educational commit flow
1 parent f5911c2 commit f6ad2a0

2 files changed

Lines changed: 32 additions & 7 deletions

File tree

packages/create-react-on-rails-app/src/create-app.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,19 @@ function gitHasPendingChanges(appPath: string): boolean {
211211
}
212212

213213
function createEducationalCommit(appPath: string, subject: string, body: string): void {
214-
ensureGitRepository(appPath);
214+
try {
215+
ensureGitRepository(appPath);
215216

216-
if (!gitHasPendingChanges(appPath)) {
217-
return;
218-
}
217+
if (!gitHasPendingChanges(appPath)) {
218+
return;
219+
}
219220

220-
execLiveArgs('git', ['add', '-A'], appPath);
221-
execLiveArgs('git', ['commit', '-m', subject, '-m', body], appPath, educationalGitEnv(appPath));
221+
execLiveArgs('git', ['add', '-A'], appPath);
222+
execLiveArgs('git', ['commit', '-m', subject, '-m', body], appPath, educationalGitEnv(appPath));
223+
} catch (error) {
224+
const message = error instanceof Error ? error.message : 'unknown git error';
225+
logInfo(`Skipping educational commit "${subject}" due to git error: ${message}`);
226+
}
222227
}
223228

224229
function railsBaselineCommitMessage(): { subject: string; body: string } {
@@ -351,7 +356,7 @@ export function createApp(appName: string, options: CliOptions): void {
351356
// so it's always a simple directory name safe to use with rails new.
352357
logStep(currentStep, totalSteps, 'Creating Rails application...');
353358
try {
354-
execLiveArgs('rails', ['new', appName, '--database=postgresql', '--skip-javascript']);
359+
execLiveArgs('rails', ['new', appName, '--database=postgresql', '--skip-javascript', '--skip-git']);
355360
const { subject, body } = railsBaselineCommitMessage();
356361
createEducationalCommit(appPath, subject, body);
357362
logStepDone('Rails application created');

packages/create-react-on-rails-app/tests/create-app.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ describe('createApp', () => {
270270
'my-app',
271271
'--database=postgresql',
272272
'--skip-javascript',
273+
'--skip-git',
273274
]);
274275
expect(mockedExecLiveArgs).toHaveBeenNthCalledWith(
275276
4,
@@ -309,6 +310,7 @@ describe('createApp', () => {
309310
'my-app',
310311
'--database=postgresql',
311312
'--skip-javascript',
313+
'--skip-git',
312314
]);
313315
expect(mockedExecLiveArgs).toHaveBeenNthCalledWith(
314316
4,
@@ -365,6 +367,7 @@ describe('createApp', () => {
365367
'my-app',
366368
'--database=postgresql',
367369
'--skip-javascript',
370+
'--skip-git',
368371
]);
369372
expect(mockedExecLiveArgs).toHaveBeenNthCalledWith(
370373
4,
@@ -391,6 +394,23 @@ describe('createApp', () => {
391394
expect(processExitSpy).not.toHaveBeenCalled();
392395
});
393396

397+
it('continues app creation when an educational commit fails', () => {
398+
const appPath = path.resolve(process.cwd(), 'my-app');
399+
mockedExecLiveArgs.mockImplementation((command, args) => {
400+
if (command === 'git' && args[0] === 'commit' && args[2] === 'Create Rails app with PostgreSQL') {
401+
throw new Error('hook rejected commit');
402+
}
403+
});
404+
405+
createApp('my-app', baseOptions);
406+
407+
expect(processExitSpy).not.toHaveBeenCalled();
408+
expect(mockedFs.rmSync).not.toHaveBeenCalledWith(appPath, { recursive: true, force: true });
409+
expect(mockedLogInfo).toHaveBeenCalledWith(
410+
expect.stringContaining('Skipping educational commit "Create Rails app with PostgreSQL" due to git error'),
411+
);
412+
});
413+
394414
it('converts pnpm scaffolds away from npm artifacts', () => {
395415
const appPath = path.resolve(process.cwd(), 'my-app');
396416
const packageJsonPath = path.join(appPath, 'package.json');

0 commit comments

Comments
 (0)