瀏覽代碼

Backport PR #10937: More Publish Integrity (#10938)

* More Publish Integrity (#10937)

* integrity

Co-authored-by: Afshin Taylor Darian <git@darian.af>
Steven Silvester 3 年之前
父節點
當前提交
278d6a1593

+ 1 - 0
builder/package.json

@@ -28,6 +28,7 @@
   ],
   "scripts": {
     "build": "tsc",
+    "build:all": "npm run build",
     "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
     "watch": "tsc -w --listEmittedFiles"
   },

+ 1 - 0
buildutils/package.json

@@ -35,6 +35,7 @@
   ],
   "scripts": {
     "build": "tsc",
+    "build:all": "npm run build",
     "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
     "watch": "tsc -w --listEmittedFiles"
   },

+ 1 - 0
buildutils/src/bump-js-major.ts

@@ -36,6 +36,7 @@ commander
   .option('--force', 'Force the upgrade')
   .option('--dry-run', 'Show what would be executed')
   .action((pkg: string, others: Array<string>, options: any) => {
+    utils.exitOnUuncaughtException();
     others.push(pkg);
     const toBump: Set<string> = new Set();
     const ignoreBump: Set<string> = new Set();

+ 3 - 1
buildutils/src/bumpversion.ts

@@ -14,6 +14,8 @@ commander
   .option('--skip-commit', 'Whether to skip commit changes')
   .arguments('<spec>')
   .action((spec: any, opts: any) => {
+    utils.exitOnUuncaughtException();
+
     // Get the previous version.
     const prev = utils.getPythonVersion();
 
@@ -94,7 +96,7 @@ commander
       lernaVersion += ' --preid=alpha';
     }
 
-    let cmd = `lerna version -m \"New version\" --force-publish=* --no-push ${lernaVersion}`;
+    let cmd = `lerna version -m \"[ci skip] New version\" --force-publish=* --no-push ${lernaVersion}`;
     if (opts.force) {
       cmd += ' --yes';
     }

+ 3 - 1
buildutils/src/clean-packages.ts

@@ -6,7 +6,9 @@
 import * as fs from 'fs-extra';
 import * as path from 'path';
 import * as glob from 'glob';
-import { readJSONFile } from './utils';
+import { exitOnUuncaughtException, readJSONFile } from './utils';
+
+exitOnUuncaughtException();
 
 // Get all of the packages.
 const basePath = path.resolve('.');

+ 52 - 40
buildutils/src/ensure-package.ts

@@ -68,6 +68,7 @@ export async function ensurePackage(
   const cssImports = options.cssImports || [];
   const cssModuleImports = options.cssModuleImports || [];
   const differentVersions = options.differentVersions || [];
+  const isPrivate = data.private == true;
 
   // Verify dependencies are consistent.
   let promises = Object.keys(deps).map(async name => {
@@ -109,13 +110,7 @@ export async function ensurePackage(
   filenames = filenames.concat(glob.sync(path.join(pkgPath, 'src/**/*.ts*')));
 
   const tsConfigPath = path.join(pkgPath, 'tsconfig.json');
-
-  if (!fs.existsSync(tsConfigPath)) {
-    if (utils.writePackageData(path.join(pkgPath, 'package.json'), data)) {
-      messages.push('Updated package.json');
-    }
-    return messages;
-  }
+  const usesTS = fs.existsSync(tsConfigPath);
 
   // Make sure typedoc config files are consistent
   if (fs.existsSync(path.join(pkgPath, 'typedoc.json'))) {
@@ -184,8 +179,9 @@ export async function ensurePackage(
 
   // Template the CSS index file.
   if (
-    cssImports.length > 0 ||
-    fs.existsSync(path.join(pkgPath, 'style/base.css'))
+    usesTS &&
+    (cssImports.length > 0 ||
+      fs.existsSync(path.join(pkgPath, 'style/base.css')))
   ) {
     const funcName = 'ensurePackage';
     const cssIndexContents = [
@@ -209,8 +205,9 @@ export async function ensurePackage(
 
   // Template the style module index file.
   if (
-    cssModuleImports.length > 0 ||
-    fs.existsSync(path.join(pkgPath, 'style/base.css'))
+    usesTS &&
+    (cssModuleImports.length > 0 ||
+      fs.existsSync(path.join(pkgPath, 'style/base.css')))
   ) {
     const funcName = 'ensurePackage';
     const jsIndexContents = [
@@ -233,27 +230,29 @@ export async function ensurePackage(
   }
 
   // Look for unused packages
-  Object.keys(deps).forEach(name => {
-    if (options.noUnused === false) {
-      return;
-    }
-    if (unused.indexOf(name) !== -1) {
-      return;
-    }
-    const isTest = data.name.indexOf('test') !== -1;
-    if (isTest) {
-      const testLibs = ['jest', 'ts-jest', '@jupyterlab/testutils'];
-      if (testLibs.indexOf(name) !== -1) {
+  if (usesTS) {
+    Object.keys(deps).forEach(name => {
+      if (options.noUnused === false) {
         return;
       }
-    }
-    if (names.indexOf(name) === -1) {
-      const version = data.dependencies[name];
-      messages.push(
-        `Unused dependency: ${name}@${version}: remove or add to list of known unused dependencies for this package`
-      );
-    }
-  });
+      if (unused.indexOf(name) !== -1) {
+        return;
+      }
+      const isTest = data.name.indexOf('test') !== -1;
+      if (isTest) {
+        const testLibs = ['jest', 'ts-jest', '@jupyterlab/testutils'];
+        if (testLibs.indexOf(name) !== -1) {
+          return;
+        }
+      }
+      if (names.indexOf(name) === -1) {
+        const version = data.dependencies[name];
+        messages.push(
+          `Unused dependency: ${name}@${version}: remove or add to list of known unused dependencies for this package`
+        );
+      }
+    });
+  }
 
   // Handle typedoc config output.
   const tdOptionsPath = path.join(pkgPath, 'tdoptions.json');
@@ -277,7 +276,9 @@ export async function ensurePackage(
     const ref = path.relative(pkgPath, locals[name]);
     references[name] = ref.split(path.sep).join('/');
   });
+
   if (
+    usesTS &&
     data.name.indexOf('example-') === -1 &&
     Object.keys(references).length > 0
   ) {
@@ -290,7 +291,7 @@ export async function ensurePackage(
   }
 
   // Inherit from the base tsconfig.
-  if (fs.existsSync(tsConfigPath)) {
+  if (usesTS) {
     const tsConfigData = utils.readJSONFile(tsConfigPath);
     tsConfigData.references = [];
     Object.keys(references).forEach(name => {
@@ -354,13 +355,13 @@ export async function ensurePackage(
   const schemas = glob.sync(
     path.join(pkgPath, schemaDir || 'schema', '*.json')
   );
-  if (schemaDir && !schemas.length) {
+  if (schemaDir && !schemas.length && pkgPath.indexOf('examples') == -1) {
     messages.push(`No schemas found in ${path.join(pkgPath, schemaDir)}.`);
   } else if (!schemaDir && schemas.length) {
     messages.push(`Schemas found, but no schema indicated in ${pkgPath}`);
   }
   for (const schema of schemas) {
-    if (!published.has(schema)) {
+    if (!published.has(schema) && !isPrivate) {
       messages.push(`Schema ${schema} not published in ${pkgPath}`);
     }
   }
@@ -368,7 +369,7 @@ export async function ensurePackage(
   // Ensure that the `style` directories match what is in the `package.json`
   const styles = glob.sync(path.join(pkgPath, 'style', '**/*.*'));
   const styleIndex: { [key: string]: string } = {};
-  if (styles.length > 0) {
+  if (styles.length && usesTS) {
     // If there is no theme path, the style/styleModule must be defined
     if (!data.jupyterlab?.themePath) {
       if (data.style === undefined) {
@@ -421,14 +422,14 @@ export async function ensurePackage(
       // Automatically add the style index files
       if (data.files !== undefined && styleIndex[style] !== undefined) {
         data.files.push(styleIndex[style]);
-      } else {
+      } else if (!isPrivate) {
         messages.push(`Style file ${style} not published in ${pkgPath}`);
       }
     }
   }
 
   // Ensure that sideEffects are declared, and that any styles are covered
-  if (styles.length > 0) {
+  if (styles.length > 0 && !isPrivate) {
     if (data.sideEffects === undefined) {
       messages.push(
         `Side effects not declared in ${pkgPath}, and styles are present.`
@@ -487,7 +488,7 @@ export async function ensurePackage(
         found = true;
       }
     });
-    if (!found) {
+    if (!found && !isPrivate) {
       messages.push(`File ${basePath} not included in files`);
     }
   });
@@ -506,7 +507,7 @@ export async function ensurePackage(
           found = true;
         }
       });
-      if (!found) {
+      if (!found && !isPrivate) {
         messages.push(`File ${targetPattern} not included in files`);
       }
     });
@@ -528,17 +529,28 @@ export async function ensurePackage(
   delete data.gitHead;
 
   // Ensure that there is a public access set, if the package is not private.
-  if (data.private !== true) {
+  if (!isPrivate) {
     data['publishConfig'] = { access: 'public' };
   }
 
   // Ensure there is not a prepublishOnly script.
   // Since publishing is handled by an automated script and we don't
   // Want to run individual scripts during publish.
-  if (data.scripts.prepublishOnly) {
+  if (data.scripts?.prepublishOnly) {
     delete data.scripts.prepublishOnly;
   }
 
+  // If the package is not in `packages` or does not use `tsc` in its
+  // build script, add a `build:all` target
+  const buildScript = data.scripts?.build || '';
+  if (
+    buildScript &&
+    (pkgPath.indexOf('packages') == -1 || buildScript.indexOf('tsc') == -1) &&
+    !isPrivate
+  ) {
+    data.scripts['build:all'] = 'npm run build';
+  }
+
   // Ensure the main module has an @packageDocumentation comment
   let mainFile = path.join(pkgPath, 'src', 'index.ts');
   if (!fs.existsSync(mainFile)) {

+ 3 - 0
buildutils/src/ensure-repo.ts

@@ -385,6 +385,9 @@ function ensureMetaPackage(): string[] {
     }
   });
 
+  // Add to build:all target
+  mpData.scripts['build:all'] = 'npm run build';
+
   // Write the files.
   if (messages.length > 0) {
     utils.writePackageData(mpJson, mpData);

+ 4 - 0
buildutils/src/local-repository.ts

@@ -263,6 +263,7 @@ program
   .option('--port <port>', 'Port to use for the registry')
   .option('--path <path>', 'Path to use for the registry')
   .action(async (options: any) => {
+    utils.exitOnUuncaughtException();
     const out_dir = options.path || DEFAULT_OUT_DIR;
     await startLocalRegistry(out_dir, options.port || DEFAULT_PORT);
   });
@@ -271,6 +272,7 @@ program
   .command('stop')
   .option('--path <path>', 'Path to use for the registry')
   .action(async (options: any) => {
+    utils.exitOnUuncaughtException();
     const out_dir = options.path || DEFAULT_OUT_DIR;
     await stopLocalRegistry(out_dir);
   });
@@ -279,6 +281,7 @@ program
   .command('fix-links')
   .option('--path <path>', 'Path to the directory with a yarn lock')
   .action((options: any) => {
+    utils.exitOnUuncaughtException();
     fixLinks(options.path || process.cwd());
   });
 
@@ -286,6 +289,7 @@ program
   .command('publish-dists')
   .option('--path <path>', 'Path to the directory with npm tar balls')
   .action((options: any) => {
+    utils.exitOnUuncaughtException();
     publishPackages(options.path || process.cwd());
   });
 

+ 3 - 1
buildutils/src/patch-release.ts

@@ -13,6 +13,8 @@ commander
   .option('--all', 'Patch all JS packages instead of the changed ones')
   .option('--skip-commit', 'Whether to skip commit changes')
   .action((options: any) => {
+    utils.exitOnUuncaughtException();
+
     // Make sure we can patch release.
     const pyVersion = utils.getPythonVersion();
     if (
@@ -27,7 +29,7 @@ commander
     utils.prebump();
 
     // Version the changed
-    let cmd = `lerna version patch -m \"New version\" --no-push`;
+    let cmd = `lerna version patch -m \"[ci skip] New version\" --no-push`;
     if (options.all) {
       cmd += ' --force-publish=*';
     }

+ 2 - 0
buildutils/src/prepare-python-release.ts

@@ -13,6 +13,8 @@ import * as utils from './utils';
 commander
   .description('Prepare the Python package for release')
   .action(async (options: any) => {
+    utils.exitOnUuncaughtException();
+
     const distDir = './dist';
 
     // Clean the dist directory.

+ 2 - 0
buildutils/src/prepublish-check.ts

@@ -8,6 +8,8 @@ import * as glob from 'glob';
 import * as path from 'path';
 import * as utils from './utils';
 
+utils.exitOnUuncaughtException();
+
 utils.run('npm run build:packages');
 
 utils.getLernaPaths().forEach(pkgPath => {

+ 3 - 3
buildutils/src/publish.ts

@@ -30,6 +30,8 @@ commander
   .option('--yes', 'Publish without confirmation')
   .option('--dry-run', 'Do not actually push any assets')
   .action(async (options: any) => {
+    utils.exitOnUuncaughtException();
+
     // No-op if we're in release helper dry run
     if (process.env.RH_DRY_RUN === 'true') {
       return;
@@ -37,9 +39,7 @@ commander
 
     if (!options.skipPublish) {
       if (!options.skipBuild) {
-        utils.run('jlpm run build:builder');
-        utils.run('jlpm run build:testutils');
-        utils.run('jlpm run build:packages');
+        utils.run('jlpm run build:all');
       }
 
       if (!options.dryRun) {

+ 10 - 0
buildutils/src/utils.ts

@@ -10,6 +10,16 @@ type Dict<T> = { [key: string]: T };
 
 const backSlash = /\\/g;
 
+/**
+ *  Exit with an error code on uncaught error.
+ */
+export function exitOnUuncaughtException(): void {
+  process.on('uncaughtException', function (err) {
+    console.error('Uncaught exception', err);
+    process.exit(1);
+  });
+}
+
 /**
  * Get all of the lerna package paths.
  */

+ 1 - 0
buildutils/template/package.json

@@ -27,6 +27,7 @@
   ],
   "scripts": {
     "build": "tsc -b",
+    "build:all": "npm run build",
     "build:test": "tsc --build tsconfig.test.json",
     "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
     "test": "jest",

+ 1 - 2
examples/app/package.json

@@ -4,8 +4,7 @@
   "private": true,
   "scripts": {
     "build": "webpack",
-    "clean": "rimraf build",
-    "prepublishOnly": "npm run build"
+    "clean": "rimraf build"
   },
   "dependencies": {
     "@jupyterlab/application": "^3.1.8",

+ 4 - 2
examples/cell/package.json

@@ -4,17 +4,19 @@
   "private": true,
   "scripts": {
     "build": "tsc -p src && webpack",
-    "clean": "rimraf build",
-    "prepublishOnly": "npm run build"
+    "clean": "rimraf build"
   },
   "dependencies": {
+    "@jupyterlab/application": "^3.1.8",
     "@jupyterlab/apputils": "^3.1.8",
     "@jupyterlab/cells": "^3.1.8",
     "@jupyterlab/codemirror": "^3.1.8",
     "@jupyterlab/completer": "^3.1.8",
+    "@jupyterlab/coreutils": "^5.1.8",
     "@jupyterlab/rendermime": "^3.1.8",
     "@jupyterlab/services": "^6.1.8",
     "@jupyterlab/theme-light-extension": "^3.1.8",
+    "@jupyterlab/ui-components": "^3.1.8",
     "@lumino/commands": "^1.12.0",
     "@lumino/widgets": "^1.19.0",
     "es6-promise": "~4.2.8"

+ 4 - 2
examples/console/package.json

@@ -4,15 +4,17 @@
   "private": true,
   "scripts": {
     "build": "tsc -p src && webpack",
-    "clean": "rimraf build",
-    "prepublishOnly": "npm run build"
+    "clean": "rimraf build"
   },
   "dependencies": {
+    "@jupyterlab/application": "^3.1.8",
     "@jupyterlab/codemirror": "^3.1.8",
     "@jupyterlab/console": "^3.1.8",
+    "@jupyterlab/coreutils": "^5.1.8",
     "@jupyterlab/rendermime": "^3.1.8",
     "@jupyterlab/services": "^6.1.8",
     "@jupyterlab/theme-light-extension": "^3.1.8",
+    "@jupyterlab/translation": "^3.1.8",
     "@lumino/commands": "^1.12.0",
     "@lumino/widgets": "^1.19.0",
     "es6-promise": "~4.2.8"

+ 0 - 1
examples/federated/md_package/package.json

@@ -3,7 +3,6 @@
   "version": "2.2.9",
   "private": true,
   "main": "./index.js",
-  "style": "./style/index.css",
   "scripts": {
     "build": "npm run clean && build-labextension --development --core-path ../core_package .",
     "clean": "rimraf ../labextensions/@jupyterlab/example-federated-md"

+ 5 - 2
examples/filebrowser/package.json

@@ -4,18 +4,21 @@
   "private": true,
   "scripts": {
     "build": "tsc -p src && webpack",
-    "clean": "rimraf build",
-    "prepublishOnly": "npm run build"
+    "clean": "rimraf build"
   },
   "dependencies": {
+    "@jupyterlab/application": "^3.1.8",
     "@jupyterlab/apputils": "^3.1.8",
     "@jupyterlab/codemirror": "^3.1.8",
+    "@jupyterlab/coreutils": "^5.1.8",
     "@jupyterlab/docmanager": "^3.1.8",
     "@jupyterlab/docregistry": "^3.1.8",
     "@jupyterlab/filebrowser": "^3.1.8",
     "@jupyterlab/fileeditor": "^3.1.8",
     "@jupyterlab/services": "^6.1.8",
     "@jupyterlab/theme-light-extension": "^3.1.8",
+    "@jupyterlab/translation": "^3.1.8",
+    "@jupyterlab/ui-components": "^3.1.8",
     "@lumino/algorithm": "^1.3.3",
     "@lumino/commands": "^1.12.0",
     "@lumino/widgets": "^1.19.0",

+ 4 - 2
examples/notebook/package.json

@@ -4,12 +4,14 @@
   "private": true,
   "scripts": {
     "build": "tsc -p src && webpack",
-    "clean": "rimraf build",
-    "prepublishOnly": "npm run build"
+    "clean": "rimraf build"
   },
   "dependencies": {
+    "@jupyterlab/application": "^3.1.8",
+    "@jupyterlab/apputils": "^3.1.8",
     "@jupyterlab/codemirror": "^3.1.8",
     "@jupyterlab/completer": "^3.1.8",
+    "@jupyterlab/coreutils": "^5.1.8",
     "@jupyterlab/docmanager": "^3.1.8",
     "@jupyterlab/docregistry": "^3.1.8",
     "@jupyterlab/documentsearch": "^3.1.8",

+ 3 - 2
examples/terminal/package.json

@@ -4,10 +4,11 @@
   "private": true,
   "scripts": {
     "build": "tsc -p src && webpack",
-    "clean": "rimraf build",
-    "prepublishOnly": "npm run build"
+    "clean": "rimraf build"
   },
   "dependencies": {
+    "@jupyterlab/application": "^3.1.8",
+    "@jupyterlab/coreutils": "^5.1.8",
     "@jupyterlab/services": "^6.1.8",
     "@jupyterlab/terminal": "^3.1.8",
     "@jupyterlab/theme-light-extension": "^3.1.8",

+ 6 - 3
package.json

@@ -2,6 +2,7 @@
   "name": "@jupyterlab/repo-top",
   "version": "0.0.1",
   "private": true,
+  "files": [],
   "workspaces": {
     "packages": [
       "dev_mode",
@@ -30,12 +31,14 @@
     "analyze:prod": "cd dev_mode && jlpm run build:prod --analyze",
     "before:build:python": "node buildutils/lib/local-repository.js publish-dists --path ./dist && node buildutils/lib/update-core-mode.js",
     "build": "jlpm run build:dev",
+    "build:all": "lerna run build:all",
     "build:builder": "cd builder && jlpm run build",
     "build:core": "cd jupyterlab/staging && jlpm && (jlpm deduplicate || jlpm) && jlpm run build",
-    "build:dev": "jlpm run integrity && jlpm run build:packages && jlpm run build:builder && cd dev_mode && jlpm run build",
-    "build:dev:prod": "jlpm run integrity && jlpm run build:packages && cd dev_mode && jlpm run build:prod",
-    "build:dev:prod:release": "jlpm run integrity && jlpm run build:packages && cd dev_mode && jlpm run build:prod:release",
+    "build:dev": "jlpm run integrity && jlpm run build:all && cd dev_mode && jlpm run build",
+    "build:dev:prod": "jlpm run integrity && jlpm run build:all && cd dev_mode && jlpm run build:prod",
+    "build:dev:prod:release": "jlpm run integrity && jlpm run build:all && cd dev_mode && jlpm run build:prod:release",
     "build:examples": "lerna run build --scope \"@jupyterlab/example-*\"",
+    "build:nbconvert:css": "cd packages/nbconvert-css && jlpm run build",
     "build:packages": "cd packages/metapackage && jlpm run build",
     "build:packages:scope": "lerna run build",
     "build:src": "lerna run build --scope \"@jupyterlab/!(test-|example-|application-top)*\" --concurrency 1",

+ 1 - 0
packages/metapackage/package.json

@@ -25,6 +25,7 @@
   ],
   "scripts": {
     "build": "tsc -b",
+    "build:all": "npm run build",
     "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
     "docs": "node build-doc-index.js",
     "watch": "tsc -b --watch"

+ 4 - 4
packages/nbconvert-css/package.json

@@ -13,10 +13,10 @@
   "license": "BSD-3-Clause",
   "author": "Project Jupyter",
   "sideEffects": [
-    "style/*.css"
+    "style/*.css",
+    "style/index.js"
   ],
   "main": "style/index.js",
-  "style": "style/index.css",
   "directories": {
     "style": "style/"
   },
@@ -25,9 +25,9 @@
     "style/*.css"
   ],
   "scripts": {
-    "build": "webpack",
+    "build": "webpack --mode=production",
+    "build:all": "npm run build",
     "clean": "rimraf style/",
-    "prepublishOnly": "npm run build",
     "watch": "webpack --watch"
   },
   "dependencies": {

+ 2 - 2
pyproject.toml

@@ -37,6 +37,6 @@ tag-message = "[ci skip] Release {tag_name}"
 
 [tool.jupyter-releaser.hooks]
 before-bump-version = ["git checkout .", "pip install bump2version"]
-before-build-npm = ["git commit -am 'Bump version'", "jlpm", "jlpm run build:utils", "jlpm run build:src"]
+before-build-npm = ["git commit -am '[ci skip] Bump version'", "jlpm", "jlpm run build:all"]
 before-build-python = ["node buildutils/lib/local-repository start", "jlpm run before:build:python", "node buildutils/lib/local-repository stop", "node buildutils/lib/local-repository fix-links --path jupyterlab/staging"]
-after-publish-assets = "jlpm run after:publish:assets"
+after-publish-assets = "npm run after:publish:assets"

+ 1 - 0
testutils/package.json

@@ -26,6 +26,7 @@
   ],
   "scripts": {
     "build": "tsc -b",
+    "build:all": "npm run build",
     "build:test": "tsc --build tsconfig.test.json",
     "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
     "test": "jest",

+ 19 - 2
yarn.lock

@@ -12119,11 +12119,16 @@ mz@^2.5.0:
     object-assign "^4.0.1"
     thenify-all "^1.0.0"
 
-nan@^2.12.1, nan@^2.14.0:
+nan@^2.12.1:
   version "2.14.2"
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
   integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
 
+nan@^2.14.0:
+  version "2.15.0"
+  resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
+  integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
+
 nanoid@^3.1.23:
   version "3.1.23"
   resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
@@ -15721,7 +15726,7 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
     safe-buffer "^5.1.2"
     yallist "^3.0.3"
 
-tar@^6.0.2, tar@^6.1.0:
+tar@^6.0.2:
   version "6.1.0"
   resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
   integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
@@ -15733,6 +15738,18 @@ tar@^6.0.2, tar@^6.1.0:
     mkdirp "^1.0.3"
     yallist "^4.0.0"
 
+tar@^6.1.0:
+  version "6.1.11"
+  resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
+  integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
+  dependencies:
+    chownr "^2.0.0"
+    fs-minipass "^2.0.0"
+    minipass "^3.0.0"
+    minizlib "^2.1.1"
+    mkdirp "^1.0.3"
+    yallist "^4.0.0"
+
 telejson@^5.0.2:
   version "5.3.3"
   resolved "https://registry.yarnpkg.com/telejson/-/telejson-5.3.3.tgz#fa8ca84543e336576d8734123876a9f02bf41d2e"