In the past, we used the `VERCEL_ANALYTICS_ID` environment variable with the previous Speed Insights feature on Vercel to activate specific logic in Next.js, Nuxt and Gatsby for collecting and sending web vitals data.
With the new Speed Insights, that's not required anymore.
We no longer want to set the environment variable when detecting the new `@vercel/speed-insights` package.
This PR confirms that the variable is not set if the new package is detected.
Updates `@vercel/client` to always use the v13 create-deployment endpoint, even when `builds` is present. This allows for `projectSettings.nodeVersion` to be passed when `builds` is present.
* Forces the AL2 build container image for fixtures that depend on it,
via `engines.node` in package.json for most cases.
* The `testDeployment()` function was updated to send
`projectSettings.nodeVersion` in the POST body, to mimic the behavior in
CLI.
* For Go, Ruby, and Python tests, the `projectSettings.nodeVersion`
property is set "globally" in the Jest setup file, so that individual
fixtures didn't need to be adjusted.
Previously, we used `semver` which correctly identified the nodeVersion used in `package.json`, but failed in two cases:
1. If the specified `engines` range started too low, it wouldn't correctly identify a later version compatible with Vercel. (`">10"` was detecting as Node `"10.x"` not `"20.x"`)
2. If the specified `engines` version was fixed too low to be compatible with Vercel, we sent it, and then Vercel predictably errored. (`"10"` was detecting as Node `"10.x"` which would lead to an error in the build process)
Now, case 1 should properly use the latest node version. And case 2 will not send a node version override to the API and will print a warning to the user on the CLI, but the deployment will still proceed with the version specified for the project in the web interface.
We chose to keep the error message shown to the user consistent with what shows in the logs for the build container, that is:
> WARN! Node.js Version "10.x" is discontinued and must be upgraded. Please set "engines": { "node": "20.x" } in your `package.json` file to use Node.js 20.
Read the package.json and use the `engines.node` value to set the
`projectSettings.nodeVersion` property on the create deployment API call
POST body. This allows for the Node 20 build container image to be
properly specified before the deployment is created on the server side.
I noticed that the framework version was not being printed on deployments in a monorepo. Turns out the framework detection logic was happening at the root of the monorepo, instead of the project directory.
- Removes all the legacy `flags`
- Renames the new `variants` to `flags`
Neither the legacy flags, nor the new variants were exposed to anyone, except for the type in build-utils, so there shouldn't be any issues removing/renaming them.
Enables the symlink optimization that currently exists for `Lambda`
instances, but now for `EdgeFunction` instances as well. This will be
particularly beneficial for Remix applications which use edge functions
for many routes, since they will now all be represented by the same
underling function in production.
---------
Co-authored-by: Sean Massa <EndangeredMassa@gmail.com>
Some of our tests take quite some time to run and occasionally timeout when accessing https://yarnpkg.com/. We decided to make sure there is a lockfile for this _and_ just move over to `npm`. Shifting the `packages/cli` fixtures over in this PR.
I possibly missed one but I changed the install commands in tests and ran
* pnpm test
* pnpm test-unit
* pnpm test-dev
* pnpm test-e2e
When this property is set to `true`, then the corresponding `package.json` script will not be invoked, allowing for the default setting value will be executed.
This is enabled for Storybook's `buildCommand`, since we do not want the "build" script to be invoked, since that would belong to the frontend application's build instead of Storybook's.
When repo linked, `vc deploy --prebuilt` will change working directory to the Project root directory, instead of the repo root, so that the project's local `.vercel/output` directory is what gets uploaded + deployed.
This is a follow up to PR #9892 which changed the default to `.env.local`.
Now that we know local files should never be committed to git, we can automatically add `.env*.local` to `.gitignore`. Note that this is the same ignore pattern that ships with create-next-app [as seen here](06abd63489/packages/create-next-app/templates/app/js/gitignore (L28)), so most Next.js users won't see anything change.
See the related [Linear ticket](https://linear.app/vercel/issue/VCCLI-461/)
When the repo is linked to Vercel with `vc link --repo`, the `vc build` command should be invoked from the project subdirectory (otherwise the project selector is displayed). The output directory is at `<projectRoot>/.vercel/output` instead of at the repo root.
When the repo is linked to Vercel with `vc link --repo`, the `.vercel` directory will be created at the _project root_ instead of the _repo root_, and will still contain the `project.json`.
The difference is that the `orgId` and `projectId` props will not be present in the `project.json` file when repo linked, since that information is available at the root level `repo.json` file.
When a project has a `.npmrc` containing `use-node-version`, package managers (notably `pnpm`) will download the specified Node.js version. This is not the correct way as it can lead to `pnpm` downloading Node.js 18 or newer which depends on a version of GLIBC that is not present in the current AWS image. The proper way is to set the `"engines"` in the `package.json`.
<img width="468" alt="image" src="https://github.com/vercel/vercel/assets/97262/0974cf05-6a11-4d95-88e8-13affc4aad2a">
Discussion: https://github.com/orgs/vercel/discussions/2436
This PR removes dependency on the deprecated `lastRollbackTarget` project property and adopts many of the code conventions used in `vc promote`.
Important! Please merge #9984 first!
`vc deploy` ignores `.env.local`. To make sure we don't inadvertently
push people's secrets to source control, have all environment pulls
default to writing to `.env.local`.
# Vercel CLI Extensions
Adds a new mechanism to add additional sub-commands to Vercel CLI, inspired by how Git handles sub-commands:
* Extensions are standalone executables that Vercel CLI will spawn as a child process.
* The name of the executable must begin with `vercel-`. For example, to add a sub-command called `vercel example`, there should exist an executable called `vercel-example`.
* The executable can either be a npm package with a `"bin"` entry installed into the local project's workspace, or be globally available in the `$PATH`.
* Extensions can access the [Vercel REST API](https://vercel.com/docs/rest-api), pre-authenticated, by utilizing the `VERCEL_API` env var. Vercel CLI spawns a local HTTP server that adds the `Authorization` header and then proxies to the Vercel REST API.
## Environment Variables
A few environment variables which provide features and context to the extension:
| Name | Description |
| ----------- | ----------- |
| `VERCEL_API` | HTTP URL to access the pre-authenticated Vercel API. |
| `VERCEL_TEAM_ID` | Provided when the currently selected scope is a Team. |
| `VERCEL_DEBUG` | Provided when the `--debug` flag is used. The command _may_ output additional debug logging. |
| `VERCEL_HELP` | Provided when the `--help` flag is used. The command _should_ print the help output and then end with exit code **2**. |
## Example
```bash
#!/usr/bin/env bash
set -euo pipefail
echo Hi, from a Vercel CLI Extension!
user="$(curl -s "$VERCEL_API/v2/user" | jq -r .user.username)"
echo "Logged in as: $user"
```
Usage:
```
$ vc example
Vercel CLI 28.18.5
Hi, from a Vercel CLI Extension!
Logged in as: tootallnate
```
This enables the CLI to pass locally detected git meta data even when there is no available remote. It requires a corresponding internal change, which is blocking the e2e tests.
There's a need to allow `vc deploy` to not block and not wait for the deployment to finish, yet return the URL.
```
$ vc deploy --no-wait
Vercel CLI 28.18.5
🔍 Inspect: https://vercel.com/chrisbarber/next13fun/L8X4oxp5LGcmy51yVptXwMK7n4wt [1s]
📝 Note: Deployment is still processing...
✅ Production: https://next13fun-kecpx6za2-chrisbarber.vercel.app [1s]
```
Normally this deployment takes around 30 seconds, but the `--no-wait` flag causes the command to exit in less than 2 seconds.
The next step is to add the ability for `vc inspect` to wait as well as specify the maximum time to wait (defaults to 3 minutes, same as `vc rollback`).
```
$ vc inspect --wait --timeout 1m https://next13fun-kecpx6za2-chrisbarber.vercel.app
Vercel CLI 28.18.5
> Fetched deployment "next13fun-ov2r4pvdz-chrisbarber.vercel.app" in chrisbarber [23s]
General
id dpl_9VUuV23EGeoqWf7akEeL8rP1c8cb
name next13fun
status ● Ready
url https://next13fun-ov2r4pvdz-chrisbarber.vercel.app
created Thu Apr 13 2023 12:25:07 GMT-0500 (Central Daylight Time) [24s ago]
<snip>
```
Also added the ability to pipe the URL into `vc inspect`:
```
echo https://next13fun-ov2r4pvdz-chrisbarber.vercel.app | vc inspect
```
Combined, it allows us to support cool things like:
```
$ vc inspect $(vc deploy --prod --no-wait) --wait
```
As reported https://github.com/vercel/vercel/discussions/9648, `vc build` does not honor the `--local-config <file>` option.
`vc build` will only load the `vercel.json` (or `now.json`) in the `workPath` which is based on the `rootDirctory`.
If `--local-config` is specified in the command line arguments, then it should take precedence.
This PR changes the way cron jobs are being created in the build output
API. This is my first time contributing here. If you see something
unusual, let me know.
✅ Good for review
Our goal is to:
- Allow creating cron jobs via the `crons` property of `vercel.json` for
end users
- Allow framework authors to create cron jobs on Vercel via the `crons`
property of the Build Output API configuration
---
As you can see, we removed the previous implementation where cron jobs
could be configured at the function code level (export const cron = ""),
on top of vercel.json `functions` property. Here's why:
- All frameworks would have to implement the configure at the function
code level
- Not all frameworks can easily map a path to a specific function
(example: SvelteKit) and would have to bail on bundling functions inside
the same lambda
- Configuring a path + scheduler provides a better mapping of what cron
jobs are as of today: API routes on a schedule and not functions on a
schedule
- Dynamic routes Cron Jobs will be supported:
/api/crons/sync-slack-team/230
- Query parameters will be supported support:
/api/crons/sync-slack-team/230?secret=32k13l2k13lk21 (= securing cron
jobs v0)
- 100% frameworks compatibility from day one
Next.js and other frameworks may choose to implement their own cron jobs
feature that will then need to be configured through the `crons`
property of `config.json` (build output API).
cc @timneutkens @Rich-Harris
Internal thread:
https://vercel.slack.com/archives/C04DWF5HB6K/p1676366892714349
This PR:
- updates `packages/frameworks` to have most supported frameworks specify which dependency version should reflect the overall framework version
- updates `packages/fs-detectors` to allow framework detection that returns the full `Framework` record instead of just the slug
- updates `packages/next` to return the detected Next.js version in the build result
- updates `packages/cli` to leverage these changes so that `vc build` can add `framework: { version: string; }` to `config.json` output
The result is that Build Output API and supported frameworks will return their framework version in the build result of `vc build` when possible, which is used by the build container when creating the deployment. The dashboard later retrieves this value to display in richer deployment outputs.
Supports:
- https://github.com/vercel/api/pull/15601
- https://github.com/vercel/front/pull/18319
---
With the related build container updates, we get to see Next.js version in the build output. You'll see this with BOA+Prebuilt or a normal deploy:
<img width="1228" alt="Screen Shot 2022-12-09 at 2 48 12 PM" src="https://user-images.githubusercontent.com/41545/206793639-f9cd3bdf-b822-45dd-9564-95b94994271d.png">
---
### The Path to this PR
I went through all the supported frameworks and figured out how to best determine their versions. For most of them, we can check a known dependency's installed version number.
We can get most of the way only checking npm. For a handful, we'd have to support Go/Ruby/Rust/Whatever dependencies.
I started with a more complex method signature to allow for later expansion without changing the signature. It looked like this, in practice:
```
async getVersion(dependencies: DependencyMap) => depedencies['next']
```
However, after checking all currently supported frameworks, I don't think this will end up being necessary. It also has the constraint that all dependencies have to be gathered and presented to the function even though it only needs to check for one or two. That's not a huge deal if we have them already where we need them, but we don't. We could use a variant here where this function does its own lookups, but this seemed unnecessary and would beg for duplication and small variances that could cause bugs.
Further, if we only look at `package.json`, we're going to either see a specific version of a version range. To be precise, we have to look at the installed version of the package. That means checking one of the various types of lockfiles that can exist or poking into node_modules.
If we poke into node_modules to detect the installed version, we introduce another point where Yarn 3 (default mode) will not be supported. If we read lockfiles, we have to potentially parse `npm`, `pnpm`, and `yarn` lockfiles.
If we use `npm ls <package-name>`, that also fails in Yarn 3 (default mode). We could accept that and go forward anyway, which would look like:
```
const args = `ls ${packageName} --depth=0 --json`.split(' ');
const { stdout } = await execa('npm', args, { cwd });
const regex = new RegExp(String.raw`${packageName}@([\.\d]+)`);
const matches = stdout.match(regex);
if (matches) {
return matches[1];
}
```
But it turns out there's a `--json` option! That's what I ended up using, for now.
We could explore the lockfile route more, but after some initial digging, it' non-trivial. There are 3 main lockfiles we'd want to check for (npm, pnpm, and yarn) and there are different lockfile versions that put necessary data in different places. I looked for existing tools that parse this, but I didn't find any. We could certainly go down this path, but the effort doesn't seem worth it when `npm ls` gets us really close.
---
### Follow-up Versioning
Now that we know how to determine version per framework, we can vary configuration by version. In a future PR, we could allow a given value to vary by version number:
```
name: (version) => {
if (semver.gt(version, '9.8.7')) {
return 'some-framework-2''
}
return 'some-framework';
}
```
However, it may still be easier to differentiate significant versions by adding multiple entries in the list.
This PR generates lockfiles for the various monorepo build tests and updates the package versions to their latest within the major. This should help make these tests less flaky.
### 📖 What's in there?
As part of Edge function GA, we're allowing `edge` as a runtime value.
This is adding to the allowed list, so we stay backward compatible.
[Linear ticket](https://linear.app/vercel/issue/EC-481/add-edge-to-the-list-of-allowed-runtimes)
I've kept one instance of `experimental-edge` in the test fixtures to ensure we still supports it.
### 📋 Checklist
#### 🧪 Tests
- [x] The code changed/added as part of this PR has been covered with tests
- [x] All tests pass locally with `yarn test-unit`
#### Code Review
- [x] This PR has a concise title and thorough description useful to a reviewer
- [x] Issue from task tracker has a link to this PR
The `vc rollback` command provides the ability to redeploy a previous
deployment and check the status of a rollback request.
#### Requesting a rollback
vc rollback <id | url>
Upon requesting a rollback, the command will being a status polling loop
for 3 minutes. This timeout can be adjusted via the `--timeout <value>`
option which accepts time formats such as `30s` or `2m`. A timeout of
`0` (zero) will skip the status polling and immediately exit after
successfully requesting a rollback.
#### Querying rollback status
vc rollback
vc rollback status
The `status` action will return the most recent rollback info within the
last 3 minutes.
### Related Issues
>
https://linear.app/vercel/issue/HIT-117/cli-add-support-for-vc-rollback-deployid
>
https://linear.app/vercel/issue/HIT-118/cli-add-support-for-vc-rollback-[status]
### 📋 Checklist
<!--
Please keep your PR as a Draft until the checklist is complete
-->
#### Tests
- [ ] The code changed/added as part of this PR has been covered with
tests
- [ ] All tests pass locally with `yarn test-unit`
#### Code Review
- [ ] This PR has a concise title and thorough description useful to a
reviewer
- [ ] Issue from task tracker has a link to this PR
### Related Issues
Includes a guard checking for `vercel-build` and a LD flag to control
rollout.
### 📋 Checklist
<!--
Please keep your PR as a Draft until the checklist is complete
-->
#### Tests
- [ ] The code changed/added as part of this PR has been covered with
tests
- [ ] All tests pass locally with `yarn test-unit`
#### Code Review
- [ ] This PR has a concise title and thorough description useful to a
reviewer
- [ ] Issue from task tracker has a link to this PR
### Related Issues
Adds support for package.json based turbo configuration.
Includes test.
Confirmed with Turbo that `turbo.json` takes precedence over
`package.json` based config so that is how it is processed here.
### 📋 Checklist
<!--
Please keep your PR as a Draft until the checklist is complete
-->
#### Tests
- [ ] The code changed/added as part of this PR has been covered with
tests
- [ ] All tests pass locally with `yarn test-unit`
#### Code Review
- [ ] This PR has a concise title and thorough description useful to a
reviewer
- [ ] Issue from task tracker has a link to this PR