Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
826 changes: 413 additions & 413 deletions .github/actions/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .github/workflows/bug-debugger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Add Comment
uses: ./.github/actions/AddComment
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/by-design-closer-debugger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/by-design-closer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/duplicate-closer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/enhancement-closer-no-milestone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/enhancement-closer-triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/enhancement-reopener.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Run Reopener
uses: ./.github/actions/Reopener
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/external-closer-debugger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/feature-request-closer-triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/feature-request-debugger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Add Comment
uses: ./.github/actions/AddComment
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/feature-request-reopener.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Run Reopener
uses: ./.github/actions/Reopener
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/investigate-closer-debugger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/job-compile-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
with:
node-version: 24

- name: Validate Yarn lockfile
run: yarn test-yarn-lock && yarn verify-yarn-lock
- name: Validate dependency lockfiles
run: yarn test-lockfiles && yarn verify-lockfiles
working-directory: Extension

- name: Install Dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/locker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Run Locker
uses: ./.github/actions/Locker
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/more-info-needed-closer-debugger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/more-info-needed-closer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/question-closer-debugger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/question-closer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Checkout Actions
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Actions
run: cd ./.github/actions && npm install --production && cd ../..
run: cd ./.github/actions && npm ci --omit=dev && cd ../..
- name: Stale Closer
uses: ./.github/actions/StaleCloser
with:
Expand Down
4 changes: 2 additions & 2 deletions Build/package/jobs_package_vsix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ jobs:
script: |
export SRC_DIR=$(echo $BUILD_SOURCESDIRECTORY | sed 's|\\|/|g')
cd "$SRC_DIR/${{ parameters.srcDir }}"
npm install
npm ci
if [ $? -ne 0 ]; then
echo "npm install failed, sleeping for 30s before retrying..."
echo "npm ci failed, sleeping for 30s before retrying..."
sleep 30
exit 1
fi
Expand Down
92 changes: 92 additions & 0 deletions Extension/.scripts/packageLockFiles.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import fs from 'node:fs';
import path from 'node:path';
import { hasLockedIntegrity } from './subresourceIntegrity.mjs';

const excludedDirectoryNames = new Set(['.git', 'node_modules']);

function findPackageLockPaths(repositoryRoot) {
const packageLockPaths = [];

function visit(directory) {
const entries = fs.readdirSync(directory, { withFileTypes: true })
.sort((left, right) => left.name.localeCompare(right.name));
for (const entry of entries) {
const entryPath = path.join(directory, entry.name);
if (entry.isDirectory() && !excludedDirectoryNames.has(entry.name)) {
visit(entryPath);
} else if (entry.isFile() && entry.name === 'package-lock.json') {
packageLockPaths.push(entryPath);
}
}
}

visit(repositoryRoot);
return packageLockPaths;
}

function getWorkspaceTargetPath(packageEntry) {
if (packageEntry.link !== true || typeof packageEntry.resolved !== 'string') {
return undefined;
}

const workspacePath = packageEntry.resolved.replaceAll('\\', '/');
const normalizedPath = path.posix.normalize(workspacePath);
return workspacePath.length > 0
&& !/^[A-Za-z][A-Za-z0-9+.-]*:/.test(workspacePath)
&& !path.posix.isAbsolute(workspacePath)
&& normalizedPath === workspacePath
&& normalizedPath !== '.'
&& normalizedPath !== '..'
&& !normalizedPath.startsWith('../')
? normalizedPath
: undefined;
}

function getWorkspacePaths(packages) {
return new Set(Object.values(packages)
.map(getWorkspaceTargetPath)
.filter(workspacePath => workspacePath !== undefined)
.filter(workspacePath => {
const workspaceEntry = packages[workspacePath];
return !workspacePath.split('/').includes('node_modules')
&& workspaceEntry !== undefined
&& workspaceEntry.resolved === undefined
&& workspaceEntry.integrity === undefined;
}));
}

