fix: prevent race conditions by creating new objects for repository configurations#943
Conversation
…onfigurations Signed-off-by: Jan Bronicki <janbronicki@microsoft.com>
|
Just fyi, I am not a JS developer at all, so this code analysis and fix was aided by AI, therefore please approach this code with skepticism, but the actual problem we are facing when trying to use |
There was a problem hiding this comment.
Pull request overview
This PR fixes a race condition in lib/settings.js where concurrent processing of repositories via Promise.all could cause name and org to leak between repos due to mutation of the shared this.config.repository object. It also adds 'name' to ignorableFields in lib/plugins/repository.js to suppress spurious diffs in dry-run mode.
Changes:
lib/settings.js: ReplaceObject.assign(repoConfig, {...})withObject.assign({}, repoConfig, {...})in two places to create new objects instead of mutating shared configuration references.lib/plugins/repository.js: Add'name'to theignorableFieldsarray to hide it from dry-run diffs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| lib/settings.js | Fix race condition by creating new objects for repoConfig and suborgRepoConfig instead of mutating shared references. |
| lib/plugins/repository.js | Add 'name' to ignorableFields to suppress it from diff comparisons. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
Hi @decyjphr could you please take a look at this PR? |
Summary
Fixes a race condition where
repository.namecould leak between repos during concurrent processing, and preventsnamefrom appearing in dry-run diffs when not explicitly configured.Problem
Race condition:
Object.assign(repoConfig, {...})mutates the sharedthis.config.repositoryobject. WhenupdateRepos()processes multiple repos concurrently viaPromise.all, one repo's name can overwrite another's between async yields.Spurious diffs:
namealways appears in dry-run diffs because Safe-Settings injects it internally but it's not inignorableFields.Changes
lib/settings.js: UseObject.assign({}, repoConfig, {...})to create new objects instead of mutating shared referenceslib/plugins/repository.js: Add'name'toignorableFieldsto hide it from diffs unless explicitly configured for renamingTesting
All 112 unit tests pass.
Related to #944