feat(cli): watch command now starts with a deployment#18057
feat(cli): watch command now starts with a deployment#18057mergify[bot] merged 12 commits intoaws:masterfrom kaizencc:conroy/watchdeploy
Conversation
|
Don't think we need a readme for this one so I'm going to say |
packages/aws-cdk/lib/cdk-toolkit.ts
Outdated
| // trigger a dummy event here to make an intial deployment, | ||
| // the values sent into workflow are dummy values. | ||
| // intentionally not awaiting the result so that we can begin to watch and queue changes. | ||
| void workflow('add', 'initial'); |
There was a problem hiding this comment.
Hmmm. Forgetting this promise like this doesn't seem great to me. Wouldn't this trigger an "uncaught promise warning" if the initial deployment fails?
Can you try returning this promise from function, and see if that helps?
There was a problem hiding this comment.
I changed it to what I think you're asking for. My thoughts here are that it feels wrong to make the 'ready' callback async because during that time we would lose track of file changes -- is my instinct there correct?
There was a problem hiding this comment.
My thoughts here are that it feels wrong to make the 'ready' callback async because during that time we would lose track of file changes -- is my instinct there correct?
Can you check what the behavior is manually, and report back here? 🙂
There was a problem hiding this comment.
So here's what I found:
You can specify async callbacks, and typescript will not yell at you, but they will be ignored. see this issue. For example, even though the handleFileChangeEvent function is async, no one is actually waiting for the event to finish. Same goes for the callback at the 'ready' event.
As to any unhandled promise warning, I think we are in the clear. It seems related to how we are catching errors in invokeDeployFromWatch anyway -- we ignore them, and deploy will show them (as I have confirmed locally when using void handleFileChangeEvent()).
aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts
Lines 609 to 611 in 264d931
All that to say, I think we are fine with void handleFileChangeEvent() we are also fine with return handleFileChangeEvent(). In both cases, a failed deployment will show on screen as expected, with no unhandled promises.
We could even do await handleFileChangeEvent(). That would result in the same behavior.
There was a problem hiding this comment.
With that in mind I've changed the function to be async and we await handleFileChangeEvent(). But it is an inconsequential change. Can confirm that the behavior for this is as expected on my local computer -- I get the deployment failure or success message printed out. And watch is immediately listening for file changes (not waiting for first deployment to finish).
…/aws-cdk into conroy/watchdeploy
skinny85
left a comment
There was a problem hiding this comment.
Looks great @kaizen3031593! One tiny small change, and then is ready to be merged.
| latch = 'open'; | ||
| debug("'watch' received the 'ready' event. From now on, all file changes will trigger a deployment"); | ||
| }).on('all', async (event, filePath) => { | ||
|
|
There was a problem hiding this comment.
One thing I think we can improve here is that the extracted function is too big. We need only the deployment part (when latch is 'open'), but we extracted all of it, even the parts that we don't need. That's why we have the awkwardness with the filePath having to be undefined.
So, I think the way to go is something like this:
chokidar.watch(watchIncludes, {
ignored: watchExcludes,
cwd: rootDir,
// ignoreInitial: true,
}).on('ready', () => {
latch = 'open';
debug("'watch' received the 'ready' event. From now on, all file changes will trigger a deployment");
print("Triggering initial 'cdk deploy'");
await deployWhileObservingForFileChanges();
}).on('all', async (event, filePath) => {
if (latch === 'pre-ready') {
print(`'watch' is observing ${event === 'addDir' ? 'directory' : 'the file'} '%s' for changes`, filePath);
} else if (latch === 'open') {
print("Detected change to '%s' (type: %s). Triggering 'cdk deploy'", filePath, event);
await deployWhileObservingForFileChanges(); // this name TBD of course
} else { // this means latch is either 'deploying' or 'queued'
latch = 'queued';
print("Detected change to '%s' (type: %s) while 'cdk deploy' is still running. " +
'Will queue for another deployment after this one finishes', filePath, event);
}
});And deployWhileObservingForFileChanges is:
async function deployWhileObservingForFileChanges() {
latch = 'deploying';
await this.invokeDeployFromWatch(options);
// If latch is still 'deploying' after the 'await', that's fine,
// but if it's 'queued', that means we need to deploy again
while ((latch as 'deploying' | 'queued') === 'queued') {
// TypeScript doesn't realize latch can change between 'awaits',
// and thinks the above 'while' condition is always 'false' without the cast
latch = 'deploying';
print("Detected file changes during deployment. Invoking 'cdk deploy' again");
await this.invokeDeployFromWatch(options);
}
latch = 'open';
}There was a problem hiding this comment.
currently named depoyAndWatch, hopefully that is reasonable.
Co-authored-by: Adam Ruka <adamruka85@gmail.com>
…/aws-cdk into conroy/watchdeploy
skinny85
left a comment
There was a problem hiding this comment.
Looks perfect, thanks @kaizen3031593!
|
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
|
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
|
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Similar to `tsc -w`, `cdk watch` should trigger an initial deployment instead of waiting for a file change event. We achieve this by pulling out the callback function for `'all'` and calling that function during the `'ready'` callback. Closes aws#17776. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*

Similar to
tsc -w,cdk watchshould trigger an initial deployment insteadof waiting for a file change event. We achieve this by pulling out the callback
function for
'all'and calling that function during the'ready'callback.Closes #17776.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license