Skip to content

feat: add ignoreAssetChanges input to drop asset-hash-only changes#163

Open
laazyj wants to merge 1 commit into
corymhall:mainfrom
laazyj:feat/ignore-asset-changes
Open

feat: add ignoreAssetChanges input to drop asset-hash-only changes#163
laazyj wants to merge 1 commit into
corymhall:mainfrom
laazyj:feat/ignore-asset-changes

Conversation

@laazyj

@laazyj laazyj commented Jun 9, 2026

Copy link
Copy Markdown

Closes #162.

Problem

A Custom::CDKBucketDeployment's SourceObjectKeys changes on every content rebuild — the everyday case for a static site. cloudformation-diff classifies that custom-resource property change as MAY_REPLACE, so by default it is reported as an update and a destructive change. With the default failOnDestructiveChanges: true, that fails the job on every content-only PR, making the destructive gate unusable for any app that ships content via BucketDeployment (or otherwise has asset-hash-only churn).

This is also inconsistent today: evaluateDiff already exempts AWS::Lambda::Function whose only changes are Code/Metadata — but only for the counts (the comment body is still rendered from the raw TemplateDiff), and there is no equivalent for Custom::CDKBucketDeployment. See also #161 and #4.

What this adds

An opt-in ignoreAssetChanges input (default false). When true, any resource difference whose property updates are entirely asset hashes — Code, Metadata, SourceObjectKeys, CodeHash — is dropped from the TemplateDiff up front, so it is absent from the change counts, the rendered comment, and the destructive-change classification alike. Resources with any non-asset change are left fully intact.

The filter is applied once to templateDiff.resources (via DifferenceCollection.filter) before evaluateDiff/render, generalizing the existing hard-coded Lambda special-case into a documented option that also fixes the rendered body and the destructive gate.

Changes

  • inputs.ts / .projenrc.ts (→ regenerated action.yml): new ignoreAssetChanges input
  • action.ts: read it via getBooleanInput
  • diff.ts: isAssetOnlyChange() predicate + dropAssetOnlyChanges(), gated on the flag in diffStack()
  • stage-processor.ts: thread the option into StackDiff
  • README.md: new "Ignore asset-only changes" section
  • test/diff.test.ts: 3 tests — asset-only change present by default, dropped when enabled, and a mixed-change resource left intact

npx projen build passes (compile + eslint + 31 tests + bundle).

Live example

Dogfooded on a real repo. Same PR, toggling only this flag (identical content, identical deployed baseline):

ignoreAssetChanges: falseJasonDuffettNetSiteStack — 0 to add, 1 to update, 0 to destroy ❌, 1 Destructive Change (MAY_REPLACE on the BucketDeployment), SourceObjectKeys diff shown.

ignoreAssetChanges: trueJasonDuffettNetSiteStack — 0 to add, 0 to update, 0 to destroy ✅, no destructive changes, SourceObjectKeys filtered — while an unrelated Description change is retained (the filter is selective).

Before/after captured here: laazyj/jasonduffett.net#48

Notes / open questions

  • Kept the existing default-on Lambda Code/Metadata count exemption untouched to avoid changing default behavior — happy to fold it into this mechanism in a follow-up if you'd prefer.
  • Matching is by property name (the four asset properties), not resource type — simpler, and these names are conventional. Easy to tighten to resource-type-aware matching if you'd rather.
  • Open to a different input name/shape — glad to adjust.

CDK references bundled assets by content hash, so rebuilding an asset
changes the synthesized template even when no infrastructure changed.
For apps that deploy content via BucketDeployment, ship Lambda code as
assets, or use custom-resource providers, every content change shows up
as an update -- and because cloudformation-diff classifies an asset
replacement as MAY_REPLACE, it trips the destructive-changes gate on
routine content PRs.

The existing AWS::Lambda::Function Code/Metadata exemption in
evaluateDiff only adjusts the counts; the comment body is still rendered
from the raw TemplateDiff, and no equivalent exists for
Custom::CDKBucketDeployment. This generalizes that idea into an opt-in
input applied to the TemplateDiff itself.

When ignoreAssetChanges is true, any resource whose property updates are
entirely asset hashes (Code, Metadata, SourceObjectKeys, CodeHash) is
removed before counting, rendering, and destructive classification.
Resources with any non-asset change are left fully intact.

Refs corymhall#162.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BucketDeployment asset-hash changes are flagged MAY_REPLACE → destructive gate blocks routine content PRs

1 participant