Skip to content

Feat: Add support for creating git prototypes to cli. #12

Merged
dlabaj merged 7 commits intomainfrom
git-updates
Feb 18, 2026
Merged

Feat: Add support for creating git prototypes to cli. #12
dlabaj merged 7 commits intomainfrom
git-updates

Conversation

@dlabaj
Copy link
Contributor

@dlabaj dlabaj commented Feb 10, 2026

Closes issue #7 :

  • Create projects and push initial project to prototype
  • Push updates to prototype
  • Retrieve latest updates from github.

@dlabaj dlabaj self-assigned this Feb 10, 2026
@dlabaj dlabaj added the enhancement New feature or request label Feb 10, 2026
@github-project-automation github-project-automation bot moved this to Needs triage in PatternFly Issues Feb 10, 2026
@dlabaj dlabaj changed the title WIP: Add support for creating git prototypes to cli. Feat: Add support for creating git prototypes to cli. Feb 12, 2026
@dlabaj dlabaj requested review from cdcabrera and jpuzz0 and removed request for cdcabrera and jpuzz0 February 12, 2026 14:20
'repo',
'create',
options.repoName,
'--public',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to provide an option to make a private project?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could have a default...and maybe the default is public, but I would think maybe the opposite actually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point let me update this to be private by default.

}

try {
await execa('git', ['add', '.'], { cwd, stdio: 'inherit' });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no selective adding ability? What if they only want to push a particular file or directory within the project?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After our meeting yesterday probably best to leave this out initially for the designer profile.

]);

const commitMessage = (message as string).trim();
if (!commitMessage) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this condition won't even be reached due to the validate function for the commit message above requiring a string, right? I think it can be removed, but maybe I'm misunderstanding.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah you're correct.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this updated with the latest changes? I think this problem still exists.

Comment on lines +22 to +36
if (err && typeof err === 'object' && 'exitCode' in err) {
const code = (err as { exitCode?: number }).exitCode;
if (code === 128) {
console.error(
'\n❌ Pull failed. You may need to set a remote (e.g. "git remote add origin <url>") or run "gh auth login".\n',
);
} else {
console.error('\n❌ Pull failed. See the output above for details.\n');
}
} else {
console.error('\n❌ An error occurred:');
if (err instanceof Error) console.error(` ${err.message}\n`);
else console.error(` ${String(err)}\n`);
}
throw err;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems this is duplicated in the save.ts file...instead of repeating the code here, maybe make a helper called something like handleGitError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

console.log('\n✅ Changes saved and pushed to GitHub successfully.\n');
} catch (err) {
if (err && typeof err === 'object' && 'exitCode' in err) {
const code = (err as { exitCode?: number }).exitCode;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can remove this casting if you update the condition above to something like if (err instanceof ExecaError) instead of if (err && typeof err === 'object' && 'exitCode' in err)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it could be other types of errors so updated to Error instead of ExecaError.

{
type: 'confirm',
name: 'useSSH',
message: 'Use SSH URL for cloning?',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will non-devs understand this question and how to answer it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the question you have to pass it in now.

src/cli.ts Outdated
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the create logic could be separated into its own function to make the CLI more readable here, and could be unit tested separately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense.

}

await execa('git', ['push'], { cwd, stdio: 'inherit' });
console.log('\n✅ Changes saved and pushed to GitHub successfully.\n');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the commit succeeds on line 64 but push fails here, the user sees an error and might think nothing was saved. Worth letting them know their changes were committed locally?

} else {
console.error('\n❌ Save or push failed. See the output above for details.\n');
}
} else if (!(err instanceof Error && err.message === 'No remote origin')) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This couples the catch to the exact string 'No remote origin' — if someone changes the message on line 80, the catch silently starts double-logging. Would a custom error class make this safer?

await execa('git', ['push'], { cwd, stdio: 'inherit' });
console.log('\n✅ Changes saved and pushed to GitHub successfully.\n');
} catch (err) {
if (err && typeof err === 'object' && 'exitCode' in err) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error narrowing pattern is duplicated in load.ts too — maybe a shared isExecaError helper?

try {
await execa('gh', ['api', `repos/${owner}/${repoName}`], { reject: true });
return true;
} catch {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repoExists returns false for any error, not just "repo doesn't exist." A network timeout or auth failure would silently proceed to create a repo that might already exist. Should non-404 errors be surfaced?

}

const pkgJson = await fs.readJson(pkgJsonPath);
const projectName = (pkgJson.name as string) ?? 'my-project';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? 'my-project' only catches null/undefined — if name is an empty string in a bad package.json, sanitizeRepoName gets it. Worth a more defensive check?

'--public',
`--source=${options.projectPath}`,
'--remote=origin',
'--push',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createRepo passes --push here, but when called from save, the flow also does git push after. Isn't the second push redundant?


try {
console.log('📥 Pulling latest updates from GitHub...\n');
await execa('git', ['pull'], { cwd, stdio: 'inherit' });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will beginners understand git's error when no upstream tracking branch is set? Might be worth a friendlier message.

]);

const commitMessage = (message as string).trim();
if (!commitMessage) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this updated with the latest changes? I think this problem still exists.

@dlabaj dlabaj merged commit 4cd82e1 into main Feb 18, 2026
@github-project-automation github-project-automation bot moved this from Needs triage to Done in PatternFly Issues Feb 18, 2026
@dlabaj
Copy link
Contributor Author

dlabaj commented Feb 18, 2026

Capturing outstanding comments in follow up issue and merging this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants

Comments