From 88f9b2cd1596f90fae52b2f4131c1604d468a921 Mon Sep 17 00:00:00 2001 From: Martin Torp Date: Thu, 18 Sep 2025 08:41:24 +0200 Subject: [PATCH 1/6] Rename onlyCompute to dontApplyFixes and add alias to old option name --- src/commands/fix/cmd-fix.mts | 3 +- src/commands/fix/cmd-fix.test.mts | 2 +- .../npm/socket-npm-integration.test.mts | 3 +- .../cmd-optimize-pnpm-versions.test.mts | 418 +++++++++--------- src/commands/pnpm/cmd-pnpm.test.mts | 93 ++-- 5 files changed, 265 insertions(+), 254 deletions(-) diff --git a/src/commands/fix/cmd-fix.mts b/src/commands/fix/cmd-fix.mts index 00b01b2f2..b2386b0ed 100644 --- a/src/commands/fix/cmd-fix.mts +++ b/src/commands/fix/cmd-fix.mts @@ -83,7 +83,8 @@ Available styles: * preserve - Retain the existing version range style as-is `.trim(), }, - onlyCompute: { + dontApplyFixes: { + aliases: ['onlyCompute'], type: 'boolean', default: false, description: diff --git a/src/commands/fix/cmd-fix.test.mts b/src/commands/fix/cmd-fix.test.mts index 083e2f6a9..9353ed723 100644 --- a/src/commands/fix/cmd-fix.test.mts +++ b/src/commands/fix/cmd-fix.test.mts @@ -157,6 +157,7 @@ describe('socket fix', async () => { Options --autopilot Enable auto-merge for pull requests that Socket opens. See GitHub documentation (https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-auto-merge-for-pull-requests-in-your-repository) for managing auto-merge for pull requests in your repository. + --dont-apply-fixes Compute fixes only, do not apply them. Logs what upgrades would be applied. If combined with --output-file, the output file will contain the upgrades that would be applied. --id Provide a list of vulnerability identifiers to compute fixes for: - GHSA IDs (https://docs.github.com/en/code-security/security-advisories/working-with-global-security-advisories-from-the-github-advisory-database/about-the-github-advisory-database#about-ghsa-ids) (e.g., GHSA-xxxx-xxxx-xxxx) - CVE IDs (https://cve.mitre.org/cve/identifiers/) (e.g., CVE-2025-1234) - automatically converted to GHSA @@ -165,7 +166,6 @@ describe('socket fix', async () => { --json Output result as json --limit The number of fixes to attempt at a time (default 10) --markdown Output result as markdown - --only-compute Compute fixes only, do not apply them. Logs what upgrades would be applied. If combined with --output-file, the output file will contain the upgrades that would be applied. --output-file Path to store upgrades as a JSON file at this path. --range-style Define how dependency version ranges are updated in package.json (default 'preserve'). Available styles: diff --git a/src/commands/npm/socket-npm-integration.test.mts b/src/commands/npm/socket-npm-integration.test.mts index e61c37d3c..2ec3b5c9f 100644 --- a/src/commands/npm/socket-npm-integration.test.mts +++ b/src/commands/npm/socket-npm-integration.test.mts @@ -106,7 +106,8 @@ for (const npmDir of [] as string[]) { 'Expected Socket to detect typosquat, but command succeeded', ) } catch (e) { - const errorMessage = (e as SpawnError)?.['stderr'] || (e as Error)?.['message'] || '' + const errorMessage = + (e as SpawnError)?.['stderr'] || (e as Error)?.['message'] || '' // Success cases: Socket detected an issue. if ( diff --git a/src/commands/optimize/cmd-optimize-pnpm-versions.test.mts b/src/commands/optimize/cmd-optimize-pnpm-versions.test.mts index 8376da043..f7125a8eb 100644 --- a/src/commands/optimize/cmd-optimize-pnpm-versions.test.mts +++ b/src/commands/optimize/cmd-optimize-pnpm-versions.test.mts @@ -22,223 +22,227 @@ const pnpm8FixtureDir = path.join(fixtureBaseDir, 'pnpm8') const pnpm9FixtureDir = path.join(fixtureBaseDir, 'pnpm9') // TODO: Revisit after socket-registry dep is updated. -describe.skip('socket optimize - pnpm versions', { timeout: 60_000 }, async () => { - const { binCliPath } = constants - - describe('pnpm v8', () => { - const pnpm8BinPath = path.join(pnpm8FixtureDir, 'node_modules/.bin') - - beforeEach(async () => { - // Ensure pnpm v8 is installed in the fixture - spawnSync('npm', ['install', '--silent'], { - cwd: pnpm8FixtureDir, - stdio: 'ignore', - }) - // Clean up any modifications from previous runs - spawnSync('git', ['restore', '.'], { - cwd: pnpm8FixtureDir, - stdio: 'ignore', +describe.skip( + 'socket optimize - pnpm versions', + { timeout: 60_000 }, + async () => { + const { binCliPath } = constants + + describe('pnpm v8', () => { + const pnpm8BinPath = path.join(pnpm8FixtureDir, 'node_modules/.bin') + + beforeEach(async () => { + // Ensure pnpm v8 is installed in the fixture + spawnSync('npm', ['install', '--silent'], { + cwd: pnpm8FixtureDir, + stdio: 'ignore', + }) + // Clean up any modifications from previous runs + spawnSync('git', ['restore', '.'], { + cwd: pnpm8FixtureDir, + stdio: 'ignore', + }) }) - }) - afterEach(async () => { - // Restore fixture to original state - spawnSync('git', ['restore', '.'], { - cwd: pnpm8FixtureDir, - stdio: 'ignore', + afterEach(async () => { + // Restore fixture to original state + spawnSync('git', ['restore', '.'], { + cwd: pnpm8FixtureDir, + stdio: 'ignore', + }) }) - }) - it( - 'should optimize packages with pnpm v8', - { timeout: 30_000 }, - async () => { - // Ensure npm install completed for pnpm v8 - const pnpmBin = path.join(pnpm8BinPath, 'pnpm') - const pnpmVersion = spawnSync(pnpmBin, ['--version'], { - encoding: 'utf8', - }) - expect(pnpmVersion.stdout?.trim()).toMatch(/^8\.\d+\.\d+$/) - - const packageJsonPath = path.join(pnpm8FixtureDir, 'package.json') - const pkgJsonBefore = await readPackageJson(packageJsonPath) - - // Check lodash is vulnerable version (easter egg!) - expect(pkgJsonBefore.dependencies?.lodash).toBe('4.17.20') - - const { code, stderr, stdout } = await spawnSocketCli( - binCliPath, - ['optimize', pnpm8FixtureDir, '--config', '{}'], - { - cwd: pnpm8FixtureDir, - env: { - ...process.env, - PATH: `${pnpm8BinPath}:${constants.ENV.PATH || process.env.PATH}`, + it( + 'should optimize packages with pnpm v8', + { timeout: 30_000 }, + async () => { + // Ensure npm install completed for pnpm v8 + const pnpmBin = path.join(pnpm8BinPath, 'pnpm') + const pnpmVersion = spawnSync(pnpmBin, ['--version'], { + encoding: 'utf8', + }) + expect(pnpmVersion.stdout?.trim()).toMatch(/^8\.\d+\.\d+$/) + + const packageJsonPath = path.join(pnpm8FixtureDir, 'package.json') + const pkgJsonBefore = await readPackageJson(packageJsonPath) + + // Check lodash is vulnerable version (easter egg!) + expect(pkgJsonBefore.dependencies?.lodash).toBe('4.17.20') + + const { code, stderr, stdout } = await spawnSocketCli( + binCliPath, + ['optimize', pnpm8FixtureDir, '--config', '{}'], + { + cwd: pnpm8FixtureDir, + env: { + ...process.env, + PATH: `${pnpm8BinPath}:${constants.ENV.PATH || process.env.PATH}`, + }, }, - }, - ) - - // stderr contains the Socket banner and info messages - expect(stderr, 'should show optimization message').toContain( - 'Optimizing packages for pnpm', - ) - expect(stdout, 'should show success message').toMatch( - /Socket\.dev optimized overrides/, - ) - expect(code, 'exit code should be 0').toBe(0) - - const pkgJsonAfter = await readPackageJson(packageJsonPath) - // Should have overrides added - expect(pkgJsonAfter.overrides).toBeDefined() - expect(pkgJsonAfter.resolutions).toBeDefined() - - // Check that pnpm-lock.yaml exists and was modified - const lockPath = path.join(pnpm8FixtureDir, PNPM_LOCK_YAML) - expect(existsSync(lockPath)).toBe(true) - }, - ) - - it( - 'should handle --prod flag with pnpm v8', - { timeout: 30_000 }, - async () => { - const packageJsonPath = path.join(pnpm8FixtureDir, 'package.json') - - const { code, stderr, stdout } = await spawnSocketCli( - binCliPath, - ['optimize', pnpm8FixtureDir, '--prod', '--config', '{}'], - { - cwd: pnpm8FixtureDir, - env: { - ...process.env, - PATH: `${pnpm8BinPath}:${constants.ENV.PATH || process.env.PATH}`, + ) + + // stderr contains the Socket banner and info messages + expect(stderr, 'should show optimization message').toContain( + 'Optimizing packages for pnpm', + ) + expect(stdout, 'should show success message').toMatch( + /Socket\.dev optimized overrides/, + ) + expect(code, 'exit code should be 0').toBe(0) + + const pkgJsonAfter = await readPackageJson(packageJsonPath) + // Should have overrides added + expect(pkgJsonAfter.overrides).toBeDefined() + expect(pkgJsonAfter.resolutions).toBeDefined() + + // Check that pnpm-lock.yaml exists and was modified + const lockPath = path.join(pnpm8FixtureDir, PNPM_LOCK_YAML) + expect(existsSync(lockPath)).toBe(true) + }, + ) + + it( + 'should handle --prod flag with pnpm v8', + { timeout: 30_000 }, + async () => { + const packageJsonPath = path.join(pnpm8FixtureDir, 'package.json') + + const { code, stderr, stdout } = await spawnSocketCli( + binCliPath, + ['optimize', pnpm8FixtureDir, '--prod', '--config', '{}'], + { + cwd: pnpm8FixtureDir, + env: { + ...process.env, + PATH: `${pnpm8BinPath}:${constants.ENV.PATH || process.env.PATH}`, + }, }, - }, - ) - - // stderr contains the Socket banner and info messages - expect(stderr, 'should show optimization message').toContain( - 'Optimizing packages for pnpm', - ) - expect(code, 'exit code should be 0').toBe(0) - - const pkgJsonAfter = await readPackageJson(packageJsonPath) - // Should have overrides for production deps only - expect(pkgJsonAfter.overrides).toBeDefined() - }, - ) - }) - - describe('pnpm v9', () => { - const pnpm9BinPath = path.join(pnpm9FixtureDir, 'node_modules/.bin') - - beforeEach(async () => { - // Ensure pnpm v9 is installed in the fixture - spawnSync('npm', ['install', '--silent'], { - cwd: pnpm9FixtureDir, - stdio: 'ignore', - }) - // Clean up any modifications from previous runs - spawnSync('git', ['restore', '.'], { - cwd: pnpm9FixtureDir, - stdio: 'ignore', - }) + ) + + // stderr contains the Socket banner and info messages + expect(stderr, 'should show optimization message').toContain( + 'Optimizing packages for pnpm', + ) + expect(code, 'exit code should be 0').toBe(0) + + const pkgJsonAfter = await readPackageJson(packageJsonPath) + // Should have overrides for production deps only + expect(pkgJsonAfter.overrides).toBeDefined() + }, + ) }) - afterEach(async () => { - // Restore fixture to original state - spawnSync('git', ['restore', '.'], { - cwd: pnpm9FixtureDir, - stdio: 'ignore', + describe('pnpm v9', () => { + const pnpm9BinPath = path.join(pnpm9FixtureDir, 'node_modules/.bin') + + beforeEach(async () => { + // Ensure pnpm v9 is installed in the fixture + spawnSync('npm', ['install', '--silent'], { + cwd: pnpm9FixtureDir, + stdio: 'ignore', + }) + // Clean up any modifications from previous runs + spawnSync('git', ['restore', '.'], { + cwd: pnpm9FixtureDir, + stdio: 'ignore', + }) }) - }) - it( - 'should optimize packages with pnpm v9', - { timeout: 30_000 }, - async () => { - // Ensure npm install completed for pnpm v9 - const pnpmBin = path.join(pnpm9BinPath, 'pnpm') - const pnpmVersion = spawnSync(pnpmBin, ['--version'], { - encoding: 'utf8', + afterEach(async () => { + // Restore fixture to original state + spawnSync('git', ['restore', '.'], { + cwd: pnpm9FixtureDir, + stdio: 'ignore', }) - expect(pnpmVersion.stdout?.trim()).toMatch(/^9\.\d+\.\d+$/) - - const packageJsonPath = path.join(pnpm9FixtureDir, 'package.json') - const pkgJsonBefore = await readPackageJson(packageJsonPath) - - // Check lodash is vulnerable version (easter egg!) - expect(pkgJsonBefore.dependencies?.lodash).toBe('4.17.20') - - const { code, stderr, stdout } = await spawnSocketCli( - binCliPath, - ['optimize', pnpm9FixtureDir, '--config', '{}'], - { - cwd: pnpm9FixtureDir, - env: { - ...process.env, - PATH: `${pnpm9BinPath}:${constants.ENV.PATH || process.env.PATH}`, + }) + + it( + 'should optimize packages with pnpm v9', + { timeout: 30_000 }, + async () => { + // Ensure npm install completed for pnpm v9 + const pnpmBin = path.join(pnpm9BinPath, 'pnpm') + const pnpmVersion = spawnSync(pnpmBin, ['--version'], { + encoding: 'utf8', + }) + expect(pnpmVersion.stdout?.trim()).toMatch(/^9\.\d+\.\d+$/) + + const packageJsonPath = path.join(pnpm9FixtureDir, 'package.json') + const pkgJsonBefore = await readPackageJson(packageJsonPath) + + // Check lodash is vulnerable version (easter egg!) + expect(pkgJsonBefore.dependencies?.lodash).toBe('4.17.20') + + const { code, stderr, stdout } = await spawnSocketCli( + binCliPath, + ['optimize', pnpm9FixtureDir, '--config', '{}'], + { + cwd: pnpm9FixtureDir, + env: { + ...process.env, + PATH: `${pnpm9BinPath}:${constants.ENV.PATH || process.env.PATH}`, + }, }, - }, - ) - - // stderr contains the Socket banner and info messages - expect(stderr, 'should show optimization message').toContain( - 'Optimizing packages for pnpm', - ) - expect(stdout, 'should show success message').toMatch( - /Socket\.dev optimized overrides/, - ) - expect(code, 'exit code should be 0').toBe(0) - - const pkgJsonAfter = await readPackageJson(packageJsonPath) - // Should have overrides added - expect(pkgJsonAfter.overrides).toBeDefined() - expect(pkgJsonAfter.resolutions).toBeDefined() - - // Check that pnpm-lock.yaml exists and was modified - const lockPath = path.join(pnpm9FixtureDir, PNPM_LOCK_YAML) - expect(existsSync(lockPath)).toBe(true) - }, - ) - - it( - 'should handle --pin flag with pnpm v9', - { timeout: 30_000 }, - async () => { - const packageJsonPath = path.join(pnpm9FixtureDir, 'package.json') - - const { code, stderr, stdout } = await spawnSocketCli( - binCliPath, - ['optimize', pnpm9FixtureDir, '--pin', '--config', '{}'], - { - cwd: pnpm9FixtureDir, - env: { - ...process.env, - PATH: `${pnpm9BinPath}:${constants.ENV.PATH || process.env.PATH}`, + ) + + // stderr contains the Socket banner and info messages + expect(stderr, 'should show optimization message').toContain( + 'Optimizing packages for pnpm', + ) + expect(stdout, 'should show success message').toMatch( + /Socket\.dev optimized overrides/, + ) + expect(code, 'exit code should be 0').toBe(0) + + const pkgJsonAfter = await readPackageJson(packageJsonPath) + // Should have overrides added + expect(pkgJsonAfter.overrides).toBeDefined() + expect(pkgJsonAfter.resolutions).toBeDefined() + + // Check that pnpm-lock.yaml exists and was modified + const lockPath = path.join(pnpm9FixtureDir, PNPM_LOCK_YAML) + expect(existsSync(lockPath)).toBe(true) + }, + ) + + it( + 'should handle --pin flag with pnpm v9', + { timeout: 30_000 }, + async () => { + const packageJsonPath = path.join(pnpm9FixtureDir, 'package.json') + + const { code, stderr, stdout } = await spawnSocketCli( + binCliPath, + ['optimize', pnpm9FixtureDir, '--pin', '--config', '{}'], + { + cwd: pnpm9FixtureDir, + env: { + ...process.env, + PATH: `${pnpm9BinPath}:${constants.ENV.PATH || process.env.PATH}`, + }, }, - }, - ) - - // stderr contains the Socket banner and info messages - expect(stderr, 'should show optimization message').toContain( - 'Optimizing packages for pnpm', - ) - expect(code, 'exit code should be 0').toBe(0) - - const pkgJsonAfter = await readPackageJson(packageJsonPath) - // Should have overrides with pinned versions - expect(pkgJsonAfter.overrides).toBeDefined() - - // Check that overrides use exact versions when pinned - const overrideValues = Object.values(pkgJsonAfter.overrides || {}) - overrideValues.forEach(value => { - if (typeof value === 'string' && !value.startsWith('$')) { - // Should not have ^ or ~ when pinned - expect(value).not.toMatch(/[\^~]/) - } - }) - }, - ) - }) -}) + ) + + // stderr contains the Socket banner and info messages + expect(stderr, 'should show optimization message').toContain( + 'Optimizing packages for pnpm', + ) + expect(code, 'exit code should be 0').toBe(0) + + const pkgJsonAfter = await readPackageJson(packageJsonPath) + // Should have overrides with pinned versions + expect(pkgJsonAfter.overrides).toBeDefined() + + // Check that overrides use exact versions when pinned + const overrideValues = Object.values(pkgJsonAfter.overrides || {}) + overrideValues.forEach(value => { + if (typeof value === 'string' && !value.startsWith('$')) { + // Should not have ^ or ~ when pinned + expect(value).not.toMatch(/[\^~]/) + } + }) + }, + ) + }) + }, +) diff --git a/src/commands/pnpm/cmd-pnpm.test.mts b/src/commands/pnpm/cmd-pnpm.test.mts index fc8ef19f1..18959037d 100644 --- a/src/commands/pnpm/cmd-pnpm.test.mts +++ b/src/commands/pnpm/cmd-pnpm.test.mts @@ -140,50 +140,55 @@ describe.skip('socket pnpm', async () => { }, ) - it.skip('should work when invoked via pnpm dlx', { timeout: 90_000 }, async () => { - // Create a temporary directory for testing. - const tmpDir = path.join(tmpdir(), `pnpm-dlx-test-${Date.now()}`) - await fs.mkdir(tmpDir, { recursive: true }) - - try { - // Create a minimal package.json. - await fs.writeFile( - path.join(tmpDir, 'package.json'), - JSON.stringify({ name: 'test-pnpm-dlx', version: '1.0.0' }), - ) - - // Run socket pnpm via pnpm dlx. - const { code, stderr, stdout } = await spawn( - 'pnpm', - [ - 'dlx', - '@socketsecurity/cli@latest', + it.skip( + 'should work when invoked via pnpm dlx', + { timeout: 90_000 }, + async () => { + // Create a temporary directory for testing. + const tmpDir = path.join(tmpdir(), `pnpm-dlx-test-${Date.now()}`) + await fs.mkdir(tmpDir, { recursive: true }) + + try { + // Create a minimal package.json. + await fs.writeFile( + path.join(tmpDir, 'package.json'), + JSON.stringify({ name: 'test-pnpm-dlx', version: '1.0.0' }), + ) + + // Run socket pnpm via pnpm dlx. + const { code, stderr, stdout } = await spawn( 'pnpm', - 'install', - '--config', - '{"apiToken":"fakeToken"}', - ], - { - cwd: tmpDir, - env: { - ...process.env, - SOCKET_CLI_ACCEPT_RISKS: '1', + [ + 'dlx', + '@socketsecurity/cli@latest', + 'pnpm', + 'install', + '--config', + '{"apiToken":"fakeToken"}', + ], + { + cwd: tmpDir, + env: { + ...process.env, + SOCKET_CLI_ACCEPT_RISKS: '1', + }, + timeout: 60_000, }, - timeout: 60_000, - }, - ) - - // Check that the command succeeded. - expect(code, 'pnpm dlx socket pnpm should exit with code 0').toBe(0) - - // Verify pnpm-lock.yaml was created. - const lockfilePath = path.join(tmpDir, 'pnpm-lock.yaml') - expect(existsSync(lockfilePath), 'pnpm-lock.yaml should be created').toBe( - true, - ) - } finally { - // Clean up the temporary directory. - await fs.rm(tmpDir, { recursive: true, force: true }) - } - }) + ) + + // Check that the command succeeded. + expect(code, 'pnpm dlx socket pnpm should exit with code 0').toBe(0) + + // Verify pnpm-lock.yaml was created. + const lockfilePath = path.join(tmpDir, 'pnpm-lock.yaml') + expect( + existsSync(lockfilePath), + 'pnpm-lock.yaml should be created', + ).toBe(true) + } finally { + // Clean up the temporary directory. + await fs.rm(tmpDir, { recursive: true, force: true }) + } + }, + ) }) From ea6a98752859f76b30a5675f8b174f42da606b93 Mon Sep 17 00:00:00 2001 From: Martin Torp Date: Thu, 18 Sep 2025 08:59:32 +0200 Subject: [PATCH 2/6] add repository name sanitization to ensure the API doesn't complain about invalid repository names --- src/utils/extract-names.mts | 55 ++++++++++++++ src/utils/extract-names.test.mts | 120 +++++++++++++++++++++++++++++++ src/utils/git.mts | 7 +- 3 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 src/utils/extract-names.mts create mode 100644 src/utils/extract-names.test.mts diff --git a/src/utils/extract-names.mts b/src/utils/extract-names.mts new file mode 100644 index 000000000..94fd4ce56 --- /dev/null +++ b/src/utils/extract-names.mts @@ -0,0 +1,55 @@ +import constants from '../constants.mts' + +/** + * Sanitizes a name to comply with repository naming constraints. + * Constraints: 100 or less A-Za-z0-9 characters only with non-repeating, + * non-leading or trailing ., _ or - only. + * + * @param name - The name to sanitize + * @returns Sanitized name that complies with repository naming rules, or empty string if no valid characters + */ +function sanitizeName(name: string): string { + if (!name) { + return '' + } + + // Replace sequences of illegal characters with underscores. + const sanitized = name + // Replace any sequence of non-alphanumeric characters (except ., _, -) with underscore. + .replace(/[^A-Za-z0-9._-]+/g, '_') + // Replace sequences of multiple allowed special chars with single underscore. + .replace(/[._-]{2,}/g, '_') + // Remove leading special characters. + .replace(/^[._-]+/, '') + // Remove trailing special characters. + .replace(/[._-]+$/, '') + // Truncate to 100 characters max. + .slice(0, 100) + + return sanitized +} + +/** + * Extracts and sanitizes a repository name. + * + * @param name - The repository name to extract and sanitize + * @returns Sanitized repository name, or default repository name if empty + */ +export function extractName(name: string): string { + const sanitized = sanitizeName(name) + return sanitized || constants.SOCKET_DEFAULT_REPOSITORY +} + +/** + * Extracts and sanitizes a repository owner name. + * + * @param owner - The repository owner name to extract and sanitize + * @returns Sanitized repository owner name, or undefined if input is empty + */ +export function extractOwner(owner: string): string | undefined { + if (!owner) { + return undefined + } + const sanitized = sanitizeName(owner) + return sanitized || undefined +} diff --git a/src/utils/extract-names.test.mts b/src/utils/extract-names.test.mts new file mode 100644 index 000000000..68ddae1c4 --- /dev/null +++ b/src/utils/extract-names.test.mts @@ -0,0 +1,120 @@ +import { describe, expect, it } from 'vitest' + +import constants from '../constants.mts' +import { extractName, extractOwner } from './extract-names.mts' + +describe('extractName', () => { + it('should return valid names unchanged', () => { + expect(extractName('myrepo')).toBe('myrepo') + expect(extractName('My-Repo_123')).toBe('My-Repo_123') + expect(extractName('repo.with.dots')).toBe('repo.with.dots') + expect(extractName('a1b2c3')).toBe('a1b2c3') + }) + + it('should replace sequences of illegal characters with underscore', () => { + expect(extractName('repo@#$%name')).toBe('repo_name') + expect(extractName('repo name')).toBe('repo_name') + expect(extractName('repo!!!name')).toBe('repo_name') + expect(extractName('repo/\\|name')).toBe('repo_name') + }) + + it('should replace sequences of multiple allowed special chars with single underscore', () => { + expect(extractName('repo...name')).toBe('repo_name') + expect(extractName('repo---name')).toBe('repo_name') + expect(extractName('repo___name')).toBe('repo_name') + expect(extractName('repo.-_name')).toBe('repo_name') + }) + + it('should remove leading special characters', () => { + expect(extractName('...repo')).toBe('repo') + expect(extractName('---repo')).toBe('repo') + expect(extractName('___repo')).toBe('repo') + expect(extractName('.-_repo')).toBe('repo') + }) + + it('should remove trailing special characters', () => { + expect(extractName('repo...')).toBe('repo') + expect(extractName('repo---')).toBe('repo') + expect(extractName('repo___')).toBe('repo') + expect(extractName('repo.-_')).toBe('repo') + }) + + it('should truncate names longer than 100 characters', () => { + const longName = 'a'.repeat(150) + expect(extractName(longName)).toBe('a'.repeat(100)) + }) + + it('should handle combined transformations', () => { + expect(extractName('---repo@#$name...')).toBe('repo_name') + expect(extractName(' ...my/repo\\name___ ')).toBe('my_repo_name') + }) + + it('should return default repository name for empty or invalid inputs', () => { + expect(extractName('')).toBe(constants.SOCKET_DEFAULT_REPOSITORY) + expect(extractName('...')).toBe(constants.SOCKET_DEFAULT_REPOSITORY) + expect(extractName('___')).toBe(constants.SOCKET_DEFAULT_REPOSITORY) + expect(extractName('---')).toBe(constants.SOCKET_DEFAULT_REPOSITORY) + expect(extractName('@#$%')).toBe(constants.SOCKET_DEFAULT_REPOSITORY) + }) +}) + +describe('extractOwner', () => { + it('should return valid owner names unchanged', () => { + expect(extractOwner('myowner')).toBe('myowner') + expect(extractOwner('My-Owner_123')).toBe('My-Owner_123') + expect(extractOwner('owner.with.dots')).toBe('owner.with.dots') + expect(extractOwner('a1b2c3')).toBe('a1b2c3') + }) + + it('should replace sequences of illegal characters with underscore', () => { + expect(extractOwner('owner@#$%name')).toBe('owner_name') + expect(extractOwner('owner name')).toBe('owner_name') + expect(extractOwner('owner!!!name')).toBe('owner_name') + expect(extractOwner('owner/\\|name')).toBe('owner_name') + }) + + it('should replace sequences of multiple allowed special chars with single underscore', () => { + expect(extractOwner('owner...name')).toBe('owner_name') + expect(extractOwner('owner---name')).toBe('owner_name') + expect(extractOwner('owner___name')).toBe('owner_name') + expect(extractOwner('owner.-_name')).toBe('owner_name') + }) + + it('should remove leading special characters', () => { + expect(extractOwner('...owner')).toBe('owner') + expect(extractOwner('---owner')).toBe('owner') + expect(extractOwner('___owner')).toBe('owner') + expect(extractOwner('.-_owner')).toBe('owner') + }) + + it('should remove trailing special characters', () => { + expect(extractOwner('owner...')).toBe('owner') + expect(extractOwner('owner---')).toBe('owner') + expect(extractOwner('owner___')).toBe('owner') + expect(extractOwner('owner.-_')).toBe('owner') + }) + + it('should truncate names longer than 100 characters', () => { + const longName = 'a'.repeat(150) + expect(extractOwner(longName)).toBe('a'.repeat(100)) + }) + + it('should handle combined transformations', () => { + expect(extractOwner('---owner@#$name...')).toBe('owner_name') + expect(extractOwner(' ...my/owner\\name___ ')).toBe('my_owner_name') + }) + + it('should return undefined for empty or invalid inputs', () => { + expect(extractOwner('')).toBeUndefined() + expect(extractOwner('...')).toBeUndefined() + expect(extractOwner('___')).toBeUndefined() + expect(extractOwner('---')).toBeUndefined() + expect(extractOwner('@#$%')).toBeUndefined() + }) + + it('should handle edge cases with mixed valid and invalid characters', () => { + expect(extractOwner('a@b#c$d')).toBe('a_b_c_d') + expect(extractOwner('123...456')).toBe('123_456') + expect(extractOwner('---a---')).toBe('a') + }) +}) diff --git a/src/utils/git.mts b/src/utils/git.mts index 9a34901eb..015888f53 100644 --- a/src/utils/git.mts +++ b/src/utils/git.mts @@ -3,6 +3,7 @@ import { normalizePath } from '@socketsecurity/registry/lib/path' import { isSpawnError, spawn } from '@socketsecurity/registry/lib/spawn' import constants from '../constants.mts' +import { extractName, extractOwner } from './extract-names.mts' import type { CResult } from '../types.mts' import type { SpawnOptions } from '@socketsecurity/registry/lib/spawn' @@ -77,14 +78,16 @@ export async function getRepoInfo( export async function getRepoName(cwd = process.cwd()): Promise { const repoInfo = await getRepoInfo(cwd) - return repoInfo?.repo ?? constants.SOCKET_DEFAULT_REPOSITORY + return repoInfo?.repo + ? extractName(repoInfo.repo) + : constants.SOCKET_DEFAULT_REPOSITORY } export async function getRepoOwner( cwd = process.cwd(), ): Promise { const repoInfo = await getRepoInfo(cwd) - return repoInfo?.owner + return repoInfo?.owner ? extractOwner(repoInfo.owner) : undefined } export async function gitBranch( From 54f22fcfdda6eccdfb474c4f96d04947a49f12f7 Mon Sep 17 00:00:00 2001 From: Martin Torp Date: Thu, 18 Sep 2025 09:02:16 +0200 Subject: [PATCH 3/6] update CHANGELOG --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eba893a5d..b55645c85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +## [1.1.17](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.16) - 2025-09-18 + +### Changed +- Rename `--only-compute` flag to `--dont-apply-fixejs` for `socket fix`, but keep old flag as an alias. + +### Fixed +- Sanitize extracted git repository names to be compatible with the Socket API. + ## [1.1.16](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.16) - 2025-09-16 ### Fixed From 091b2c5f324b2db46a425b3817d092780e664ac2 Mon Sep 17 00:00:00 2001 From: Martin Torp Date: Thu, 18 Sep 2025 09:19:13 +0200 Subject: [PATCH 4/6] fix rename of --only-compute flag --- src/commands/fix/cmd-fix.mts | 20 ++++++++++---------- src/commands/fix/coana-fix.mts | 6 +++--- src/commands/fix/handle-fix.mts | 6 +++--- src/commands/fix/types.mts | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/commands/fix/cmd-fix.mts b/src/commands/fix/cmd-fix.mts index b2386b0ed..121b81faf 100644 --- a/src/commands/fix/cmd-fix.mts +++ b/src/commands/fix/cmd-fix.mts @@ -49,6 +49,13 @@ const generalFlags: MeowFlags = { 'https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-auto-merge-for-pull-requests-in-your-repository', )} for managing auto-merge for pull requests in your repository.`, }, + dontApplyFixes: { + aliases: ['onlyCompute'], + type: 'boolean', + default: false, + description: + 'Compute fixes only, do not apply them. Logs what upgrades would be applied. If combined with --output-file, the output file will contain the upgrades that would be applied.', + }, id: { type: 'string', default: [], @@ -83,13 +90,6 @@ Available styles: * preserve - Retain the existing version range style as-is `.trim(), }, - dontApplyFixes: { - aliases: ['onlyCompute'], - type: 'boolean', - default: false, - description: - 'Compute fixes only, do not apply them. Logs what upgrades would be applied. If combined with --output-file, the output file will contain the upgrades that would be applied.', - }, outputFile: { type: 'string', default: '', @@ -204,12 +204,12 @@ async function run( const { autopilot, + dontApplyFixes, glob, json, limit, markdown, maxSatisfying, - onlyCompute, outputFile, prCheck, rangeStyle, @@ -218,6 +218,7 @@ async function run( unknownFlags = [], } = cli.flags as { autopilot: boolean + dontApplyFixes: boolean glob: string limit: number json: boolean @@ -228,7 +229,6 @@ async function run( rangeStyle: RangeStyle unknownFlags?: string[] outputFile: string - onlyCompute: boolean } const dryRun = !!cli.flags['dryRun'] @@ -287,6 +287,7 @@ async function run( await handleFix({ autopilot, + dontApplyFixes, cwd, ghsas, glob, @@ -298,7 +299,6 @@ async function run( rangeStyle, spinner, unknownFlags, - onlyCompute, outputFile, }) } diff --git a/src/commands/fix/coana-fix.mts b/src/commands/fix/coana-fix.mts index e70f5df80..e61f94b27 100644 --- a/src/commands/fix/coana-fix.mts +++ b/src/commands/fix/coana-fix.mts @@ -43,11 +43,11 @@ export async function coanaFix( ): Promise> { const { autopilot, + dontApplyFixes, cwd, ghsas, glob, limit, - onlyCompute, orgSlug, outputFile, spinner, @@ -105,7 +105,7 @@ export async function coanaFix( if (!shouldOpenPrs) { // Inform user about local mode when fixes will be applied. - if (!onlyCompute && ghsas.length) { + if (!dontApplyFixes && ghsas.length) { const envCheck = checkCiEnvVars() if (envCheck.present.length) { // Some CI vars are set but not all - show what's missing. @@ -142,7 +142,7 @@ export async function coanaFix( ? ['--range-style', fixConfig.rangeStyle] : []), ...(glob ? ['--glob', glob] : []), - ...(onlyCompute ? ['--dry-run'] : []), + ...(dontApplyFixes ? ['--dry-run'] : []), ...(outputFile ? ['--output-file', outputFile] : []), ...fixConfig.unknownFlags, ], diff --git a/src/commands/fix/handle-fix.mts b/src/commands/fix/handle-fix.mts index 9d06810e4..b132d03df 100644 --- a/src/commands/fix/handle-fix.mts +++ b/src/commands/fix/handle-fix.mts @@ -15,12 +15,12 @@ const CVE_FORMAT_REGEXP = /^CVE-\d{4}-\d{4,}$/ export type HandleFixConfig = Remap< FixConfig & { + dontApplyFixes: boolean ghsas: string[] glob: string orgSlug: string outputKind: OutputKind unknownFlags: string[] - onlyCompute: boolean outputFile: string } > @@ -91,12 +91,12 @@ export async function convertIdsToGhsas(ids: string[]): Promise { export async function handleFix({ autopilot, + dontApplyFixes, cwd, ghsas, glob, limit, minSatisfying, - onlyCompute, orgSlug, outputFile, outputKind, @@ -108,6 +108,7 @@ export async function handleFix({ await outputFixResult( await coanaFix({ autopilot, + dontApplyFixes, cwd, // Convert mixed CVE/GHSA/PURL inputs to GHSA IDs only ghsas: await convertIdsToGhsas(ghsas), @@ -119,7 +120,6 @@ export async function handleFix({ rangeStyle, spinner, unknownFlags, - onlyCompute, outputFile, }), outputKind, diff --git a/src/commands/fix/types.mts b/src/commands/fix/types.mts index 14ede6afb..a21b7bda8 100644 --- a/src/commands/fix/types.mts +++ b/src/commands/fix/types.mts @@ -3,6 +3,7 @@ import type { Spinner } from '@socketsecurity/registry/lib/spinner' export type FixConfig = { autopilot: boolean + dontApplyFixes: boolean cwd: string ghsas: string[] glob: string @@ -13,6 +14,5 @@ export type FixConfig = { rangeStyle: RangeStyle spinner: Spinner | undefined unknownFlags: string[] - onlyCompute: boolean outputFile: string } From 3bd4d61620e9d838466bfa62f5d8e1ea0ca8e3c3 Mon Sep 17 00:00:00 2001 From: Martin Torp Date: Sat, 20 Sep 2025 19:43:28 +0200 Subject: [PATCH 5/6] fix lint errors --- src/commands/fix/coana-fix.mts | 16 ++++++++-------- src/commands/fix/handle-fix.mts | 4 ++-- src/commands/npm/socket-npm-integration.test.mts | 1 + .../optimize/cmd-optimize-pnpm-versions.test.mts | 1 + src/commands/pnpm/cmd-pnpm.test.mts | 1 + 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/commands/fix/coana-fix.mts b/src/commands/fix/coana-fix.mts index 7a751e7eb..5365d3c97 100644 --- a/src/commands/fix/coana-fix.mts +++ b/src/commands/fix/coana-fix.mts @@ -5,6 +5,13 @@ import { debugDir, debugFn } from '@socketsecurity/registry/lib/debug' import { logger } from '@socketsecurity/registry/lib/logger' import { pluralize } from '@socketsecurity/registry/lib/words' +import { + checkCiEnvVars, + getCiEnvInstructions, + getFixEnv, +} from './env-helpers.mts' +import { getSocketFixBranchName, getSocketFixCommitMessage } from './git.mts' +import { getSocketFixPrs, openSocketFixPr } from './pull-request.mts' import { FLAG_DRY_RUN, GQL_PR_STATE_OPEN } from '../../constants.mts' import { handleApiCall } from '../../utils/api.mts' import { cmdFlagValueToArray } from '../../utils/cmd.mts' @@ -28,13 +35,6 @@ import { import { getPackageFilesForScan } from '../../utils/path-resolve.mts' import { setupSdk } from '../../utils/sdk.mts' import { fetchSupportedScanFileNames } from '../scan/fetch-supported-scan-file-names.mts' -import { - checkCiEnvVars, - getCiEnvInstructions, - getFixEnv, -} from './env-helpers.mts' -import { getSocketFixBranchName, getSocketFixCommitMessage } from './git.mts' -import { getSocketFixPrs, openSocketFixPr } from './pull-request.mts' import type { FixConfig } from './types.mts' import type { CResult } from '../../types.mts' @@ -44,8 +44,8 @@ export async function coanaFix( ): Promise> { const { autopilot, - dontApplyFixes, cwd, + dontApplyFixes, ghsas, glob, limit, diff --git a/src/commands/fix/handle-fix.mts b/src/commands/fix/handle-fix.mts index 4c1df5f68..c37fb9e7e 100644 --- a/src/commands/fix/handle-fix.mts +++ b/src/commands/fix/handle-fix.mts @@ -99,8 +99,8 @@ export async function convertIdsToGhsas(ids: string[]): Promise { export async function handleFix({ autopilot, - dontApplyFixes, cwd, + dontApplyFixes, ghsas, glob, limit, @@ -121,7 +121,7 @@ export async function handleFix({ glob, limit, minSatisfying, - onlyCompute, + dontApplyFixes, outputFile, outputKind, prCheck, diff --git a/src/commands/npm/socket-npm-integration.test.mts b/src/commands/npm/socket-npm-integration.test.mts index c481e8bbe..0ac917ff6 100644 --- a/src/commands/npm/socket-npm-integration.test.mts +++ b/src/commands/npm/socket-npm-integration.test.mts @@ -1,4 +1,5 @@ import path from 'node:path' + import { describe, expect, it } from 'vitest' import { isDebug } from '@socketsecurity/registry/lib/debug' diff --git a/src/commands/optimize/cmd-optimize-pnpm-versions.test.mts b/src/commands/optimize/cmd-optimize-pnpm-versions.test.mts index c57208d7a..432a252ec 100644 --- a/src/commands/optimize/cmd-optimize-pnpm-versions.test.mts +++ b/src/commands/optimize/cmd-optimize-pnpm-versions.test.mts @@ -1,5 +1,6 @@ import { existsSync } from 'node:fs' import path from 'node:path' + import { afterEach, beforeEach, describe, expect, it } from 'vitest' import { readPackageJson } from '@socketsecurity/registry/lib/packages' diff --git a/src/commands/pnpm/cmd-pnpm.test.mts b/src/commands/pnpm/cmd-pnpm.test.mts index 5e56fb752..6b2eb6c2e 100644 --- a/src/commands/pnpm/cmd-pnpm.test.mts +++ b/src/commands/pnpm/cmd-pnpm.test.mts @@ -1,6 +1,7 @@ import { existsSync, promises as fs } from 'node:fs' import { tmpdir } from 'node:os' import path from 'node:path' + import trash from 'trash' import { describe, expect, it } from 'vitest' From cc802962a718996f639de065678db47525d5c10c Mon Sep 17 00:00:00 2001 From: jdalton Date: Sat, 20 Sep 2025 13:44:13 -0400 Subject: [PATCH 6/6] Update actions --- .github/actions/setup/action.yml | 28 ---------------- .github/workflows/claude-auto-review.yml | 37 ++++----------------- .github/workflows/claude.yml | 24 +++----------- .github/workflows/lint.yml | 14 ++------ .github/workflows/provenance.yml | 9 ++--- .github/workflows/socket-fix.yml | 42 ------------------------ .github/workflows/test.yml | 19 ++++------- .github/workflows/types.yml | 19 +++++------ 8 files changed, 32 insertions(+), 160 deletions(-) delete mode 100644 .github/actions/setup/action.yml delete mode 100644 .github/workflows/socket-fix.yml diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml deleted file mode 100644 index 33c548abb..000000000 --- a/.github/actions/setup/action.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: 'Setup' -description: 'Setup Node.js and pnpm with caching' - -inputs: - node-version: - description: 'Node.js version' - required: false - default: '22' - -runs: - using: 'composite' - steps: - - name: Setup pnpm - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 - with: - version: '^10.16.0' - - - name: Setup Node.js with pnpm cache - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 - with: - node-version: ${{ inputs.node-version }} - cache: 'pnpm' - - - name: Install dependencies - shell: bash - run: | - pnpm install - # pnpm dlx @socketsecurity/cli pnpm install --config '{"issueRules":{"malware":true}}' diff --git a/.github/workflows/claude-auto-review.yml b/.github/workflows/claude-auto-review.yml index 245927333..21fe49d23 100644 --- a/.github/workflows/claude-auto-review.yml +++ b/.github/workflows/claude-auto-review.yml @@ -1,37 +1,14 @@ -name: Claude Auto Review +name: ⚙️ Claude Auto Review on: pull_request: types: [opened] + workflow_dispatch: jobs: auto-review: - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - id-token: write - steps: - - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - fetch-depth: 1 - - - name: Automatic PR Review - uses: anthropics/claude-code-action@28f83620103c48a57093dcc2837eec89e036bb9f # beta - with: - anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} - timeout_minutes: "60" - direct_prompt: | - Please review this pull request and provide actionable feedback. - - Focus on: - - Code quality and best practices - - Potential bugs or issues - - Performance considerations - - Security implications - - Overall architecture and design decisions - - Provide constructive feedback with specific suggestions for improvement. - Use inline comments to highlight specific areas of concern. Be concise and clear in your feedback. - allowed_tools: "mcp__github__create_pending_pull_request_review,mcp__github__add_pull_request_review_comment_to_pending_review,mcp__github__submit_pending_pull_request_review,mcp__github__get_pull_request_diff" + uses: SocketDev/socket-registry/.github/workflows/claude-auto-review.yml@main + secrets: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + with: + timeout_minutes: '60' diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index d6d76afc6..21d92418d 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -1,4 +1,4 @@ -name: Claude Code +name: ⚙️ Claude Code on: issue_comment: @@ -9,6 +9,7 @@ on: types: [opened, assigned] pull_request_review: types: [submitted] + workflow_dispatch: jobs: claude: @@ -17,21 +18,6 @@ jobs: (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - issues: write - id-token: write - steps: - - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - fetch-depth: 1 - - - name: Run Claude Code - id: claude - uses: anthropics/claude-code-action@28f83620103c48a57093dcc2837eec89e036bb9f # beta - with: - anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} - + uses: SocketDev/socket-registry/.github/workflows/claude.yml@main + secrets: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d041cc182..c9a9a6b67 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,4 +1,4 @@ -name: Linting +name: ⚙️ Linting on: push: @@ -9,6 +9,7 @@ on: pull_request: branches: - main + workflow_dispatch: permissions: contents: read @@ -19,13 +20,4 @@ concurrency: jobs: linting: - name: 'Linting' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: SocketDev/socket-cli/.github/actions/setup@6f2ee2a68551ced5ffab8ae144bdd74067b62529 - with: - node-version: '22' - - - name: Run linting - run: pnpm run check-ci + uses: SocketDev/socket-registry/.github/workflows/lint.yml@main diff --git a/.github/workflows/provenance.yml b/.github/workflows/provenance.yml index e8951d7a6..851ecb47d 100644 --- a/.github/workflows/provenance.yml +++ b/.github/workflows/provenance.yml @@ -1,4 +1,4 @@ -name: Publish Package to npm +name: ⚙️ Provenance on: workflow_dispatch: @@ -21,15 +21,10 @@ jobs: steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 - with: - version: 10 - run_install: false - - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + - uses: SocketDev/socket-registry/.github/actions/setup@main with: node-version: '22' registry-url: 'https://registry.npmjs.org' - cache: pnpm scope: '@socketsecurity' - run: pnpm install - run: INLINED_SOCKET_CLI_PUBLISHED_BUILD=1 pnpm run build:dist diff --git a/.github/workflows/socket-fix.yml b/.github/workflows/socket-fix.yml deleted file mode 100644 index 996ad0303..000000000 --- a/.github/workflows/socket-fix.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Socket Fix - -on: - schedule: - - cron: '0 0 * * *' # Run daily at midnight UTC - - cron: '0 12 * * *' # Run daily at noon UTC - workflow_dispatch: - inputs: - debug: - description: 'Enable debug output' - required: false - default: '0' - type: string - options: - - '0' - - '1' - -permissions: - contents: write # Required to push branches - pull-requests: write # Required to open PRs - -jobs: - socket-fix: - runs-on: ubuntu-latest - - steps: - - name: Checkout repo - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - - uses: SocketDev/socket-cli/.github/actions/setup@6f2ee2a68551ced5ffab8ae144bdd74067b62529 - with: - node-version: '22' - - - name: Run Socket Fix CLI - env: - DEBUG: ${{ inputs.debug == '1' && 'notice,error,inspect' || '' }} - SOCKET_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SOCKET_CLI_GIT_USER_EMAIL: socket-fix[bot]@users.noreply.github.com - SOCKET_CLI_GIT_USER_NAME: socket-fix[bot] - SOCKET_CLI_API_TOKEN: ${{ secrets.SOCKET_CLI_API_TOKEN }} - SOCKET_CLI_DEBUG: ${{ inputs.debug }} - run: pnpm dlx @socketsecurity/cli fix --autopilot --glob '!test/fixtures/**' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 33f47bd09..99b13436d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: CI +name: ⚙️ Tests on: push: @@ -19,18 +19,13 @@ concurrency: cancel-in-progress: true jobs: - test: - runs-on: ${{ matrix.os }} - timeout-minutes: 10 + test-matrix: strategy: matrix: node-version: [20, 22, 24] os: [ubuntu-latest, windows-latest] - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: SocketDev/socket-cli/.github/actions/setup@6f2ee2a68551ced5ffab8ae144bdd74067b62529 - with: - node-version: ${{ matrix.node-version }} - - - name: Run tests - run: pnpm run test-ci + name: Test Node ${{ matrix.node-version }} on ${{ matrix.os }} + uses: SocketDev/socket-registry/.github/workflows/test.yml@main + with: + node-version: '${{ matrix.node-version }}' + os: ${{ matrix.os }} diff --git a/.github/workflows/types.yml b/.github/workflows/types.yml index 9f240ba06..e4d87e07e 100644 --- a/.github/workflows/types.yml +++ b/.github/workflows/types.yml @@ -1,4 +1,4 @@ -name: Type Checks +name: ⚙️ Types on: push: @@ -9,18 +9,15 @@ on: pull_request: branches: - main + workflow_dispatch: permissions: contents: read -jobs: - type-check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: SocketDev/socket-cli/.github/actions/setup@6f2ee2a68551ced5ffab8ae144bdd74067b62529 - with: - node-version: '22' +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true - - name: Run type check - run: pnpm run check:tsc +jobs: + types: + uses: SocketDev/socket-registry/.github/workflows/types.yml@main