Compare commits

..
Author SHA1 Message Date
evanbacon e9088dbb93 [eas-cli] Add changelog entry for non-interactive git fix 2026-02-07 12:56:02 -08:00
evanbacon f08392888d Update git.ts 2026-02-07 11:34:28 -08:00
evanbacon fbcc04eb62 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.
2026-02-07 11:32:51 -08:00
12 changed files with 49 additions and 34 deletions

No files matched your search

+5 -2
View File
@@ -9,11 +9,13 @@ This is the log of notable changes to EAS CLI and related packages.
- Drop support for Node 18 and Node 19. Require Node 20+. ([#3343](https://github.com/expo/eas-cli/pull/3343) by [@sjchmiela](https://github.com/sjchmiela))
### 🎉 New features
- Add `--browser` flag to `eas login` for browser-based authentication. ([#3312](https://github.com/expo/eas-cli/pull/3312) by [@byronkarlen](https://github.com/byronkarlen))
- 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
- 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))
- 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
@@ -23,6 +25,7 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Add `--browser` flag to `eas login` for browser-based authentication. ([#3312](https://github.com/expo/eas-cli/pull/3312) by [@byronkarlen](https://github.com/byronkarlen))
- List available options in non-interactive mode errors instead of generic "unable to select" messages, making CLI usable by agents and scripts. ([#3359](https://github.com/expo/eas-cli/pull/3359) by [@EvanBacon](https://github.com/EvanBacon))
- Hidden beta version of new `eas account:usage` command for viewing account usage and billing estimates. ([#3334](https://github.com/expo/eas-cli/pull/3334) by [@douglowder](https://github.com/douglowder), [@EvanBacon](https://github.com/EvanBacon))
- Add `--no-bytecode` and `--source-maps [mode]` flags to `eas update`. ([#3339](https://github.com/expo/eas-cli/pull/3339) by [@brentvatne](https://github.com/brentvatne))
@@ -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({
@@ -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);
+2 -2
View File
@@ -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,
@@ -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 {
@@ -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'] =
@@ -240,7 +240,7 @@ export default class UpdatePublish extends EasCommand {
enableJsonOutput();
}
await vcsClient.ensureRepoExistsAsync();
await vcsClient.ensureRepoExistsAsync({ nonInteractive });
await ensureRepoIsCleanAsync(vcsClient, nonInteractive);
const {
+36 -11
View File
@@ -31,7 +31,11 @@ export default class GitClient extends Client {
this.requireCommit = options.requireCommit;
}
public override async ensureRepoExistsAsync(): Promise<void> {
public override async ensureRepoExistsAsync(options?: {
nonInteractive?: boolean;
}): Promise<void> {
const nonInteractive = options?.nonInteractive ?? false;
try {
if (!(await isGitInstalledAsync())) {
Log.error(
@@ -66,11 +70,26 @@ export default class GitClient extends Client {
return;
}
const cwd = process.cwd();
const repoRoot = PackageManagerUtils.resolveWorkspaceRoot(cwd) ?? cwd;
if (nonInteractive) {
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,
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 +438,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 "[email protected]"',
]
.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({
+1 -1
View File
@@ -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<void> {}
public async ensureRepoExistsAsync(_options?: { nonInteractive?: boolean }): Promise<void> {}
// (optional) checks whether commit is necessary before calling makeShallowCopyAsync
//
-1
View File
@@ -52,7 +52,6 @@
"semver": "7.6.3",
"tar": "7.5.7",
"uuid": "3.4.0",
"uuidv7": "1.1.0",
"ws": "8.18.0",
"xml2js": "0.6.2",
"zod": "4.1.8"
-5
View File
@@ -2,7 +2,6 @@ import { LogBuffer } from '@expo/build-tools';
import { EnvironmentSecret } from '@expo/eas-build-job';
import { LoggerLevel, createLogger } from '@expo/logger';
import { Transform, TransformCallback, Writable } from 'stream';
import { uuidv7 } from 'uuidv7';
import config from './config';
import { maybeStringBase64Decode, simpleSecretsWhitelist } from './secrets';
@@ -15,10 +14,6 @@ export interface BuildLogger extends CommonBuildLogger {
const defaultLogger = createLogger({
name: config.loggers.base.name,
level: LoggerLevel.INFO,
log_id: true,
serializers: {
log_id: () => uuidv7(),
},
});
const MAX_LINES_IN_BUFFER = 100;
Generated
-5
View File
@@ -17217,11 +17217,6 @@ uuid@^8.0.0, uuid@^8.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
[email protected]:
version "1.1.0"
resolved "https://registry.yarnpkg.com/uuidv7/-/uuidv7-1.1.0.tgz#6ef58df2dd7377083de1f70eec29cb66a0baf30c"
integrity sha512-2VNnOC0+XQlwogChUDzy6pe8GQEys9QFZBGOh54l6qVfwoCUwwRvk7rDTgaIsRgsF5GFa5oiNg8LqXE3jofBBg==
v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"