Keep a Cloudflare deploy from serving HTML that its own build invalidated - #17675
Open
danielmlr wants to merge 1 commit into
Open
Keep a Cloudflare deploy from serving HTML that its own build invalidated#17675danielmlr wants to merge 1 commit into
danielmlr wants to merge 1 commit into
Conversation
Add the Worker version id from the `CF_VERSION_METADATA` binding as an `astro-version:` cache tag, and fold it into a weak `ETag` on responses that already carry `Last-Modified`. Responses without a validator keep none, so no route gains a validator it did not have before.
🦋 Changeset detectedLatest commit: 38213ad The changes in this PR will be included in the next version bump. This PR includes changesets to release 43 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
A deploy that changes rendered output without changing content leaves the validator of a cached page untouched: revalidation resolves to
304, and clients keep HTML that references hashed assets from the previous build (/_astro/<hash>.cssis gone after the next build). The cause: every validator the Cloudflare provider can send comes from the caller —cache.set(),CacheHint,routeRules— and describes the content, never the build.With the
CF_VERSION_METADATAbinding configured, the provider now reads the Worker version id andastro-version:<id>cache tag, which enables version-specific purging, andETag(W/"<id>:<lastModified-ms>") on responses that already sendLast-Modifiedand do not supply their ownetag.Without the binding, every header is exactly what it was before.
Testing
test/cache-provider.test.tsgains four cases against the preview server:ETagcarries the same id and thelastModifiedtimestamp,etagsurvives untouched, andTwo fixture pages (
/lastmod,/explicit-etag) and theversion_metadatabinding in the fixture'swrangler.jsoncsupport them. TheprerenderEnvironment: 'node'build path has no automated case because it would need a second fixture build per run; a manual fixture build with a prerendered route and the provider enabled passes.Docs
The adapter README does not cover route caching, so there is no section to update here. The behavior is worth a paragraph in the Cloudflare adapter guide on docs.astro.build, and I am happy to open that PR.
Details
Responses that carry no validator keep none. Minting
W/"<id>"for them would be the wider fix, but it hands a validator to pages whose content changes between deploys, and a cache may then answer304until the next deploy. The narrow rule only makes an existing validator deploy-sensitive, which cannot regress a route.The version id is read through a dynamic
import('cloudflare:workers')resolved once at module load, for the same reasoninvalidate()imports lazily (#16335): a static import breaks theprerenderEnvironment: 'node'build.onRequest()would be the other place to reach the runtime, but a provider that defines it counts as a runtime cache, andCacheHandlerthen stripsCache-Tagfrom the response.This picks up #17038, which targeted the
feat/cdn-cache-providersbranch and was closed when that branch was deleted. The version tag that it built on never reachedmain, so this change adds it.