Skip to content

Commit

Permalink
fix(lambda): save params before running sam command when --watch is s…
Browse files Browse the repository at this point in the history
…elected (#6089)

## Problem
When --watch flag is used, the sync process remains alive. The region
and stack_name info get written to config file only after the process
finishes. This means customer would not be able to see (or refresh) the
latest deployed resoures during the sync process.

## Solution
Write to samconfig.toml before running sam sync

---

<!--- REMINDER: Ensure that your PR meets the guidelines in
CONTRIBUTING.md -->

License: I confirm that my contribution is made under the terms of the
Apache 2.0 license.
  • Loading branch information
mbfreder authored Nov 27, 2024
1 parent 61d67f8 commit 3b45960
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 1 deletion.
8 changes: 7 additions & 1 deletion packages/core/src/shared/sam/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,15 @@ export async function runSamSync(args: SyncParams) {
}),
})

await runInTerminal(sam, 'sync')
// with '--watch' selected, the sync process will run in the background until the user manually kills it
// we need to save the stack and region to the samconfig file now, otherwise the user would not see latest deployed resoure during this sync process
const { paramsSource, stackName, region, projectRoot } = args
const shouldWriteSyncSamconfigGlobal = paramsSource !== ParamsSource.SamConfig && !!stackName && !!region
if (boundArgs.includes('--watch')) {
shouldWriteSyncSamconfigGlobal && (await writeSamconfigGlobal(projectRoot, stackName, region))
}

await runInTerminal(sam, 'sync')
shouldWriteSyncSamconfigGlobal && (await writeSamconfigGlobal(projectRoot, stackName, region))
}

Expand Down
85 changes: 85 additions & 0 deletions packages/core/src/test/shared/sam/sync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,91 @@ describe('SAM runSync', () => {
prompterTester.assertCallAll()
})

it('[entry: command palette] specify and save flag (with --watch) should save params before starting SAM process', async () => {
const prompterTester = PrompterTester.init()
.handleQuickPick('Select a SAM/CloudFormation Template', async (quickPick) => {
// Need sometime to wait for the template to search for template file
await quickPick.untilReady()
assert.strictEqual(quickPick.items[0].label, templateFile.fsPath)
quickPick.acceptItem(quickPick.items[0])
})
.handleQuickPick('Specify parameter source for sync', async (picker) => {
// Need time to check samconfig.toml file and generate options
await picker.untilReady()
assert.strictEqual(picker.items[0].label, 'Specify required parameters and save as defaults')
picker.acceptItem(picker.items[0])
})
.handleQuickPick('Select a region', (quickPick) => {
const select = quickPick.items.filter((i) => i.detail === 'us-west-2')[0]
quickPick.acceptItem(select || quickPick.items[0])
})
.handleQuickPick('Select a CloudFormation Stack', async (picker) => {
await picker.untilReady()
assert.strictEqual(picker.items[2].label, 'stack3')
picker.acceptItem(picker.items[2])
})
.handleQuickPick('Specify S3 bucket for deployment artifacts', async (picker) => {
await picker.untilReady()
assert.strictEqual(picker.items.length, 2)
assert.strictEqual(picker.items[0].label, 'Create a SAM CLI managed S3 bucket')
picker.acceptItem(picker.items[0])
})
.handleQuickPick('Specify parameters for sync', async (picker) => {
await picker.untilReady()
assert.strictEqual(picker.items.length, 9)
const dependencyLayer = picker.items.filter((item) => item.label === 'Dependency layer')[0]
const useContainer = picker.items.filter((item) => item.label === 'Use container')[0]
const watch = picker.items.filter((item) => item.label === 'Watch')[0]
picker.acceptItems(dependencyLayer, useContainer, watch)
})
.build()

// Invoke sync command from command palette
await runSync('code', undefined)

assert(mockGetSamCliPath.calledOnce)
assert(mockChildProcessClass.calledOnce)
assert.deepEqual(mockChildProcessClass.getCall(0).args, [
'sam-cli-path',
[
'sync',
'--code',
'--template',
`${templateFile.fsPath}`,
'--stack-name',
'stack3',
'--region',
'us-west-2',
'--no-dependency-layer',
'--save-params',
'--dependency-layer',
'--use-container',
'--watch',
],
{
spawnOptions: {
cwd: projectRoot?.fsPath,
env: {
AWS_TOOLING_USER_AGENT: 'AWS-Toolkit-For-VSCode/testPluginVersion',
SAM_CLI_TELEMETRY: '0',
},
},
},
])
assert(mockGetSpawnEnv.calledOnce)
assert(spyRunInterminal.calledOnce)
assert.deepEqual(spyRunInterminal.getCall(0).args, [mockSamSyncChildProcess, 'sync'])
assert.strictEqual(spyWriteSamconfigGlobal.callCount, 2)
assert(spyWriteSamconfigGlobal.calledBefore(spyRunInterminal))
// Check telementry
assertTelemetry('sam_sync', { result: 'Succeeded', source: undefined })
assertTelemetryCurried('sam_sync')({
syncedResources: 'CodeOnly',
source: undefined,
})
prompterTester.assertCallAll()
})

it('[entry: template file] specify flag should instantiate correct process in terminal', async () => {
const prompterTester = PrompterTester.init()
.handleQuickPick('Specify parameter source for sync', async (picker) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "appBuilder refresh feature doesnt work during sync --watch"
}

0 comments on commit 3b45960

Please sign in to comment.