Compare commits

..

11 Commits

Author SHA1 Message Date
Steven
3407e6bd1a Publish Canary
- @now/build-utils@2.1.1-canary.0
 - @now/ruby@1.0.3-canary.3
2020-02-29 18:40:49 -05:00
Steven
553ad240f0 [now-build-utils] Fix NODE_ENV assignment (#3862)
Fixes a regression in #3847 which was preventing the user from assigning `NODE_ENV`.

The root cause was that the spread operator (`...`) performs a shallow clone, not a deep clone. So we must perform another spread to clone the user-provided `env` object before deleting `NODE_ENV` during `npm install`.
2020-02-29 18:37:59 -05:00
m5o
964ce1bb5a [now-ruby] update bundler on ruby rack examples (#3856)
* update bundler on ruby rack examples
  * bundle with latest bundler `v2.1.4`
  * update rack to `v2.2.2`
  🔗 https://github.com/zeit/now/pull/3626
2020-02-28 23:45:54 +00:00
Steven
995aa6eddf Publish Canary
- now@17.0.5-canary.7
2020-02-28 17:39:42 -05:00
Steven
095805e3ad [tests] Fix missing await (#3860)
Follow up to #3858
2020-02-28 17:35:02 -05:00
Steven
b461ed238c [tests] Fix code coverage upload (#3859)
The code coverage report stopped uploading after we switched to GitHub Actions because its not a recognized CI provider.

This PR adds a secret with the code coverage token from [codecov.io](https://codecov.io/gh/zeit/now/settings).
2020-02-28 22:13:04 +00:00
Steven
01e7124189 Publish Canary
- now@17.0.5-canary.6
 - @now/ruby@1.0.3-canary.2
2020-02-28 16:21:56 -05:00
Steven
acd3ac2f98 [now-cli] Disable sentry during local development (#3858)
This PR changes the behavior of error reporting and metrics so that developers who build and run Now CLI locally won't accidentally report any metrics. It also prevents errors during CI tests from being reported.

The env vars are only assigned during the publishing step so that the official Now CLI hosted on npm is the only way to report metrics.
2020-02-28 21:20:36 +00:00
Steven
b50e4209e1 [now-cli] Fix "The specified token is not valid" (#3857)
Fixes https://sentry.io/organizations/zeithq/issues/1537743736/?project=1323225&referrer=slack
2020-02-28 19:59:51 +00:00
m5o
147b4e870c [now-ruby] Add test fixture for ActiveSupport gem (#3853)
* add ruby ActiveSupport test fixture
  > ActiveSupport is a Ruby module & a stand-alone component of Rails that includes additional functionality to core Ruby classes, like Array, String & Numeric.
  🔗 https://guides.rubyonrails.org/active_support_core_extensions.html

* add `Date.current + 10.years` calculation example
2020-02-28 12:56:06 -05:00
Steven
df8327d14c [docs] Update readme (#3855)
Updates the readme to mention the Git Integration and fixes some misinformation.
2020-02-28 12:53:40 -05:00
30 changed files with 200 additions and 58 deletions

View File

@@ -94,7 +94,7 @@ jobs:
coverage:
name: Coverage
timeout-minutes: 10
timeout-minutes: 5
needs: [test-unit, test-now-cli, test-now-dev, test-integration]
runs-on: ubuntu-latest
steps:
@@ -107,3 +107,5 @@ jobs:
path: packages/now-cli/.nyc_output
- run: yarn install
- run: yarn workspace now run coverage
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -20,6 +20,9 @@ jobs:
run: yarn install --check-files --frozen-lockfile
- name: Build
run: yarn build
env:
GA_TRACKING_ID: ${{ secrets.GA_TRACKING_ID }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
- name: Publish
run: yarn publish-from-github
env:

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@ coverage
packages/now-cli/.builders
packages/now-cli/assets
packages/now-cli/src/util/dev/templates/*.ts
packages/now-cli/src/util/constants.ts
packages/now-cli/test/**/yarn.lock
!packages/now-cli/test/dev/**/yarn.lock
packages/now-cli/test/**/node_modules

View File

@@ -5,30 +5,18 @@
## Usage
To install the latest version of Now CLI, visit [zeit.co/download](https://zeit.co/download) or run this command:
```
npm i -g now
```
To quickly start a new project, run the following commands:
```
now init # Pick an example project to clone
cd <PROJECT> # Change directory to the newly created project
now # Deploy to the cloud
```
Get started by [Importing a Git Project](https://zeit.co/import) and use `git push` to deploy. Alternatively, you can [install Now CLI](https://zeit.co/download).
## Documentation
For details on how to use Now CLI, check out our [documentation](https://zeit.co/docs/now-cli).
For details on how to use ZEIT Now, check out our [documentation](https://zeit.co/docs).
## Caught a Bug?
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
2. Install dependencies with `yarn install`
3. Compile the code: `yarn build`
4. Link the package to the global module directory: `yarn link`
4. Link the package to the global module directory: `cd ./packages/now-cli && yarn link`
5. You can now start using `now` anywhere inside the command line
As always, you should use `yarn test-unit` to run the tests and see if your changes have broken anything.

View File

@@ -1,6 +1,6 @@
{
"name": "@now/build-utils",
"version": "2.1.0",
"version": "2.1.1-canary.0",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",

View File

@@ -207,7 +207,7 @@ export async function runNpmInstall(
const { hasPackageLockJson } = await scanParentDirs(destPath);
const opts: SpawnOptions = { cwd: destPath, ...spawnOpts };
const env = opts.env || { ...process.env };
const env = opts.env ? { ...opts.env } : { ...process.env };
delete env.NODE_ENV;
opts.env = env;

View File

@@ -0,0 +1,8 @@
{
"version": 2,
"builds": [{ "src": "package.json", "use": "@now/static-build" }],
"build": { "env": { "NODE_ENV": "custom-value:RANDOMNESS_PLACEHOLDER" } },
"probes": [
{ "path": "/", "mustContain": "custom-value:RANDOMNESS_PLACEHOLDER" }
]
}

View File

@@ -0,0 +1,6 @@
{
"private": true,
"scripts": {
"build": "mkdir public && echo $NODE_ENV > public/index.html"
}
}

View File

@@ -15,7 +15,6 @@ To quickly start a new project, run the following commands:
```
now init # Pick an example project
cd <PROJECT> # Change directory to the new project
now dev # Run locally during development
now # Deploy to the cloud
```

View File

@@ -1,6 +1,6 @@
{
"name": "now",
"version": "17.0.5-canary.5",
"version": "17.0.5-canary.7",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Now",

View File

@@ -4,7 +4,13 @@ import execa from 'execa';
import { join } from 'path';
import pipe from 'promisepipe';
import { createGzip } from 'zlib';
import { createWriteStream, mkdirp, remove, writeJSON } from 'fs-extra';
import {
createWriteStream,
mkdirp,
remove,
writeJSON,
writeFile,
} from 'fs-extra';
import { getDistTag } from '../src/util/get-dist-tag';
import pkg from '../package.json';
@@ -47,10 +53,34 @@ async function createBuildersTarball() {
);
}
async function createConstants() {
console.log('Creating constants.ts');
const filename = join(dirRoot, 'src/util/constants.ts');
const contents = `// This file is auto-generated
export const GA_TRACKING_ID: string | undefined = ${envToString(
'GA_TRACKING_ID'
)};
export const SENTRY_DSN: string | undefined = ${envToString('SENTRY_DSN')};
`;
await writeFile(filename, contents, 'utf8');
}
function envToString(key: string) {
const value = process.env[key];
if (!value) {
console.log(`- Constant ${key} is not assigned`);
}
return JSON.stringify(value);
}
async function main() {
const isDev = process.argv[2] === '--dev';
if (!isDev) {
// Read the secrets from GitHub Actions and generate a file.
// During local development, these secrets will be empty.
await createConstants();
// Create a tarball from all the `@now` scoped builders which will be bundled
// with Now CLI
await createBuildersTarball();

View File

@@ -284,13 +284,22 @@ export default async function main(
return 0;
}
org = await selectOrg(
output,
'Which scope do you want to deploy to?',
client,
ctx.config.currentTeam,
autoConfirm
);
try {
org = await selectOrg(
output,
'Which scope do you want to deploy to?',
client,
ctx.config.currentTeam,
autoConfirm
);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
throw err;
}
// We use `localConfig` here to read the name
// even though the `now.json` file can change

View File

@@ -37,7 +37,7 @@ export default async function add(
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED') {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}

View File

@@ -27,7 +27,7 @@ export default async function add(
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED') {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}

View File

@@ -42,7 +42,7 @@ export default async function move(
try {
({ contextName, user } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED') {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
@@ -214,4 +214,4 @@ async function findDestinationMatch(
}
return null;
}
}

View File

@@ -40,7 +40,7 @@ export default async function transferIn(
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED') {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}

View File

@@ -9,6 +9,7 @@ import exit from '../util/exit';
import Client from '../util/client.ts';
import logo from '../util/output/logo';
import getScope from '../util/get-scope';
import createOutput from '../util/output';
const e = encodeURIComponent;
@@ -63,13 +64,26 @@ const main = async ctx => {
await exit(0);
}
const output = createOutput({ debug });
const {
authConfig: { token },
config: { currentTeam },
} = ctx;
const client = new Client({ apiUrl, token, currentTeam, debug });
const { contextName } = await getScope(client);
let contextName = null;
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
throw err;
}
try {
await run({ client, contextName });

View File

@@ -76,7 +76,17 @@ export default async function({
const stopUserSpinner = wait('Fetching user information');
const client = new Client({ apiUrl, token });
const user = await getUser(client);
let user;
try {
user = await getUser(client);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
console.error(error(err.message));
return 1;
}
throw err;
}
stopUserSpinner();

View File

@@ -21,7 +21,17 @@ export default async function({ teams, config, apiUrl, token }) {
const stopUserSpinner = wait('Fetching user information');
const client = new Client({ apiUrl, token, currentTeam });
const user = await getUser(client);
let user;
try {
user = await getUser(client);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
console.error(error(err.message));
return 1;
}
throw err;
}
stopUserSpinner();

View File

@@ -40,13 +40,23 @@ export default async function({ apiUrl, token, debug, args, config }) {
const stopUserSpinner = wait('Fetching user information');
const client = new Client({ apiUrl, token });
const user = await getUser(client);
let user;
try {
user = await getUser(client);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
console.error(error(err.message));
return 1;
}
throw err;
}
stopUserSpinner();
if (accountIsCurrent) {
currentTeam = {
slug: user.username || user.email
slug: user.username || user.email,
};
} else {
currentTeam = list.find(team => team.id === currentTeam);

View File

@@ -1,2 +0,0 @@
export const GA_TRACKING_ID = 'UA-117491914-3';
export const SENTRY_DSN = 'https://26a24e59ba954011919a524b341b6ab5@sentry.io/1323225';

View File

@@ -8,22 +8,26 @@ import * as configFiles from './config/files';
const config: any = configFiles.getConfigFilePath();
export const shouldCollectMetrics = (
config.collectMetrics === undefined
|| config.collectMetrics === true)
&& process.env.NOW_CLI_COLLECT_METRICS !== '0';
export const shouldCollectMetrics =
(config.collectMetrics === undefined || config.collectMetrics === true) &&
process.env.NOW_CLI_COLLECT_METRICS !== '0' &&
GA_TRACKING_ID;
export const metrics = () => {
const token = typeof config.token === 'string' ? config.token : platform() + release();
export const metrics = (): ua.Visitor => {
const token =
typeof config.token === 'string' ? config.token : platform() + release();
const salt = userInfo().username;
const hash = crypto.pbkdf2Sync(token, salt, 1000, 64, 'sha512').toString('hex').substring(0, 24);
const hash = crypto
.pbkdf2Sync(token, salt, 1000, 64, 'sha512')
.toString('hex')
.substring(0, 24);
return ua(GA_TRACKING_ID, {
return ua(GA_TRACKING_ID || '', {
cid: hash,
strictCidFormat: false,
uid: hash,
headers: {
'User-Agent': userAgent
}
'User-Agent': userAgent,
},
});
}
};

View File

@@ -247,12 +247,14 @@ function testFixtureStdio(directory, fn) {
if (stderr.includes(`Requested port ${port} is already in use`)) {
dev.kill('SIGTERM');
throw new Error(`Failed for "${directory}" with port ${port}.`);
throw new Error(
`Failed for "${directory}" with port ${port} with stderr "${stderr}".`
);
}
if (stderr.includes('Command failed') || stderr.includes('Error!')) {
dev.kill('SIGTERM');
throw new Error(`Failed for "${directory}".`);
throw new Error(`Failed for "${directory}" with stderr "${stderr}".`);
}
});

View File

@@ -1,7 +1,7 @@
{
"name": "@now/ruby",
"author": "Nathan Cahill <nathan@nathancahill.com>",
"version": "1.0.3-canary.1",
"version": "1.0.3-canary.3",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://zeit.co/docs/runtimes#official-runtimes/ruby",

View File

@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
rack (2.1.1)
rack (2.2.2)
PLATFORMS
ruby
@@ -10,4 +10,4 @@ DEPENDENCIES
rack (~> 2.0)
BUNDLED WITH
1.17.3
2.1.4

View File

@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
rack (2.1.1)
rack (2.2.2)
PLATFORMS
ruby
@@ -10,4 +10,4 @@ DEPENDENCIES
rack (~> 2.0)
BUNDLED WITH
1.17.3
2.1.4

View File

@@ -0,0 +1,3 @@
source "https://rubygems.org"
gem "activesupport", "~> 6.0"

View File

@@ -0,0 +1,26 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.0.2.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2)
concurrent-ruby (1.1.6)
i18n (1.8.2)
concurrent-ruby (~> 1.0)
minitest (5.14.0)
thread_safe (0.3.6)
tzinfo (1.2.6)
thread_safe (~> 0.1)
zeitwerk (2.2.2)
PLATFORMS
ruby
DEPENDENCIES
activesupport (~> 6.0)
BUNDLED WITH
2.1.4

View File

@@ -0,0 +1,14 @@
require 'active_support'
require 'active_support/core_ext'
Handler = Proc.new do |request, response|
response.status = 200
response["Content-Type"] = "text/plain"
response.body = <<-BODY
10y+ future:
#{Date.current + 10.years}
test:
gem:RANDOMNESS_PLACEHOLDER
BODY
end

View File

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