[rush] package using rig with sharding defined is required to define _phase:name:shard script, even if it doesn't have the phase
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 68/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 静か
- 技術スタック
- typescript
- 領域
- build-system, tooling
調査の方向性
Start in libraries/rush-lib/src/logic/operations/ShardedPhaseOperationPlugin.ts and compare its handling of the base phase script with the operation setup in PhasedOperationPlugin.ts. Review plugin registration in PhasedScriptAction.ts, then reproduce the rig-based sharding case; done means non-participating projects are skipped while projects defining the base phase still receive the missing shard-script error.
索引モデルが issue の本文から書いたものです。
説明
Summary
I'm working on converting our Rush monorepo to shard our various test related processes. One issue I have run into is that now that I have added sharding for the test phases into our shared rig configs, EVERY PACKAGE must have every shard phase's script defined or Rush throws The project 'X' does not define a '_phase:name:shard' command in the 'scripts' section of its package.json for each package that doesn't define it. Which means I need to add dummy shard phase scripts to all packages that don't even participate in the phase, which is less than ideal.
Repro steps
- In a Rush monorepo, put
sharding: { count: N }on a phase operation (e.g._phase:test) inside a rig'sconfig/rush-project.json. - Have two kinds of projects using that rig:
- Project A: defines both
_phase:testand_phase:test:shardin itspackage.jsonscripts. - Project B: defines neither — it simply doesn't participate in the test phase.
- Project A: defines both
- Run
rush test(or any phased command that includes_phase:testand selects both projects).
Expected result: Project A gets sharded. Project B's _phase:test op resolves to a no-op (same as it does today for a project that doesn't define a phase script), and sharding is skipped for it.
Actual result: Rush throws during operation graph construction:
The project '@kx/bulk-package-json-editor' does not define a
'_phase:test:shard' command in the 'scripts' section of its package.json
…even though @kx/bulk-package-json-editor also does not define _phase:test and would otherwise be treated as a no-op for that phase.
Details
This was generated by opus 4.7 with claude code, I don't know the details of the code but it seems accurate.
Root cause, tracing through rush-lib on main:
-
PhasedOperationPlugin(libraries/rush-lib/src/logic/operations/PhasedOperationPlugin.ts:44-48) creates an operation for every(phase, project)pair in the selection, regardless of whether the project defines a script for that phase. The "this project doesn't use this phase" decision is deferred to whichever runner plugin picks it up. -
Each operation's
settingsis pulled fromprojectConfigurations.get(project)?.operationSettingsByOperationName.get(name)(same file, line 63–65). Because settings originate from the rig'srush-project.json, they apply to every project using that rig — including projects that don't implement the phase at all. Sosettings.shardingis attached to those ops. -
Plugin registration order in
PhasedScriptAction.ts:417-421:new PhasedOperationPlugin().apply(hooks); new ShardedPhasedOperationPlugin().apply(hooks); new ShellOperationRunnerPlugin().apply(hooks);ShardedPhasedOperationPlugintaps intocreateOperationsbeforeShellOperationRunnerPlugindoes. -
The guard in
ShardedPhaseOperationPlugin.ts:59is:if (operationSettings?.sharding && !operation.runner) { ... }This appears to be trying to skip sharding for operations that have already been marked as no-ops — but because the sharding plugin runs before the shell plugin,
operation.runneris always stillundefinedat this point, even for projects that have no_phase:testscript and would be turned into aNullOperationRunnermoments later. -
The strict throw at
ShardedPhaseOperationPlugin.ts:148-152then fires, because the project doesn't define_phase:test:shard:const baseCommand: string | undefined = scripts?.[shardOperationName]; if (baseCommand === undefined) { throw new Error( `The project '${project.packageName}' does not define a '${phase.name}:shard' command in the 'scripts' section of its package.json` ); }Nothing checks whether the base phase script (
scripts[phase.name]) exists. If it had, we could cleanly distinguish "this project uses the phase but has no shard script" (keep throwing — that's a real config mistake) from "this project doesn't use the phase at all" (skip sharding, let ShellOperationRunnerPlugin NullOp it).
Suggested fix — either of:
-
(a) Skip sharding when the base phase script is not defined, in
ShardedPhaseOperationPlugin.ts:const { scripts } = project.packageJson; const phaseCommand = phase.shellCommand ?? scripts?.[phase.name]; if (phaseCommand === undefined) { continue; // no-op for this project; let ShellOperationRunnerPlugin handle it }Inserted before the current work at line 60. Preserves the strict error for projects that do define the base phase script but forgot the
:shardvariant. -
(b) Swap plugin registration order so
ShellOperationRunnerPluginruns first and the existing!operation.runnerguard actually does what it looks like it was intended to do. More invasive — likely has other ordering implications.
(a) is the minimal fix and preserves existing behaviour for correctly-configured projects.
Standard questions
Please answer these questions to help us investigate your issue more quickly:
| Question | Answer |
|---|---|
@microsoft/rush globally installed version? |
5.165.0 |
rushVersion from rush.json? |
5.165.0 |
pnpmVersion, npmVersion, or yarnVersion from rush.json? |
pnpm@10.24.0 |
(if pnpm) useWorkspaces from pnpm-config.json? |
true |
| Operating system? | Linux |
| Would you consider contributing a PR? | Yes |
Node.js version (node -v)? |
22.14.0 |
- 主要言語
- TypeScript
- スター
- 6.5k
- フォーク
- 708
- 平均マージ
- 5日 19時間
- マージ済み PR(30日)
- 48
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/rushstack のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
microsoft/rushstack の issue をすべて見る
似ている issue
-
blocklist removal
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
MetaMask/eth-phishing-detect#296544 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
pastelsky/bundlephobia#1122 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
category/development priority/P2 scope/file-operations scope/testing type/enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
Enatega Customer and Rider app: Add-ons price is not visible to customer after order is placed. オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100