Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Jun 9, 2025. It is now read-only.

Commit 5ef7d0e

Browse filesBrowse files
committed
fix: only purge alias by default if the purgeCache function is called within a deployed function
linear ticket: http://linear.app/netlify/issue/RUN-1417/quantexa-or-content-not-invalidated-when-calling-purgecache
1 parent e01516d commit 5ef7d0e
Copy full SHA for 5ef7d0e

File tree

Expand file treeCollapse file tree

2 files changed

+107
-1
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+107
-1
lines changed

‎src/lib/purge_cache.test.ts

Copy file name to clipboardExpand all lines: src/lib/purge_cache.test.ts
+100Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,106 @@ test('Calls the purge API endpoint and returns `undefined` if the operation was
5858
expect(mockAPI.fulfilled).toBeTruthy()
5959
})
6060

61+
test('Does not default the deploy_alias field to process.env.NETLIFY_BRANCH if supplied in the options', async () => {
62+
const mockSiteID = '123456789'
63+
const mockToken = '1q2w3e4r5t6y7u8i9o0p'
64+
65+
process.env.NETLIFY_PURGE_API_TOKEN = mockToken
66+
process.env.SITE_ID = mockSiteID
67+
process.env.NETLIFY_BRANCH = 'main'
68+
69+
const mockAPI = new MockFetch().post({
70+
body: (payload: string) => {
71+
const data = JSON.parse(payload)
72+
73+
expect(data.site_id).toBe(mockSiteID)
74+
expect(data.deploy_alias).toBe('test')
75+
},
76+
headers: { Authorization: `Bearer ${mockToken}` },
77+
method: 'post',
78+
response: new Response(null, { status: 202 }),
79+
url: `https://api.netlify.com/api/v1/purge`,
80+
})
81+
// eslint-disable-next-line unicorn/consistent-function-scoping
82+
const myFunction = async () => {
83+
await purgeCache({ deployAlias: 'test' })
84+
}
85+
86+
globalThis.fetch = mockAPI.fetcher
87+
88+
const response = await invokeLambda(myFunction)
89+
90+
expect(response).toBeUndefined()
91+
expect(mockAPI.fulfilled).toBeTruthy()
92+
})
93+
94+
test('Defaults the deploy_alias field to process.env.NETLIFY_BRANCH if not running locally', async () => {
95+
const mockSiteID = '123456789'
96+
const mockToken = '1q2w3e4r5t6y7u8i9o0p'
97+
98+
process.env.NETLIFY_PURGE_API_TOKEN = mockToken
99+
process.env.SITE_ID = mockSiteID
100+
process.env.NETLIFY_BRANCH = 'main'
101+
102+
const mockAPI = new MockFetch().post({
103+
body: (payload: string) => {
104+
const data = JSON.parse(payload)
105+
106+
expect(data.site_id).toBe(mockSiteID)
107+
expect(data.deploy_alias).toBe(process.env.NETLIFY_BRANCH)
108+
},
109+
headers: { Authorization: `Bearer ${mockToken}` },
110+
method: 'post',
111+
response: new Response(null, { status: 202 }),
112+
url: `https://api.netlify.com/api/v1/purge`,
113+
})
114+
// eslint-disable-next-line unicorn/consistent-function-scoping
115+
const myFunction = async () => {
116+
await purgeCache()
117+
}
118+
119+
globalThis.fetch = mockAPI.fetcher
120+
121+
const response = await invokeLambda(myFunction)
122+
123+
expect(response).toBeUndefined()
124+
expect(mockAPI.fulfilled).toBeTruthy()
125+
})
126+
127+
test('Does not default the deploy_alias field to process.env.NETLIFY_BRANCH when running locally', async () => {
128+
const mockSiteID = '123456789'
129+
const mockToken = '1q2w3e4r5t6y7u8i9o0p'
130+
131+
process.env.NETLIFY_PURGE_API_TOKEN = mockToken
132+
process.env.SITE_ID = mockSiteID
133+
process.env.NETLIFY_LOCAL = 'true'
134+
process.env.NETLIFY_BRANCH = 'main'
135+
136+
const mockAPI = new MockFetch().post({
137+
body: (payload: string) => {
138+
const data = JSON.parse(payload)
139+
140+
expect(data.site_id).toBe(mockSiteID)
141+
expect(data.deploy_alias).toBeUndefined()
142+
},
143+
headers: { Authorization: `Bearer ${mockToken}` },
144+
method: 'post',
145+
response: new Response(null, { status: 202 }),
146+
url: `https://api.netlify.com/api/v1/purge`,
147+
})
148+
// eslint-disable-next-line unicorn/consistent-function-scoping
149+
const myFunction = async () => {
150+
await purgeCache()
151+
}
152+
153+
globalThis.fetch = mockAPI.fetcher
154+
155+
const response = await invokeLambda(myFunction)
156+
157+
expect(response).toBeUndefined()
158+
expect(mockAPI.fulfilled).toBeTruthy()
159+
})
160+
61161
test('Throws an error if the API response does not have a successful status code, using the response body as part of the error message', async () => {
62162
if (!hasFetchAPI) {
63163
console.warn('Skipping test requires the fetch API')

‎src/lib/purge_cache.ts

Copy file name to clipboardExpand all lines: src/lib/purge_cache.ts
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,14 @@ export const purgeCache = async (options: PurgeCacheOptions = {}) => {
4848

4949
const payload: PurgeAPIPayload = {
5050
cache_tags: options.tags,
51-
deploy_alias: options.deployAlias,
5251
}
52+
53+
if ('deployAlias' in options) {
54+
payload.deploy_alias = options.deployAlias
55+
} else if (!env.NETLIFY_LOCAL) {
56+
payload.deploy_alias = env.NETLIFY_BRANCH
57+
}
58+
5359
const token = env.NETLIFY_PURGE_API_TOKEN || options.token
5460

5561
if (env.NETLIFY_LOCAL && !token) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.