fix: sort object keys before JSON.stringify in transformProjectGraphForRust#35298
fix: sort object keys before JSON.stringify in transformProjectGraphForRust#35298omer-za wants to merge 1 commit intonrwl:masterfrom
Conversation
✅ Deploy Preview for nx-docs canceled.
|
✅ Deploy Preview for nx-dev canceled.
|
…orRust JSON.stringify() preserves JavaScript object key insertion order. The Rust native hasher receives these serialized strings and hashes them as-is for ProjectConfiguration. If any plugin or the target-defaults merge produces options/configurations objects with keys in a different insertion order on different CI runners, the serialized string changes, causing the ProjectConfiguration hash to become non-deterministic. This leads to Nx Cloud cache invalidation and unnecessary task re-execution when rerunning failed CI pipelines. The fix adds a recursive sortObjectKeys helper that normalizes key order before serialization, making the hash independent of JS object construction order. Fixes nrwl#35297
b2ef079 to
0a44149
Compare
|
View your CI Pipeline Execution ↗ for commit 0a44149
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
Nx Cloud is proposing a fix for your failed CI:
We applied a prettier formatting fix to packages/nx/src/native/transform-objects.ts to resolve the format:check failure. The configurations line introduced by the PR exceeded prettier's line length limit and needed to be wrapped across multiple lines. This change is purely cosmetic and does not affect the runtime behavior of the sortObjectKeys fix.
Tip
✅ We verified this fix by re-running nx-cloud record -- nx format:check.
diff --git a/packages/nx/src/native/transform-objects.ts b/packages/nx/src/native/transform-objects.ts
index c4164ea1..3f4e03af 100644
--- a/packages/nx/src/native/transform-objects.ts
+++ b/packages/nx/src/native/transform-objects.ts
@@ -36,7 +36,9 @@ export function transformProjectGraphForRust(
inputs: targetConfig.inputs,
outputs: targetConfig.outputs,
options: JSON.stringify(sortObjectKeys(targetConfig.options)),
- configurations: JSON.stringify(sortObjectKeys(targetConfig.configurations)),
+ configurations: JSON.stringify(
+ sortObjectKeys(targetConfig.configurations)
+ ),
parallelism: targetConfig.parallelism,
};
}
🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.
Because this branch comes from a fork, it is not possible for us to apply fixes directly, but you can apply the changes locally using the available options below.
Apply changes locally with:
npx nx-cloud apply-locally ois5-3knp
Apply fix locally with your editor ↗ View interactive diff ↗
🎓 Learn more about Self-Healing CI on nx.dev
Summary
Fixes #35297
JSON.stringify()preserves JavaScript object key insertion order. IntransformProjectGraphForRust, targetoptionsandconfigurationsare serialized withJSON.stringify()and passed to the Rust native hasher, which hashes them as-is forProjectConfiguration.If any Nx plugin or the target-defaults merge step produces these objects with keys in a different insertion order on different CI runners, the serialized string changes, causing the
ProjectConfigurationhash to become non-deterministic. This leads to:The Fix
Adds a recursive
sortObjectKeyshelper that normalizes key order before serialization, making theProjectConfigurationhash independent of JS object construction order.Note: The Rust hasher already sorts target names before hashing (making the hash independent of target insertion order), but it does not normalize the content of the stringified
options/configurations. This fix closes that gap.Evidence
Tested locally using the native
HashPlanner+TaskHasherAPIs:Without fix
{"cwd":"...","env":{...},"command":"jest","passWithNoTests":true}10839486168096120338{"passWithNoTests":true,"command":"jest","env":{...},"cwd":"..."}14689511571626992510With fix
Reversed ALL target orders AND ALL options/configurations key orders for ALL projects across the entire project graph:
ProjectConfigurationentries, 0 mismatchesRelated
This is analogous to the fix in commit
db31f30which sorted keys before hashing forAllExternalDependenciesviahashObject.