From fbcc04eb626efaa253b7b14d222ed421604a9e10 Mon Sep 17 00:00:00 2001 From: evanbacon Date: Sat, 7 Feb 2026 11:32:51 -0800 Subject: [PATCH 1/3] Support nonInteractive in vcs ensureRepoExists Add an optional nonInteractive parameter to Client.ensureRepoExistsAsync and implement it in GitClient. When nonInteractive is true, GitClient will auto-init the repo (git init), create an initial commit, and surface a single error with suggested git config commands if user.name/email are missing. Update callers across build/update/inspect/configure commands to pass the appropriate nonInteractive flag and adjust ensureRepoIsCleanAsync calls. Also resolve the workspace root for init operations and improve related log messages. --- .../eas-cli/src/build/runBuildAndSubmit.ts | 2 +- .../eas-cli/src/commands/build/configure.ts | 4 +- packages/eas-cli/src/commands/build/dev.ts | 4 +- .../eas-cli/src/commands/build/inspect.ts | 2 +- .../eas-cli/src/commands/update/configure.ts | 2 +- packages/eas-cli/src/commands/update/index.ts | 2 +- packages/eas-cli/src/vcs/clients/git.ts | 44 ++++++++++++++----- packages/eas-cli/src/vcs/vcs.ts | 2 +- 8 files changed, 41 insertions(+), 21 deletions(-) diff --git a/packages/eas-cli/src/build/runBuildAndSubmit.ts b/packages/eas-cli/src/build/runBuildAndSubmit.ts index 0b2fb7aa1e..fd7715a16c 100644 --- a/packages/eas-cli/src/build/runBuildAndSubmit.ts +++ b/packages/eas-cli/src/build/runBuildAndSubmit.ts @@ -128,7 +128,7 @@ export async function runBuildAndSubmitAsync({ buildIds: string[]; buildProfiles?: ProfileData<'build'>[]; }> { - await vcsClient.ensureRepoExistsAsync(); + await vcsClient.ensureRepoExistsAsync({ nonInteractive: flags.nonInteractive }); await ensureRepoIsCleanAsync(vcsClient, flags.nonInteractive); await ensureProjectConfiguredAsync({ diff --git a/packages/eas-cli/src/commands/build/configure.ts b/packages/eas-cli/src/commands/build/configure.ts index 2448e1d5d3..eb9df79c56 100644 --- a/packages/eas-cli/src/commands/build/configure.ts +++ b/packages/eas-cli/src/commands/build/configure.ts @@ -46,9 +46,7 @@ export default class BuildConfigure extends EasCommand { '๐Ÿ’ก The following process will configure your iOS and/or Android project to be compatible with EAS Build. These changes only apply to your local project files and you can safely revert them at any time.' ); - // BuildConfigure.ContextOptions.Vcs.client.getValueAsync() - - await vcsClient.ensureRepoExistsAsync(); + await vcsClient.ensureRepoExistsAsync({ nonInteractive: false }); const expoUpdatesIsInstalled = isExpoUpdatesInstalled(projectDir); diff --git a/packages/eas-cli/src/commands/build/dev.ts b/packages/eas-cli/src/commands/build/dev.ts index 7570168807..2cfe85f81a 100644 --- a/packages/eas-cli/src/commands/build/dev.ts +++ b/packages/eas-cli/src/commands/build/dev.ts @@ -74,8 +74,8 @@ export default class BuildDev extends EasCommand { Errors.error('Running iOS builds in simulator is only supported on macOS.', { exit: 1 }); } - await vcsClient.ensureRepoExistsAsync(); - await ensureRepoIsCleanAsync(vcsClient, flags.nonInteractive); + await vcsClient.ensureRepoExistsAsync({ nonInteractive: false }); + await ensureRepoIsCleanAsync(vcsClient, false); await ensureProjectConfiguredAsync({ projectDir, nonInteractive: false, diff --git a/packages/eas-cli/src/commands/build/inspect.ts b/packages/eas-cli/src/commands/build/inspect.ts index 472ce41a63..14d3cace0e 100644 --- a/packages/eas-cli/src/commands/build/inspect.ts +++ b/packages/eas-cli/src/commands/build/inspect.ts @@ -94,7 +94,7 @@ export default class BuildInspect extends EasCommand { await this.prepareOutputDirAsync(outputDirectory, flags.force); if (flags.stage === InspectStage.ARCHIVE) { - await vcsClient.ensureRepoExistsAsync(); + await vcsClient.ensureRepoExistsAsync({ nonInteractive: false }); await vcsClient.makeShallowCopyAsync(tmpWorkingdir); await this.copyToOutputDirAsync(tmpWorkingdir, outputDirectory); } else { diff --git a/packages/eas-cli/src/commands/update/configure.ts b/packages/eas-cli/src/commands/update/configure.ts index 8b86d4f036..90d13c2901 100644 --- a/packages/eas-cli/src/commands/update/configure.ts +++ b/packages/eas-cli/src/commands/update/configure.ts @@ -46,7 +46,7 @@ export default class UpdateConfigure extends EasCommand { '๐Ÿ’ก The following process will configure your project to use EAS Update. These changes only apply to your local project files and you can safely revert them at any time.' ); - await vcsClient.ensureRepoExistsAsync(); + await vcsClient.ensureRepoExistsAsync({ nonInteractive: flags['non-interactive'] }); const easJsonAccessor = EasJsonAccessor.fromProjectPath(projectDir); const easJsonCliConfig: EasJson['cli'] = diff --git a/packages/eas-cli/src/commands/update/index.ts b/packages/eas-cli/src/commands/update/index.ts index d3ba7a6697..282b712268 100644 --- a/packages/eas-cli/src/commands/update/index.ts +++ b/packages/eas-cli/src/commands/update/index.ts @@ -240,7 +240,7 @@ export default class UpdatePublish extends EasCommand { enableJsonOutput(); } - await vcsClient.ensureRepoExistsAsync(); + await vcsClient.ensureRepoExistsAsync({ nonInteractive }); await ensureRepoIsCleanAsync(vcsClient, nonInteractive); const { diff --git a/packages/eas-cli/src/vcs/clients/git.ts b/packages/eas-cli/src/vcs/clients/git.ts index ffb8140660..489a3130b0 100644 --- a/packages/eas-cli/src/vcs/clients/git.ts +++ b/packages/eas-cli/src/vcs/clients/git.ts @@ -31,7 +31,11 @@ export default class GitClient extends Client { this.requireCommit = options.requireCommit; } - public override async ensureRepoExistsAsync(): Promise { + public override async ensureRepoExistsAsync(options?: { + nonInteractive?: boolean; + }): Promise { + const nonInteractive = options?.nonInteractive ?? false; + try { if (!(await isGitInstalledAsync())) { Log.error( @@ -66,11 +70,23 @@ export default class GitClient extends Client { return; } + const cwd = process.cwd(); + const repoRoot = PackageManagerUtils.resolveWorkspaceRoot(cwd) ?? cwd; + + if (nonInteractive) { + Log.log(`Initializing git repository in ${this.maybeCwdOverride ?? repoRoot}...`); + await spawnAsync('git', ['init'], { cwd: this.maybeCwdOverride ?? repoRoot }); + await this.commitAsync({ + commitAllFiles: true, + commitMessage: 'Initial commit', + nonInteractive: true, + }); + return; + } + Log.warn("It looks like you haven't initialized the git repository yet."); Log.warn('EAS requires you to use a git repository for your project.'); - const cwd = process.cwd(); - const repoRoot = PackageManagerUtils.resolveWorkspaceRoot(cwd) ?? cwd; const confirmInit = await confirmAsync({ message: `Would you like us to run 'git init' in ${ this.maybeCwdOverride ?? repoRoot @@ -419,16 +435,22 @@ export default class GitClient extends Client { return; } - Log.warn( - `You need to configure Git with your ${[ - !usernameConfigured && 'username (user.name)', - !emailConfigured && 'email address (user.email)', + const missingConfig = [ + !usernameConfigured && 'username (user.name)', + !emailConfigured && 'email address (user.email)', + ].filter(i => i); + + Log.warn(`You need to configure Git with your ${missingConfig.join(' and ')}`); + if (nonInteractive) { + const configCommands = [ + !usernameConfigured && 'git config --global user.name "Your Name"', + !emailConfigured && 'git config --global user.email "your@email.com"', ] .filter(i => i) - .join(' and ')}` - ); - if (nonInteractive) { - throw new Error('Git cannot be configured automatically in non-interactive mode'); + .join(' && '); + throw new Error( + `Git ${missingConfig.join(' and ')} must be configured. Run: ${configCommands}` + ); } if (!usernameConfigured) { const { username } = await promptAsync({ diff --git a/packages/eas-cli/src/vcs/vcs.ts b/packages/eas-cli/src/vcs/vcs.ts index 189f777c7c..e7e0855c8f 100644 --- a/packages/eas-cli/src/vcs/vcs.ts +++ b/packages/eas-cli/src/vcs/vcs.ts @@ -14,7 +14,7 @@ export abstract class Client { // (optional) ensureRepoExistsAsync should verify whether repository exists and tooling is installed // it's not required for minimal support, but lack of validation might cause the failure at a later stage. - public async ensureRepoExistsAsync(): Promise {} + public async ensureRepoExistsAsync(_options?: { nonInteractive?: boolean }): Promise {} // (optional) checks whether commit is necessary before calling makeShallowCopyAsync // From f08392888d4d3aa99ee4aa463b22aac6e5bd0363 Mon Sep 17 00:00:00 2001 From: evanbacon Date: Sat, 7 Feb 2026 11:34:28 -0800 Subject: [PATCH 2/3] Update git.ts --- packages/eas-cli/src/vcs/clients/git.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/eas-cli/src/vcs/clients/git.ts b/packages/eas-cli/src/vcs/clients/git.ts index 489a3130b0..f25db75ec7 100644 --- a/packages/eas-cli/src/vcs/clients/git.ts +++ b/packages/eas-cli/src/vcs/clients/git.ts @@ -74,7 +74,10 @@ export default class GitClient extends Client { const repoRoot = PackageManagerUtils.resolveWorkspaceRoot(cwd) ?? cwd; if (nonInteractive) { - Log.log(`Initializing git repository in ${this.maybeCwdOverride ?? repoRoot}...`); + Log.log( + `No git repository found. Auto initializing in ${this.maybeCwdOverride ?? repoRoot}. ` + + `Set ${chalk.bold('EAS_NO_VCS=1')} to skip.` + ); await spawnAsync('git', ['init'], { cwd: this.maybeCwdOverride ?? repoRoot }); await this.commitAsync({ commitAllFiles: true, From e9088dbb933c0d8b20ad41474852dba7f71ab701 Mon Sep 17 00:00:00 2001 From: evanbacon Date: Sat, 7 Feb 2026 12:56:02 -0800 Subject: [PATCH 3/3] [eas-cli] Add changelog entry for non-interactive git fix --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08498a97ed..25cee42465 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ This is the log of notable changes to EAS CLI and related packages. - Hide progress bar in build credits warning when usage reaches 100%. ([#3371](https://github.com/expo/eas-cli/pull/3371) by [@mackenco](https://github.com/mackenco)) +### ๐Ÿ› Bug fixes + +- Fix `--non-interactive` mode prompting for git initialization. Now auto-initializes git with an initial commit when needed. Set `EAS_NO_VCS=1` to skip. ([#3387](https://github.com/expo/eas-cli/pull/3387) by [@evanbacon](https://github.com/evanbacon)) + ### ๐Ÿงน Chores - Upgrade `tar` to v7. ([#3327](https://github.com/expo/eas-cli/pull/3327) by [@KarolRzeminski](https://github.com/KarolRzeminski))