diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9bb38332fe8..94dc5a2bbcb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,6 +79,10 @@ jobs: run: node common/scripts/install-run-rush.js retest --verbose --production working-directory: repo-a + - name: Run package manager integration tests + run: npm run test + working-directory: repo-a/build-tests/rush-package-manager-integration-test + - name: Ensure repo README is up-to-date run: node repo-scripts/repo-toolbox/lib/start.js readme --verify working-directory: repo-a diff --git a/README.md b/README.md index 82f7b7c8a39..dbd56229562 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,7 @@ These GitHub repositories provide supplementary resources for Rush Stack: | [/build-tests/rush-amazon-s3-build-cache-plugin-integration-test](./build-tests/rush-amazon-s3-build-cache-plugin-integration-test/) | Tests connecting to an amazon S3 endpoint | | [/build-tests/rush-lib-declaration-paths-test](./build-tests/rush-lib-declaration-paths-test/) | This project ensures all of the paths in rush-lib/lib/... have imports that resolve correctly. If this project builds, all `lib/**/*.d.ts` files in the `@microsoft/rush-lib` package are valid. | | [/build-tests/rush-mcp-example-plugin](./build-tests/rush-mcp-example-plugin/) | Example showing how to create a plugin for @rushstack/mcp-server | +| [/build-tests/rush-package-manager-integration-test](./build-tests/rush-package-manager-integration-test/) | Integration tests for non-pnpm package managers in Rush. | | [/build-tests/rush-project-change-analyzer-test](./build-tests/rush-project-change-analyzer-test/) | This is an example project that uses rush-lib's ProjectChangeAnalyzer to | | [/build-tests/rush-redis-cobuild-plugin-integration-test](./build-tests/rush-redis-cobuild-plugin-integration-test/) | Tests connecting to an redis server | | [/build-tests/set-webpack-public-path-plugin-test](./build-tests/set-webpack-public-path-plugin-test/) | Building this project tests the set-webpack-public-path-plugin | diff --git a/build-tests/rush-package-manager-integration-test/README.md b/build-tests/rush-package-manager-integration-test/README.md new file mode 100644 index 00000000000..5563850776f --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/README.md @@ -0,0 +1,97 @@ +# Rush Package Manager Integration Tests + +This directory contains integration tests for verifying Rush works correctly with different package managers after the tar 7.x upgrade. + +## Background + +Rush's npm and yarn modes use temp project tarballs (stored in `common/temp/projects/`) to simulate package installations. The tar library is used to: +1. **Create** tarballs from temp project folders (`TempProjectHelper.createTempProjectTarball`) +2. **Extract** tarballs during the linking process (`NpmLinkManager._linkProjectAsync`) + +These tests ensure the tar 7.x upgrade works correctly with these workflows. + +## Tests + +The test suite is written in TypeScript using `@rushstack/node-core-library` for cross-platform compatibility. + +### testNpmMode.ts +Tests Rush npm mode by: +- Initializing a Rush repo with `npmVersion` configured +- Creating two projects with dependencies +- Running `rush update` +- Running `rush install` +- Running `rush build` (verifies everything works end-to-end) + +### testYarnMode.ts +Tests Rush yarn mode by: +- Initializing a Rush repo with `yarnVersion` configured +- Creating two projects with dependencies +- Running `rush update` +- Running `rush install` +- Running `rush build` (verifies everything works end-to-end) + +## Prerequisites + +Before running these tests: +1. Build Rush locally: `rush build --to rush` +2. Build this test project: `rush build --to rush-package-manager-integration-test` +3. Ensure you have Node.js 18+ installed + +## Running the Tests + +```bash +# Build the test project first +cd build-tests/rush-package-manager-integration-test +rush build + +# Run all tests +npm run test +``` + +Or from the root of the repo: +```bash +rush build --to rush-package-manager-integration-test +cd build-tests/rush-package-manager-integration-test +npm run test +``` + +## What Gets Tested + +These integration tests verify: +- ✓ Temp project tarballs are created correctly using tar 7.x +- ✓ Tarballs are extracted correctly during `rush install` +- ✓ File permissions are preserved (tar filter function works) +- ✓ Dependencies are linked properly between projects +- ✓ The complete workflow (update → install → build) succeeds +- ✓ Built code executes correctly + +## Test Output + +Each test creates a temporary Rush repository in `/tmp/rush-package-manager-test/`: +- `/tmp/rush-package-manager-test/npm-test-repo/` - npm mode test repository +- `/tmp/rush-package-manager-test/yarn-test-repo/` - yarn mode test repository + +These directories are cleaned up at the start of each test run. + +## Implementation + +The tests use: +- **TypeScript** for type safety and better IDE support +- **@rushstack/node-core-library** for cross-platform file operations and process execution +- **TestHelper class** to encapsulate common test operations +- Modular test functions that can be run independently or together + +## Related Code + +The tar library is used in: +- `libraries/rush-lib/src/logic/TempProjectHelper.ts` - Creates tarballs +- `libraries/rush-lib/src/logic/npm/NpmLinkManager.ts` - Extracts tarballs + +## Troubleshooting + +If tests fail: +1. Check that Rush built successfully: `rush build --to rush` +2. Check that the test project built: `rush build --to rush-package-manager-integration-test` +3. Verify Node.js version: `node --version` (should be 18+) +4. Look for error messages in the test output +5. Inspect the temp test repo: `ls -la temp/npm-test-repo/common/temp/projects/` diff --git a/build-tests/rush-package-manager-integration-test/config/rig.json b/build-tests/rush-package-manager-integration-test/config/rig.json new file mode 100644 index 00000000000..165ffb001f5 --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/config/rig.json @@ -0,0 +1,7 @@ +{ + // The "rig.json" file directs tools to look for their config files in an external package. + // Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + + "rigPackageName": "local-node-rig" +} diff --git a/build-tests/rush-package-manager-integration-test/eslint.config.js b/build-tests/rush-package-manager-integration-test/eslint.config.js new file mode 100644 index 00000000000..95db6d06e12 --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/eslint.config.js @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +const nodeProfile = require('local-node-rig/profiles/default/includes/eslint/flat/profile/node'); + +module.exports = [ + ...nodeProfile, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + tsconfigRootDir: __dirname + } + } + } +]; diff --git a/build-tests/rush-package-manager-integration-test/package.json b/build-tests/rush-package-manager-integration-test/package.json new file mode 100644 index 00000000000..a8c688eb316 --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/package.json @@ -0,0 +1,20 @@ +{ + "name": "rush-package-manager-integration-test", + "version": "1.0.0", + "private": true, + "description": "Integration tests for non-pnpm package managers in Rush.", + "license": "MIT", + "scripts": { + "_phase:build": "heft build --clean", + "build": "heft build --clean", + "test": "node lib/runTests.js" + }, + "devDependencies": { + "@microsoft/rush": "workspace:*", + "@microsoft/rush-lib": "workspace:*", + "@rushstack/heft": "workspace:*", + "@rushstack/node-core-library": "workspace:*", + "@rushstack/terminal": "workspace:*", + "local-node-rig": "workspace:*" + } +} diff --git a/build-tests/rush-package-manager-integration-test/src/TestHelper.ts b/build-tests/rush-package-manager-integration-test/src/TestHelper.ts new file mode 100644 index 00000000000..e711014973d --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/src/TestHelper.ts @@ -0,0 +1,205 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import * as path from 'node:path'; +import type * as child_process from 'node:child_process'; + +import { FileSystem, Executable, JsonFile, type JsonObject } from '@rushstack/node-core-library'; +import type { ITerminal } from '@rushstack/terminal'; + +/** + * Helper class for running integration tests with Rush package managers + */ +export class TestHelper { + private readonly _rushBinPath: string; + private readonly _terminal: ITerminal; + + public constructor(terminal: ITerminal) { + this._terminal = terminal; + // Resolve rush bin path from @microsoft/rush dependency + this._rushBinPath = require.resolve('@microsoft/rush/lib/start-dev'); + } + + /** + * Execute a Rush command using the locally-built Rush + */ + public async executeRushAsync(args: string[], workingDirectory: string): Promise { + this._terminal.writeLine(`Executing: ${process.argv0} ${this._rushBinPath} ${args.join(' ')}`); + + const childProcess: child_process.ChildProcess = Executable.spawn( + process.argv0, + [this._rushBinPath, ...args], + { + currentWorkingDirectory: workingDirectory, + stdio: 'inherit' + } + ); + + await Executable.waitForExitAsync(childProcess, { + throwOnNonZeroExitCode: true + }); + } + + /** + * Create a test Rush repository with the specified package manager + */ + public async createTestRepoAsync( + testRepoPath: string, + packageManagerType: 'npm' | 'yarn', + packageManagerVersion: string + ): Promise { + // Clean up previous test run and create empty test repo directory + this._terminal.writeLine(`Creating test repository at ${testRepoPath}...`); + await FileSystem.ensureEmptyFolderAsync(testRepoPath); + + // Initialize Rush repo + this._terminal.writeLine('Initializing Rush repo...'); + await this.executeRushAsync(['init'], testRepoPath); + + // Configure rush.json for the specified package manager + this._terminal.writeLine(`Configuring rush.json for ${packageManagerType} mode...`); + const rushJsonPath: string = path.join(testRepoPath, 'rush.json'); + const rushJson: JsonObject = await JsonFile.loadAsync(rushJsonPath); + + // Update package manager configuration + if (packageManagerType === 'npm') { + delete rushJson.pnpmVersion; + delete rushJson.yarnVersion; + rushJson.npmVersion = packageManagerVersion; + } else if (packageManagerType === 'yarn') { + delete rushJson.pnpmVersion; + delete rushJson.npmVersion; + rushJson.yarnVersion = packageManagerVersion; + } + + // Add test projects + rushJson.projects = [ + { + packageName: 'test-project-a', + projectFolder: 'projects/test-project-a' + }, + { + packageName: 'test-project-b', + projectFolder: 'projects/test-project-b' + } + ]; + + // Update nodeSupportedVersionRange to match current environment + rushJson.nodeSupportedVersionRange = '>=18.0.0'; + + await JsonFile.saveAsync(rushJson, rushJsonPath, { updateExistingFile: true }); + } + + /** + * Create a test project with the specified configuration + */ + public async createTestProjectAsync( + testRepoPath: string, + projectName: string, + version: string, + dependencies: Record, + buildScript: string + ): Promise { + const projectPath: string = path.join(testRepoPath, 'projects', projectName); + await FileSystem.ensureFolderAsync(projectPath); + + const packageJson: JsonObject = { + name: projectName, + version: version, + main: 'lib/index.js', + scripts: { + build: buildScript + }, + dependencies: dependencies + }; + + await JsonFile.saveAsync(packageJson, path.join(projectPath, 'package.json')); + } + + /** + * Verify that temp project tarballs were created + */ + public async verifyTempTarballsAsync(testRepoPath: string, projectNames: string[]): Promise { + this._terminal.writeLine('\nVerifying temp project tarballs were created...'); + for (const projectName of projectNames) { + const tarballPath: string = path.join(testRepoPath, 'common/temp/projects', `${projectName}.tgz`); + if (!(await FileSystem.existsAsync(tarballPath))) { + throw new Error(`ERROR: ${projectName}.tgz was not created!`); + } + } + this._terminal.writeLine('✓ Temp project tarballs created successfully'); + } + + /** + * Verify that dependencies are installed correctly + */ + public async verifyDependenciesAsync( + testRepoPath: string, + projectName: string, + expectedDependencies: string[] + ): Promise { + this._terminal.writeLine('\nVerifying node_modules structure...'); + const projectPath: string = path.join(testRepoPath, 'projects', projectName); + const projectNodeModules: string = path.join(projectPath, 'node_modules'); + + for (const dep of expectedDependencies) { + const depPath: string = path.join(projectNodeModules, dep); + if (!(await FileSystem.existsAsync(depPath))) { + throw new Error(`ERROR: ${dep} not found in ${projectName}!`); + } + + // Verify symlinks resolve correctly for local dependencies + if (dep.startsWith('test-project-')) { + const depRealPath: string = await FileSystem.getRealPathAsync(depPath); + const expectedRealPath: string = path.join(testRepoPath, 'projects', dep); + if (depRealPath !== expectedRealPath) { + throw new Error( + `ERROR: Symlink for ${dep} does not resolve correctly!\n` + + `Expected: ${expectedRealPath}\n` + + `Actual: ${depRealPath}` + ); + } + } + } + this._terminal.writeLine('✓ Dependencies installed correctly'); + } + + /** + * Verify that build outputs were created + */ + public async verifyBuildOutputsAsync(testRepoPath: string, projectNames: string[]): Promise { + this._terminal.writeLine('\nVerifying build outputs...'); + for (const projectName of projectNames) { + const outputPath: string = path.join(testRepoPath, 'projects', projectName, 'lib/index.js'); + if (!(await FileSystem.existsAsync(outputPath))) { + throw new Error(`ERROR: ${projectName} build output not found!`); + } + } + this._terminal.writeLine('✓ Build completed successfully'); + } + + /** + * Test that the built code executes correctly + */ + public async testBuiltCodeAsync(testRepoPath: string, projectName: string): Promise { + this._terminal.writeLine('\nTesting built code...'); + const projectLib: string = path.join(testRepoPath, 'projects', projectName, 'lib/index.js'); + + // Use forward slashes for require() path on all platforms + const projectLibPosix: string = projectLib.split(path.sep).join(path.posix.sep); + + // Use Executable.spawnSync to capture output + const result: string = Executable.spawnSync( + process.argv0, + ['-e', `const b = require('${projectLibPosix}'); console.log(b.test());`], + { + currentWorkingDirectory: testRepoPath + } + ).stdout.toString(); + + if (!result.includes('Using: Hello from A')) { + throw new Error('ERROR: Built code did not execute as expected!'); + } + this._terminal.writeLine('✓ Built code executes correctly'); + } +} diff --git a/build-tests/rush-package-manager-integration-test/src/runTests.ts b/build-tests/rush-package-manager-integration-test/src/runTests.ts new file mode 100644 index 00000000000..e531c6251bb --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/src/runTests.ts @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import { Terminal, ConsoleTerminalProvider } from '@rushstack/terminal'; + +import { testNpmModeAsync } from './testNpmMode'; +import { testYarnModeAsync } from './testYarnMode'; + +/** + * Main test runner that executes all package manager integration tests + */ +async function runTestsAsync(): Promise { + const terminal: Terminal = new Terminal(new ConsoleTerminalProvider()); + + terminal.writeLine('=========================================='); + terminal.writeLine('Rush Package Manager Integration Tests'); + terminal.writeLine('=========================================='); + terminal.writeLine(''); + terminal.writeLine('These tests verify that the tar 7.x upgrade works correctly'); + terminal.writeLine('with different Rush package managers (npm, yarn).'); + terminal.writeLine(''); + terminal.writeLine('Tests will:'); + terminal.writeLine(' 1. Create Rush repos using locally-built Rush'); + terminal.writeLine(' 2. Add projects with dependencies'); + terminal.writeLine(' 3. Run rush update (creates and extracts temp tarballs)'); + terminal.writeLine(' 4. Run rush install (extracts tarballs)'); + terminal.writeLine(' 5. Run rush build (end-to-end verification)'); + terminal.writeLine(''); + + let testsPassed: number = 0; + let testsFailed: number = 0; + const failedTests: string[] = []; + + // Run npm mode test + terminal.writeLine('=========================================='); + terminal.writeLine('Running NPM mode test...'); + terminal.writeLine('=========================================='); + try { + await testNpmModeAsync(terminal); + testsPassed++; + } catch (error) { + testsFailed++; + failedTests.push('NPM mode'); + terminal.writeErrorLine('⚠️ NPM mode test FAILED'); + terminal.writeErrorLine(String(error)); + } + + // Run yarn mode test + terminal.writeLine('=========================================='); + terminal.writeLine('Running Yarn mode test...'); + terminal.writeLine('=========================================='); + try { + await testYarnModeAsync(terminal); + testsPassed++; + } catch (error) { + testsFailed++; + failedTests.push('Yarn mode'); + terminal.writeErrorLine('⚠️ Yarn mode test FAILED'); + terminal.writeErrorLine(String(error)); + } + + // Print summary + terminal.writeLine('=========================================='); + terminal.writeLine('Test Summary'); + terminal.writeLine('=========================================='); + terminal.writeLine(''); + terminal.writeLine(`Tests passed: ${testsPassed}`); + terminal.writeLine(`Tests failed: ${testsFailed}`); + terminal.writeLine(''); + + if (testsFailed > 0) { + terminal.writeLine('Failed tests:'); + for (const test of failedTests) { + terminal.writeLine(` - ${test}`); + } + terminal.writeLine(''); + terminal.writeLine('❌ Some tests failed'); + process.exit(1); + } else { + terminal.writeLine('✅ All tests passed!'); + terminal.writeLine(''); + terminal.writeLine('The tar 7.x upgrade is working correctly with:'); + terminal.writeLine(' - NPM package manager'); + terminal.writeLine(' - Yarn package manager'); + terminal.writeLine(''); + process.exit(0); + } +} + +// Run tests and handle errors +runTestsAsync().catch((error) => { + // eslint-disable-next-line no-console + console.error('Fatal error running tests:'); + // eslint-disable-next-line no-console + console.error(error); + process.exit(1); +}); diff --git a/build-tests/rush-package-manager-integration-test/src/testNpmMode.ts b/build-tests/rush-package-manager-integration-test/src/testNpmMode.ts new file mode 100644 index 00000000000..3392e90eac3 --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/src/testNpmMode.ts @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import * as os from 'node:os'; +import * as path from 'node:path'; + +import type { ITerminal } from '@rushstack/terminal'; + +import { TestHelper } from './TestHelper'; + +/** + * Integration test for Rush npm mode with tar 7.x + * This test verifies that temp project tarballs work correctly with npm package manager + */ +export async function testNpmModeAsync(terminal: ITerminal): Promise { + const helper: TestHelper = new TestHelper(terminal); + // Use system temp directory to avoid rush init detecting parent rush.json + const testRepoPath: string = path.join(os.tmpdir(), 'rush-package-manager-test', 'npm-test-repo'); + + terminal.writeLine('=========================================='); + terminal.writeLine('Rush NPM Mode Integration Test'); + terminal.writeLine('=========================================='); + terminal.writeLine(''); + terminal.writeLine('This test verifies that tar 7.x changes work correctly with npm package manager'); + terminal.writeLine('by creating temp project tarballs and extracting them during rush install.'); + terminal.writeLine(''); + + // Create test repository with npm 6.14.15 (the version from rush init template) + await helper.createTestRepoAsync(testRepoPath, 'npm', '6.14.15'); + + // Create project A (dependency) + terminal.writeLine('Creating test-project-a...'); + await helper.createTestProjectAsync( + testRepoPath, + 'test-project-a', + '1.0.0', + { lodash: '^4.17.21' }, + `node -e "const fs = require('fs'); fs.mkdirSync('lib', {recursive: true}); fs.writeFileSync('lib/index.js', 'module.exports = { greet: () => \\"Hello from A\\" };');"` + ); + + // Create project B (depends on A) + terminal.writeLine('Creating test-project-b...'); + await helper.createTestProjectAsync( + testRepoPath, + 'test-project-b', + '1.0.0', + { + 'test-project-a': '1.0.0', + moment: '^2.29.4' + }, + `node -e "const a = require('test-project-a'), fs = require('fs'); fs.mkdirSync('lib', {recursive: true}); fs.writeFileSync('lib/index.js', 'module.exports = { test: () => \\"Using: \\" + require(\\'test-project-a\\').greet() };');"` + ); + + // Run rush update (creates and extracts temp project tarballs) + terminal.writeLine(''); + terminal.writeLine("Running 'rush update' (creates and extracts temp project tarballs using tar 7.x)..."); + await helper.executeRushAsync(['update'], testRepoPath); + + // Verify temp project tarballs were created + await helper.verifyTempTarballsAsync(testRepoPath, ['test-project-a', 'test-project-b']); + + // Run rush install (extracts temp project tarballs) + terminal.writeLine(''); + terminal.writeLine("Running 'rush install' (extracts temp project tarballs using tar 7.x)..."); + await helper.executeRushAsync(['install'], testRepoPath); + + // Verify node_modules were populated correctly + await helper.verifyDependenciesAsync(testRepoPath, 'test-project-a', ['lodash']); + await helper.verifyDependenciesAsync(testRepoPath, 'test-project-b', ['test-project-a']); + + // Run rush build + terminal.writeLine(''); + terminal.writeLine("Running 'rush build'..."); + await helper.executeRushAsync(['build'], testRepoPath); + + // Verify build outputs + await helper.verifyBuildOutputsAsync(testRepoPath, ['test-project-a', 'test-project-b']); + + // Test that the built code actually works + await helper.testBuiltCodeAsync(testRepoPath, 'test-project-b'); + + terminal.writeLine(''); + terminal.writeLine('=========================================='); + terminal.writeLine('✓ NPM Mode Integration Test PASSED'); + terminal.writeLine('=========================================='); + terminal.writeLine(''); + terminal.writeLine('The tar 7.x changes work correctly with npm mode:'); + terminal.writeLine(' - Temp project tarballs created successfully'); + terminal.writeLine(' - Tarballs extracted correctly during install'); + terminal.writeLine(' - Dependencies linked properly'); + terminal.writeLine(' - Build completed successfully'); + terminal.writeLine(''); +} diff --git a/build-tests/rush-package-manager-integration-test/src/testYarnMode.ts b/build-tests/rush-package-manager-integration-test/src/testYarnMode.ts new file mode 100644 index 00000000000..5a097c61688 --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/src/testYarnMode.ts @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import * as os from 'node:os'; +import * as path from 'node:path'; + +import type { ITerminal } from '@rushstack/terminal'; + +import { TestHelper } from './TestHelper'; + +/** + * Integration test for Rush yarn mode with tar 7.x + * This test verifies that temp project tarballs work correctly with yarn package manager + */ +export async function testYarnModeAsync(terminal: ITerminal): Promise { + const helper: TestHelper = new TestHelper(terminal); + // Use system temp directory to avoid rush init detecting parent rush.json + const testRepoPath: string = path.join(os.tmpdir(), 'rush-package-manager-test', 'yarn-test-repo'); + + terminal.writeLine('=========================================='); + terminal.writeLine('Rush Yarn Mode Integration Test'); + terminal.writeLine('=========================================='); + terminal.writeLine(''); + terminal.writeLine('This test verifies that tar 7.x changes work correctly with yarn package manager'); + terminal.writeLine('by creating temp project tarballs and extracting them during rush install.'); + terminal.writeLine(''); + + // Create test repository with yarn 1.9.4 (the version from rush init template) + await helper.createTestRepoAsync(testRepoPath, 'yarn', '1.9.4'); + + // Create project A (dependency) + terminal.writeLine('Creating test-project-a...'); + await helper.createTestProjectAsync( + testRepoPath, + 'test-project-a', + '1.0.0', + { lodash: '^4.17.21' }, + `node -e "const fs = require('fs'); fs.mkdirSync('lib', {recursive: true}); fs.writeFileSync('lib/index.js', 'module.exports = { greet: () => \\"Hello from A\\" };');"` + ); + + // Create project B (depends on A) + terminal.writeLine('Creating test-project-b...'); + await helper.createTestProjectAsync( + testRepoPath, + 'test-project-b', + '1.0.0', + { + 'test-project-a': '1.0.0', + moment: '^2.29.4' + }, + `node -e "const a = require('test-project-a'), fs = require('fs'); fs.mkdirSync('lib', {recursive: true}); fs.writeFileSync('lib/index.js', 'module.exports = { test: () => \\"Using: \\" + require(\\'test-project-a\\').greet() };');"` + ); + + // Run rush update (creates and extracts temp project tarballs) + terminal.writeLine(''); + terminal.writeLine("Running 'rush update' (creates and extracts temp project tarballs using tar 7.x)..."); + await helper.executeRushAsync(['update'], testRepoPath); + + // Verify temp project tarballs were created + await helper.verifyTempTarballsAsync(testRepoPath, ['test-project-a', 'test-project-b']); + + // Run rush install (extracts temp project tarballs) + terminal.writeLine(''); + terminal.writeLine("Running 'rush install' (extracts temp project tarballs using tar 7.x)..."); + await helper.executeRushAsync(['install'], testRepoPath); + + // Verify node_modules were populated correctly + await helper.verifyDependenciesAsync(testRepoPath, 'test-project-a', ['lodash']); + await helper.verifyDependenciesAsync(testRepoPath, 'test-project-b', ['test-project-a']); + + // Run rush build + terminal.writeLine(''); + terminal.writeLine("Running 'rush build'..."); + await helper.executeRushAsync(['build'], testRepoPath); + + // Verify build outputs + await helper.verifyBuildOutputsAsync(testRepoPath, ['test-project-a', 'test-project-b']); + + // Test that the built code actually works + await helper.testBuiltCodeAsync(testRepoPath, 'test-project-b'); + + terminal.writeLine(''); + terminal.writeLine('=========================================='); + terminal.writeLine('✓ Yarn Mode Integration Test PASSED'); + terminal.writeLine('=========================================='); + terminal.writeLine(''); + terminal.writeLine('The tar 7.x changes work correctly with yarn mode:'); + terminal.writeLine(' - Temp project tarballs created successfully'); + terminal.writeLine(' - Tarballs extracted correctly during install'); + terminal.writeLine(' - Dependencies linked properly'); + terminal.writeLine(' - Build completed successfully'); + terminal.writeLine(''); +} diff --git a/build-tests/rush-package-manager-integration-test/tsconfig.json b/build-tests/rush-package-manager-integration-test/tsconfig.json new file mode 100644 index 00000000000..b98cc4ab57c --- /dev/null +++ b/build-tests/rush-package-manager-integration-test/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "local-node-rig/profiles/default/tsconfig-base.json" +} diff --git a/common/changes/@microsoft/rush-lib/filter-npmrc-properties_2026-01-26-23-12.json b/common/changes/@microsoft/rush/filter-npmrc-properties_2026-01-26-23-12.json similarity index 100% rename from common/changes/@microsoft/rush-lib/filter-npmrc-properties_2026-01-26-23-12.json rename to common/changes/@microsoft/rush/filter-npmrc-properties_2026-01-26-23-12.json diff --git a/common/changes/@microsoft/rush/upgrade-tar-security_2026-01-26-23-56.json b/common/changes/@microsoft/rush/upgrade-tar-security_2026-01-26-23-56.json new file mode 100644 index 00000000000..102132590cb --- /dev/null +++ b/common/changes/@microsoft/rush/upgrade-tar-security_2026-01-26-23-56.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "Upgrade tar dependency from 6.2.1 to 7.5.6 to fix security vulnerability GHSA-8qq5-rm4j-mr97", + "type": "none" + } + ], + "packageName": "@microsoft/rush", + "email": "copilot@github.com" +} diff --git a/common/config/azure-pipelines/templates/build.yaml b/common/config/azure-pipelines/templates/build.yaml index 05f11e3d677..0d1204c016d 100644 --- a/common/config/azure-pipelines/templates/build.yaml +++ b/common/config/azure-pipelines/templates/build.yaml @@ -24,3 +24,7 @@ steps: - script: 'node common/scripts/install-run-rush.js retest --verbose --production ${{ parameters.BuildParameters }}' displayName: 'Rush retest (install-run-rush)' + + - script: 'npm run test' + workingDirectory: 'build-tests/rush-package-manager-integration-test' + displayName: 'Run package manager integration tests' diff --git a/common/config/rush/nonbrowser-approved-packages.json b/common/config/rush/nonbrowser-approved-packages.json index 6a51100d230..3f6756df1a8 100644 --- a/common/config/rush/nonbrowser-approved-packages.json +++ b/common/config/rush/nonbrowser-approved-packages.json @@ -62,6 +62,10 @@ "name": "@microsoft/load-themed-styles", "allowedCategories": [ "libraries" ] }, + { + "name": "@microsoft/rush", + "allowedCategories": [ "tests" ] + }, { "name": "@microsoft/rush-lib", "allowedCategories": [ "libraries", "tests", "vscode-extensions" ] diff --git a/common/config/subspaces/build-tests-subspace/pnpm-lock.yaml b/common/config/subspaces/build-tests-subspace/pnpm-lock.yaml index d5a0bc83b4f..6de7624d794 100644 --- a/common/config/subspaces/build-tests-subspace/pnpm-lock.yaml +++ b/common/config/subspaces/build-tests-subspace/pnpm-lock.yaml @@ -429,6 +429,10 @@ packages: resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} engines: {node: 20 || >=22} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@istanbuljs/load-nyc-config@1.1.0': resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -1471,9 +1475,9 @@ packages: chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} chrome-trace-event@1.0.4: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} @@ -1985,10 +1989,6 @@ packages: resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} engines: {node: '>=14.14'} - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2772,17 +2772,13 @@ packages: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} @@ -3447,10 +3443,9 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} - tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} - deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me + tar@7.5.6: + resolution: {integrity: sha512-xqUeu2JAIJpXyvskvU3uvQW8PAmHrtXp2KDuMJwQqW8Sqq0CaZBAQ+dKS3RBXVhU4wC5NjAdKrmh84241gO9cA==} + engines: {node: '>=18'} terser-webpack-plugin@5.3.16: resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} @@ -3704,6 +3699,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml@2.4.1: resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==} engines: {node: '>= 14'} @@ -4010,6 +4009,10 @@ snapshots: dependencies: '@isaacs/balanced-match': 4.0.1 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 @@ -4334,7 +4337,7 @@ snapshots: ssri: 8.0.1 strict-uri-encode: 2.0.0 tapable: 2.2.1 - tar: 6.2.1 + tar: 7.5.6 true-case-path: 2.2.1 transitivePeerDependencies: - '@types/node' @@ -4411,7 +4414,7 @@ snapshots: '@pnpm/crypto.base32-hash': 2.0.0 '@pnpm/types': 9.4.2 encode-registry: 3.0.1 - semver: 7.5.4 + semver: 7.7.3 '@pnpm/dependency-path@5.1.7': dependencies: @@ -4477,7 +4480,7 @@ snapshots: js-yaml: '@zkochan/js-yaml@0.0.6' normalize-path: 3.0.0 ramda: '@pnpm/ramda@0.28.1' - semver: 7.5.4 + semver: 7.7.3 sort-keys: 4.2.0 strip-bom: 4.0.0 write-file-atomic: 5.0.1 @@ -4556,7 +4559,7 @@ snapshots: '@pnpm/lockfile-types': 5.1.5 comver-to-semver: 1.0.0 ramda: '@pnpm/ramda@0.28.1' - semver: 7.5.4 + semver: 7.7.3 '@pnpm/object.key-sorting@1000.0.1': dependencies: @@ -5719,7 +5722,7 @@ snapshots: chardet@2.1.1: {} - chownr@2.0.0: {} + chownr@3.0.0: {} chrome-trace-event@1.0.4: {} @@ -6409,10 +6412,6 @@ snapshots: jsonfile: 6.2.0 universalify: 2.0.1 - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -7459,14 +7458,11 @@ snapshots: dependencies: yallist: 4.0.0 - minipass@5.0.0: {} - minipass@7.1.2: {} - minizlib@2.1.2: + minizlib@3.1.0: dependencies: - minipass: 3.3.6 - yallist: 4.0.0 + minipass: 7.1.2 mkdirp@0.5.6: dependencies: @@ -7516,7 +7512,7 @@ snapshots: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.16.1 - semver: 7.5.4 + semver: 7.7.3 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} @@ -7675,7 +7671,7 @@ snapshots: got: 11.8.6 registry-auth-token: 4.2.2 registry-url: 5.1.0 - semver: 7.5.4 + semver: 7.7.3 pako@1.0.11: {} @@ -8207,14 +8203,13 @@ snapshots: tapable@2.3.0: {} - tar@6.2.1: + tar@7.5.6: dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 terser-webpack-plugin@5.3.16(webpack@5.103.0): dependencies: @@ -8533,6 +8528,8 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yaml@2.4.1: {} yocto-queue@0.1.0: {} diff --git a/common/config/subspaces/build-tests-subspace/repo-state.json b/common/config/subspaces/build-tests-subspace/repo-state.json index 6c578d03e7e..6c5fab479be 100644 --- a/common/config/subspaces/build-tests-subspace/repo-state.json +++ b/common/config/subspaces/build-tests-subspace/repo-state.json @@ -1,6 +1,6 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "3821e72a3e032f9d3bfc8da6115cea4275a0fe2b", + "pnpmShrinkwrapHash": "da80c128380df78244e113861884b5e6a38ad7c5", "preferredVersionsHash": "550b4cee0bef4e97db6c6aad726df5149d20e7d9", - "packageJsonInjectedDependenciesHash": "f0c6fee692b330a1de08fb064f17fa7612920cd4" + "packageJsonInjectedDependenciesHash": "1c312688ef85bfdb64079cc271a46b18d816d411" } diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index 330c74bd4ca..38034be545c 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -2761,6 +2761,27 @@ importers: specifier: workspace:* version: link:../../rigs/local-node-rig + ../../../build-tests/rush-package-manager-integration-test: + devDependencies: + '@microsoft/rush': + specifier: workspace:* + version: link:../../apps/rush + '@microsoft/rush-lib': + specifier: workspace:* + version: link:../../libraries/rush-lib + '@rushstack/heft': + specifier: workspace:* + version: link:../../apps/heft + '@rushstack/node-core-library': + specifier: workspace:* + version: link:../../libraries/node-core-library + '@rushstack/terminal': + specifier: workspace:* + version: link:../../libraries/terminal + local-node-rig: + specifier: workspace:* + version: link:../../rigs/local-node-rig + ../../../build-tests/rush-project-change-analyzer-test: dependencies: '@microsoft/rush-lib': @@ -4112,8 +4133,8 @@ importers: specifier: 2.2.1 version: 2.2.1 tar: - specifier: ~6.2.1 - version: 6.2.1 + specifier: ~7.5.6 + version: 7.5.6 true-case-path: specifier: ~2.2.1 version: 2.2.1 @@ -4163,9 +4184,6 @@ importers: '@types/strict-uri-encode': specifier: 2.0.0 version: 2.0.0 - '@types/tar': - specifier: 6.1.6 - version: 6.1.6 '@types/webpack-env': specifier: 1.18.8 version: 1.18.8 @@ -7936,6 +7954,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@istanbuljs/load-nyc-config@1.1.0': resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -10190,9 +10212,6 @@ packages: '@types/tapable@1.0.6': resolution: {integrity: sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==} - '@types/tar@6.1.6': - resolution: {integrity: sha512-HQ06kiiDXz9uqtmE9ksQUn1ovcPr1gGV9EgaCWo6FGYKD0onNBCetBzL0kfcS8Kbj1EFxJWY9jL2W4ZvvtGI8Q==} - '@types/through@0.0.33': resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} @@ -11502,6 +11521,10 @@ packages: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + chrome-trace-event@1.0.4: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} @@ -15166,10 +15189,6 @@ packages: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} - minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - minipass@5.0.0: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} @@ -15182,6 +15201,10 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + mississippi@3.0.0: resolution: {integrity: sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==} engines: {node: '>=4.0.0'} @@ -17623,6 +17646,10 @@ packages: engines: {node: '>=10'} deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me + tar@7.5.6: + resolution: {integrity: sha512-xqUeu2JAIJpXyvskvU3uvQW8PAmHrtXp2KDuMJwQqW8Sqq0CaZBAQ+dKS3RBXVhU4wC5NjAdKrmh84241gO9cA==} + engines: {node: '>=18'} + telejson@5.3.3: resolution: {integrity: sha512-PjqkJZpzEggA9TBpVtJi1LVptP7tYtXB6rEubwlHap76AMjzvOdKX41CxyaW7ahhzDU1aftXnMCx5kAPDZTQBA==} @@ -18626,6 +18653,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -22293,6 +22324,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 @@ -26292,11 +26327,6 @@ snapshots: '@types/tapable@1.0.6': {} - '@types/tar@6.1.6': - dependencies: - '@types/node': 22.9.3 - minipass: 4.2.8 - '@types/through@0.0.33': dependencies: '@types/node': 22.9.3 @@ -28323,6 +28353,8 @@ snapshots: chownr@2.0.0: {} + chownr@3.0.0: {} + chrome-trace-event@1.0.4: {} ci-info@2.0.0: {} @@ -33286,8 +33318,6 @@ snapshots: dependencies: yallist: 4.0.0 - minipass@4.2.8: {} - minipass@5.0.0: {} minipass@7.1.2: {} @@ -33297,6 +33327,10 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + minizlib@3.1.0: + dependencies: + minipass: 7.1.2 + mississippi@3.0.0: dependencies: concat-stream: 1.6.2 @@ -36134,6 +36168,14 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + tar@7.5.6: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 + telejson@5.3.3: dependencies: '@types/is-function': 1.0.3 @@ -37405,6 +37447,8 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yaml@1.10.2: {} yaml@2.4.1: {} diff --git a/common/config/subspaces/default/repo-state.json b/common/config/subspaces/default/repo-state.json index cb27decae5d..6f7b9aabb5c 100644 --- a/common/config/subspaces/default/repo-state.json +++ b/common/config/subspaces/default/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "627024553ddfaf140f96522acefe4e7a4895a0b3", + "pnpmShrinkwrapHash": "aebea9e28d4e012d8a37fc57c92bd28eb386df5b", "preferredVersionsHash": "a9b67c38568259823f9cfb8270b31bf6d8470b27" } diff --git a/libraries/rush-lib/package.json b/libraries/rush-lib/package.json index e8ae5199e13..d0274ed0734 100644 --- a/libraries/rush-lib/package.json +++ b/libraries/rush-lib/package.json @@ -66,7 +66,7 @@ "ssri": "~8.0.0", "strict-uri-encode": "~2.0.0", "tapable": "2.2.1", - "tar": "~6.2.1", + "tar": "~7.5.6", "true-case-path": "~2.2.1" }, "devDependencies": { @@ -85,7 +85,6 @@ "@types/semver": "7.5.0", "@types/ssri": "~7.1.0", "@types/strict-uri-encode": "2.0.0", - "@types/tar": "6.1.6", "@types/webpack-env": "1.18.8", "eslint": "~9.37.0", "local-node-rig": "workspace:*", diff --git a/libraries/rush-lib/src/logic/TempProjectHelper.ts b/libraries/rush-lib/src/logic/TempProjectHelper.ts index 8cd0bcc94e2..10c27d2e847 100644 --- a/libraries/rush-lib/src/logic/TempProjectHelper.ts +++ b/libraries/rush-lib/src/logic/TempProjectHelper.ts @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. import * as path from 'node:path'; +import type { Stats } from 'node:fs'; import * as tar from 'tar'; @@ -46,7 +47,7 @@ export class TempProjectHelper { noPax: true, sync: true, prefix: npmPackageFolder, - filter: (tarPath: string, stat: tar.FileStat): boolean => { + filter: (tarPath: string, stat: Stats): boolean => { if ( !this._rushConfiguration.experimentsConfiguration.configuration.noChmodFieldInTarHeaderNormalization ) { diff --git a/rush.json b/rush.json index 6cfc842f2fb..12aee249709 100644 --- a/rush.json +++ b/rush.json @@ -1058,6 +1058,12 @@ "reviewCategory": "tests", "shouldPublish": false }, + { + "packageName": "rush-package-manager-integration-test", + "projectFolder": "build-tests/rush-package-manager-integration-test", + "reviewCategory": "tests", + "shouldPublish": false + }, { "packageName": "rush-redis-cobuild-plugin-integration-test", "projectFolder": "build-tests/rush-redis-cobuild-plugin-integration-test",