Skip to content

fix(deps): update dependency execa to v10 - #10320

Closed
metamask-ci[bot] wants to merge 1 commit into
mainfrom
renovate/execa-10.x
Closed

metamask-ci[bot] wants to merge 1 commit into
mainfrom
renovate/execa-10.x

Conversation

@metamask-ci

@metamask-ci metamask-ci Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
execa ^5.0.0 → ^10.0.1 age confidence

Release Notes

sindresorhus/execa (execa)

v10.0.1

Compare Source

  • Fix preferLocal argument escaping edge-case on Windows (#​1259) e771733

v10.0.0

Compare Source

Breaking
const subprocess = execa('node', ['file.js']);
- subprocess.on('spawn', onSpawn);
+ subprocess.nodeChildProcess.on('spawn', onSpawn);
- await execaCommand('npm run build');
+ await execa`npm run build`;

- await execaCommand(commandString);
+ await execa`${parseCommandString(commandString)}`;
- await execa('node', ['file.js'], {stdio: ['pipe', 'pipe', 'pipe', 'ipc']});
+ await execa('node', ['file.js'], {ipc: true});
  • When the input or inputFile option is combined with an inherited stdin (for example stdio: 'inherit'), the explicit input is now used, instead of being ignored. To combine multiple inputs, pass an array like stdin: ['inherit', {string: 'input'}]. (#​1232) 3ed0544
Improvements
await execa('npm', ['run', 'build'], {killDescendants: true, timeout: 5000});
await execa`npm run build`
	.readableStream()
	.pipeTo(writableWebStream);
for await (const line of execa`npm run build`.pipe`sort`) {
	console.log(line);
}
const subprocess = execa({stdio: ['pipe', 'pipe', 'pipe', {value: 'pipe', input: true}]})`npm run scaffold`;

const writable = subprocess.writable({to: 'fd3'});
Fixes

v9.6.1

Compare Source


v9.6.0

Compare Source


v9.5.3

Compare Source


v9.5.2

Compare Source

Bug fixes

v9.5.1

Compare Source

Bug fixes

v9.5.0

Compare Source

Features
await execa({stdout: {file: 'output.txt', append: true}})`npm run build`;

v9.4.1

Compare Source

Bug fixes

v9.4.0

Compare Source

Features
  • We've created a separate package called nano-spawn. It is similar to Execa but with fewer features, for a much smaller package size. More info.
Bug fixes
Documentation

v9.3.1

Compare Source

Thanks @​holic and @​jimhigson for your contributions!

Bugs
Bugs (types)
  • Fix type of the env option. It was currently failing for Remix or Next.js users. (by @​holic) (#​1141)
Documentation

v9.3.0

Compare Source

Features

v9.2.0

Compare Source

This release includes a new set of methods to exchange messages between the current process and a Node.js subprocess, also known as "IPC". This allows passing and returning almost any message type to/from a Node.js subprocess. Also, debugging IPC is now much easier.

Moreover, a new gracefulCancel option has also been added to terminate a subprocess gracefully.

For a deeper dive-in, please check and share the release post!

Thanks @​iiroj for your contribution, @​SimonSiefke and @​adymorz for reporting the bugs fixed in this release, and @​karlhorky for improving the documentation!

Deprecations
  • Passing 'ipc' to the stdio option has been deprecated. It will be removed in the next major release. Instead, the ipc: true option should be used. (#​1056)
- await execa('npm', ['run', 'build'], {stdio: ['pipe', 'pipe', 'pipe', 'ipc']});
+ await execa('npm', ['run', 'build'], {ipc: true});
- import {execaCommand} from 'execa';
+ import {execa} from 'execa';

- await execaCommand('npm run build');
+ await execa`npm run build`;

const taskName = 'build';
- await execaCommand(`npm run ${taskName}`);
+ await execa`npm run ${taskName}`;

const commandArguments = ['run', 'task with space'];
await execa`npm ${commandArguments}`;

If the file and/or multiple arguments are supplied as a single string, parseCommandString(command) can split that string into an array. More info. (#​1054)

- import {execaCommand} from 'execa';
+ import {execa, parseCommandString} from 'execa';

const commandString = 'npm run task';
- await execaCommand(commandString);
+ const commandArray = parseCommandString(commandString); // ['npm', 'run', 'task']
+ await execa`${commandArray}`;

// Or alternatively:
const [file, ...commandArguments] = commandArray;
await execa(file, commandArguments);
Features
Types
Bug fixes

v9.1.0

Compare Source

Features (types)

v9.0.2

Compare Source

Bug fixes (types)

v9.0.1

Compare Source

Bug fixes (types)

v9.0.0

Compare Source

This major release brings many important features including:

Please check the release post for a high-level overview! For the full list of breaking changes, features and bug fixes, please read below.

Thanks @​younggglcy, @​koshic, @​am0o0 and @​codesmith-emmy for your help!


One of the maintainers @​ehmicky is looking for a remote full-time position. Specialized in Node.js back-ends and CLIs, he led Netlify Build, Plugins and Configuration for 2.5 years. Feel free to contact him on his website or on LinkedIn!


Breaking changes (not types)
const {stdout} = await execa('node', ['file.js'], {encoding: 'buffer'});
console.log(stdout); // This is now an Uint8Array
- await execa('node', ['file.js'], {encoding: null});
+ await execa('node', ['file.js'], {encoding: 'buffer'});

- await execa('node', ['file.js'], {encoding: 'utf-8'});
+ await execa('node', ['file.js'], {encoding: 'utf8'});

- await execa('node', ['file.js'], {encoding: 'UTF8'});
+ await execa('node', ['file.js'], {encoding: 'utf8'});

- await execa('node', ['file.js'], {encoding: 'utf-16le'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'ucs2'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'ucs-2'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'binary'});
+ await execa('node', ['file.js'], {encoding: 'latin1'});
  • Passing a file path to subprocess.pipeStdout(), subprocess.pipeStderr() and subprocess.pipeAll() has been removed. Instead, a {file: './path'} object should be passed to the stdout or stderr option. (#​752)
- await execa('node', ['file.js']).pipeStdout('output.txt');
+ await execa('node', ['file.js'], {stdout: {file: 'output.txt'}});

- await execa('node', ['file.js']).pipeStderr('output.txt');
+ await execa('node', ['file.js'], {stderr: {file: 'output.txt'}});

- await execa('node', ['file.js']).pipeAll('output.txt');
+ await execa('node', ['file.js'], {
+	stdout: {file: 'output.txt'},
+	stderr: {file: 'output.txt'},
+});
- await execa('node', ['file.js']).pipeStdout(stream);
+ await execa('node', ['file.js'], {stdout: ['pipe', stream]});

- await execa('node', ['file.js']).pipeStderr(stream);
+ await execa('node', ['file.js'], {stderr: ['pipe', stream]});

- await execa('node', ['file.js']).pipeAll(stream);
+ await execa('node', ['file.js'], {
+	stdout: ['pipe', stream],
+	stderr: ['pipe', stream],
+});
  • The subprocess.pipeStdout(), subprocess.pipeStderr() and subprocess.pipeAll() methods have been renamed to subprocess.pipe(). The command and its arguments can be passed to subprocess.pipe() directly, without calling execa() a second time. The from piping option can specify 'stdout' (the default value), 'stderr' or 'all'. (#​757)
- await execa('node', ['file.js']).pipeStdout(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js']);

- await execa('node', ['file.js']).pipeStderr(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js'], {from: 'stderr'});

- await execa('node', ['file.js']).pipeAll(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js'], {from: 'all'});
- await execa('node', ['file.js'], {signal: abortController.signal});
+ await execa('node', ['file.js'], {cancelSignal: abortController.signal});
try {
	await execa('node', ['file.js']);
} catch (error) {
- if (error.killed) {
+ if (error.isTerminated) {
		// ...
	}
}
- subprocess.cancel();
+ subprocess.kill();
- const subprocess = execa('node', ['file.js']);
- subprocess.kill('SIGTERM', {forceKillAfterTimeout: 1000});
+ const subprocess = execa('node', ['file.js'], {forceKillAfterDelay: 1000});
+ subprocess.kill('SIGTERM');
  • The verbose option is now a string enum instead of a boolean. false has been renamed to 'none' and true has been renamed to 'short'. (#​884)
- await execa('node', ['file.js'], {verbose: false});
+ await execa('node', ['file.js'], {verbose: 'none'});

- await execa('node', ['file.js'], {verbose: true});
+ await execa('node', ['file.js'], {verbose: 'short'});
- await execa('node', ['file.js'], {execPath: './path/to/node'});
+ await execa('node', ['file.js'], {nodePath: './path/to/node'});
- subprocess.send({example: true, getExample() {}});
+ subprocess.send({example: true});
const subprocess = execa('node', ['file.js']);
- setTimeout(() => {
	subprocess.stdout.pipe(process.stdout);
- }, 0);
- const subprocess = execa('node', ['file.js'], {killSignal: 'sigterm'});
+ const subprocess = execa('node', ['file.js'], {killSignal: 'SIGTERM'});

- subprocess.kill('sigterm');
+ subprocess.kill('SIGTERM');
Features
Execution
Text lines
Piping multiple subprocesses
Input/output
Streams
Verbose mode
Debugging
Errors
Termination
Node.js files
Synchronous execution
Inter-process communication
Input validation
Bug fixes

❗ Important

✂ PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate CLI.

@metamask-ci
metamask-ci Bot requested a review from a team as a code owner September 21, 2026 15:14
@metamask-ci
metamask-ci Bot deployed to default-branch September 21, 2026 15:14 Active
@socket-security

socket-security Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedexeca@​10.0.19810010086100

View full report

@socket-security

socket-security Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Warning

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Action Severity Alert  (click "▶" to expand/collapse)
Warn Low
Environment variable access: npm which-command reads PATH

Env Vars: PATH

Location: Package overview

From: package.json → npm/execa@10.0.1 → npm/which-command@0.1.0

ℹ Read more on: This package | This alert | What is environment variable access?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should be clear about which environment variables they access, and care should be taken to ensure they only access environment variables they claim to.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/which-command@0.1.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Environment variable access: npm which-command reads Path

Env Vars: Path

Location: Package overview

From: package.json → npm/execa@10.0.1 → npm/which-command@0.1.0

ℹ Read more on: This package | This alert | What is environment variable access?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should be clear about which environment variables they access, and care should be taken to ensure they only access environment variables they claim to.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/which-command@0.1.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Environment variable access: npm which-command reads PATHEXT

Env Vars: PATHEXT

Location: Package overview

From: package.json → npm/execa@10.0.1 → npm/which-command@0.1.0

ℹ Read more on: This package | This alert | What is environment variable access?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should be clear about which environment variables they access, and care should be taken to ensure they only access environment variables they claim to.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/which-command@0.1.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@metamask-ci
metamask-ci Bot force-pushed the renovate/execa-10.x branch from e6922dc to 01e5b27 Compare September 21, 2026 15:16
pull Bot pushed a commit to Reality2byte/core that referenced this pull request Sep 21, 2026
## Explanation

Renovate pull requests reach this workflow but the job skips. The gate
matches `dependabot[bot]`, and Renovate pull requests are authored by
`metamask-ci[bot]`, the identity of the token it runs with. Confirmed on
the first batch: the workflow triggered on `renovate/execa-10.x`,
`renovate/unzipper-0.x-lockfile` and `renovate/tstyche-7.x-lockfile` and
skipped all three, while MetaMask#10320 sits red on `Check changelog`.

So the gate also matches a `renovate/` branch prefix now. Everything
else about the job already applies: Renovate leaves the same changelog
gap, and `yarn dedupe` and the constraints fixer are harmless no ops
when there is nothing to repair.

The file name and `environment: dependabot` are both left alone on
purpose, and now carry a comment saying why. The token exchange policy
keys on the `environment` claim and globs on the workflow path, so
renaming either one breaks the token request before the job starts.

One behaviour worth noting: Renovate's default `rebaseWhen: auto` stops
updating a branch once someone else pushes to it, so the repairs will
not be clobbered the way Dependabot clobbers them.

## References

Follows MetaMask#10317. Part of WPC-1161.

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> The workflow can push commits to dependency-update branches using
elevated token permissions, but behavior matches the existing Dependabot
path with a narrower trigger.
> 
> **Overview**
> Extends the existing **repair constraints, lockfile and changelogs**
workflow so it runs on **Renovate** PRs, not only Dependabot. The job
gate now also matches branches whose head ref starts with `renovate/`,
because Renovate PRs are opened by `metamask-ci[bot]` rather than
`dependabot[bot]`.
> 
> Repair commits are authored as **`github-actions[bot]`** instead of
`metamask-ci[bot]`, so Renovate’s auto-rebase stops overwriting the
fixes after an “external” commit. The workflow display name is
generalized; the file path and `environment: dependabot` are unchanged
so OIDC token exchange keeps working.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
bcbce01. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
pull Bot pushed a commit to Reality2byte/core that referenced this pull request Sep 21, 2026
## Explanation

By default Renovate leaves a manifest alone when the new version already
satisfies the declared range, so MetaMask#10318 bumped `ts-jest` to 29.4.12 in
`yarn.lock` and touched no `package.json` at all. That keeps the
declared minimum at the old version and produces no changelog entry,
since nothing published changed.

We want a changelog entry for every dependency bump, so `rangeStrategy:
bump` moves the range with the release: `^29.4.11` becomes `^29.4.12`
across every workspace that declares it, the same as Dependabot does
today. Out of range updates like MetaMask#10320 already behaved this way.

`peerDependencies` are exempted back to `widen`. An explicit
`rangeStrategy` overrides Renovate's peer handling
([`npm/range.ts`](https://github.com/renovatebot/renovate/blob/main/lib/modules/manager/npm/range.ts)),
and 11 peer entries here have simple ranges that would be narrowed
rather than broadened, `@babel/runtime ^7.0.0` most obviously. The other
11 are complex ranges like `^16.8.0 || ^17.0.0` and widen regardless.

The cost is diff size. A single patch now rewrites the same line in
every manifest that declares the dependency, and each of those packages
needs an entry. MetaMask#10322 is what writes them.

> [!IMPORTANT]
> Depends on MetaMask#10322. Without it the repair workflow still skips Renovate
pull requests, and every one of them lands red on `Check changelog`.

## References

Depends on MetaMask#10322. Follows MetaMask#10317. Part of WPC-1161.

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Tooling-only change to Renovate; it does not alter runtime code, but
it will enlarge dependency PR diffs across workspaces.
> 
> **Overview**
> Renovate is configured to **raise semver ranges in `package.json`**
when a newer release still satisfies the existing constraint
(`rangeStrategy: bump`), matching Dependabot behavior so lockfile-only
bumps no longer skip manifest updates and downstream changelog tooling
can see a published change.
> 
> A **peer-only override** sets `rangeStrategy: widen` for
`peerDependencies`, undoing the global bump so wide peer ranges stay
broadened instead of tightened.
> 
> **Note:** This is meant to work with the changelog repair workflow in
MetaMask#10322; without that, Renovate PRs may fail `Check changelog`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
9ab221a. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant