diff --git a/.changeset/neat-otters-happen.md b/.changeset/neat-otters-happen.md new file mode 100644 index 000000000..ed99b35bf --- /dev/null +++ b/.changeset/neat-otters-happen.md @@ -0,0 +1,5 @@ +--- +'vercel': major +--- + +Change `vc env pull` default output file to `.env.local` diff --git a/errors/missing-env-file.md b/errors/missing-env-file.md index d5f9cf8c2..f1d2703a0 100644 --- a/errors/missing-env-file.md +++ b/errors/missing-env-file.md @@ -4,7 +4,7 @@ You ran `vercel dev` inside a project that contains a `vercel.json` file with `env` or `build.env` properties that use [Vercel Secrets](https://vercel.com/docs/concepts/projects/environment-variables). -In order to use environment variables in your project locally that have values defined using the Vercel Secrets format (e.g. `@my-secret-value`), you will need to provide the value as an environment variable using a `.env`. +In order to use environment variables in your project locally that have values defined using the Vercel Secrets format (e.g. `@my-secret-value`), you will need to provide the value as an environment variable using a `.env.local`. We require this to ensure your app works as you intend it to, in the development environment, and to provide you with a way to mirror or separate private environment variables within your applications, for example when connecting to a database. @@ -12,11 +12,11 @@ Read below for how to address this error. #### Possible Ways to Fix It -The error message will list environment variables that are required and which file they are required to be included in `.env`. +The error message will list environment variables that are required and which file they are required to be included in `.env.local`. If the file does not exist yet, please create the file that the error message mentions and insert the missing environment variable into it. -For example, if the error message shows that the environment variable `TEST` is missing from `.env`, then the `.env` file should look like this: +For example, if the error message shows that the environment variable `TEST` is missing from `.env.local`, then the `.env.local` file should look like this: ``` TEST=value diff --git a/examples/sanity/.env.template b/examples/sanity/.env.local.template similarity index 100% rename from examples/sanity/.env.template rename to examples/sanity/.env.local.template diff --git a/packages/cli/src/commands/env/index.ts b/packages/cli/src/commands/env/index.ts index 6caac729d..3ac26c50d 100644 --- a/packages/cli/src/commands/env/index.ts +++ b/packages/cli/src/commands/env/index.ts @@ -26,7 +26,7 @@ const help = () => { ls [environment] [gitbranch] List all variables for the specified Environment add [name] [environment] [gitbranch] Add an Environment Variable (see examples below) rm [name] [environment] [gitbranch] Remove an Environment Variable (see examples below) - pull [filename] Pull all Development Environment Variables from the cloud and write to a file [.env] + pull [filename] Pull all Development Environment Variables from the cloud and write to a file [.env.local] ${chalk.dim('Options:')} diff --git a/packages/cli/src/commands/env/pull.ts b/packages/cli/src/commands/env/pull.ts index 1eff09c3a..73cc53a61 100644 --- a/packages/cli/src/commands/env/pull.ts +++ b/packages/cli/src/commands/env/pull.ts @@ -67,7 +67,7 @@ export default async function pull( } // handle relative or absolute filename - const [filename = '.env'] = args; + const [filename = '.env.local'] = args; const fullPath = resolve(cwd, filename); const skipConfirmation = opts['--yes']; const gitBranch = opts['--git-branch']; diff --git a/packages/cli/test/fixtures/unit/vercel-env-pull-delta-corrupt/.env b/packages/cli/test/fixtures/unit/vercel-env-pull-delta-corrupt/.env.local similarity index 100% rename from packages/cli/test/fixtures/unit/vercel-env-pull-delta-corrupt/.env rename to packages/cli/test/fixtures/unit/vercel-env-pull-delta-corrupt/.env.local diff --git a/packages/cli/test/fixtures/unit/vercel-env-pull-delta-no-changes/.env b/packages/cli/test/fixtures/unit/vercel-env-pull-delta-no-changes/.env.local similarity index 100% rename from packages/cli/test/fixtures/unit/vercel-env-pull-delta-no-changes/.env rename to packages/cli/test/fixtures/unit/vercel-env-pull-delta-no-changes/.env.local diff --git a/packages/cli/test/fixtures/unit/vercel-env-pull-delta-quotes/.env b/packages/cli/test/fixtures/unit/vercel-env-pull-delta-quotes/.env.local similarity index 100% rename from packages/cli/test/fixtures/unit/vercel-env-pull-delta-quotes/.env rename to packages/cli/test/fixtures/unit/vercel-env-pull-delta-quotes/.env.local diff --git a/packages/cli/test/fixtures/unit/vercel-env-pull-delta/.env b/packages/cli/test/fixtures/unit/vercel-env-pull-delta/.env.local similarity index 100% rename from packages/cli/test/fixtures/unit/vercel-env-pull-delta/.env rename to packages/cli/test/fixtures/unit/vercel-env-pull-delta/.env.local diff --git a/packages/cli/test/integration-1.test.ts b/packages/cli/test/integration-1.test.ts index 0fc68d6d7..64f33155a 100644 --- a/packages/cli/test/integration-1.test.ts +++ b/packages/cli/test/integration-1.test.ts @@ -751,9 +751,9 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => { ); expect(exitCode, formatOutput({ stdout, stderr })).toBe(0); - expect(stderr).toMatch(/Created .env file/gm); + expect(stderr).toMatch(/Created .env.local file/gm); - const contents = fs.readFileSync(path.join(target, '.env'), 'utf8'); + const contents = fs.readFileSync(path.join(target, '.env.local'), 'utf8'); expect(contents).toMatch(/^# Created by Vercel CLI\n/); expect(contents).toMatch(/MY_NEW_ENV_VAR="my plaintext value"/); expect(contents).toMatch(/MY_STDIN_VAR="{"expect":"quotes"}"/); @@ -771,12 +771,12 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => { ); expect(exitCode, formatOutput({ stdout, stderr })).toBe(0); - expect(stderr).toMatch(/Overwriting existing .env file/gm); - expect(stderr).toMatch(/Updated .env file/gm); + expect(stderr).toMatch(/Overwriting existing .env.local file/gm); + expect(stderr).toMatch(/Updated .env.local file/gm); } async function vcEnvPullConfirm() { - fs.writeFileSync(path.join(target, '.env'), 'hahaha'); + fs.writeFileSync(path.join(target, '.env.local'), 'hahaha'); const vc = execCli(binaryPath, ['env', 'pull'], { cwd: target, @@ -784,7 +784,7 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => { await waitForPrompt( vc, - 'Found existing file ".env". Do you want to overwrite?' + 'Found existing file ".env.local". Do you want to overwrite?' ); vc.stdin?.end('y\n'); @@ -904,7 +904,7 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => { expect(exitCode, formatOutput({ stdout, stderr })).toBe(0); - const contents = fs.readFileSync(path.join(target, '.env'), 'utf8'); + const contents = fs.readFileSync(path.join(target, '.env.local'), 'utf8'); const lines = new Set(contents.split('\n')); @@ -1024,11 +1024,11 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => { await vcEnvPullConfirm(); await vcDeployWithVar(); await vcDevWithEnv(); - fs.unlinkSync(path.join(target, '.env')); + fs.unlinkSync(path.join(target, '.env.local')); await vcDevAndFetchCloudVars(); await enableAutoExposeSystemEnvs(); await vcEnvPullFetchSystemVars(); - fs.unlinkSync(path.join(target, '.env')); + fs.unlinkSync(path.join(target, '.env.local')); await vcDevAndFetchSystemVars(); await vcEnvRemove(); await vcEnvRemoveWithArgs(); diff --git a/packages/cli/test/unit/commands/env.test.ts b/packages/cli/test/unit/commands/env.test.ts index 135c4f82d..6a603c510 100644 --- a/packages/cli/test/unit/commands/env.test.ts +++ b/packages/cli/test/unit/commands/env.test.ts @@ -24,10 +24,10 @@ describe('env', () => { await expect(client.stderr).toOutput( 'Downloading `development` Environment Variables for Project vercel-env-pull' ); - await expect(client.stderr).toOutput('Created .env file'); + await expect(client.stderr).toOutput('Created .env.local file'); await expect(exitCodePromise).resolves.toEqual(0); - const rawDevEnv = await fs.readFile(path.join(cwd, '.env')); + const rawDevEnv = await fs.readFile(path.join(cwd, '.env.local')); // check for development env value const devFileHasDevEnv = rawDevEnv.toString().includes('SPECIAL_FLAG'); @@ -56,11 +56,11 @@ describe('env', () => { await expect(client.stderr).toOutput( 'Downloading `preview` Environment Variables for Project vercel-env-pull' ); - await expect(client.stderr).toOutput('Created .env file'); + await expect(client.stderr).toOutput('Created .env.local file'); await expect(exitCodePromise).resolves.toEqual(0); // check for Preview env vars - const rawDevEnv = await fs.readFile(path.join(cwd, '.env'), 'utf8'); + const rawDevEnv = await fs.readFile(path.join(cwd, '.env.local'), 'utf8'); expect(rawDevEnv).toContain( 'REDIS_CONNECTION_STRING="redis://abc123@redis.example.com:6379"' ); @@ -93,11 +93,11 @@ describe('env', () => { await expect(client.stderr).toOutput( 'Downloading `preview` Environment Variables for Project vercel-env-pull' ); - await expect(client.stderr).toOutput('Created .env file'); + await expect(client.stderr).toOutput('Created .env.local file'); await expect(exitCodePromise).resolves.toEqual(0); // check for Preview env vars - const rawDevEnv = await fs.readFile(path.join(cwd, '.env'), 'utf8'); + const rawDevEnv = await fs.readFile(path.join(cwd, '.env.local'), 'utf8'); expect(rawDevEnv).toContain( 'REDIS_CONNECTION_STRING="redis://abc123@redis.example.com:6379"' ); @@ -159,10 +159,10 @@ describe('env', () => { await expect(client.stderr).toOutput( `Downloading \`production\` Environment Variables for Project vercel-env-pull` ); - await expect(client.stderr).toOutput('Created .env file'); + await expect(client.stderr).toOutput('Created .env.local file'); await expect(exitCodePromise).resolves.toEqual(0); - const rawProdEnv = await fs.readFile(path.join(cwd, '.env')); + const rawProdEnv = await fs.readFile(path.join(cwd, '.env.local')); // check for development env value const envFileHasEnv = rawProdEnv @@ -261,7 +261,7 @@ describe('env', () => { await expect(client.stderr).toOutput( '+ SPECIAL_FLAG (Updated)\n+ NEW_VAR\n- TEST\n' ); - await expect(client.stderr).toOutput('Updated .env file'); + await expect(client.stderr).toOutput('Updated .env.local file'); await expect(pullPromise).resolves.toEqual(0); } finally { @@ -282,7 +282,7 @@ describe('env', () => { client.setArgv('env', 'pull', '--yes', '--cwd', cwd); const pullPromise = env(client); - await expect(client.stderr).toOutput('Updated .env file'); + await expect(client.stderr).toOutput('Updated .env.local file'); await expect(pullPromise).resolves.toEqual(0); }); @@ -299,7 +299,7 @@ describe('env', () => { client.setArgv('env', 'pull', '--yes', '--cwd', cwd); const pullPromise = env(client); await expect(client.stderr).toOutput('> No changes found.'); - await expect(client.stderr).toOutput('Updated .env file'); + await expect(client.stderr).toOutput('Updated .env.local file'); await expect(pullPromise).resolves.toEqual(0); }); @@ -335,7 +335,7 @@ describe('env', () => { 'Downloading `development` Environment Variables for Project env-pull-delta' ); await expect(client.stderr).toOutput('No changes found.\n'); - await expect(client.stderr).toOutput('Updated .env file'); + await expect(client.stderr).toOutput('Updated .env.local file'); await expect(pullPromise).resolves.toEqual(0); } finally {