function isBundledPackageEntry(packages, packagePath, packageEntry) {
if (packageEntry.inBundle !== true || !packagePath.includes('/node_modules/')) {
return false;
}

let ancestorPath = packagePath.slice(0, packagePath.lastIndexOf('/node_modules/'));
while (ancestorPath) {
const ancestorEntry = packages[ancestorPath];
if (ancestorEntry && hasLockedIntegrity(ancestorEntry.integrity)) {
const relativePath = packagePath.slice(`${ancestorPath}/node_modules/`.length);
const relativeSegments = relativePath.split('/');
const packageName = relativeSegments[0].startsWith('@')
? relativeSegments.slice(0, 2).join('/')
: relativeSegments[0];
return Array.isArray(ancestorEntry.bundleDependencies) && ancestorEntry.bundleDependencies.includes(packageName);
}

const nextSeparator = ancestorPath.lastIndexOf('/node_modules/');
if (nextSeparator === -1) {
break;
}
ancestorPath = ancestorPath.slice(0, nextSeparator);
}
return false;
}

function isExplicitLocalPackageEntry(packages, workspacePaths, packagePath, packageEntry) {
const normalizedPackagePath = packagePath.replaceAll('\\', '/');
return workspacePaths.has(getWorkspaceTargetPath(packageEntry))
|| workspacePaths.has(normalizedPackagePath)
|| (packageEntry.link !== true && typeof packageEntry.resolved === 'string' && /^(?:file|link|workspace):/i.test(packageEntry.resolved))
|| isBundledPackageEntry(packages, normalizedPackagePath, packageEntry);
}

export { findPackageLockPaths, getWorkspacePaths, isExplicitLocalPackageEntry };
52 changes: 52 additions & 0 deletions Extension/.scripts/subresourceIntegrity.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Buffer } from 'node:buffer';
import { createHash } from 'node:crypto';

const digestLengths = new Map([
['sha1', 20],
['sha256', 32],
['sha384', 48],
['sha512', 64]
]);
const supportedAlgorithms = new Set(['sha256', 'sha384', 'sha512']);

function calculateIntegrity(algorithm, content) {
return `${algorithm}-${createHash(algorithm).update(content).digest('base64')}`;
}

function parseValidDigest(digest) {
const metadataSeparator = digest.indexOf('?');
const digestWithoutMetadata = metadataSeparator === -1 ? digest : digest.slice(0, metadataSeparator);
const match = /^(sha1|sha256|sha384|sha512)-([A-Za-z0-9+/]+={0,2})$/.exec(digestWithoutMetadata);
if (!match) {
return undefined;
}

const [, algorithm, serializedDigest] = match;
const decodedDigest = Buffer.from(serializedDigest, 'base64');
return decodedDigest.length === digestLengths.get(algorithm)
&& decodedDigest.toString('base64').replace(/=+$/, '') === serializedDigest.replace(/=+$/, '')
? { algorithm, digest: decodedDigest }
: undefined;
}

function hasLockedIntegrity(integrity) {
return typeof integrity === 'string' && integrity.split(/\s+/).some(digest => parseValidDigest(digest) !== undefined);
}

function hasSupportedIntegrityAlgorithm(integrity) {
return typeof integrity === 'string' && integrity.split(/\s+/).some(digest => supportedAlgorithms.has(parseValidDigest(digest)?.algorithm));
}

function integrityMatchesContent(integrity, algorithm, content) {
if (typeof integrity !== 'string') {
return false;
}

const expectedDigest = createHash(algorithm).update(content).digest();
return integrity.split(/\s+/).some(serializedDigest => {
const parsedDigest = parseValidDigest(serializedDigest);
return parsedDigest?.algorithm === algorithm && parsedDigest.digest.equals(expectedDigest);
});
}

export { calculateIntegrity, hasLockedIntegrity, hasSupportedIntegrityAlgorithm, integrityMatchesContent };
Loading
Loading