Skip to content

Commit

Permalink
fix: don't prompt for input when running in CI (#6541)
Browse files Browse the repository at this point in the history
* fix: don't prompt for input when running in CI

Co-authored-by: Eduardo Bouças <[email protected]>
  • Loading branch information
davbree and eduardoboucas authored May 7, 2024
1 parent fdc34d4 commit a3c496b
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 2 deletions.
12 changes: 12 additions & 0 deletions src/commands/base-command.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isCI } from 'ci-info'

import { existsSync } from 'fs'
import { join, relative, resolve } from 'path'
import process from 'process'
Expand Down Expand Up @@ -103,6 +105,16 @@ async function selectWorkspace(project: Project, filter?: string): Promise<strin
log()
log(chalk.cyan(`We've detected multiple sites inside your repository`))

if (isCI) {
throw new Error(
`Sites detected: ${(project.workspace?.packages || [])
.map((pkg) => pkg.name || pkg.path)
.join(
', ',
)}. Configure the site you want to work with and try again. Refer to https://ntl.fyi/configure-site for more information.`,
)
}

const { result } = await inquirer.prompt({
name: 'result',
// @ts-expect-error TS(2769) FIXME: No overload matches this call.
Expand Down
12 changes: 12 additions & 0 deletions src/utils/build-info.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Settings } from '@netlify/build-info'
import { isCI } from 'ci-info'
import fuzzy from 'fuzzy'
import inquirer from 'inquirer'

Expand Down Expand Up @@ -77,6 +78,17 @@ export const detectFrameworkSettings = async (
}

if (settings.length > 1) {
if (isCI) {
log(`Multiple possible ${type} commands found`)
throw new Error(
`Detected commands for: ${settings
.map((setting) => setting.framework.name)
.join(
', ',
)}. Update your settings to specify which to use. Refer to https://ntl.fyi/dev-monorepo for more information.`,
)
}

// multiple matching detectors, make the user choose
const scriptInquirerOptions = formatSettingsArrForInquirer(settings, type)
const { chosenSettings } = await inquirer.prompt<{ chosenSettings: Settings }>({
Expand Down
31 changes: 30 additions & 1 deletion tests/integration/commands/dev/dev-miscellaneous.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ import path from 'path'
import { fileURLToPath } from 'url'

import { setProperty } from 'dot-prop'
import execa from 'execa'
import getAvailablePort from 'get-port'
import jwt from 'jsonwebtoken'
import fetch from 'node-fetch'
import { describe, test } from 'vitest'

import { withDevServer } from '../../utils/dev-server.ts'
import { cliPath } from '../../utils/cli-path.js'
import { getExecaOptions, withDevServer } from '../../utils/dev-server.ts'
import got from '../../utils/got.js'
import { withMockApi } from '../../utils/mock-api.js'
import { pause } from '../../utils/pause.js'
import { withSiteBuilder } from '../../utils/site-builder.ts'
import { normalize } from '../../utils/snapshots.js'

// eslint-disable-next-line no-underscore-dangle
const __dirname = path.dirname(fileURLToPath(import.meta.url))
Expand Down Expand Up @@ -1318,4 +1321,30 @@ describe.concurrent('commands/dev-miscellaneous', () => {
)
})
})

test('should fail in CI with multiple projects', async (t) => {
await withSiteBuilder('site-with-multiple-packages', async (builder) => {
await builder
.withPackageJson({ packageJson: { name: 'main', workspaces: ['*'] } })
.withPackageJson({ packageJson: { name: 'package1' }, pathPrefix: 'package1' })
.withPackageJson({ packageJson: { name: 'package2' }, pathPrefix: 'package2' })
.buildAsync()

const asyncErrorBlock = async () => {
const childProcess = execa(
cliPath,
['dev', '--offline'],
getExecaOptions({ cwd: builder.directory, env: { CI: true } }),
)
await childProcess
}
const error = await asyncErrorBlock().catch((error_) => error_)
t.expect(
normalize(error.stderr, { duration: true, filePath: true }).includes(
'Sites detected: package1, package2. Configure the site you want to work with and try again. Refer to https://ntl.fyi/configure-site for more information.',
),
)
t.expect(error.exitCode).toBe(1)
})
})
})
37 changes: 36 additions & 1 deletion tests/integration/framework-detection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,11 @@ describe.concurrent('frameworks/framework-detection', () => {

// a failure is expected since this is not a true framework project
const asyncErrorBlock = async () => {
const childProcess = execa(cliPath, ['dev', '--offline'], getExecaOptions({ cwd: builder.directory }))
const childProcess = execa(
cliPath,
['dev', '--offline'],
getExecaOptions({ cwd: builder.directory, env: { CI: 'false' } }),
)

handleQuestions(childProcess, [
{
Expand All @@ -252,6 +256,37 @@ describe.concurrent('frameworks/framework-detection', () => {
})
})

test('should fail in CI when multiple frameworks are detected', async (t) => {
await withSiteBuilder('site-with-multiple-frameworks', async (builder) => {
await builder
.withPackageJson({
packageJson: {
dependencies: { 'react-scripts': '1.0.0', gatsby: '^3.0.0' },
scripts: { start: 'react-scripts start', develop: 'gatsby develop' },
},
})
.withContentFile({ path: 'gatsby-config.js', content: '' })
.buildAsync()

// a failure is expected since this is not a true framework project
const asyncErrorBlock = async () => {
const childProcess = execa(
cliPath,
['dev', '--offline'],
getExecaOptions({ cwd: builder.directory, env: { CI: true } }),
)
await childProcess
}
const error = await asyncErrorBlock().catch((error_) => error_)
t.expect(
normalize(error.stdout, { duration: true, filePath: true }).includes(
'Detected commands for: Gatsby, Create React App. Update your settings to specify which to use. Refer to https://ntl.fyi/dev-monorepo for more information.',
),
)
t.expect(error.exitCode).toBe(1)
})
})

test('should not run framework detection if command and targetPort are configured', async (t) => {
await withSiteBuilder('site-with-hugo-config', async (builder) => {
await builder.withContentFile({ path: 'config.toml', content: '' }).buildAsync()
Expand Down

2 comments on commit a3c496b

@github-actions
Copy link

Choose a reason for hiding this comment

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

📊 Benchmark results

  • Dependency count: 1,329
  • Package size: 310 MB
  • Number of ts-expect-error directives: 997

@github-actions
Copy link

Choose a reason for hiding this comment

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

📊 Benchmark results

  • Dependency count: 1,329
  • Package size: 310 MB
  • Number of ts-expect-error directives: 997

Please sign in to comment.