ac-lambda-deployment 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +66 -45
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -114,7 +114,7 @@ class LambdaDeployer {
114
114
 
115
115
  const params = {
116
116
  FunctionName: config.functionName,
117
- Runtime: config.runtime || 'nodejs18.x',
117
+ Runtime: config.runtime || 'nodejs22.x',
118
118
  Role: config.roleArn,
119
119
  Handler: config.handler || 'lambda.handler',
120
120
  Code: { ZipFile: zipBuffer },
@@ -129,26 +129,17 @@ class LambdaDeployer {
129
129
  return this.lambda.send(command)
130
130
  }
131
131
 
132
- // Update existing Lambda function code with retry
133
- async updateFunction(functionName, zipPath) {
134
- const zipBuffer = fs.readFileSync(zipPath)
135
-
136
- const params = {
137
- FunctionName: functionName,
138
- ZipFile: zipBuffer
139
- }
140
-
141
- const command = new UpdateFunctionCodeCommand(params)
142
-
143
- // Retry logic for concurrent updates
132
+ // Generic retry logic for any command
133
+ async updateWithRetry(command, updateType) {
144
134
  for (let i = 0; i < 3; i++) {
145
135
  try {
146
- return this.lambda.send(command)
136
+ return await this.lambda.send(command)
147
137
  }
148
138
  catch (err) {
149
139
  if (err.name === 'ResourceConflictException' && i < 2) {
150
- console.log(`Function is being updated, waiting 30 seconds... (attempt ${i + 1}/3)`)
151
- await new Promise(resolve => setTimeout(resolve, 30000))
140
+ const waitTime = (i + 1) * 30000
141
+ console.log(`Function ${updateType} is being updated, waiting ${waitTime/1000} seconds... (attempt ${i + 1}/3)`)
142
+ await new Promise(resolve => setTimeout(resolve, waitTime))
152
143
  continue
153
144
  }
154
145
  throw err
@@ -156,34 +147,68 @@ class LambdaDeployer {
156
147
  }
157
148
  }
158
149
 
159
- // Update function configuration (layers, environment, etc.) with retry
160
- async updateFunctionConfig(config) {
161
- const params = {
162
- FunctionName: config.functionName,
163
- Runtime: config.runtime,
164
- Handler: config.handler,
165
- Description: config.description,
166
- Timeout: config.timeout,
167
- MemorySize: config.memorySize,
168
- Environment: config.environment ? { Variables: config.environment } : undefined,
169
- Layers: config.layers || []
170
- }
171
-
172
- const command = new UpdateFunctionConfigurationCommand(params)
150
+ // Wait until function is in Active state and ready for next update
151
+ async waitForFunctionReady(functionName, maxWaitMs = 120000) {
152
+ const startTime = Date.now()
173
153
 
174
- // Retry logic for concurrent updates
175
- for (let i = 0; i < 3; i++) {
154
+ while (Date.now() - startTime < maxWaitMs) {
176
155
  try {
177
- return this.lambda.send(command)
156
+ const result = await this.lambda.send(new GetFunctionCommand({ FunctionName: functionName }))
157
+ const state = result.Configuration?.State
158
+ const lastUpdateStatus = result.Configuration?.LastUpdateStatus
159
+
160
+ if (state === 'Active' && lastUpdateStatus === 'Successful') {
161
+ return
162
+ }
163
+
164
+ if (lastUpdateStatus === 'Failed') {
165
+ throw new Error('Previous update failed')
166
+ }
178
167
  }
179
168
  catch (err) {
180
- if (err.name === 'ResourceConflictException' && i < 2) {
181
- console.log(`Function config is being updated, waiting 20 seconds... (attempt ${i + 1}/3)`)
182
- await new Promise(resolve => setTimeout(resolve, 20000))
183
- continue
169
+ if (err.message === 'Previous update failed') {
170
+ throw err
184
171
  }
185
- throw err
172
+ // Ignore other errors during polling
186
173
  }
174
+
175
+ await new Promise(resolve => setTimeout(resolve, 3000))
176
+ }
177
+
178
+ throw new Error('Timeout waiting for function to be ready')
179
+ }
180
+
181
+ // Update function code, then config sequentially
182
+ async updateFunctionSequential(functionName, zipPath, config) {
183
+ const zipBuffer = fs.readFileSync(zipPath)
184
+
185
+ // Step 1: Update code
186
+ console.log('Updating function code...')
187
+ const codeParams = {
188
+ FunctionName: functionName,
189
+ ZipFile: zipBuffer
190
+ }
191
+
192
+ await this.updateWithRetry(new UpdateFunctionCodeCommand(codeParams), 'code')
193
+
194
+ // Step 2: Wait for function to be ready, then update configuration
195
+ if (config.layers || config.environment || config.timeout || config.memorySize || config.description) {
196
+ console.log('Waiting for code update to complete...')
197
+ await this.waitForFunctionReady(functionName)
198
+
199
+ const configParams = {
200
+ FunctionName: functionName,
201
+ Runtime: config.runtime || 'nodejs18.x',
202
+ Handler: config.handler || 'lambda.handler',
203
+ Description: config.description,
204
+ Timeout: config.timeout || 30,
205
+ MemorySize: config.memorySize || 128,
206
+ Environment: config.environment ? { Variables: config.environment } : undefined,
207
+ Layers: config.layers || []
208
+ }
209
+
210
+ console.log('Updating function configuration...')
211
+ await this.updateWithRetry(new UpdateFunctionConfigurationCommand(configParams), 'configuration')
187
212
  }
188
213
  }
189
214
 
@@ -279,15 +304,11 @@ class LambdaDeployer {
279
304
 
280
305
  if (exists) {
281
306
  console.log('Updating existing function...')
282
- await this.updateFunction(functionName, zipPath)
283
307
 
284
- // Update function configuration (layers, environment, etc.)
285
- if (config.layers || config.environment || config.timeout || config.memorySize) {
286
- console.log('Updating function configuration...')
287
- await this.updateFunctionConfig(config)
288
- }
308
+ // Update function code and config sequentially
309
+ await this.updateFunctionSequential(functionName, zipPath, config)
289
310
 
290
- // Update SQS triggers
311
+ // Update SQS triggers (separate API)
291
312
  if (config.sqsTriggers) {
292
313
  console.log('Updating SQS triggers...')
293
314
  await this.updateEventSourceMappings(functionName, config.sqsTriggers)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ac-lambda-deployment",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Simple AWS Lambda deployment tool using AWS SDK v3",
5
5
  "main": "index.js",
6
6
  "bin": {