@go-to-k/cdkd 0.264.1 → 0.264.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.
- package/dist/{asg-provider-ByH521ze.js → asg-provider-Bxida3ei.js} +2 -2
- package/dist/{asg-provider-ByH521ze.js.map → asg-provider-Bxida3ei.js.map} +1 -1
- package/dist/cli.js +3 -3
- package/dist/{deploy-engine-DNLQYYBx.js → deploy-engine-CaquB01e.js} +76 -13
- package/dist/{deploy-engine-DNLQYYBx.js.map → deploy-engine-CaquB01e.js.map} +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -11260,7 +11260,7 @@ var CloudControlProvider = class {
|
|
|
11260
11260
|
this.logger.debug(`Deleting resource ${logicalId} (${resourceType}), physical ID: ${physicalId}`);
|
|
11261
11261
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
11262
11262
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
11263
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
11263
|
+
const { ASGProvider } = await import("./asg-provider-Bxida3ei.js").then((n) => n.n);
|
|
11264
11264
|
await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
11265
11265
|
return;
|
|
11266
11266
|
}
|
|
@@ -16395,6 +16395,53 @@ function isRetryableTransientError(error, message) {
|
|
|
16395
16395
|
if (isThrottlingError(error)) return true;
|
|
16396
16396
|
return RETRYABLE_ERROR_MESSAGE_PATTERNS.some((p) => message.includes(p));
|
|
16397
16397
|
}
|
|
16398
|
+
/**
|
|
16399
|
+
* Match the "already exists" name-collision signature raised when a create
|
|
16400
|
+
* targets a physical name still held by another resource (or by the same
|
|
16401
|
+
* name's not-yet-released tombstone after an async delete).
|
|
16402
|
+
*
|
|
16403
|
+
* Deliberately NOT part of {@link RETRYABLE_ERROR_MESSAGE_PATTERNS}: a name
|
|
16404
|
+
* collision is only worth retrying at the specific re-create sites that just
|
|
16405
|
+
* deleted the old holder (the deploy engine's --replace delete-first fallback
|
|
16406
|
+
* and the rollback executor's reverse-replacement) — everywhere else it is a
|
|
16407
|
+
* genuine conflict that must fail fast. Shared by those sites' collision
|
|
16408
|
+
* detection + retry filters so a signature extension lands in one place.
|
|
16409
|
+
*/
|
|
16410
|
+
function isNameCollisionError(message) {
|
|
16411
|
+
return /already exists/i.test(message) || message.includes("AlreadyExists");
|
|
16412
|
+
}
|
|
16413
|
+
/**
|
|
16414
|
+
* Match the SQS same-name re-creation cooldown: after `DeleteQueue`, creating
|
|
16415
|
+
* a queue with the SAME name inside ~60s fails with
|
|
16416
|
+
* `AWS.SimpleQueueService.QueueDeletedRecently` ("You must wait 60 seconds
|
|
16417
|
+
* after deleting a queue before you can create another with the same name").
|
|
16418
|
+
*
|
|
16419
|
+
* The generic transient table above already carries 'wait 60 seconds' for
|
|
16420
|
+
* plain CREATEs (rapid destroy → redeploy loops), but the delete-then-re-create
|
|
16421
|
+
* sites (the deploy engine's --replace delete-first fallback and the rollback
|
|
16422
|
+
* executor's reverse-replacement) override the retry filter with
|
|
16423
|
+
* {@link isNameCollisionError}, which this signature does NOT match — so a
|
|
16424
|
+
* replacement revert used to fail fast mid-flight with the resource absent
|
|
16425
|
+
* from both AWS and state (issue #1206). Those sites now OR this matcher into
|
|
16426
|
+
* their retry filter, with a schedule long enough to cover the 60s window.
|
|
16427
|
+
*
|
|
16428
|
+
* Kept separate from {@link isNameCollisionError} on purpose: a cooldown at a
|
|
16429
|
+
* create-first site must NOT be treated as a collision (deleting the new
|
|
16430
|
+
* resource would not release the cooldown on the old name).
|
|
16431
|
+
*/
|
|
16432
|
+
function isNameCooldownError(message) {
|
|
16433
|
+
return message.includes("QueueDeletedRecently") || message.includes("wait 60 seconds");
|
|
16434
|
+
}
|
|
16435
|
+
/**
|
|
16436
|
+
* Retry filter for the delete-then-re-create sites: the old name holder was
|
|
16437
|
+
* just deleted, so both the late name release ("already exists" from an async
|
|
16438
|
+
* delete) and the SQS 60s name cooldown are worth waiting out. Pair with a
|
|
16439
|
+
* schedule that covers the full cooldown window (maxRetries 8, delays
|
|
16440
|
+
* 2s/4s/8s then capped at 10s ≈ 64s total sleep).
|
|
16441
|
+
*/
|
|
16442
|
+
function isRecreateRetryableError(message) {
|
|
16443
|
+
return isNameCollisionError(message) || isNameCooldownError(message);
|
|
16444
|
+
}
|
|
16398
16445
|
|
|
16399
16446
|
//#endregion
|
|
16400
16447
|
//#region src/deployment/retry.ts
|
|
@@ -16514,6 +16561,17 @@ async function withResourceDeadline(operation, opts) {
|
|
|
16514
16561
|
//#endregion
|
|
16515
16562
|
//#region src/deployment/rollback-executor.ts
|
|
16516
16563
|
/**
|
|
16564
|
+
* Retry schedule for a re-create that must wait out a name-release delay:
|
|
16565
|
+
* an async delete's late name release ("already exists") or the SQS 60s
|
|
16566
|
+
* same-name cooldown (issue #1206). 2s/4s/8s then capped at 10s over 8
|
|
16567
|
+
* retries ≈ 64s of total sleep — enough to cover the full cooldown window.
|
|
16568
|
+
*/
|
|
16569
|
+
const RECREATE_RETRY_SCHEDULE = {
|
|
16570
|
+
maxRetries: 8,
|
|
16571
|
+
initialDelayMs: 2e3,
|
|
16572
|
+
maxDelayMs: 1e4
|
|
16573
|
+
};
|
|
16574
|
+
/**
|
|
16517
16575
|
* True when the op recorded a replacement (old physical id differs from the
|
|
16518
16576
|
* new one). The old physical resource is already gone / orphaned, so an
|
|
16519
16577
|
* in-place revert is best-effort — the plan labels these explicitly.
|
|
@@ -16783,10 +16841,17 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
|
|
|
16783
16841
|
let deletedNewFirst = false;
|
|
16784
16842
|
let createResult;
|
|
16785
16843
|
try {
|
|
16786
|
-
createResult = await createProvider.create(op.logicalId, op.resourceType, { ...prev.properties })
|
|
16844
|
+
createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }), op.logicalId, {
|
|
16845
|
+
...RECREATE_RETRY_SCHEDULE,
|
|
16846
|
+
logger,
|
|
16847
|
+
...isInterrupted && {
|
|
16848
|
+
isInterrupted,
|
|
16849
|
+
onInterrupted: () => /* @__PURE__ */ new Error("Rollback interrupted while waiting out the name cooldown")
|
|
16850
|
+
},
|
|
16851
|
+
isRetryable: isNameCooldownError
|
|
16852
|
+
});
|
|
16787
16853
|
} catch (createError) {
|
|
16788
|
-
|
|
16789
|
-
if (!(/already exists/i.test(msg) || msg.includes("AlreadyExists"))) throw createError;
|
|
16854
|
+
if (!isNameCollisionError(createError instanceof Error ? createError.message : String(createError))) throw createError;
|
|
16790
16855
|
logger.info(` Rollback: re-create collided with the new resource's name — deleting the new resource (${current.physicalId}) first...`);
|
|
16791
16856
|
await newDeleteProvider.delete(op.logicalId, current.physicalId, op.resourceType, current.properties, { expectedRegion: ctx.region });
|
|
16792
16857
|
deletedNewFirst = true;
|
|
@@ -16794,15 +16859,13 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
|
|
|
16794
16859
|
await afterOp?.(op.logicalId);
|
|
16795
16860
|
try {
|
|
16796
16861
|
createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }), op.logicalId, {
|
|
16797
|
-
|
|
16798
|
-
initialDelayMs: 2e3,
|
|
16799
|
-
maxDelayMs: 1e4,
|
|
16862
|
+
...RECREATE_RETRY_SCHEDULE,
|
|
16800
16863
|
logger,
|
|
16801
16864
|
...isInterrupted && {
|
|
16802
16865
|
isInterrupted,
|
|
16803
16866
|
onInterrupted: () => /* @__PURE__ */ new Error("Rollback interrupted while waiting for the old name to release")
|
|
16804
16867
|
},
|
|
16805
|
-
isRetryable:
|
|
16868
|
+
isRetryable: isRecreateRetryableError
|
|
16806
16869
|
});
|
|
16807
16870
|
} catch (recreateError) {
|
|
16808
16871
|
throw new Error(`Failed to re-create the old ${op.logicalId} after the new resource (${current.physicalId}) was already deleted: ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. The resource is now absent — fix forward with 'cdkd deploy'.`);
|
|
@@ -17080,7 +17143,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
17080
17143
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
17081
17144
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
17082
17145
|
function getCdkdVersion() {
|
|
17083
|
-
return "0.264.
|
|
17146
|
+
return "0.264.2";
|
|
17084
17147
|
}
|
|
17085
17148
|
/**
|
|
17086
17149
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -18651,7 +18714,7 @@ var DeployEngine = class {
|
|
|
18651
18714
|
createResult = await this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps), logicalId, void 0, void 0, replaceProvider);
|
|
18652
18715
|
} catch (createError) {
|
|
18653
18716
|
const createMsg = createError instanceof Error ? createError.message : String(createError);
|
|
18654
|
-
if (!(
|
|
18717
|
+
if (!isNameCollisionError(createMsg)) throw createError;
|
|
18655
18718
|
if (updateReplacePolicy === "Retain") throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but its user-supplied physical name is still held by the existing resource AND UpdateReplacePolicy: Retain pins that resource in place. Rename the resource in your CDK code — with Retain, the old resource keeps the name, so a same-name replacement can never proceed.`, "NAMED_REPLACEMENT_COLLISION");
|
|
18656
18719
|
if (this.options.replace !== true) throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but the create-first attempt collided with the existing resource: ${createMsg}. The resource has a user-supplied physical name, so the CloudFormation-style safe replacement order (create the new resource before deleting the old) cannot reuse the occupied name — CloudFormation refuses this shape with "cannot update a stack when a custom-named resource requires replacing". Either rename the resource in your CDK code (a fresh name lets the safe create-first order proceed), or re-run with \`cdkd deploy --replace\` to delete the old resource FIRST and recreate it under the same name (the resource is briefly unavailable while it is recreated).`, "NAMED_REPLACEMENT_COLLISION");
|
|
18657
18720
|
this.logger.info(` Create-first collided with the custom-named resource and --replace is set — deleting old ${logicalId} (${currentResource.physicalId}) first...`);
|
|
@@ -18665,13 +18728,13 @@ var DeployEngine = class {
|
|
|
18665
18728
|
this.logger.info(` Re-creating ${logicalId}...`);
|
|
18666
18729
|
try {
|
|
18667
18730
|
createResult = await withRetry(() => this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps), logicalId, void 0, void 0, replaceProvider), logicalId, {
|
|
18668
|
-
maxRetries:
|
|
18731
|
+
maxRetries: 8,
|
|
18669
18732
|
initialDelayMs: 2e3,
|
|
18670
18733
|
maxDelayMs: 1e4,
|
|
18671
18734
|
logger: this.logger,
|
|
18672
18735
|
isInterrupted: () => this.interrupted,
|
|
18673
18736
|
onInterrupted: () => new InterruptedError(this.interruptCause ?? "user"),
|
|
18674
|
-
isRetryable:
|
|
18737
|
+
isRetryable: isRecreateRetryableError
|
|
18675
18738
|
});
|
|
18676
18739
|
} catch (recreateError) {
|
|
18677
18740
|
throw new Error(`Failed to re-create ${logicalId} after the --replace delete-first fallback already deleted the old resource (${currentResource.physicalId}): ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. Re-run the deploy to create it fresh.`);
|
|
@@ -19017,4 +19080,4 @@ var DeployEngine = class {
|
|
|
19017
19080
|
|
|
19018
19081
|
//#endregion
|
|
19019
19082
|
export { createAssetRedirectResolver as $, ResourceTimeoutError as $t, CloudControlProvider as A, MIGRATE_TMP_PREFIX as At, assertRegionMatch as B, setAwsClients as Bt, green as C, resolveSkipPrefix as Ct, collectInlinePolicyNamesManagedBySiblings as D, warnDeprecatedNoPrefixCliFlag as Dt, IAMRoleProvider as E, resolveUseCdkBootstrapAssets as Et, cfnRefValueFromPhysicalId as F, clearBucketRegionCache as Ft, LockManager as G, LocalInvokeBuildError as Gt, DiffCalculator as H, CdkdError as Ht, refStateLookupFromResource as I, resolveBucketRegion as It, shouldRetainResource as J, LockError as Jt, S3StateBackend as K, LocalMigrateError as Kt, WAFv2WebACLProvider as L, AwsClients as Lt, disableInstanceApiTermination as M, uploadCfnTemplate as Mt, isTerminationProtectionPropagationError as N, expectedOwnerParam as Nt, ProviderRegistry as O, CFN_TEMPLATE_BODY_LIMIT as Ot, IntrinsicFunctionResolver as P, AssemblyReader as Pt, buildAssetRedirectMap as Q, ProvisioningError as Qt, normalizeAwsTagsToCfn as R, getAwsClients as Rt, gray as S, resolveCaptureObservedState as St, yellow as T, resolveStateBucketWithDefaultAndSource as Tt, DagBuilder as U, ConfigError as Ut, applyRoleArnIfSet as V, AssetError as Vt, TemplateParser as W, DependencyError as Wt, stringifyValue as X, NestedStackChildDirectDestroyError as Xt, AssetPublisher as Y, MissingCdkCliError as Yt, WorkGraph as Z, PartialFailureError as Zt, isStatefulRecreateTargetSync as _, synthesisStatusMessage as _t, DeploymentEventsStore as a, formatError as an, getBootstrapMarkerKey as at, bold as b, resolveApp as bt, replayFailedOperations as c, withErrorHandling as cn, validateContainerRepoName as ct, withRetry as d, getDockerCmd as dt, ResourceUpdateNotSupportedError as en, loadPublishableAssetManifest as et, isRetryableTransientError as f, runDockerForeground as ft, MULTI_REGION_RECREATE_BLOCKED_TYPES as g, Synthesizer as gt, extractDeploymentEventError as h, getDockerImageBySourceHash as ht, DeploymentEventsReader as i, SynthesisError as in, ensureAssetStorage as it, slowCcOperationTimeoutMs as j, findLargeInlineResources as jt, findActionableSilentDrops as k, CFN_TEMPLATE_URL_LIMIT as kt, replayRollback as l, __exportAll as ln, buildDockerImage as lt, computeImplicitDeleteEdges as m, AssetManifestLoader as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, StackTerminationProtectionError as nn, AssetModeResolver as nt, planFailedOps as o, isCdkdError as on, parseBootstrapMarker as ot, IMPLICIT_DELETE_DEPENDENCIES as p, runDockerStreaming as pt, rebuildClientForBucketRegion as q, LocalStartServiceError as qt, DeployEngine as r, StateError as rn, BOOTSTRAP_MARKER_PREFIX as rt, planRollback as s, normalizeAwsError as sn, validateAssetBucketName as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, StackHasActiveImportsError as tn, rewriteTemplateAssetReferences as tt, withResourceDeadline as u, formatDockerLoginError as ut, renderStatefulReason as v, getDefaultStateBucketName as vt, red as w, resolveStateBucketWithDefault as wt, cyan as x, resolveAutoAssetStorage as xt, formatResourceLine as y, getLegacyStateBucketName as yt, resolveExplicitPhysicalId as z, resetAwsClients as zt };
|
|
19020
|
-
//# sourceMappingURL=deploy-engine-
|
|
19083
|
+
//# sourceMappingURL=deploy-engine-CaquB01e.js.map
|