Skip to content
Merged
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
5 changes: 4 additions & 1 deletion .dep-stats.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
"yargs-parser": "21.1.1",
"yoctocolors-cjs": "2.1.2"
},
"devDependencies": {},
"devDependencies": {
"@octokit/openapi-types": "^24.2.0",
"@octokit/types": "^13.10.0"
},
"esm": {
"@octokit/auth-token": "^5.0.0",
"@octokit/core": "^6.1.4",
Expand Down
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@
"@cyclonedx/cdxgen": "^11.2.3",
"@eslint/compat": "^1.2.8",
"@eslint/js": "^9.24.0",
"@octokit/openapi-types": "^24.2.0",
"@octokit/types": "^13.10.0",
"@rollup/plugin-commonjs": "28.0.3",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.1",
Expand Down
4 changes: 3 additions & 1 deletion src/commands/fix/cmd-fix.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ describe('socket fix', async () => {
$ socket fix

Options
--autoMerge Enable auto-merge for pull requests that Socket opens.
See GitHub documentation (\\u200bhttps://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\\u200b) for managing auto-merge for pull requests in your repository.
--dryRun Do input validation for a command and exit 0 when input is ok
--help Print this help
--rangeStyle Define how updated dependency versions should be written in package.json.
Expand All @@ -34,7 +36,7 @@ describe('socket fix', async () => {
*\\x09pin - Use the exact version (e.g. 1.2.3)
*\\x09preserve - Retain the existing version range as-is
*\\x09tilde - Use ~ range for patch/minor updates (e.g. ~1.2.3)
--test Very the fix by running unit tests
--test Verify the fix by running unit tests
--testScript The test script to run for each fix attempt"
`
)
Expand Down
14 changes: 12 additions & 2 deletions src/commands/fix/cmd-fix.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { stripIndent } from 'common-tags'
import terminalLink from 'terminal-link'

import { joinOr } from '@socketsecurity/registry/lib/arrays'
import { logger } from '@socketsecurity/registry/lib/logger'

import { runFix } from './run-fix'
import { RangeStyles } from './types'
import { RangeStyles } from './shared'
import constants from '../../constants'
import { commonFlags } from '../../flags'
import { handleBadInput } from '../../utils/handle-bad-input'
Expand All @@ -22,6 +23,14 @@ const config: CliCommandConfig = {
hidden: true,
flags: {
...commonFlags,
autoMerge: {
type: 'boolean',
default: true,
description: `Enable auto-merge for pull requests that Socket opens.\n See ${terminalLink(
'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.`
},
rangeStyle: {
type: 'string',
default: 'preserve',
Expand All @@ -39,7 +48,7 @@ const config: CliCommandConfig = {
test: {
type: 'boolean',
default: true,
description: 'Very the fix by running unit tests'
description: 'Verify the fix by running unit tests'
},
testScript: {
type: 'string',
Expand Down Expand Up @@ -93,6 +102,7 @@ async function run(
const { spinner } = constants

await runFix({
autoMerge: Boolean(cli.flags['autoMerge']),
spinner,
rangeStyle: (cli.flags['rangeStyle'] ?? undefined) as
| RangeStyle
Expand Down
46 changes: 25 additions & 21 deletions src/commands/fix/npm-fix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
readPackageJson
} from '@socketsecurity/registry/lib/packages'

import { openGitHubPullRequest } from './open-pr'
import { enableAutoMerge, openGitHubPullRequest } from './open-pr'
import { NormalizedFixOptions } from './types'
import constants from '../../constants'
import {
Arborist,
Expand All @@ -22,11 +23,9 @@ import {
} from '../../utils/arborist-helpers'
import { getCveInfoByAlertsMap } from '../../utils/socket-package-alert'

import type { RangeStyle } from './types'
import type { SafeNode } from '../../shadow/npm/arborist/lib/node'
import type { EnvDetails } from '../../utils/package-environment'
import type { PackageJson } from '@socketsecurity/registry/lib/packages'
import type { Spinner } from '@socketsecurity/registry/lib/spinner'

const { CI, NPM } = constants

Expand All @@ -47,25 +46,17 @@ async function install(
await arb2.reify()
}

type NpmFixOptions = {
cwd?: string | undefined
rangeStyle?: RangeStyle | undefined
spinner?: Spinner | undefined
test?: boolean | undefined
testScript?: string | undefined
}

export async function npmFix(
_pkgEnvDetails: EnvDetails,
options?: NpmFixOptions | undefined
) {
const {
cwd = process.cwd(),
{
autoMerge,
cwd,
rangeStyle,
spinner,
test = false,
testScript = 'test'
} = { __proto__: null, ...options } as NpmFixOptions

test,
testScript
}: NormalizedFixOptions
) {
spinner?.start()

const arb = new SafeArborist({
Expand Down Expand Up @@ -158,7 +149,12 @@ export async function npmFix(
let saved = false
let installed = false
try {
updatePackageJsonFromNode(editablePkgJson, arb.idealTree!, node)
updatePackageJsonFromNode(
editablePkgJson,
arb.idealTree!,
node,
rangeStyle
)
// eslint-disable-next-line no-await-in-loop
await editablePkgJson.save()
saved = true
Expand All @@ -177,7 +173,15 @@ export async function npmFix(
// Lazily access constants.ENV[CI].
if (constants.ENV[CI]) {
// eslint-disable-next-line no-await-in-loop
await openGitHubPullRequest(name, targetVersion, cwd)
const prResponse = await openGitHubPullRequest(
name,
targetVersion,
cwd
)
if (autoMerge) {
// eslint-disable-next-line no-await-in-loop
await enableAutoMerge(prResponse.data)
}
}
} catch {
spinner?.error(`Reverting ${fixSpec}`)
Expand Down
42 changes: 40 additions & 2 deletions src/commands/fix/open-pr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import { spawn } from '@socketsecurity/registry/lib/spawn'

import constants from '../../constants'

import type { components } from '@octokit/openapi-types'
import type { OctokitResponse } from '@octokit/types'

type PullsCreateResponseData = components['schemas']['pull-request']

const {
GITHUB_ACTIONS,
GITHUB_REF_NAME,
Expand Down Expand Up @@ -79,11 +84,44 @@ function getOctokit() {
return _octokit
}

export async function enableAutoMerge(
prResponseData: PullsCreateResponseData
): Promise<void> {
const octokit = getOctokit()
const { node_id: prId, number: prNumber } = prResponseData

try {
await octokit.graphql(
`
mutation EnableAutoMerge($pullRequestId: ID!) {
enablePullRequestAutoMerge(input: {
pullRequestId: $pullRequestId,
mergeMethod: SQUASH
}) {
pullRequest {
number
autoMergeRequest {
enabledAt
}
}
}
}
`,
{
pullRequestId: prId
}
)
logger.info(`Auto-merge enabled for PR #${prNumber}`)
} catch (e) {
logger.error(`Failed to enable auto-merge for PR #${prNumber}:`, e)
}
}

export async function openGitHubPullRequest(
name: string,
targetVersion: string,
cwd = process.cwd()
) {
): Promise<OctokitResponse<PullsCreateResponseData>> {
// Lazily access constants.ENV[GITHUB_ACTIONS].
if (constants.ENV[GITHUB_ACTIONS]) {
// Lazily access constants.ENV[SOCKET_SECURITY_GITHUB_PAT].
Expand Down Expand Up @@ -116,7 +154,7 @@ export async function openGitHubPullRequest(
await spawn('git', ['push', '--set-upstream', 'origin', branch], { cwd })
}
const octokit = getOctokit()
await octokit.pulls.create({
return await octokit.pulls.create({
owner,
repo,
title: commitMsg,
Expand Down
45 changes: 25 additions & 20 deletions src/commands/fix/pnpm-fix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
readPackageJson
} from '@socketsecurity/registry/lib/packages'

import { openGitHubPullRequest } from './open-pr'
import { enableAutoMerge, openGitHubPullRequest } from './open-pr'
import constants from '../../constants'
import {
SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES,
Expand All @@ -24,7 +24,7 @@ import { getAlertsMapFromPnpmLockfile } from '../../utils/pnpm-lock-yaml'
import { getCveInfoByAlertsMap } from '../../utils/socket-package-alert'
import { runAgentInstall } from '../optimize/run-agent'

import type { RangeStyle } from './types'
import type { NormalizedFixOptions } from './types'
import type { StringKeyValueObject } from '../../types'
import type { EnvDetails } from '../../utils/package-environment'
import type { PackageJson } from '@socketsecurity/registry/lib/packages'
Expand All @@ -48,25 +48,17 @@ async function install(
})
}

type PnpmFixOptions = {
cwd?: string | undefined
rangeStyle?: RangeStyle | undefined
spinner?: Spinner | undefined
test?: boolean | undefined
testScript?: string | undefined
}

export async function pnpmFix(
pkgEnvDetails: EnvDetails,
options?: PnpmFixOptions
) {
const {
cwd = process.cwd(),
{
autoMerge,
cwd,
rangeStyle,
spinner,
test = false,
testScript = 'test'
} = { __proto__: null, ...options } as PnpmFixOptions

test,
testScript
}: NormalizedFixOptions
) {
const lockfile = await readWantedLockfile(cwd, { ignoreIncompatible: false })
if (!lockfile) {
return
Expand Down Expand Up @@ -185,7 +177,12 @@ export async function pnpmFix(
let installed = false
try {
editablePkgJson.update(updateData)
updatePackageJsonFromNode(editablePkgJson, arb.actualTree!, node)
updatePackageJsonFromNode(
editablePkgJson,
arb.actualTree!,
node,
rangeStyle
)
// eslint-disable-next-line no-await-in-loop
await editablePkgJson.save()
saved = true
Expand All @@ -206,7 +203,15 @@ export async function pnpmFix(
// Lazily access constants.ENV[CI].
if (constants.ENV[CI]) {
// eslint-disable-next-line no-await-in-loop
await openGitHubPullRequest(name, targetVersion, cwd)
const prResponse = await openGitHubPullRequest(
name,
targetVersion,
cwd
)
if (autoMerge) {
// eslint-disable-next-line no-await-in-loop
await enableAutoMerge(prResponse.data)
}
}
} catch {
spinner?.error(`Reverting ${fixSpec}`)
Expand Down
Loading