fix(site-secrets): mirror secrets before pushing artifact data connections to the DCL

Final review M2: HandleDeployArtifacts now sends ApplyArtifactDataConnectionsToDcl after the
shipped secrets are written and mirrored (from a finally, so the push still goes out if the
secrets step fails), so a connection created by the same deploy resolves a newly shipped
secret on first connect. Definitions are still stored at the same point; response semantics
unchanged.
This commit is contained in:
Joseph Doherty
2026-09-28 21:08:34 -04:00
parent 6f1787abe1
commit b1b49bb36c
2 changed files with 77 additions and 4 deletions
@@ -3231,6 +3231,13 @@ public class DeploymentManagerActor : ReceiveActor, IWithTimers
Task.Run(async () =>
{
// M2 (final review): the DCL push for this deploy's data connections is captured
// here and sent only AFTER the shipped secrets are written and mirrored (in the
// finally below), so a connection whose config references a secret this same deploy
// ships resolves it on its FIRST connect instead of failing "not found" and waiting
// out the reconnect interval. The definitions are still stored in SQLite at the same
// point as before, and the push still goes out if the secrets step throws.
ApplyArtifactDataConnectionsToDcl? pendingDclApply = null;
try
{
// Each non-null artifact list is the COMPLETE system-wide set
@@ -3328,8 +3335,9 @@ public class DeploymentManagerActor : ReceiveActor, IWithTimers
// artifact bundle. Reconciled removals ride the same
// message so the live DCL connection actor is stopped
// on the actor thread alongside the hash-cache eviction.
self.Tell(new ApplyArtifactDataConnectionsToDcl(
command.DataConnections, removedConnections));
// Sent after the secrets step — see pendingDclApply above (M2).
pendingDclApply = new ApplyArtifactDataConnectionsToDcl(
command.DataConnections, removedConnections);
}
// SMTP configuration is
@@ -3417,6 +3425,15 @@ public class DeploymentManagerActor : ReceiveActor, IWithTimers
return new ArtifactDeploymentResponse(
command.DeploymentId, "", false, ex.Message, DateTimeOffset.UtcNow);
}
finally
{
// Runs before the Task completes, so the DCL push is still enqueued ahead of the
// PipeTo reply, as it was before the reorder.
if (pendingDclApply != null)
{
self.Tell(pendingDclApply);
}
}
}).PipeTo(sender);
}