fix(toolkit-lib): every change-set deployment announces "waiting in review for manual execution (--no-execute)" although the change set is executed - #1818
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1818 +/- ##
=======================================
Coverage 90.32% 90.32%
=======================================
Files 80 80
Lines 12124 12124
Branches 1716 1716
=======================================
Hits 10951 10951
Misses 1139 1139
Partials 34 34
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Head branch was pushed to by a user without write access
bd16b7b to
844a87a
Compare
…ution (--no-execute)" although the change set is executed
844a87a to
e2c6083
Compare
…-stack behind an internal option instead of in the callers
9pace
left a comment
There was a problem hiding this comment.
Thanks for the contribution! You have correctly identified an issue here.
on announceNoExecuteChangeSet:
-
PrepareStackOptionsextendsOmit<DeployStackOptions, 'deploymentMethod'>, so it inheritsannounceNoExecuteChangeSet, butprepareStack()overwrites it after the spread with!options.cleanupOnNoOp. A caller-supplied value is ignored. -
cleanupOnNoOpandannounceNoExecuteChangeSetare two booleans derived from one underlying fact: whether the change set is the user's final artifact (--no-execute) or the first phase of a deployment that will execute it. The proposed change (Syncing them with an inversion at one call site) invites drift, and the announce flag is named for the message it controls rather than the intent behind it.
Suggestion: Rename cleanupOnNoOp to something intent-revealing (e.g. willExecuteChangeSet) and derive both behaviors (empty-change-set cleanup and announcement suppression) from it.
| // prepare is the internal first phase of an executing deployment | ||
| // (cleanupOnNoOp), the change set is about to be executed and the | ||
| // announcement would be misleading. | ||
| announceNoExecuteChangeSet: !options.cleanupOnNoOp, |
There was a problem hiding this comment.
If caller passed announceNoExecuteChangeSet here it would be ignored. Effectively the options.announceNoExecuteChangeSet is unused.
…m a single intent flag (willExecuteChangeSet)
|
Thanks for the review! Applied in d4e3f5f: renamed |
Fixes #1815
Problem
Since #1273, the deploy action always creates the change set upfront (to get an accurate diff for the approval prompt) by calling
Deployments.prepareStack(), which internally forcesexecute: false, and then executes the prepared change set in a second phase.deploy-stack.tsprintswhenever
executeisfalse, so every change-set deployment with actual changes now prints this message and then executes the change set anyway. The message is misleading:--no-executewas never requested, and the change set does not wait for anything. This also surfaces in flows that deploy internally, e.g. the finalizing deployment aftercdk import.Fix
deploy-stack.tscannot know whetherexecute: falseis user-requested or the internal first phase of an executing deployment, so the caller now tells it, via a single intent-revealing option:willExecuteChangeSet(defaultfalse: the change set is the user's final artifact). Both behaviors that depend on this intent are derived from the one flag:deploy-stack.tsannounces a created-but-not-executed change set as waiting for manual execution only whenwillExecuteChangeSetis not set (this is the fix);Deployments.prepareStack()cleans up an empty change set only whenwillExecuteChangeSetis set (this replaces the formercleanupOnNoOpoption, which encoded the same fact under a behavior-specific name).The deploy flows (the toolkit deploy action and the CLI's deploy flow, which share
prepareStack) passwillExecuteChangeSet: isExecutingChangeSetDeployment(deploymentMethod);prepareStackpasses the flag through todeployStackunchanged. The default preserves today's behavior for every other caller, includingcdk import --no-execute, which keeps its announcement without any change to the importer.The option lives on the internal
DeployStackOptionsinterfaces (api/deploymentsis not part of the toolkit-lib public API), so there is no public API change.Alternative considered
An alternative implementation was initially committed (e2c6083): removing the announcement from
deploy-stack.tsentirely and emitting it from the callers that know the user's intent (prepareStackand the resource importer). Its appeal is that it structurally removesdeploy-stack's ability to assert a user intent it cannot know.It was replaced with the current approach because:
cdk import --no-executekeeps its announcement via the default, instead of re-implementing it);deployStackwithexecute: false.Both directions are kept in the branch history.
Testing
test/api/deployments/deploy-stack.test.ts: withexecute: false, the change set is announced as awaiting manual execution by default, and not announced withwillExecuteChangeSet: true.test/api/deployments/cloudformation-deployments.test.ts:prepareStackpasseswillExecuteChangeSetthrough todeployStackunchanged (set for the internal prepare of an executing deployment, unset for a user-requested--no-executeprepare).cdk deploywith changes prints the misleading message and then executes the change set.cdk deploy --method=prepare-change-setstill prints the message and leaves the change set unexecuted (stackUPDATE_COMPLETEand unchanged, change setCREATE_COMPLETE/AVAILABLE).By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license