Compare commits

...

43 Commits

Author SHA1 Message Date
Nathan Rajlich
4c0055eaf0 Publish Stable
- vercel@21.3.2
 - @vercel/python@2.0.0
2021-03-02 11:03:53 -08:00
Nathan Rajlich
910a905192 Remove @vercel/python stable publish blacklist (#5920) 2021-03-02 11:01:02 -08:00
Steven
156a9be06e Publish Stable
- vercel@21.3.1
 - @vercel/go@1.2.1
2021-02-26 16:21:51 -05:00
Steven
e2132ee36d Publish Canary
- vercel@21.3.1-canary.0
 - @vercel/go@1.2.1-canary.0
2021-02-26 15:22:59 -05:00
Steven
4572230c1d [go] Fix analyze ignore list (#5906)
A regression was introduced in #5873 that caused the analyze step to parse Go's internal source files (eg `golang/test/bombad.go`) instead of only parsing the user's source code (eg `api/users.go`).

This resulted in the error:

```
Failed to parse AST for "api/users.go"
Error: Command failed: /vercel/1ab928d537d26157/.build-utils/.builder/node_modules/@vercel/go/dist/analyze -modpath=/vercel/workpath1 /vercel/workpath1/api/users.go
2021/02/26 14:26:42 Could not parse Go file "/vercel/workpath1/.vercel/cache/golang/test/bombad.go"
```
2021-02-26 20:15:34 +00:00
Steven
8cfac4cf86 Publish Stable
- @vercel/frameworks@0.3.0
 - @vercel/build-utils@2.10.0
 - vercel@21.3.0
 - @vercel/client@9.0.7
 - @vercel/go@1.2.0
 - @vercel/routing-utils@1.10.0
2021-02-25 19:53:07 -05:00
Steven
4f20783000 Publish Canary
- vercel@21.2.4-canary.14
2021-02-25 17:47:42 -05:00
Mark Glagola
968b7c3fb5 [cli] Use inspectorUrl from api (#5904)
Uses inspector url from api rather than generating one locally.

### 📋 Checklist

#### 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
2021-02-25 22:29:19 +00:00
Steven
407c4ec5f4 Publish Canary
- @vercel/build-utils@2.9.1-canary.10
 - vercel@21.2.4-canary.13
 - @vercel/client@9.0.7-canary.10
2021-02-24 17:52:33 -05:00
Steven
bcf393d125 [build-utils] Fix warning for canary (#5892)
### Related Issues

Follow up to #5888

### 📋 Checklist

<!--
  Please keep your PR as a Draft until the checklist is complete
-->

#### 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
2021-02-24 17:52:03 -05:00
Steven
115ae0a229 Publish Canary
- @vercel/build-utils@2.9.1-canary.9
 - vercel@21.2.4-canary.12
 - @vercel/client@9.0.7-canary.9
2021-02-24 08:43:24 -05:00
Steven
d149489c9e [build-utils] Update warning for api + pages/api (#5888)
This PR updates the warning for `api` + `pages/api` to only be printed when Next.js is mixed with `@vercel/node` functions. It should not print the warning with `@vercel/go` functions for example.

### 📋 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
2021-02-24 01:12:14 +00:00
Steven
5b2e6052fc Publish Canary
- vercel@21.2.4-canary.11
 - @vercel/go@1.1.9-canary.1
2021-02-23 17:45:14 -05:00
Steven
38cb5a3b99 [go] Add Go version selection via go.mod (#5873)
### 📋 Checklist

<!--
  Please keep your PR as a Draft until the checklist is complete
-->

#### 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
2021-02-23 16:41:59 -05:00
Steven
84e828a0ca Publish Canary
- @vercel/frameworks@0.2.1-canary.7
 - @vercel/build-utils@2.9.1-canary.8
 - vercel@21.2.4-canary.10
 - @vercel/client@9.0.7-canary.8
2021-02-23 13:13:43 -05:00
Steven
157ce5346d [build-utils] Update Node.js 10 deprecation message (#5881)
This PR updates the discontinued date according to the changelog.

It also conditionally prints a hint to update `engines` if present or update Project Settings.

https://vercel.com/changelog/node-js-10-is-being-deprecated
2021-02-23 18:12:43 +00:00
Nathan Rajlich
0256157391 [examples] Fix "nuxtjs" example by adding a yarn.lock file (#5882)
`@babel/preset-env` shipped a change that broke Nuxt.js usage of the
module, so here we add a `yarn.lock` file that pins the preset-env
version to 7.12.17.

See: https://github.com/nuxt/nuxt.js/issues/8882
2021-02-22 18:03:50 -08:00
Steven
a45b3d0982 [examples] Update jekyll and middleman (#5871)
This PR updates the examples for jekyll and middleman to use the latest version.

I confirmed these examples work with both stable and canary.
2021-02-22 10:14:32 -05:00
Connor Davis
26af6dbc03 [tests] Update 502 to 504 for Serverless Function timeout (#5874)
We now return a 504 for lambda timeouts

### Related Issues

Related to https://github.com/vercel/now-proxy/pull/1970

#### Tests

- [x] The code changed/added as part of this PR has been covered with tests
- [ ] All tests pass locally with `yarn test-unit`

#### Code Review

- [x] This PR has a concise title and thorough description useful to a reviewer
2021-02-20 17:04:29 +00:00
Mark Glagola
38130103a0 [cli] Replace now.sh tests with vercel.app 2021-02-19 19:22:51 -05:00
Steven
978485818a Publish Canary
- @vercel/build-utils@2.9.1-canary.7
 - vercel@21.2.4-canary.9
 - @vercel/client@9.0.7-canary.7
2021-02-19 14:38:17 -05:00
Steven
0270784cbb [build-utils] Remove flags from bundle install (#5865)
This PR removes the flags from `bundle install` which fixes the deprecated warnings such as 

```
[DEPRECATED] The `--no-prune` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set --local no_prune 'true'`, and stop using this flag
```

These flags already represent the defaults for `bundle install` anyway and we can pass environment variables in the spawn options instead.
2021-02-19 19:37:39 +00:00
Naoyuki Kanezawa
345e514924 [build-utils] Fix glob to find symlinks pointing to a directory (#5870)
https://app.clubhouse.io/vercel/story/16876

This will fix the issue that symlinks pointing to a directory is not returned on `prepareCache` and node modules linked to local files don't work.

### Related Issues

### 📋 Checklist

<!--
  Please keep your PR as a Draft until the checklist is complete
-->

#### 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

Co-authored-by: Steven <steven@ceriously.com>
2021-02-19 12:43:52 -05:00
Steven
df62ec6ed0 [cli] Disable Next.js gif test and Node.js 10 tests (#5867)
* Disable gif optimization test

* Disable Node 10 tests
2021-02-19 11:20:35 -05:00
Steven
f7f81fb896 Publish Canary
- @vercel/frameworks@0.2.1-canary.6
 - @vercel/build-utils@2.9.1-canary.6
 - vercel@21.2.4-canary.8
 - @vercel/client@9.0.7-canary.6
2021-02-18 09:53:11 -05:00
Steven
a210c6e4f0 [frameworks] Add cachePattern to jekyll and middleman (#5862)
Cache the results of `bundle install`.

Related to #3908
2021-02-18 09:52:22 -05:00
Steven
50080e4b92 Publish Canary
- @vercel/frameworks@0.2.1-canary.5
 - @vercel/build-utils@2.9.1-canary.5
 - vercel@21.2.4-canary.7
 - @vercel/client@9.0.7-canary.5
 - @vercel/go@1.1.9-canary.0
2021-02-17 19:48:18 -05:00
Steven
5845bebe2d [go] Update to version 1.16 (#5858)
https://blog.golang.org/go1.16

[ch19891]
2021-02-18 00:39:09 +00:00
Steven
3e18146846 [frameworks][examples] Update RedwoodJS to 0.25.0 (#5842)
RedwoodJS [v0.25.0](https://github.com/redwoodjs/redwood/releases/tag/v0.25.0) changed to a different build command: [yarn rw deploy vercel](https://redwoodjs.com/docs/cli-commands#vercel)

This also updates the example to use the latest template from `created-redwood-app`.
2021-02-17 16:02:53 -05:00
Steven
dbde60f47f [tests] Add test for animated gif bypass (#5851)
Animated gif should bypass (serve as-is).

This is to avoid the time it takes to optimize animated images which can sometimes take minutes.

It also matches how `next dev` works so we want to stay consistent (this tests both dev and a deployment).
2021-02-16 12:16:45 -05:00
luc
aa3db23cad Publish Canary
- vercel@21.2.4-canary.6
2021-02-16 15:45:00 +01:00
Luc Leray
60a5b0a586 [cli] Use POST /projects for vc projects add (#5824)
* replace "ensure project" with "create project"

* Revert "replace "ensure project" with "create project""

This reverts commit c6955d5abda5eb9e1140d5d1d76ec7a4b193fe90.

* add test

* upsert project
2021-02-15 21:29:23 +01:00
Nathan Rajlich
8b682ccc41 Publish Canary
- @vercel/frameworks@0.2.1-canary.4
 - @vercel/build-utils@2.9.1-canary.4
 - vercel@21.2.4-canary.5
 - @vercel/client@9.0.7-canary.4
2021-02-12 18:08:29 -08:00
Nathan Rajlich
50055963af [frameworks] Fix "zola" framework detection (#5844)
`"hugo"` was a false-positive.
2021-02-12 18:07:53 -08:00
Nathan Rajlich
43fa6e6d97 Publish Canary
- @vercel/frameworks@0.2.1-canary.3
 - @vercel/build-utils@2.9.1-canary.3
 - vercel@21.2.4-canary.4
 - @vercel/client@9.0.7-canary.3
2021-02-12 16:08:49 -08:00
Nathan Rajlich
98c0b9b573 [frameworks] Add "detectors" for Zola framework (#5843) 2021-02-12 16:04:25 -08:00
Nathan Rajlich
8b8541f4aa Publish Canary
- @vercel/frameworks@0.2.1-canary.2
 - @vercel/build-utils@2.9.1-canary.2
 - vercel@21.2.4-canary.3
 - @vercel/client@9.0.7-canary.2
2021-02-12 14:22:16 -08:00
Nathan Rajlich
59cc2bf0f2 [build-utils] Inherit process.env when runPackageJsonScript() is invoking yarn (#5841)
This is a more proper fix for #5825.
2021-02-12 14:17:59 -08:00
Nathan Rajlich
30e078062f [frameworks] Add defaultVersion field (#5839)
This will be used on the docs page to render the default version that is
included in the build image.
2021-02-12 12:21:05 -08:00
Nathan Rajlich
4d015a60ef [tests] Add --network-timeout 1000000 to yarn install (#5840)
Seems like this might help with the networking issues in CI.
See https://github.com/yarnpkg/yarn/issues/4890#issuecomment-358179301
2021-02-12 12:20:48 -08:00
Nathan Rajlich
ad0e66242d [build-utils] Fix unit tests from @vercel/frameworks type change (#5829)
Fixes TypeScript error:

```
test/unit.framework-detector.test.ts:52:40 - error TS4104: The type 'readonly Framework[]' is 'readonly' and cannot be assigned to the mutable type 'Framework[]'.

52     expect(await detectFramework({ fs, frameworkList })).toBe(null);
                                          ~~~~~~~~~~~~~
```
2021-02-12 15:51:34 +00:00
Ana Jovanova
044f956de2 Publish Canary
- vercel@21.2.4-canary.2
2021-02-12 11:38:39 +01:00
Ana Trajkovska
d26ed43d26 [cli] Implement generic announcement system (#5697)
This PR improves the CLI in a way that if the API from any request returns a response which contains a header with the prefix `x-vercel-warning-*`, `x-vercel-notice-*` or `x-vercel-tip-*`, it will print out the message to the output to let the user know.

This new feature also supports additional headers which improve the message, so that a link can be printed out for more information. Those are `x-vercel-link-*`, where we specify a link, and `x-vercel-action`, where we specify the text before the link.

Here's an example for a warning message which warns the user if they add a DNS record for a domain which does not use Vercel Nameservers:

<img width="719" alt="Screenshot 2021-01-18 at 17 49 14" src="https://user-images.githubusercontent.com/35507539/104943788-8da12400-59b6-11eb-8e54-77a3c517e56d.png">

The API request from above which creates a DNS record has the following HTTP response headers set:

```
x-vercel-warning-create-domain-record: Your Domain isn't using Vercel nameservers. In order for the changes to your DNS Records to get applied, however, it needs to.
x-vercel-link-create-domain-record: https://vercel.link/configure-vercel-nameservers
```

If `x-vercel-action` is not specified, it defaults to `Learn More`.

### 📋 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
- [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
2021-02-12 09:28:47 +00:00
98 changed files with 13113 additions and 3868 deletions

View File

@@ -17,7 +17,7 @@ jobs:
with:
node-version: 12
- name: Install
run: yarn install --check-files --frozen-lockfile
run: yarn install --check-files --frozen-lockfile --network-timeout 1000000
- name: Build
run: yarn build
env:

View File

@@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
node: [10, 12]
node: [12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
@@ -26,7 +26,7 @@ jobs:
- run: git fetch origin master --depth=100
- run: git fetch origin ${{ github.ref }} --depth=100
- run: git diff origin/master...HEAD --name-only
- run: yarn install
- run: yarn install --network-timeout 1000000
- run: yarn run build
- uses: actions/setup-node@v1
with:

View File

@@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
node: [10, 12]
node: [12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
@@ -29,7 +29,7 @@ jobs:
- name: Install Hugo
if: matrix.os == 'macos-latest'
run: curl -L -O https://github.com/gohugoio/hugo/releases/download/v0.56.0/hugo_0.56.0_macOS-64bit.tar.gz && tar -xzf hugo_0.56.0_macOS-64bit.tar.gz && mv ./hugo packages/now-cli/test/dev/fixtures/08-hugo/
- run: yarn install
- run: yarn install --network-timeout 1000000
- run: yarn run build
- uses: actions/setup-node@v1
with:

View File

@@ -21,7 +21,7 @@ jobs:
- run: git fetch origin master --depth=100
- run: git fetch origin ${{ github.ref }} --depth=100
- run: git diff origin/master...HEAD --name-only
- run: yarn install
- run: yarn install --network-timeout 1000000
- run: yarn run build
- run: yarn test-integration-once --clean false
env:

View File

@@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [10, 12]
node: [12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
@@ -29,7 +29,7 @@ jobs:
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: yarn install
- run: yarn install --network-timeout 1000000
- run: yarn run build
- run: yarn run lint
if: matrix.os == 'ubuntu-latest' && matrix.node == 12 # only run lint once

View File

@@ -1,6 +1,9 @@
_site
public
.sass-cache
.jekyll-cache
.jekyll-metadata
vendor
public
.env
.env.build
.vercel

View File

@@ -1,2 +0,0 @@
README.md
yarn.lock

View File

@@ -1,4 +1,5 @@
---
permalink: /404.html
layout: default
---

View File

@@ -1,5 +1,4 @@
source "https://rubygems.org"
# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
@@ -8,27 +7,23 @@ source "https://rubygems.org"
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
gem "jekyll", "~> 3.8.6"
gem "jekyll", "~> 4.2.0"
# This is the default theme for new Jekyll sites. You may change this to anything you like.
gem "minima", "~> 2.0"
gem "minima", "~> 2.5"
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
# gem "github-pages", group: :jekyll_plugins
# If you have any plugins, put them here!
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.6"
gem "jekyll-feed", "~> 0.12"
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
# and associated library.
install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
platforms :mingw, :x64_mingw, :mswin, :jruby do
gem "tzinfo", "~> 1.2"
gem "tzinfo-data"
end
# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]

View File

@@ -1,82 +1,80 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
colorator (1.1.0)
concurrent-ruby (1.1.5)
em-websocket (0.5.1)
concurrent-ruby (1.1.8)
em-websocket (0.5.2)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
eventmachine (1.2.7)
ffi (1.11.1)
ffi (1.14.2)
forwardable-extended (2.6.0)
http_parser.rb (0.6.0)
i18n (0.9.5)
i18n (1.8.9)
concurrent-ruby (~> 1.0)
jekyll (3.8.6)
jekyll (4.2.0)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (~> 0.7)
jekyll-sass-converter (~> 1.0)
i18n (~> 1.0)
jekyll-sass-converter (~> 2.0)
jekyll-watch (~> 2.0)
kramdown (~> 1.14)
kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.0)
liquid (~> 4.0)
mercenary (~> 0.3.3)
mercenary (~> 0.4.0)
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
rouge (~> 3.0)
safe_yaml (~> 1.0)
jekyll-feed (0.12.1)
terminal-table (~> 2.0)
jekyll-feed (0.15.1)
jekyll (>= 3.7, < 5.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.6.1)
jekyll (>= 3.3, < 5.0)
jekyll-sass-converter (2.1.0)
sassc (> 2.0.1, < 3.0)
jekyll-seo-tag (2.7.1)
jekyll (>= 3.8, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
kramdown (1.17.0)
kramdown (2.3.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.3)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
mercenary (0.3.6)
minima (2.5.0)
jekyll (~> 3.5)
listen (3.4.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.4.0)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (3.1.1)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
public_suffix (4.0.6)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
rouge (3.6.0)
ruby_dep (1.5.0)
rexml (3.2.4)
rouge (3.26.0)
safe_yaml (1.0.5)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
thread_safe (0.3.6)
tzinfo (1.2.5)
thread_safe (~> 0.1)
tzinfo-data (1.2019.2)
tzinfo (>= 1.0.0)
wdm (0.1.1)
sassc (2.4.0)
ffi (~> 1.9)
terminal-table (2.0.0)
unicode-display_width (~> 1.1, >= 1.1.1)
unicode-display_width (1.7.0)
PLATFORMS
ruby
x86_64-linux
DEPENDENCIES
jekyll (~> 3.8.6)
jekyll-feed (~> 0.6)
minima (~> 2.0)
jekyll (~> 4.2.0)
jekyll-feed (~> 0.12)
minima (~> 2.5)
tzinfo (~> 1.2)
tzinfo-data
wdm (~> 0.1.0)
wdm (~> 0.1.1)
BUNDLED WITH
2.1.4
2.2.4

View File

@@ -7,12 +7,17 @@
#
# For technical reasons, this file is *NOT* reloaded automatically when you use
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
#
# If you need help with YAML syntax, here are some quick references for you:
# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
# https://learnxinyminutes.com/docs/yaml/
#
# Site settings
# These are used to personalize your new site. If you look in the HTML files,
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
# You can create any custom variable you would like, and they will be accessible
# in the templates via {{ site.myvariable }}.
title: Your awesome title
email: your-email@example.com
description: >- # this means to ignore newlines until "baseurl:"
@@ -23,21 +28,27 @@ baseurl: "" # the subpath of your site, e.g. /blog
url: "" # the base hostname & protocol for your site, e.g. http://example.com
twitter_username: jekyllrb
github_username: jekyll
permalink: pretty
# Build settings
markdown: kramdown
theme: minima
plugins:
- jekyll-feed
# Exclude from processing.
# The following items will not be processed, by default. Create a custom list
# to override the default setting.
# The following items will not be processed, by default.
# Any item listed under the `exclude:` key here will be automatically added to
# the internal "default list".
#
# Excluded items can be processed by explicitly listing the directories or
# their entries' file path in the `include:` list.
#
# exclude:
# - .sass-cache/
# - .jekyll-cache/
# - gemfiles/
# - Gemfile
# - Gemfile.lock
# - node_modules
# - node_modules/
# - vendor/bundle/
# - vendor/cache/
# - vendor/gems/

View File

@@ -1,18 +1,23 @@
---
layout: post
title: "Welcome to Jekyll!"
date: 2019-07-18 00:15:52 +0100
title: 'Welcome to Jekyll!'
date: 2021-02-19 23:17:16 +0000
categories: jekyll update
---
Youll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.
Jekyll requires blog post files to be named according to the following format:
`YEAR-MONTH-DAY-title.MARKUP`
Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.
Jekyll also offers powerful support for code snippets:
{% highlight ruby %}
def print_hi(name)
puts "Hi, #{name}"
puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
@@ -21,5 +26,5 @@ print_hi('Tom')
Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekylls GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
[jekyll-docs]: https://jekyllrb.com/docs/home
[jekyll-gh]: https://github.com/jekyll/jekyll
[jekyll-gh]: https://github.com/jekyll/jekyll
[jekyll-talk]: https://talk.jekyllrb.com/

View File

@@ -3,3 +3,4 @@
.DS_Store
.sass-cache
build/
.vercel

View File

@@ -1,29 +1,29 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (5.0.7.2)
activesupport (5.2.4.5)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
autoprefixer-rails (9.6.1.1)
autoprefixer-rails (9.8.6.5)
execjs
backports (3.15.0)
backports (3.20.2)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.1.5)
concurrent-ruby (1.1.8)
contracts (0.13.0)
dotenv (2.7.5)
dotenv (2.7.6)
erubis (2.7.0)
execjs (2.7.0)
fast_blank (1.0.0)
fastimage (2.1.7)
ffi (1.11.1)
haml (5.1.2)
fastimage (2.2.2)
ffi (1.14.2)
haml (5.2.1)
temple (>= 0.8.0)
tilt
hamster (3.0.0)
@@ -31,24 +31,25 @@ GEM
hashie (3.6.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
kramdown (1.17.0)
kramdown (2.3.0)
rexml
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
memoist (0.16.0)
middleman (4.3.5)
memoist (0.16.2)
middleman (4.3.11)
coffee-script (~> 2.2)
haml (>= 4.0.5)
kramdown (~> 1.2)
middleman-cli (= 4.3.5)
middleman-core (= 4.3.5)
kramdown (>= 2.3.0)
middleman-cli (= 4.3.11)
middleman-core (= 4.3.11)
middleman-autoprefixer (2.10.1)
autoprefixer-rails (~> 9.1)
middleman-core (>= 3.3.3)
middleman-cli (4.3.5)
middleman-cli (4.3.11)
thor (>= 0.17.0, < 2.0)
middleman-core (4.3.5)
activesupport (>= 4.2, < 5.1)
middleman-core (4.3.11)
activesupport (>= 4.2, < 6.0)
addressable (~> 2.3)
backports (~> 3.6)
bundler
@@ -70,33 +71,34 @@ GEM
servolux
tilt (~> 2.0.9)
uglifier (~> 3.0)
minitest (5.12.2)
minitest (5.14.3)
padrino-helpers (0.13.3.4)
i18n (~> 0.6, >= 0.6.7)
padrino-support (= 0.13.3.4)
tilt (>= 1.4.1, < 3)
padrino-support (0.13.3.4)
activesupport (>= 3.1)
parallel (1.17.0)
public_suffix (4.0.1)
rack (2.0.7)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
parallel (1.20.1)
public_suffix (4.0.6)
rack (2.2.3)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
sassc (2.2.1)
rexml (3.2.4)
sassc (2.4.0)
ffi (~> 1.9)
servolux (0.13.0)
temple (0.8.2)
thor (0.20.3)
thor (1.1.0)
thread_safe (0.3.6)
tilt (2.0.10)
tzinfo (1.2.5)
tzinfo (1.2.9)
thread_safe (~> 0.1)
uglifier (3.2.0)
execjs (>= 0.3.0, < 3)
PLATFORMS
ruby
x86_64-linux
DEPENDENCIES
middleman (~> 4.2)
@@ -105,4 +107,4 @@ DEPENDENCIES
wdm (~> 0.1)
BUNDLED WITH
2.1.4
2.2.4

View File

@@ -1,2 +0,0 @@
README.md
yarn.lock

View File

@@ -1,2 +1 @@
README.md
build

View File

@@ -13,6 +13,6 @@
"nuxt": "^2.0.0"
},
"devDependencies": {
"nodemon": "^1.18.9"
"nodemon": "^2.0.7"
}
}

8116
examples/nuxtjs/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +0,0 @@
# editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

View File

@@ -3,5 +3,11 @@
# system. Any custom values should go in .env and .env should *not* be checked
# into version control.
# schema.prisma defaults
DATABASE_URL=file:./dev.db
BINARY_TARGET=native
# location of the test database for api service scenarios (defaults to ./.redwood/test.db if not set)
# TEST_DATABASE_URL=file:./.redwood/test.db
# disables Prisma CLI update notifier
PRISMA_HIDE_UPDATE_MESSAGE=true

View File

@@ -1,10 +1,13 @@
.idea
.DS_Store
.env
.netlify
.redwood
dev.db
dist
dist-babel
node_modules
yarn-error.log
web/public/mockServiceWorker.js
.vercel

View File

@@ -1 +0,0 @@
lts/*

View File

@@ -5,11 +5,11 @@ datasource DS {
generator client {
provider = "prisma-client-js"
binaryTargets = env("BINARY_TARGET")
binaryTargets = "native"
}
// Define your own datamodels here and run `yarn redwood db save` to create
// migrations for them.
// Define your own datamodels here and run `yarn redwood prisma migrate dev`
// to create migrations for them and apply to your dev DB.
// TODO: Please remove the following example:
model UserExample {
id Int @id @default(autoincrement())

View File

@@ -6,6 +6,8 @@ dotenv.config()
const db = new PrismaClient()
async function main() {
// https://www.prisma.io/docs/guides/prisma-guides/seed-database
//
// Seed data is database data that needs to exist for your app to run.
// Ideally this file should be idempotent: running it multiple times
// will result in the same database state (usually by checking for the
@@ -16,11 +18,11 @@ async function main() {
// await db.user.create({ data: { name: 'Admin', email: 'admin@email.com' }})
// }
console.info('No data to seed. See api/prisma/seeds.js for info.')
console.info('No data to seed. See api/db/seed.js for info.')
}
main()
.catch((e) => console.error(e))
.finally(async () => {
await db.disconnect()
await db.$disconnect()
})

View File

@@ -0,0 +1,6 @@
const { getConfig } = require('@redwoodjs/core')
const config = getConfig({ type: 'jest', target: 'node' })
config.displayName.name = 'api'
module.exports = config

View File

@@ -5,5 +5,5 @@
"src/*": ["./src/*"]
}
},
"include": ["src/**/*"]
"include": ["src/**/*", "../.redwood/index.d.ts"]
}

View File

@@ -3,6 +3,6 @@
"version": "0.0.0",
"private": true,
"dependencies": {
"@redwoodjs/api": "0.15.0"
"@redwoodjs/api": "^0.25.0"
}
}

View File

@@ -3,17 +3,18 @@ import {
makeMergedSchema,
makeServices,
} from '@redwoodjs/api'
import importAll from '@redwoodjs/api/importAll.macro'
import schemas from 'src/graphql/**/*.{js,ts}'
import { db } from 'src/lib/db'
const schemas = importAll('api', 'graphql')
const services = importAll('api', 'services')
import services from 'src/services/**/*.{js,ts}'
export const handler = createGraphQLHandler({
schema: makeMergedSchema({
schemas,
services: makeServices({ services }),
}),
db,
onException: () => {
// Disconnect from your database with an unhandled exception.
db.$disconnect()
},
})

View File

@@ -1,4 +1,4 @@
// See https://github.com/prisma/prisma2/blob/master/docs/prisma-client-js/api.md#constructor
// See https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/constructor
// for options.
import { PrismaClient } from '@prisma/client'

View File

@@ -0,0 +1,7 @@
const { getConfig } = require('@redwoodjs/internal')
const config = getConfig()
module.exports = {
schema: `http://${config.api.host}:${config.api.port}/graphql`,
}

View File

@@ -3,11 +3,12 @@
"workspaces": {
"packages": [
"api",
"web"
"web",
"packages/*"
]
},
"devDependencies": {
"@redwoodjs/core": "0.15.0"
"@redwoodjs/core": "^0.25.0"
},
"eslintConfig": {
"extends": "@redwoodjs/eslint-config"

View File

@@ -6,4 +6,12 @@ module.exports = {
semi: false,
singleQuote: true,
arrowParens: 'always',
overrides: [
{
files: 'Routes.js',
options: {
printWidth: 200,
},
},
],
}

View File

@@ -1,7 +1,15 @@
# This file contains the configuration settings for your Redwood app.
# This file is also what makes your Redwood app a Redwood app.
# If you remove it and try to run `yarn rw dev`, you'll get an error.
#
# For the full list of options, see the "App Configuration: redwood.toml" doc:
# https://redwoodjs.com/docs/app-configuration-redwood-toml
[web]
port = 8910
apiProxyPath = "/api"
[api]
port = 8911
schemaPath = "./api/db/schema.prisma"
[browser]
open = false

View File

@@ -0,0 +1,6 @@
const { getConfig } = require('@redwoodjs/core')
const config = getConfig({ type: 'jest', target: 'browser' })
config.displayName.name = 'web'
module.exports = config

View File

@@ -6,5 +6,5 @@
},
"jsx": "preserve"
},
"include": ["src/**/*"]
"include": ["src/**/*", "../.redwood/index.d.ts"]
}

View File

@@ -2,12 +2,20 @@
"name": "web",
"version": "0.0.0",
"private": true,
"browserslist": [
"defaults"
],
"browserslist": {
"development": [
"last 1 version"
],
"production": [
"defaults",
"not IE 11",
"not IE_Mob 11"
]
},
"dependencies": {
"@redwoodjs/router": "0.15.0",
"@redwoodjs/web": "0.15.0",
"@redwoodjs/forms": "^0.25.0",
"@redwoodjs/router": "^0.25.0",
"@redwoodjs/web": "^0.25.0",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1"

View File

@@ -1,13 +1,19 @@
# Static Assets
Use this folder to add static files directly to your app. All included files and folders will be copied directly into the `/dist` folder (created when Webpack builds for production). They will also be available during development when you run `yarn rw dev`.
>Note: files will *not* hot reload while the development server is running. You'll need to manually stop/start to access file changes.
> Note: files will _not_ hot reload while the development server is running. You'll need to manually stop/start to access file changes.
### Example Use
A file like `favicon.png` will be copied to `/dist/favicon.png`. A folder containing a file such as `static-files/my-logo.jpg` will be copied to `/dist/static-files/my-logo.jpg`. These can be referenced in your code directly without any special handling, e.g.
```
<link rel="icon" type="image/png" href="/favicon.png" />
```
and
```
<img src="/static-files/my-logo.jpg"> alt="Logo" />
```
@@ -15,12 +21,15 @@ and
Behind the scenes, we are using Webpack's ["copy-webpack-plugin"](https://github.com/webpack-contrib/copy-webpack-plugin).
## Best Practices
Because assets in this folder are bypassing the javascript module system, **this folder should be used sparingly** for assets such as favicons, robots.txt, manifests, libraries incompatible with Webpack, etc.
In general, it's best to import files directly into a template, page, or component. This allows Webpack to include that file in the bundle, which ensures Webpack will correctly process and move assets into the distribution folder, providing error checks and correct paths along the way.
### Example Asset Import with Webpack
Instead of handling our logo image as a static file per the example above, we can do the following:
```
import React from "react"
import logo from "./my-logo.jpg"

View File

@@ -1,16 +1,18 @@
import ReactDOM from 'react-dom'
import { RedwoodProvider, FatalErrorBoundary } from '@redwoodjs/web'
import FatalErrorPage from 'src/pages/FatalErrorPage'
import { FatalErrorBoundary } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'
import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'
import './index.css'
ReactDOM.render(
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider>
<RedwoodApolloProvider>
<Routes />
</RedwoodProvider>
</RedwoodApolloProvider>
</FatalErrorBoundary>,
document.getElementById('redwood-app')
)

View File

@@ -1,4 +1,6 @@
export default () => (
import { Link, routes } from '@redwoodjs/router'
const AboutPage = () => (
<main>
<style
dangerouslySetInnerHTML={{
@@ -36,9 +38,16 @@ export default () => (
}}
/>
<section>
<h1>
<span>About RedwoodJS</span>
</h1>
<h1>About</h1>
<p>
Find me in <code>./web/src/pages/AboutPage/AboutPage.js</code>
</p>
<p>
My default route is named <code>about</code>, link to me with `
<Link to={routes.about()}>About</Link>`
</p>
</section>
</main>
)
export default AboutPage

View File

@@ -1,4 +1,6 @@
export default () => (
import { Link, routes } from '@redwoodjs/router'
const HomePage = () => (
<main>
<style
dangerouslySetInnerHTML={{
@@ -36,9 +38,16 @@ export default () => (
}}
/>
<section>
<h1>
<span>Welcome to RedwoodJS!</span>
</h1>
<h1>Welcome to RedwoodJS!</h1>
<p>
Find me in <code>./web/src/pages/HomePage/HomePage.js</code>
</p>
<p>
My default route is named <code>home</code>, link to me with `
<Link to={routes.home()}>Home</Link>`
</p>
</section>
</main>
)
export default HomePage

View File

@@ -0,0 +1,7 @@
import HomePage from './HomePage'
export const generated = () => {
return <HomePage />
}
export default { title: 'Pages/HomePage' }

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/frameworks",
"version": "0.2.1-canary.1",
"version": "0.3.0",
"main": "./dist/frameworks.js",
"types": "./dist/frameworks.d.ts",
"files": [
@@ -20,7 +20,7 @@
"@types/js-yaml": "3.12.1",
"@types/node": "12.0.4",
"@types/node-fetch": "2.5.8",
"@vercel/routing-utils": "1.9.3-canary.0",
"@vercel/routing-utils": "1.10.0",
"ajv": "6.12.2",
"jest": "24.9.0",
"ts-jest": "24.1.0",

View File

@@ -1320,8 +1320,7 @@ export const frameworks = [
placeholder: '`yarn install` or `npm install`',
},
buildCommand: {
value:
'yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up',
value: 'yarn rw deploy vercel',
},
devCommand: {
value: 'yarn rw dev --fwd="--port=$PORT --open=false"',
@@ -1331,8 +1330,7 @@ export const frameworks = [
},
},
devCommand: 'yarn rw dev --fwd="--port=$PORT --open=false',
buildCommand:
'yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up',
buildCommand: 'yarn rw deploy vercel',
getOutputDirName: async () => 'public',
},
{
@@ -1350,12 +1348,15 @@ export const frameworks = [
some: [
{
path: 'config.yaml',
matchContent: 'baseURL',
},
{
path: 'config.toml',
matchContent: 'baseURL',
},
{
path: 'config.json',
matchContent: 'baseURL',
},
],
},
@@ -1385,11 +1386,12 @@ export const frameworks = [
return (config && config.publishDir) || 'public';
},
defaultVersion: '0.58.2',
},
{
name: 'Jekyll',
slug: 'jekyll',
demo: 'https://jekyll.now-examples.now.sh',
demo: 'https://jekyll.now-examples.vercel.app',
logo:
'https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/jekyll.svg',
tagline:
@@ -1426,6 +1428,7 @@ export const frameworks = [
);
return (config && config.destination) || '_site';
},
cachePattern: '{vendor/bin,vendor/cache,vendor/bundle}/**',
},
{
name: 'Brunch',
@@ -1465,7 +1468,7 @@ export const frameworks = [
{
name: 'Middleman',
slug: 'middleman',
demo: 'https://middleman.now-examples.now.sh',
demo: 'https://middleman.now-examples.vercel.app',
logo:
'https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/middleman.svg',
tagline:
@@ -1496,6 +1499,7 @@ export const frameworks = [
devCommand: 'bundle exec middleman server -p $PORT',
buildCommand: 'bundle exec middleman build',
getOutputDirName: async () => 'build',
cachePattern: '{vendor/bin,vendor/cache,vendor/bundle}/**',
},
{
name: 'Zola',
@@ -1506,6 +1510,14 @@ export const frameworks = [
tagline: 'Everything you need to make a static site engine in one binary.',
description: 'A Zola app, created with the "Getting Started" tutorial.',
website: 'https://www.getzola.org',
detectors: {
every: [
{
path: 'config.toml',
matchContent: 'base_url',
},
],
},
settings: {
installCommand: {
placeholder: 'None',
@@ -1523,6 +1535,7 @@ export const frameworks = [
devCommand: 'zola serve --port $PORT',
buildCommand: 'zola build',
getOutputDirName: async () => 'public',
defaultVersion: '0.13.0',
},
{
name: 'Other',

View File

@@ -170,4 +170,10 @@ export interface Framework {
* @example "next dev"
*/
devCommand: string | null;
/**
* The default version of the framework command that is available within the
* build image. Usually an environment variable can be set to override this.
* @example "0.13.0"
*/
defaultVersion?: string;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "2.9.1-canary.1",
"version": "2.10.0",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",
@@ -29,7 +29,7 @@
"@types/node-fetch": "^2.1.6",
"@types/semver": "6.0.0",
"@types/yazl": "^2.4.1",
"@vercel/frameworks": "0.2.1-canary.1",
"@vercel/frameworks": "0.3.0",
"@vercel/ncc": "0.24.0",
"aggregate-error": "3.0.1",
"async-retry": "1.2.3",

View File

@@ -311,11 +311,16 @@ export async function detectBuilders(
if (frontendBuilder) {
builders.push(frontendBuilder);
if (hasNextApiFiles && apiBuilders.length) {
if (
hasNextApiFiles &&
apiBuilders.some(b => isOfficialRuntime('node', b.use))
) {
warnings.push({
code: 'conflicting_files',
message:
'It is not possible to use `api` and `pages/api` at the same time, please only use one option',
'When using Next.js, it is recommended to place Node.js Serverless Functions inside of the `pages/api` (provided by Next.js) directory instead of `api` (provided by Vercel).',
link: 'https://nextjs.org/docs/api-routes/introduction',
action: 'Learn More',
});
}
}
@@ -944,8 +949,8 @@ function getRouteResult(
const rewriteRoutes: Route[] = [];
const errorRoutes: Route[] = [];
const framework = frontendBuilder?.config?.framework || '';
const use = frontendBuilder?.use || '';
const isNextjs = framework === 'nextjs' || use.startsWith('@vercel/next');
const isNextjs =
framework === 'nextjs' || isOfficialRuntime('next', frontendBuilder?.use);
const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
if (apiRoutes && apiRoutes.length > 0) {

View File

@@ -3,7 +3,7 @@ import { DetectorFilesystem } from './detectors/filesystem';
export interface DetectFrameworkOptions {
fs: DetectorFilesystem;
frameworkList: Framework[];
frameworkList: readonly Framework[];
}
async function matches(fs: DetectorFilesystem, framework: Framework) {

View File

@@ -51,8 +51,8 @@ export default async function glob(
stat,
`statCache does not contain value for ${relativePath} (resolved to ${fsPath})`
);
if (stat.isFile()) {
const isSymlink = options.symlinks![fsPath];
const isSymlink = options.symlinks![fsPath];
if (isSymlink || stat.isFile()) {
if (isSymlink) {
stat = await lstat(fsPath);
}

View File

@@ -1,5 +1,4 @@
import { intersects, validRange } from 'semver';
import boxen from 'boxen';
import { NodeVersion } from '../types';
import { NowBuildError } from '../errors';
import debug from '../debug';
@@ -11,7 +10,7 @@ const allOptions = [
major: 10,
range: '10.x',
runtime: 'nodejs10.x',
discontinueDate: new Date('2021-03-30'),
discontinueDate: new Date('2021-04-20'),
},
{
major: 8,
@@ -21,15 +20,15 @@ const allOptions = [
},
] as const;
const pleaseSet =
'Please change your Project Settings or set "engines": { "node": "' +
getLatestNodeVersion().range +
'" } in your `package.json` file to use Node.js ' +
getLatestNodeVersion().major +
'.';
function getHint(isAuto: boolean) {
const { major, range } = getLatestNodeVersion();
return isAuto
? `Please set Node.js Version to ${range} in your Project Settings to use Node.js ${major}.`
: `Please set "engines": { "node": "${range}" } in your \`package.json\` file to use Node.js ${major}.`;
}
const upstreamProvider =
'This change is the result of a decision made by an upstream infrastructure provider (AWS).' +
'\nRead more: https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html';
'This change is the result of a decision made by an upstream infrastructure provider (AWS).';
export function getLatestNodeVersion() {
return allOptions[0];
@@ -40,8 +39,8 @@ export function getDiscontinuedNodeVersions(): NodeVersion[] {
}
export async function getSupportedNodeVersion(
engineRange?: string,
isAuto?: boolean
engineRange: string | undefined,
isAuto: boolean
): Promise<NodeVersion> {
let selection: NodeVersion = getLatestNodeVersion();
@@ -55,60 +54,35 @@ export async function getSupportedNodeVersion(
return intersects(o.range, engineRange);
});
if (!found) {
const intro =
isAuto || !engineRange
? 'This project is using an invalid version of Node.js and must be changed.'
: 'Found `engines` in `package.json` with an invalid Node.js version range: "' +
engineRange +
'".';
throw new NowBuildError({
code: 'BUILD_UTILS_NODE_VERSION_INVALID',
link:
'https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version',
message: intro + '\n' + pleaseSet,
link: 'http://vercel.link/node-version',
message: `Found invalid Node.js Version: "${engineRange}". ${getHint(
isAuto
)}`,
});
}
}
if (isDiscontinued(selection)) {
const intro =
isAuto || !engineRange
? 'This project is using a discontinued version of Node.js (' +
selection.range +
') and must be upgraded.'
: 'Found `engines` in `package.json` with a discontinued Node.js version range: "' +
engineRange +
'".';
const intro = `Node.js Version "${selection.range}" is discontinued and must be upgraded.`;
throw new NowBuildError({
code: 'BUILD_UTILS_NODE_VERSION_DISCONTINUED',
link:
'https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version',
message: intro + '\n' + pleaseSet + '\n' + upstreamProvider,
link: 'http://vercel.link/node-version',
message: `${intro} ${getHint(isAuto)} ${upstreamProvider}`,
});
}
debug(
isAuto || !engineRange
? 'Using default Node.js range: "' + selection.range + '".'
: 'Found `engines` in `package.json`, selecting range: "' +
selection.range +
'".'
);
debug(`Selected Node.js ${selection.range}`);
if (selection.discontinueDate) {
const d = selection.discontinueDate.toISOString().split('T')[0];
console.warn(
boxen(
'NOTICE' +
'\n' +
`\nNode.js version ${selection.range} has reached end-of-life.` +
`\nAs a result, deployments created on or after ${d} will fail to build.` +
'\n' +
pleaseSet +
'\n' +
upstreamProvider,
{ padding: 1 }
)
`Error: Node.js version ${
selection.range
} is deprecated. Deployments created on or after ${d} will fail to build. ${getHint(
isAuto
)} ${upstreamProvider}`
);
}

View File

@@ -5,7 +5,6 @@ import debug from '../debug';
import spawn from 'cross-spawn';
import { SpawnOptions } from 'child_process';
import { deprecate } from 'util';
import { cpus } from 'os';
import { NowBuildError } from '../errors';
import { Meta, PackageJson, NodeVersion, Config } from '../types';
import { getSupportedNodeVersion, getLatestNodeVersion } from './node-version';
@@ -177,16 +176,13 @@ export async function getNodeVersion(
let { nodeVersion } = config;
let isAuto = true;
if (packageJson && packageJson.engines && packageJson.engines.node) {
if (
nodeVersion &&
nodeVersion !== packageJson.engines.node &&
!meta.isDev
) {
const { node } = packageJson.engines;
if (nodeVersion && nodeVersion !== node && !meta.isDev) {
console.warn(
'Warning: Due to `engines` existing in your `package.json` file, the Node.js Version defined in your Project Settings will not apply. Learn More: http://vercel.link/node-version'
`Warning: Due to "engines": { "node": "${node}" } in your \`package.json\` file, the Node.js Version defined in your Project Settings ("${nodeVersion}") will not apply. Learn More: http://vercel.link/node-version`
);
}
nodeVersion = packageJson.engines.node;
nodeVersion = node;
isAuto = false;
}
return getSupportedNodeVersion(nodeVersion, isAuto);
@@ -328,18 +324,7 @@ export async function runBundleInstall(
assert(path.isAbsolute(destPath));
const opts = { ...spawnOpts, cwd: destPath, prettyCommand: 'bundle install' };
await spawnAsync(
'bundle',
args.concat([
'install',
'--no-prune',
'--retry',
'3',
'--jobs',
String(cpus().length || 1),
]),
opts
);
await spawnAsync('bundle', args.concat(['install']), opts);
}
export async function runPipInstall(
@@ -403,7 +388,7 @@ export async function runPackageJsonScript(
});
} else {
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style
const env: typeof process.env = { ...spawnOpts?.env };
const env: typeof process.env = { ...process.env, ...spawnOpts?.env };
if (!env.YARN_NODE_LINKER) {
env.YARN_NODE_LINKER = 'node-modules';
}

View File

@@ -1,3 +1,4 @@
/env.txt
/node_modules/
/public/build/

View File

@@ -4,7 +4,8 @@
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public"
"start": "sirv public",
"env": "echo \"$PATH\" > env.txt"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^12.0.0",

View File

@@ -0,0 +1 @@
contents

View File

@@ -0,0 +1 @@
dir

View File

@@ -2572,6 +2572,101 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
]);
}
{
const files = ['api/external.js', 'pages/api/internal.js'];
const { builders, warnings } = await detectBuilders(files, null, {
featHandleMiss,
projectSettings: { framework: 'nextjs' },
});
expect(builders).toStrictEqual([
{
config: {
zeroConfig: true,
},
src: 'api/external.js',
use: '@vercel/node',
},
{
config: {
framework: 'nextjs',
zeroConfig: true,
},
src: 'package.json',
use: '@vercel/next',
},
]);
expect(warnings).toStrictEqual([
{
code: 'conflicting_files',
message:
'When using Next.js, it is recommended to place Node.js Serverless Functions inside of the `pages/api` (provided by Next.js) directory instead of `api` (provided by Vercel).',
link: 'https://nextjs.org/docs/api-routes/introduction',
action: 'Learn More',
},
]);
}
{
const files = ['api/external.js', 'pages/api/internal.js'];
const { builders, warnings } = await detectBuilders(files, null, {
featHandleMiss,
tag: 'canary',
projectSettings: { framework: 'nextjs' },
});
expect(builders).toStrictEqual([
{
config: {
zeroConfig: true,
},
src: 'api/external.js',
use: '@vercel/node@canary',
},
{
config: {
framework: 'nextjs',
zeroConfig: true,
},
src: 'package.json',
use: '@vercel/next@canary',
},
]);
expect(warnings).toStrictEqual([
{
code: 'conflicting_files',
message:
'When using Next.js, it is recommended to place Node.js Serverless Functions inside of the `pages/api` (provided by Next.js) directory instead of `api` (provided by Vercel).',
link: 'https://nextjs.org/docs/api-routes/introduction',
action: 'Learn More',
},
]);
}
{
const files = ['api/external.go', 'pages/api/internal.js'];
const { builders, warnings } = await detectBuilders(files, null, {
featHandleMiss,
projectSettings: { framework: 'nextjs' },
});
expect(builders).toStrictEqual([
{
config: {
zeroConfig: true,
},
src: 'api/external.go',
use: '@vercel/go',
},
{
config: {
framework: 'nextjs',
zeroConfig: true,
},
src: 'package.json',
use: '@vercel/next',
},
]);
expect(warnings).toStrictEqual([]);
}
{
const files = ['public/index.html'];

View File

@@ -90,7 +90,7 @@ describe('#detectFramework', () => {
it('Detect Hugo #1', async () => {
const fs = new VirtualFilesystem({
'config.yaml': 'config',
'config.yaml': 'baseURL: http://example.org/',
'content/post.md': '# hello world',
});
@@ -99,7 +99,7 @@ describe('#detectFramework', () => {
it('Detect Hugo #2', async () => {
const fs = new VirtualFilesystem({
'config.json': 'config',
'config.json': '{ "baseURL": "http://example.org/" }',
'content/post.md': '# hello world',
});
@@ -108,7 +108,7 @@ describe('#detectFramework', () => {
it('Detect Hugo #3', async () => {
const fs = new VirtualFilesystem({
'config.toml': 'config',
'config.toml': 'baseURL = "http://example.org/"',
'content/post.md': '# hello world',
});
@@ -143,4 +143,12 @@ describe('#detectFramework', () => {
expect(await detectFramework({ fs, frameworkList })).toBe('scully');
});
it('Detect Zola', async () => {
const fs = new VirtualFilesystem({
'config.toml': 'base_url = "/"',
});
expect(await detectFramework({ fs, frameworkList })).toBe('zola');
});
});

View File

@@ -1,3 +1,4 @@
const ms = require('ms');
const path = require('path');
const fs = require('fs-extra');
const assert = require('assert').strict;
@@ -8,6 +9,8 @@ const {
getNodeVersion,
getLatestNodeVersion,
getDiscontinuedNodeVersions,
runNpmInstall,
runPackageJsonScript,
} = require('../dist');
async function expectBuilderError(promise, pattern) {
@@ -19,7 +22,11 @@ async function expectBuilderError(promise, pattern) {
}
assert('message' in result, `Expected error message but found ${result}`);
assert(
pattern.test(result.message),
typeof result.message === 'string',
`Expected error to be a string but found ${typeof result.message}`
);
assert(
result.message.includes(pattern),
`Expected ${pattern} but found "${result.message}"`
);
}
@@ -43,19 +50,21 @@ it('should re-create symlinks properly', async () => {
return;
}
const files = await glob('**', path.join(__dirname, 'symlinks'));
assert.equal(Object.keys(files).length, 2);
assert.equal(Object.keys(files).length, 4);
const outDir = path.join(__dirname, 'symlinks-out');
await fs.remove(outDir);
const files2 = await download(files, outDir);
assert.equal(Object.keys(files2).length, 2);
assert.equal(Object.keys(files2).length, 4);
const [linkStat, aStat] = await Promise.all([
const [linkStat, linkDirStat, aStat] = await Promise.all([
fs.lstat(path.join(outDir, 'link.txt')),
fs.lstat(path.join(outDir, 'link-dir')),
fs.lstat(path.join(outDir, 'a.txt')),
]);
assert(linkStat.isSymbolicLink());
assert(linkDirStat.isSymbolicLink());
assert(aStat.isFile());
});
@@ -65,7 +74,7 @@ it('should create zip files with symlinks properly', async () => {
return;
}
const files = await glob('**', path.join(__dirname, 'symlinks'));
assert.equal(Object.keys(files).length, 2);
assert.equal(Object.keys(files).length, 4);
const outFile = path.join(__dirname, 'symlinks.zip');
await fs.remove(outFile);
@@ -77,15 +86,17 @@ it('should create zip files with symlinks properly', async () => {
await fs.writeFile(outFile, await createZip(files));
await spawnAsync('unzip', [outFile], { cwd: outDir });
const [linkStat, aStat] = await Promise.all([
const [linkStat, linkDirStat, aStat] = await Promise.all([
fs.lstat(path.join(outDir, 'link.txt')),
fs.lstat(path.join(outDir, 'link-dir')),
fs.lstat(path.join(outDir, 'a.txt')),
]);
assert(linkStat.isSymbolicLink());
assert(linkDirStat.isSymbolicLink());
assert(aStat.isFile());
});
it('should only match supported node versions', async () => {
it('should only match supported node versions, otherwise throw an error', async () => {
expect(await getSupportedNodeVersion('10.x', false)).toHaveProperty(
'major',
10
@@ -98,12 +109,9 @@ it('should only match supported node versions', async () => {
'major',
14
);
expect(getSupportedNodeVersion('8.11.x', false)).rejects.toThrow();
expect(getSupportedNodeVersion('6.x', false)).rejects.toThrow();
expect(getSupportedNodeVersion('999.x', false)).rejects.toThrow();
expect(getSupportedNodeVersion('foo', false)).rejects.toThrow();
const autoMessage = /This project is using an invalid version of Node.js and must be changed/;
const autoMessage =
'Please set Node.js Version to 14.x in your Project Settings to use Node.js 14.';
await expectBuilderError(
getSupportedNodeVersion('8.11.x', true),
autoMessage
@@ -125,7 +133,9 @@ it('should only match supported node versions', async () => {
'major',
14
);
const foundMessage = /Found `engines` in `package\.json` with an invalid Node\.js version range/;
const foundMessage =
'Please set "engines": { "node": "14.x" } in your `package.json` file to use Node.js 14.';
await expectBuilderError(
getSupportedNodeVersion('8.11.x', false),
foundMessage
@@ -188,7 +198,7 @@ it('should prefer package.json engines over project setting from config and warn
)
).toHaveProperty('range', '14.x');
expect(warningMessages).toStrictEqual([
'Warning: Due to `engines` existing in your `package.json` file, the Node.js Version defined in your Project Settings will not apply. Learn More: http://vercel.link/node-version',
'Warning: Due to "engines": { "node": "14.x" } in your `package.json` file, the Node.js Version defined in your Project Settings ("12.x") will not apply. Learn More: http://vercel.link/node-version',
]);
});
@@ -209,9 +219,9 @@ it('should get latest node version', async () => {
});
it('should throw for discontinued versions', async () => {
// Mock a future date so that Node 8 becomes discontinued
// Mock a future date so that Node 8 and 10 become discontinued
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => new Date('2021-04-01').getTime();
global.Date.now = () => new Date('2021-05-01').getTime();
expect(getSupportedNodeVersion('8.10.x', false)).rejects.toThrow();
expect(getSupportedNodeVersion('8.10.x', true)).rejects.toThrow();
@@ -226,6 +236,27 @@ it('should throw for discontinued versions', async () => {
global.Date.now = realDateNow;
});
it('should warn for deprecated versions, soon to be discontinued', async () => {
// Mock a future date so that Node 10 warns
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => new Date('2021-02-23').getTime();
expect(await getSupportedNodeVersion('10.x', false)).toHaveProperty(
'major',
10
);
expect(await getSupportedNodeVersion('10.x', true)).toHaveProperty(
'major',
10
);
expect(warningMessages).toStrictEqual([
'Error: Node.js version 10.x is deprecated. Deployments created on or after 2021-04-20 will fail to build. Please set "engines": { "node": "14.x" } in your `package.json` file to use Node.js 14. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
'Error: Node.js version 10.x is deprecated. Deployments created on or after 2021-04-20 will fail to build. Please set Node.js Version to 14.x in your Project Settings to use Node.js 14. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
]);
global.Date.now = realDateNow;
});
it('should support require by path for legacy builders', () => {
const index = require('@vercel/build-utils');
@@ -255,3 +286,18 @@ it('should support require by path for legacy builders', () => {
expect(FileRef2).toBe(index.FileRef);
expect(Lambda2).toBe(index.Lambda);
});
it(
'should have correct $PATH when running `runPackageJsonScript()` with yarn',
async () => {
const fixture = path.join(__dirname, 'fixtures', '19-yarn-v2');
await runNpmInstall(fixture);
await runPackageJsonScript(fixture, 'env');
// `yarn` was failing with ENOENT before, so as long as the
// script was invoked at all is enough to verify the fix
const out = await fs.readFile(path.join(fixture, 'env.txt'), 'utf8');
expect(out.trim()).toBeTruthy();
},
ms('1m')
);

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "21.2.4-canary.1",
"version": "21.3.2",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -61,10 +61,10 @@
"node": ">= 10"
},
"dependencies": {
"@vercel/build-utils": "2.9.1-canary.1",
"@vercel/go": "1.1.8",
"@vercel/build-utils": "2.10.0",
"@vercel/go": "1.2.1",
"@vercel/node": "1.9.1-canary.0",
"@vercel/python": "1.2.5-canary.1",
"@vercel/python": "2.0.0",
"@vercel/ruby": "1.2.6-canary.0",
"update-notifier": "4.1.0"
},
@@ -100,7 +100,7 @@
"@types/universal-analytics": "0.4.2",
"@types/which": "1.3.2",
"@types/write-json-file": "2.2.1",
"@vercel/frameworks": "0.2.1-canary.1",
"@vercel/frameworks": "0.3.0",
"@vercel/ncc": "0.24.0",
"@zeit/fun": "0.11.2",
"@zeit/source-map-support": "0.6.2",

View File

@@ -248,10 +248,19 @@ async function run({ client, contextName }) {
}
const [name] = args;
await client.fetch('/projects/ensure-project', {
method: 'POST',
body: { name },
});
try {
await client.fetch('/projects', {
method: 'POST',
body: { name },
});
} catch (error) {
if (error.status === 409) {
// project already exists, so we can
// show a success message
} else {
throw error;
}
}
const elapsed = ms(new Date() - start);
console.log(

View File

@@ -141,6 +141,7 @@ async function run({ output, token, contextName, currentTeam, ctx }) {
const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam, output });
const args = argv._.slice(1);
const start = Date.now();
const { 'test-warning': testWarningFlag } = argv;
if (subcommand === 'ls' || subcommand === 'list') {
if (args.length > 1) {
@@ -154,7 +155,10 @@ async function run({ output, token, contextName, currentTeam, ctx }) {
return exit(1);
}
const { secrets: list, pagination } = await secrets.ls(nextTimestamp);
const { secrets: list, pagination } = await secrets.ls(
nextTimestamp,
testWarningFlag
);
const elapsed = ms(Date.now() - start);
console.log(

View File

@@ -6,6 +6,7 @@ import retry, { RetryFunction, Options as RetryOptions } from 'async-retry';
import createOutput, { Output } from './output/create-output';
import responseError from './response-error';
import ua from './ua';
import printIndications from './print-indications';
export interface FetchOptions {
body?: NodeJS.ReadableStream | object | string;
@@ -119,6 +120,8 @@ export default class Client extends EventEmitter {
return null;
}
printIndications(res);
return res.headers.get('content-type').includes('application/json')
? res.json()
: res;

View File

@@ -17,29 +17,12 @@ import { prependEmoji, emoji } from '../emoji';
function printInspectUrl(
output: Output,
deploymentUrl: string,
deployStamp: () => string,
orgSlug: string
inspectorUrl: string,
deployStamp: () => string
) {
const url = deploymentUrl.replace('https://', '');
// example urls:
// lucim-fyulaijvg.now.sh
// s-66p6vb23x.n8.io (custom domain suffix)
const [sub, ...p] = url.split('.');
const apex = p.join('.');
const q = sub.split('-');
const deploymentShortId = q.pop();
const projectName = q.join('-');
const inspectUrl = `https://vercel.com/${orgSlug}/${projectName}/${deploymentShortId}${
apex !== 'now.sh' && apex !== 'vercel.app' ? `/${apex}` : ''
}`;
output.print(
prependEmoji(
`Inspect: ${chalk.bold(inspectUrl)} ${deployStamp()}`,
`Inspect: ${chalk.bold(inspectorUrl)} ${deployStamp()}`,
emoji('inspect')
) + `\n`
);
@@ -178,7 +161,7 @@ export default async function processDeployment({
output.stopSpinner();
printInspectUrl(output, event.payload.url, deployStamp, org.slug);
printInspectUrl(output, event.payload.inspectorUrl, deployStamp);
if (quiet) {
process.stdout.write(`https://${event.payload.url}`);

View File

@@ -589,7 +589,9 @@ export default class DevServer {
}
if (warnings && warnings.length > 0) {
warnings.forEach(warning => this.output.warn(warning.message));
warnings.forEach(warning =>
this.output.warn(warning.message, null, warning.link, warning.action)
);
}
if (builders) {

View File

@@ -14,6 +14,7 @@ import createOutput from './output';
import { responseError } from './error';
import stamp from './output/stamp';
import { BuildError } from './errors-ts';
import printIndications from './print-indications.ts';
export default class Now extends EventEmitter {
constructor({
@@ -225,7 +226,7 @@ export default class Now extends EventEmitter {
return new Error(error.message);
}
async listSecrets(next) {
async listSecrets(next, testWarningFlag) {
const payload = await this.retry(async bail => {
let secretsUrl = '/v3/now/secrets?limit=20';
@@ -233,6 +234,10 @@ export default class Now extends EventEmitter {
secretsUrl += `&until=${next}`;
}
if (testWarningFlag) {
secretsUrl += '&testWarning=1';
}
const res = await this._fetch(secretsUrl);
if (res.status === 200) {
@@ -427,7 +432,7 @@ export default class Now extends EventEmitter {
return this._syncAmount;
}
_fetch(_url, opts = {}) {
async _fetch(_url, opts = {}) {
if (opts.useCurrentTeam !== false && this.currentTeam) {
const parsedUrl = parseUrl(_url, true);
const query = parsedUrl.query;
@@ -450,11 +455,12 @@ export default class Now extends EventEmitter {
opts.body = JSON.stringify(opts.body);
opts.headers['Content-Type'] = 'application/json';
}
return this._output.time(
const res = await this._output.time(
`${opts.method || 'GET'} ${this._apiUrl}${_url} ${opts.body || ''}`,
fetch(`${this._apiUrl}${_url}`, opts)
);
printIndications(res);
return res;
}
// public retry with built-in retrying that can be

View File

@@ -0,0 +1,32 @@
import chalk from 'chalk';
import { Response } from 'node-fetch';
import { emoji, EmojiLabel, prependEmoji } from './emoji';
import createOutput from './output';
import linkStyle from './output/link';
export default function printIndications(res: Response) {
const _output = createOutput();
const indications = new Set(['warning', 'notice', 'tip']);
const regex = /^x-(?:vercel|now)-(warning|notice|tip)-(.*)$/;
for (const [name, payload] of res.headers) {
const match = name.match(regex);
if (match) {
const [, type, identifier] = match;
const action = res.headers.get(`x-vercel-action-${identifier}`);
const link = res.headers.get(`x-vercel-link-${identifier}`);
if (indications.has(type)) {
const newline = '\n';
const message =
prependEmoji(chalk.dim(payload), emoji(type as EmojiLabel)) + newline;
let finalLink = '';
if (link) {
finalLink =
chalk.dim(`${action || 'Learn More'}: ${linkStyle(link)}`) +
newline;
}
_output.print(message + finalLink);
}
}
}
}

View File

@@ -1,8 +1,8 @@
import Now from '.';
export default class Secrets extends Now {
ls(next) {
return this.listSecrets(next);
ls(next, testWarningFlag) {
return this.listSecrets(next, testWarningFlag);
}
getSecretByNameOrId(nameOrId) {

View File

@@ -425,7 +425,7 @@ test(
method: 'POST',
body: '{"query":"{redwood{version}}"}',
};
const resBody = '{"data":{"redwood":{"version":"0.15.0"}}}';
const resBody = '{"data":{"redwood":{"version":"0.25.0"}}}';
await testPath(200, '/api/graphql', resBody, {}, fetchOpts);
},
{ isExample: true }
@@ -1692,6 +1692,9 @@ test(
expectHeader('image/webp'),
fetchOpts('image/webp')
);
/*
* Disabled gif in https://github.com/vercel/next.js/pull/22253
* Eventually we should enable again when `next dev` supports it
await testPath(
200,
toUrl('/test.gif', 64, 80),
@@ -1699,6 +1702,7 @@ test(
expectHeader('image/webp'),
fetchOpts('image/webp')
);
*/
await testPath(
200,
toUrl('/test.svg', 64, 70),
@@ -1706,12 +1710,13 @@ test(
expectHeader('image/svg+xml'),
fetchOpts('image/webp')
);
// animated gif should bypass: serve as-is
await testPath(
200,
toUrl('/animated.gif', 64, 60),
null,
expectHeader('image/gif'),
fetchOpts('image/gif')
fetchOpts('image/webp')
);
})
);

View File

@@ -1029,6 +1029,41 @@ test('Deploy `api-env` fixture and test `vercel env` command', async t => {
await nowEnvLsIsEmpty();
});
test('[vc projects] should create a project successfully', async t => {
const projectName = `vc-projects-add-${
Math.random().toString(36).split('.')[1]
}`;
const vc = execa(binaryPath, [
'projects',
'add',
projectName,
...defaultArgs,
]);
await waitForPrompt(vc, chunk =>
chunk.includes(`Success! Project ${projectName} added`)
);
const { exitCode, stderr, stdout } = await vc;
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
// creating the same project again should succeed
const vc2 = execa(binaryPath, [
'projects',
'add',
projectName,
...defaultArgs,
]);
await waitForPrompt(vc2, chunk =>
chunk.includes(`Success! Project ${projectName} added`)
);
const { exitCode: exitCode2, stderr: stderr2, stdout: stdout2 } = await vc;
t.is(exitCode2, 0, formatOutput({ stderr2, stdout2 }));
});
test('deploy with metadata containing "=" in the value', async t => {
const target = fixture('static-v2-meta');
@@ -1904,6 +1939,11 @@ test('create a production deployment', async t => {
/Setting target to production/gm,
formatOutput(targetCall)
);
t.regex(
targetCall.stderr,
/Inspect: https:\/\/vercel.com\//gm,
formatOutput(targetCall)
);
t.regex(targetCall.stdout, /https:\/\//gm);
const { host: targetHost } = new URL(targetCall.stdout);
@@ -2558,6 +2598,19 @@ test('vercel secret ls', async t => {
t.regex(output.stdout, new RegExp(), formatOutput(output));
});
test('vercel secret ls --test-warning', async t => {
const output = await execute(['secret', 'ls', '--test-warning']);
t.is(output.exitCode, 0, formatOutput(output));
t.regex(output.stderr, /Test warning message./gm, formatOutput(output));
t.regex(
output.stderr,
/Learn more: https:\/\/vercel.com/gm,
formatOutput(output)
);
t.regex(output.stdout, /No secrets found under/gm, formatOutput(output));
});
test('vercel secret rename', async t => {
const nextName = `renamed-secret-${Date.now().toString(36)}`;
const output = await execute([
@@ -2626,7 +2679,7 @@ test('deploy a Lambda with 3 seconds of maxDuration', async t => {
]);
t.is(response1.status, 200, url);
t.is(response2.status, 502, url);
t.is(response2.status, 504, url);
});
test('fail to deploy a Lambda with an incorrect value for maxDuration', async t => {
@@ -2678,7 +2731,7 @@ test('fail to deploy a Lambda with a specific runtime but without a locked versi
});
test('fail to add a domain without a project', async t => {
const output = await execute(['domains', 'add', 'my-domain.now.sh']);
const output = await execute(['domains', 'add', 'my-domain.vercel.app']);
t.is(output.exitCode, 1, formatOutput(output));
t.regex(output.stderr, /expects two arguments/gm, formatOutput(output));
});
@@ -2711,7 +2764,7 @@ test('change user', async t => {
});
test('assign a domain to a project', async t => {
const domain = `project-domain.${contextName}.now.sh`;
const domain = `project-domain.${contextName}.vercel.app`;
const directory = fixture('static-deployment');
const deploymentOutput = await execute([directory, '--public', '--confirm']);

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "9.0.7-canary.1",
"version": "9.0.7",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"homepage": "https://vercel.com",
@@ -37,7 +37,7 @@
]
},
"dependencies": {
"@vercel/build-utils": "2.9.1-canary.1",
"@vercel/build-utils": "2.10.0",
"@zeit/fetch": "5.2.0",
"async-retry": "1.2.3",
"async-sema": "3.0.0",

View File

@@ -26,30 +26,6 @@ async function main() {
stdio: 'inherit',
}
);
const installDir = join(outDir, 'install');
await execa(
'ncc',
[
'build',
'install.ts',
'-e',
'@vercel/build-utils',
'-e',
'@now/build-utils',
'-o',
installDir,
],
{
stdio: 'inherit',
}
);
// Move compiled ncc file to out dir
await fs.rename(join(installDir, 'index.js'), join(outDir, 'install.js'));
// Delete leftover "install" dir
await fs.remove(installDir);
}
main().catch(err => {

View File

@@ -1,19 +1,26 @@
import tar from 'tar';
import execa from 'execa';
import fetch from 'node-fetch';
import { mkdirp, pathExists } from 'fs-extra';
import { dirname, join } from 'path';
import { mkdirp, pathExists, readFile } from 'fs-extra';
import { join } from 'path';
import buildUtils from './build-utils';
import stringArgv from 'string-argv';
const { debug } = buildUtils;
const archMap = new Map([['x64', 'amd64'], ['x86', '386']]);
const versionMap = new Map([
['1.16', '1.16'],
['1.15', '1.15.8'],
['1.14', '1.14.15'],
['1.13', '1.13.15'],
]);
const archMap = new Map([
['x64', 'amd64'],
['x86', '386'],
]);
const platformMap = new Map([['win32', 'windows']]);
// Location where the `go` binary will be installed after `postinstall`
const GO_DIR = join(__dirname, 'go');
const GO_BIN = join(GO_DIR, 'bin', 'go');
export const cacheDir = join('.vercel', 'cache', 'golang');
const getGoDir = (workPath: string) => join(workPath, cacheDir);
const GO_FLAGS = process.platform === 'win32' ? [] : ['-ldflags', '-s -w'];
const GO_MIN_VERSION = 13;
const getPlatform = (p: string) => platformMap.get(p) || p;
const getArch = (a: string) => archMap.get(a) || a;
const getGoUrl = (version: string, platform: string, arch: string) => {
@@ -25,14 +32,18 @@ const getGoUrl = (version: string, platform: string, arch: string) => {
export const OUT_EXTENSION = process.platform === 'win32' ? '.exe' : '';
export async function getAnalyzedEntrypoint(filePath: string, modulePath = '') {
debug('Analyzing entrypoint %o', filePath);
export async function getAnalyzedEntrypoint(
workPath: string,
filePath: string,
modulePath: string
) {
debug('Analyzing entrypoint %o with modulePath %o', filePath, modulePath);
const bin = join(__dirname, `analyze${OUT_EXTENSION}`);
const isAnalyzeExist = await pathExists(bin);
if (!isAnalyzeExist) {
const src = join(__dirname, 'util', 'analyze.go');
const go = await downloadGo();
const go = await downloadGo(workPath, modulePath);
await go.build(src, bin);
}
@@ -100,13 +111,16 @@ class GoWrapper {
}
export async function createGo(
workPath: string,
goPath: string,
platform = process.platform,
arch = process.arch,
opts: execa.Options = {},
goMod = false
) {
const path = `${dirname(GO_BIN)}:${process.env.PATH}`;
const binPath = join(getGoDir(workPath), 'bin');
debug(`Adding ${binPath} to PATH`);
const path = `${binPath}:${process.env.PATH}`;
const env: { [key: string]: string } = {
...process.env,
PATH: path,
@@ -120,21 +134,20 @@ export async function createGo(
return new GoWrapper(env, opts);
}
export async function downloadGo(
dir = GO_DIR,
version = '1.13.7',
platform = process.platform,
arch = process.arch
) {
export async function downloadGo(workPath: string, modulePath: string) {
const dir = getGoDir(workPath);
const { platform, arch } = process;
const version = await parseGoVersion(modulePath);
// Check if `go` is already installed in user's `$PATH`
const { failed, stdout } = await execa('go', ['version'], { reject: false });
if (!failed && parseInt(stdout.split('.')[1]) >= 11) {
if (!failed && parseInt(stdout.split('.')[1]) >= GO_MIN_VERSION) {
debug('Using system installed version of `go`: %o', stdout.trim());
return createGo(dir, platform, arch);
return createGo(workPath, dir, platform, arch);
}
// Check `go` bin in builder CWD
// Check `go` bin in cacheDir
const isGoExist = await pathExists(join(dir, 'bin'));
if (!isGoExist) {
debug('Installing `go` v%s to %o for %s %s', version, dir, platform, arch);
@@ -156,5 +169,32 @@ export async function downloadGo(
.on('finish', resolve);
});
}
return createGo(dir, platform, arch);
return createGo(workPath, dir, platform, arch);
}
async function parseGoVersion(modulePath: string): Promise<string> {
// default to newest (first)
let version = Array.from(versionMap.values())[0];
const file = join(modulePath, 'go.mod');
try {
const content = await readFile(file, 'utf8');
const matches = /^go (\d+)\.(\d+)\.?$/gm.exec(content) || [];
const major = parseInt(matches[1], 10);
const minor = parseInt(matches[2], 10);
const full = versionMap.get(`${major}.${minor}`);
if (major === 1 && minor >= GO_MIN_VERSION && full) {
version = full;
} else {
console.log(`Warning: Unknown Go version in ${file}`);
}
} catch (err) {
if (err.code === 'ENOENT') {
debug(`File not found: ${file}`);
} else {
throw err;
}
}
debug(`Selected Go version ${version}`);
return version;
}

View File

@@ -17,6 +17,7 @@ import {
BuildOptions,
Meta,
Files,
PrepareCacheOptions,
StartDevServerOptions,
StartDevServerResult,
} from '@vercel/build-utils';
@@ -33,7 +34,12 @@ const {
const TMP = tmpdir();
import { createGo, getAnalyzedEntrypoint, OUT_EXTENSION } from './go-helpers';
import {
createGo,
getAnalyzedEntrypoint,
cacheDir,
OUT_EXTENSION,
} from './go-helpers';
const handlerFileName = `handler${OUT_EXTENSION}`;
export { shouldServe };
@@ -125,7 +131,7 @@ Learn more: https://github.com/golang/go/wiki/Modules
const forceMove = Boolean(meta.isDev);
const srcPath = join(goPath, 'src', 'lambda');
let downloadPath = (meta.isDev || meta.skipDownload) ? workPath : srcPath;
let downloadPath = meta.isDev || meta.skipDownload ? workPath : srcPath;
let downloadedFiles = await download(files, downloadPath, meta);
debug(`Parsing AST for "${entrypoint}"`);
@@ -136,8 +142,12 @@ Learn more: https://github.com/golang/go/wiki/Modules
if (fileName in downloadedFiles) {
goModAbsPathDir = dirname(downloadedFiles[fileName].fsPath);
debug(`Found ${fileName} file in "${goModAbsPathDir}"`);
} else if ('api/go.mod' in downloadedFiles) {
goModAbsPathDir = dirname(downloadedFiles['api/go.mod'].fsPath);
debug(`Found ${fileName} file in "${goModAbsPathDir}"`);
}
analyzed = await getAnalyzedEntrypoint(
workPath,
downloadedFiles[entrypoint].fsPath,
goModAbsPathDir
);
@@ -244,6 +254,7 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
if (packageName !== 'main') {
const go = await createGo(
workPath,
goPath,
process.platform,
process.arch,
@@ -392,6 +403,7 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
// we need `main.go` in the same dir as the entrypoint,
// otherwise `go build` will refuse to build
const go = await createGo(
workPath,
goPath,
process.platform,
process.arch,
@@ -515,6 +527,7 @@ export async function startDevServer(
goModAbsPathDir = workPath;
}
const analyzedRaw = await getAnalyzedEntrypoint(
workPath,
entrypointWithExt,
goModAbsPathDir
);
@@ -620,3 +633,10 @@ async function waitForPortFile_(opts: {
}
}
}
export async function prepareCache({
workPath,
}: PrepareCacheOptions): Promise<Files> {
const cache = await glob(`${cacheDir}/**`, workPath);
return cache;
}

View File

@@ -1,6 +0,0 @@
import { downloadGo } from './go-helpers';
downloadGo().catch(err => {
console.error(err);
process.exit(1);
});

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/go",
"version": "1.1.8",
"version": "1.2.1",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
@@ -12,8 +12,7 @@
"scripts": {
"build": "node build",
"test-integration-once": "jest --env node --verbose --runInBand --bail",
"prepublish": "node build",
"now-postinstall": "node dist/install.js"
"prepublishOnly": "node build"
},
"files": [
"dist"

View File

@@ -3,11 +3,12 @@ package cowsay
import (
"fmt"
"net/http"
"runtime"
say "github.com/dhruvbird/go-cowsay"
)
// Handler function
func Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, say.Format("cow:RANDOMNESS_PLACEHOLDER"))
fmt.Fprintf(w, say.Format("cow:" + runtime.Version() + ":RANDOMNESS_PLACEHOLDER"))
}

View File

@@ -1,11 +0,0 @@
{
"version": 2,
"builds": [
{ "src": "index.go", "use": "@vercel/go" },
{ "src": "subdirectory/index.go", "use": "@vercel/go" }
],
"probes": [
{ "path": "/", "mustContain": "cow:RANDOMNESS_PLACEHOLDER" },
{ "path": "/subdirectory", "mustContain": "subcow:RANDOMNESS_PLACEHOLDER" }
]
}

View File

@@ -3,11 +3,12 @@ package subcow
import (
"fmt"
"net/http"
"runtime"
say "github.com/dhruvbird/go-cowsay"
)
// Handler function
func Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, say.Format("subcow:RANDOMNESS_PLACEHOLDER"))
fmt.Fprintf(w, say.Format("subcow:" + runtime.Version() + ":RANDOMNESS_PLACEHOLDER"))
}

View File

@@ -0,0 +1,14 @@
{
"version": 2,
"builds": [
{ "src": "index.go", "use": "@vercel/go" },
{ "src": "subdirectory/index.go", "use": "@vercel/go" }
],
"probes": [
{ "path": "/", "mustContain": "cow:go1.16:RANDOMNESS_PLACEHOLDER" },
{
"path": "/subdirectory",
"mustContain": "subcow:go1.16:RANDOMNESS_PLACEHOLDER"
}
]
}

View File

@@ -1,3 +1,3 @@
module go-mod
go 1.12
go 1.15

View File

@@ -3,9 +3,10 @@ package handler
import (
"fmt"
"net/http"
"runtime"
)
// Handler func
func Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "RANDOMNESS_PLACEHOLDER")
fmt.Fprintf(w, "version:%s:RANDOMNESS_PLACEHOLDER", runtime.Version())
}

View File

@@ -1,5 +0,0 @@
{
"version": 2,
"builds": [{ "src": "index.go", "use": "@vercel/go" }],
"probes": [{ "path": "/", "mustContain": "RANDOMNESS_PLACEHOLDER" }]
}

View File

@@ -0,0 +1,7 @@
{
"version": 2,
"builds": [{ "src": "index.go", "use": "@vercel/go" }],
"probes": [
{ "path": "/", "mustContain": "version:go1.15.8:RANDOMNESS_PLACEHOLDER" }
]
}

View File

@@ -3,10 +3,11 @@ package api
import (
"fmt"
"net/http"
"runtime"
"with-shared/shared"
)
// Handler func
func Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, shared.Say("RANDOMNESS_PLACEHOLDER"))
fmt.Fprintf(w, "version:%s:%s", runtime.Version(), shared.Say("RANDOMNESS_PLACEHOLDER"))
}

View File

@@ -1,3 +1,3 @@
module with-shared
go 1.12
go 1.13

View File

@@ -1,5 +0,0 @@
{
"version": 2,
"builds": [{ "src": "api/*.go", "use": "@vercel/go" }],
"probes": [{ "path": "/api", "mustContain": "RANDOMNESS_PLACEHOLDER" }]
}

View File

@@ -0,0 +1,10 @@
{
"version": 2,
"builds": [{ "src": "api/*.go", "use": "@vercel/go" }],
"probes": [
{
"path": "/api",
"mustContain": "version:go1.13.15:RANDOMNESS_PLACEHOLDER"
}
]
}

View File

@@ -1,3 +1,3 @@
module custom-flag
go 1.12
go 1.14

View File

@@ -3,11 +3,12 @@ package handler
import (
"fmt"
"net/http"
"runtime"
"custom-flag/custom"
)
// Index func
func Index(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, custom.Random)
fmt.Fprintf(w, "version:%v:%v", runtime.Version(), custom.Random)
}

View File

@@ -2,5 +2,10 @@
"version": 2,
"builds": [{ "src": "index.go", "use": "@vercel/go" }],
"build": { "env": { "GO_BUILD_FLAGS": "-tags first -ldflags '-s -w'" } },
"probes": [{ "path": "/", "mustContain": "first:RANDOMNESS_PLACEHOLDER" }]
"probes": [
{
"path": "/",
"mustContain": "version:go1.14.15:first:RANDOMNESS_PLACEHOLDER"
}
]
}

View File

@@ -3,10 +3,11 @@ package routes
import (
"fmt"
"net/http"
"runtime"
"github.com/vercel/does-not-exist/api/_pkg/somepackage"
)
func Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello %v", somepackage.Foo)
fmt.Fprintf(w, "version:%v:%v", runtime.Version(), somepackage.Foo)
}

View File

@@ -2,7 +2,7 @@
"version": 2,
"builds": [
{
"src": "api/v1/**/*.go",
"src": "api/v1/routes/**/*.go",
"use": "@vercel/go",
"config": { "zeroConfig": true }
}
@@ -10,7 +10,7 @@
"probes": [
{
"path": "/api/v1/routes/someroute.go",
"mustContain": "Hello Dependency:RANDOMNESS_PLACEHOLDER"
"mustContain": "version:go1.13.15:Dependency:RANDOMNESS_PLACEHOLDER"
}
]
}

View File

@@ -13,6 +13,6 @@
"noImplicitThis": false,
"types": ["node"],
"strict": true,
"target": "esnext"
"target": "es2018"
}
}

View File

@@ -18,7 +18,7 @@ import (
var ignoredFoldersRegex []*regexp.Regexp
func init() {
ignoredFolders := []string{"vendor", "testdata", ".now"}
ignoredFolders := []string{"vendor", "testdata", ".now", ".vercel"}
// Build the regex that matches if a path contains the respective ignored folder
// The pattern will look like: (.*/)?vendor/.*, which matches every path that contains a vendor folder

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/python",
"version": "1.2.5-canary.1",
"version": "2.0.0",
"main": "./dist/index.js",
"license": "MIT",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/routing-utils",
"version": "1.9.3-canary.0",
"version": "1.10.0",
"description": "Vercel routing utilities",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",

6
utils/changelog.js vendored
View File

@@ -48,12 +48,6 @@ async function main() {
pkgs.add('vercel');
}
// NOTE: `@vercel/python` stable must not be released
// until March 1st, 2021 due to breaking behavior with
// the request URL (https://github.com/vercel/vercel/pull/5739).
// After that date this can be removed.
pkgs.delete('@vercel/python');
const pub = Array.from(pkgs).join(',');
console.log('To publish a stable release, execute the following:');