Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(command-deploy): align file filtering with buildbot #1272

Merged
merged 2 commits into from Sep 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/commands/deploy.js
Expand Up @@ -132,6 +132,31 @@ const validateFolders = async ({ deployFolder, functionsFolder, error, log }) =>
return { deployFolderStat, functionsFolderStat }
}

const getDeployFilesFilter = ({ site, deployFolder }) => {
// site.root === deployFolder can happen when users run `netlify deploy --dir .`
// in that specific case we don't want to publish the repo node_modules
// when site.root !== deployFolder the behaviour matches our buildbot
const skipNodeModules = site.root === deployFolder

return filename => {
if (filename == null) {
return false
}
if (filename === deployFolder) {
return true
}

const basename = path.basename(filename)
const skipFile =
(skipNodeModules && basename === 'node_modules') ||
(basename.startsWith('.') && basename !== '.well-known') ||
basename.startsWith('__MACOSX') ||
basename.includes('/.')

return !skipFile
}
}

const runDeploy = async ({
flags,
deployToProduction,
Expand Down Expand Up @@ -192,6 +217,7 @@ const runDeploy = async ({
syncFileLimit: 100,
// pass an existing deployId to update
deployId,
filter: getDeployFilesFilter({ site, deployFolder }),
})
} catch (e) {
switch (true) {
Expand Down
153 changes: 145 additions & 8 deletions tests/command.deploy.test.js
Expand Up @@ -7,18 +7,27 @@ const { generateSiteName, createLiveTestSite } = require('./utils/createLiveTest

const siteName = generateSiteName('netlify-test-deploy-')

const validateContent = async ({ siteUrl, path, content, t }) => {
let actualContent
try {
const response = await fetch(`${siteUrl}${path}`)
if (response.ok) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the test always fail when response.ok is not true? If so, I am wondering if there should be a t.true(response.ok)?
Also wondering about whether the test should always fail when fetch() or response.text() throws. In which case, t.notThrowsAsync() could be used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, nevermind, I see that content is sometimes undefined in some of the tests. 馃憤

actualContent = await response.text()
}
} catch (e) {
// no op
}
t.is(actualContent, content)
}

const validateDeploy = async ({ deploy, siteName, content, t }) => {
t.truthy(deploy.site_name)
t.truthy(deploy.deploy_url)
t.truthy(deploy.deploy_id)
t.truthy(deploy.logs)
t.is(deploy.site_name, siteName)

const actualContent = await fetch(deploy.deploy_url)
.then(r => r.text())
.catch(() => undefined)

t.is(actualContent, content)
await validateContent({ siteUrl: deploy.deploy_url, path: '', content, t })
}

if (process.env.IS_FORK !== 'true') {
Expand All @@ -42,7 +51,7 @@ if (process.env.IS_FORK !== 'true') {
env: { NETLIFY_SITE_ID: t.context.siteId },
}).then(output => JSON.parse(output))

validateDeploy({ deploy, siteName, content, t })
await validateDeploy({ deploy, siteName, content, t })
})
})

Expand All @@ -67,7 +76,7 @@ if (process.env.IS_FORK !== 'true') {
env: { NETLIFY_SITE_ID: t.context.siteId },
}).then(output => JSON.parse(output))

validateDeploy({ deploy, siteName, content, t })
await validateDeploy({ deploy, siteName, content, t })
})
})

Expand Down Expand Up @@ -105,7 +114,7 @@ if (process.env.IS_FORK !== 'true') {
await callCli(['build'], options)
const deploy = await callCli(['deploy', '--json'], options).then(output => JSON.parse(output))

validateDeploy({ deploy, siteName, content, t })
await validateDeploy({ deploy, siteName, content, t })

// validate edge handlers
// use this until we can use `netlify api`
Expand Down Expand Up @@ -154,6 +163,134 @@ if (process.env.IS_FORK !== 'true') {
})
})

test.serial('should deploy hidden public folder but ignore hidden/__MACOSX files', async t => {
await withSiteBuilder('site-with-a-dedicated-publish-folder', async builder => {
builder
.withContentFiles([
{
path: '.public/index.html',
content: 'index',
},
{
path: '.public/.hidden-file.html',
content: 'hidden-file',
},
{
path: '.public/.hidden-dir/index.html',
content: 'hidden-dir',
},
{
path: '.public/__MACOSX/index.html',
content: 'macosx',
},
])
.withNetlifyToml({
config: {
build: { publish: '.public' },
},
})

await builder.buildAsync()

const deploy = await callCli(['deploy', '--json'], {
cwd: builder.directory,
env: { NETLIFY_SITE_ID: t.context.siteId },
}).then(output => JSON.parse(output))

await validateDeploy({ deploy, siteName, content: 'index', t })
await validateContent({
siteUrl: deploy.deploy_url,
content: undefined,
path: '/.hidden-file',
t,
})
await validateContent({
siteUrl: deploy.deploy_url,
content: undefined,
path: '/.hidden-dir',
t,
})
await validateContent({
siteUrl: deploy.deploy_url,
content: undefined,
path: '/__MACOSX',
t,
})
})
})

test.serial('should filter node_modules from root directory', async t => {
await withSiteBuilder('site-with-a-project-directory', async builder => {
builder
.withContentFiles([
{
path: 'index.html',
content: 'index',
},
{
path: 'node_modules/package.json',
content: '{}',
},
])
.withNetlifyToml({
config: {
build: { publish: '.' },
},
})

await builder.buildAsync()

const deploy = await callCli(['deploy', '--json'], {
cwd: builder.directory,
env: { NETLIFY_SITE_ID: t.context.siteId },
}).then(output => JSON.parse(output))

await validateDeploy({ deploy, siteName, content: 'index', t })
await validateContent({
siteUrl: deploy.deploy_url,
content: undefined,
path: '/node_modules/package.json',
t,
})
})
})

test.serial('should not filter node_modules from publish directory', async t => {
await withSiteBuilder('site-with-a-project-directory', async builder => {
builder
.withContentFiles([
{
path: 'public/index.html',
content: 'index',
},
{
path: 'public/node_modules/package.json',
content: '{}',
},
])
.withNetlifyToml({
config: {
build: { publish: 'public' },
},
})

await builder.buildAsync()

const deploy = await callCli(['deploy', '--json'], {
cwd: builder.directory,
env: { NETLIFY_SITE_ID: t.context.siteId },
}).then(output => JSON.parse(output))

await validateDeploy({ deploy, siteName, content: 'index', t })
await validateContent({
siteUrl: deploy.deploy_url,
content: '{}',
path: '/node_modules/package.json',
t,
})
})
})

test.after('cleanup', async t => {
const { siteId } = t.context
console.log(`deleting test site "${siteName}". ${siteId}`)
Expand Down
4 changes: 4 additions & 0 deletions tests/utils/siteBuilder.js
Expand Up @@ -86,6 +86,10 @@ const createSiteBuilder = ({ siteName }) => {
})
return builder
},
withContentFiles: files => {
files.forEach(builder.withContentFile)
return builder
},
withEnvFile: ({ path: filePath = '.env', pathPrefix = '', env = {} }) => {
const dest = path.join(directory, pathPrefix, filePath)
tasks.push(async () => {
Expand Down