Skip to content

Commit

Permalink
[tests] Create tarballs of all packages in Vercel deployment (vercel#…
Browse files Browse the repository at this point in the history
…7967)

For the Vercel deployment, run `yarn pack` in each of the packages in the monorepo and place them in the "public/tarballs" directory so that we can have npm-installable URLs of each package for every commit. The `package.json` of each package is also updated to reference the tarball when a package depends on other packages within the monorepo.

Try it out like:

```
$ npm i -g https://vercel-biww73ffq.vercel.sh/tarballs/vercel.tgz

# Notice how the package.json has the monorepo dependencies
# updated to point to the related tarballs from the same deployment:

$ cat /usr/local/lib/node_modules/vercel/package.json | grep biww
    "@vercel/build-utils": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/build-utils.tgz",
    "@vercel/go": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/go.tgz",
    "@vercel/next": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/next.tgz",
    "@vercel/node": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/node.tgz",
    "@vercel/python": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/python.tgz",
    "@vercel/redwood": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/redwood.tgz",
    "@vercel/remix": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/remix.tgz",
    "@vercel/ruby": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/ruby.tgz",
    "@vercel/static-build": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/static-build.tgz",
    "@vercel/client": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/client.tgz",
    "@vercel/frameworks": "https://vercel-biww73ffq.vercel.sh/tarballs/@vercel/frameworks.tgz",

# Also notice that the "version" in `package.json` gets updated to include the commit
# SHA so that we can easily identify which commit a given tarball was generated from:

$ vercel --version
25.1.1-canary.1-727b290
```
  • Loading branch information
TooTallNate authored Jun 15, 2022
1 parent 32ee6ab commit 8167233
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 24 deletions.
19 changes: 1 addition & 18 deletions .vercelignore
Original file line number Diff line number Diff line change
@@ -1,18 +1 @@
*

# general
!utils/
!utils/run.js
!.yarnrc
!yarn.lock
!package.json
!turbo.json

# api
!api/
!api/**

# packages
!packages/
!packages/frameworks
!packages/frameworks/**
packages/*/test/**
30 changes: 28 additions & 2 deletions api/_lib/script/build.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fs from 'fs/promises';
import { join } from 'path';
import { join, dirname } from 'path';
import execa from 'execa';
import { getExampleList } from '../examples/example-list';
import { mapOldToNew } from '../examples/map-old-to-new';

Expand Down Expand Up @@ -40,7 +41,32 @@ async function main() {
JSON.stringify([...existingExamples, ...oldExamples])
);

const { stdout: sha } = await execa('git', ['rev-parse', '--short', 'HEAD'], {
cwd: repoRoot,
});

const tarballsDir = join(pubDir, 'tarballs');
const packagesDir = join(repoRoot, 'packages');
const packages = await fs.readdir(packagesDir);
for (const pkg of packages) {
const fullDir = join(packagesDir, pkg);
const packageJsonRaw = await fs.readFile(
join(fullDir, 'package.json'),
'utf-8'
);
const packageJson = JSON.parse(packageJsonRaw);
const tarballName = `${packageJson.name
.replace('@', '')
.replace('/', '-')}-v${packageJson.version}-${sha.trim()}.tgz`;
const destTarballPath = join(tarballsDir, `${packageJson.name}.tgz`);
await fs.mkdir(dirname(destTarballPath), { recursive: true });
await fs.copyFile(join(fullDir, tarballName), destTarballPath);
}

console.log('Completed building static frontend.');
}

main().catch(console.error);
main().catch(err => {
console.log('error running build:', err);
process.exit(1);
});
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,16 @@
"publish-from-github": "./utils/publish.sh",
"changelog": "node utils/changelog.js",
"build": "turbo run build",
"vercel-build": "yarn build && cd api && node -r ts-eager/register ./_lib/script/build.ts",
"vercel-build": "yarn build && yarn run pack && cd api && node -r ts-eager/register ./_lib/script/build.ts",
"pre-commit": "lint-staged",
"test": "jest --rootDir=\"test\" --testPathPattern=\"\\.test.js\"",
"test-unit": "yarn test && turbo run test-unit",
"test-integration-cli": "turbo run test-integration-cli",
"test-integration-once": "turbo run test-integration-once",
"test-integration-dev": "turbo run test-integration-dev",
"lint": "eslint . --ext .ts,.js",
"prepare": "husky install"
"prepare": "husky install",
"pack": "cd utils && node -r ts-eager/register ./pack.ts"
},
"lint-staged": {
"./{*,{api,packages,test,utils}/**/*}.{js,ts}": [
Expand Down
12 changes: 10 additions & 2 deletions packages/cli/src/util/pkg.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import _pkg from '../../package.json';
import fs from 'fs';
import { join } from 'path';
import { PackageJson } from '@vercel/build-utils';

const pkg: PackageJson & typeof _pkg = _pkg;
let rootDir = __dirname;
while (!fs.existsSync(join(rootDir, 'package.json'))) {
rootDir = join(rootDir, '..');
}

const pkgPath = join(rootDir, 'package.json');
const pkg: PackageJson & typeof import('../../package.json') = JSON.parse(
fs.readFileSync(pkgPath, 'utf8')
);
export default pkg;
52 changes: 52 additions & 0 deletions utils/pack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import execa from 'execa';
import path from 'path';
import fs from 'fs-extra';
import { TurboDryRun } from './types';

const rootDir = path.join(__dirname, '..');

async function main() {
const { stdout: sha } = await execa('git', ['rev-parse', '--short', 'HEAD'], {
cwd: rootDir,
});
const { stdout: turboStdout } = await execa(
'turbo',
['run', 'build', '--dry=json'],
{
cwd: rootDir,
}
);
const turboJson: TurboDryRun = JSON.parse(turboStdout);
for (const task of turboJson.tasks) {
const dir = path.join(rootDir, task.directory);
const packageJsonPath = path.join(dir, 'package.json');
const originalPackageObj = await fs.readJson(packageJsonPath);
const packageObj = await fs.readJson(packageJsonPath);
packageObj.version += `-${sha.trim()}`;

if (task.dependencies.length > 0) {
for (const dependency of task.dependencies) {
const name = dependency.split('#')[0];
const tarballUrl = `https://${process.env.VERCEL_URL}/tarballs/${name}.tgz`;
if (packageObj.dependencies && name in packageObj.dependencies) {
packageObj.dependencies[name] = tarballUrl;
}
if (packageObj.devDependencies && name in packageObj.devDependencies) {
packageObj.devDependencies[name] = tarballUrl;
}
}
}
await fs.writeJson(packageJsonPath, packageObj, { spaces: 2 });

await execa('yarn', ['pack'], {
cwd: dir,
stdio: 'inherit',
});
await fs.writeJson(packageJsonPath, originalPackageObj, { spaces: 2 });
}
}

main().catch(err => {
console.log('error running pack:', err);
process.exit(1);
});
16 changes: 16 additions & 0 deletions utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "ES2020",
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"noEmitOnError": true,
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true
},
"include": ["*.ts"]
}
17 changes: 17 additions & 0 deletions utils/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface TurboDryRun {
packages: Array<string>;
tasks: Array<Task>;
}

export interface Task {
taskId: string;
task: string;
package: string;
hash: string;
command: string;
outputs: Array<string>;
logFile: string;
directory: string;
dependencies: Array<string>;
dependents: Array<string>;
}

0 comments on commit 8167233

Please sign in to comment.