Attach deployment approvals to per-deployment copies of approval rules
What does this MR do and why?
Fixes a bug where the approval summaries of two deployments to protected environments can overwrite each other when their environments share a protected environment instance.
Preloaders::Environments::ProtectedEnvironmentPreloader, used by the environments index page and by GraphQL environments, gives every environment in the same deployment tier one shared group-level ProtectedEnvironment instance. Their associated_approval_rules are memoized on the environment, so those rules are shared Ruby objects too. Deployments::ApprovalSummary#rules attached each deployment's approvals directly to those shared rule objects, by setting rule.approvals_for_summary = .... When a second deployment's summary computed and attached its approvals, it overwrote the approvals the first summary had already attached to the same objects. Because ApprovalSummary memoizes its rules, the first summary then kept reporting the wrong pending approval count, status, and approvals list.
The fix makes each summary attach its approvals to a clone of the rule instead of the shared rule itself. Rails runs no hook on clone, so the copy shares the same attributes and id as the original, but only the approvals live on the per-summary copy, so summaries no longer overwrite each other.
This is also needed ahead of an upcoming change that shares environment instances across a whole page of pipeline jobs. Without this fix first, that change would trigger the same overwrite for every deployment shown on the page.
References
- Related to #629310
Screenshots or screen recordings
No UI change. This is a model-level fix to how approval data is attached in memory.
How to set up and validate locally
Run the spec:
bin/rspec ee/spec/models/deployments/approval_summary_spec.rbThe new context "when another deployment shares the environment instance and its rules" creates two deployments that share one environment instance and checks that reading one deployment's summary does not change the pending approval count reported by the other. Reverting only the change in approval_summary.rb makes it fail.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.