Skip to content

Commit

Permalink
Skip auto-install for missing deps in CI (#39882)
Browse files Browse the repository at this point in the history
Follow-up to #39838 this skips auto-installing missing TypeScript dependencies in CI environments as this creates a side-effect which we want to avoid. 

x-ref: [slack thread](https://vercel.slack.com/archives/C03KAR5DCKC/p1661301586792559?thread_ts=1661299706.559769&cid=C03KAR5DCKC)

## Bug

- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
  • Loading branch information
ijjk committed Aug 24, 2022
1 parent 9d4bb49 commit 08dd08e
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 1 deletion.
43 changes: 43 additions & 0 deletions packages/next/lib/typescript/missingDependencyError.ts
@@ -0,0 +1,43 @@
import chalk from 'next/dist/compiled/chalk'

import { getOxfordCommaList } from '../oxford-comma-list'
import { MissingDependency } from '../has-necessary-dependencies'
import { FatalError } from '../fatal-error'
import { getPkgManager } from '../helpers/get-pkg-manager'

export async function missingDepsError(
dir: string,
missingPackages: MissingDependency[]
) {
const packagesHuman = getOxfordCommaList(missingPackages.map((p) => p.pkg))
const packagesCli = missingPackages.map((p) => p.pkg).join(' ')
const packageManager = getPkgManager(dir)

const removalMsg =
'\n\n' +
chalk.bold(
'If you are not trying to use TypeScript, please remove the ' +
chalk.cyan('tsconfig.json') +
' file from your package root (and any TypeScript files in your pages directory).'
)

throw new FatalError(
chalk.bold.red(
`It looks like you're trying to use TypeScript but do not have the required package(s) installed.`
) +
'\n\n' +
chalk.bold(`Please install ${chalk.bold(packagesHuman)} by running:`) +
'\n\n' +
`\t${chalk.bold.cyan(
(packageManager === 'yarn'
? 'yarn add --dev'
: packageManager === 'pnpm'
? 'pnpm install --save-dev'
: 'npm install --save-dev') +
' ' +
packagesCli
)}` +
removalMsg +
'\n'
)
}
10 changes: 9 additions & 1 deletion packages/next/lib/verifyTypeScriptSetup.ts
Expand Up @@ -14,6 +14,8 @@ import { TypeCheckResult } from './typescript/runTypeCheck'
import { writeAppTypeDeclarations } from './typescript/writeAppTypeDeclarations'
import { writeConfigurationDefaults } from './typescript/writeConfigurationDefaults'
import { installDependencies } from './install-dependencies'
import { isCI } from '../telemetry/ci-info'
import { missingDepsError } from './typescript/missingDependencyError'

const requiredPackages = [
{
Expand Down Expand Up @@ -64,6 +66,11 @@ export async function verifyTypeScriptSetup({
)

if (deps.missing?.length > 0) {
if (isCI) {
// we don't attempt auto install in CI to avoid side-effects
// and instead log the error for installing needed packages
await missingDepsError(dir, deps.missing)
}
console.log(
chalk.bold.yellow(
`It looks like you're trying to use TypeScript but do not have the required package(s) installed.`
Expand All @@ -82,7 +89,8 @@ export async function verifyTypeScriptSetup({
if (err && typeof err === 'object' && 'command' in err) {
console.error(
`Failed to install required TypeScript dependencies, please install them manually to continue:\n` +
(err as any).command
(err as any).command +
'\n'
)
}
throw err
Expand Down
10 changes: 10 additions & 0 deletions test/development/typescript-auto-install/index.test.ts
Expand Up @@ -17,6 +17,16 @@ describe('typescript-auto-install', () => {
}
`,
},
env: {
// unset CI env as this skips the auto-install behavior
// being tested
CI: '',
CIRCLECI: '',
GITHUB_ACTIONS: '',
CONTINUOUS_INTEGRATION: '',
RUN_ID: '',
BUILD_NUMBER: '',
},
startCommand: 'yarn next dev',
installCommand: 'yarn',
dependencies: {},
Expand Down
33 changes: 33 additions & 0 deletions test/production/ci-missing-typescript-deps/index.test.ts
@@ -0,0 +1,33 @@
import { createNext } from 'e2e-utils'

describe('ci-missing-typescript-deps', () => {
it('should show missing TypeScript dependencies error in CI', async () => {
const next = await createNext({
files: {
'pages/index.tsx': `
export default function Page() {
return <p>hello world</p>
}
`,
},
env: {
CI: '1',
},
skipStart: true,
})
try {
let error
await next.start().catch((err) => {
error = err
})

expect(error).toBeDefined()
expect(next.cliOutput).toContain(
`It looks like you're trying to use TypeScript but do not have the required package(s) installed.`
)
expect(next.cliOutput).toContain(`Please install`)
} finally {
await next.destroy()
}
})
})

0 comments on commit 08dd08e

Please sign in to comment.