Skip to content

Commit a94ec62

Browse files
committed
Enable auto-merge and range styles
1 parent 559893b commit a94ec62

File tree

12 files changed

+216
-92
lines changed

12 files changed

+216
-92
lines changed

.dep-stats.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232
"yargs-parser": "21.1.1",
3333
"yoctocolors-cjs": "2.1.2"
3434
},
35-
"devDependencies": {},
35+
"devDependencies": {
36+
"@octokit/openapi-types": "^24.2.0",
37+
"@octokit/types": "^13.10.0"
38+
},
3639
"esm": {
3740
"@octokit/auth-token": "^5.0.0",
3841
"@octokit/core": "^6.1.4",

package-lock.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@
122122
"@cyclonedx/cdxgen": "^11.2.3",
123123
"@eslint/compat": "^1.2.8",
124124
"@eslint/js": "^9.24.0",
125+
"@octokit/openapi-types": "^24.2.0",
126+
"@octokit/types": "^13.10.0",
125127
"@rollup/plugin-commonjs": "28.0.3",
126128
"@rollup/plugin-json": "^6.1.0",
127129
"@rollup/plugin-node-resolve": "^16.0.1",

src/commands/fix/cmd-fix.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ describe('socket fix', async () => {
2424
$ socket fix
2525
2626
Options
27+
--autoMerge Enable auto-merge for pull requests that Socket opens.
28+
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.
2729
--dryRun Do input validation for a command and exit 0 when input is ok
2830
--help Print this help
2931
--rangeStyle Define how updated dependency versions should be written in package.json.
@@ -34,7 +36,7 @@ describe('socket fix', async () => {
3436
*\\x09pin - Use the exact version (e.g. 1.2.3)
3537
*\\x09preserve - Retain the existing version range as-is
3638
*\\x09tilde - Use ~ range for patch/minor updates (e.g. ~1.2.3)
37-
--test Very the fix by running unit tests
39+
--test Verify the fix by running unit tests
3840
--testScript The test script to run for each fix attempt"
3941
`
4042
)

src/commands/fix/cmd-fix.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { stripIndent } from 'common-tags'
2+
import terminalLink from 'terminal-link'
23

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

67
import { runFix } from './run-fix'
7-
import { RangeStyles } from './types'
8+
import { RangeStyles } from './shared'
89
import constants from '../../constants'
910
import { commonFlags } from '../../flags'
1011
import { handleBadInput } from '../../utils/handle-bad-input'
@@ -22,6 +23,14 @@ const config: CliCommandConfig = {
2223
hidden: true,
2324
flags: {
2425
...commonFlags,
26+
autoMerge: {
27+
type: 'boolean',
28+
default: true,
29+
description: `Enable auto-merge for pull requests that Socket opens.\n See ${terminalLink(
30+
'GitHub documentation',
31+
'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'
32+
)} for managing auto-merge for pull requests in your repository.`
33+
},
2534
rangeStyle: {
2635
type: 'string',
2736
default: 'preserve',
@@ -39,7 +48,7 @@ const config: CliCommandConfig = {
3948
test: {
4049
type: 'boolean',
4150
default: true,
42-
description: 'Very the fix by running unit tests'
51+
description: 'Verify the fix by running unit tests'
4352
},
4453
testScript: {
4554
type: 'string',
@@ -93,6 +102,7 @@ async function run(
93102
const { spinner } = constants
94103

95104
await runFix({
105+
autoMerge: Boolean(cli.flags['autoMerge']),
96106
spinner,
97107
rangeStyle: (cli.flags['rangeStyle'] ?? undefined) as
98108
| RangeStyle

src/commands/fix/npm-fix.ts

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
readPackageJson
77
} from '@socketsecurity/registry/lib/packages'
88

9-
import { openGitHubPullRequest } from './open-pr'
9+
import { enableAutoMerge, openGitHubPullRequest } from './open-pr'
10+
import { NormalizedFixOptions } from './types'
1011
import constants from '../../constants'
1112
import {
1213
Arborist,
@@ -22,11 +23,9 @@ import {
2223
} from '../../utils/arborist-helpers'
2324
import { getCveInfoByAlertsMap } from '../../utils/socket-package-alert'
2425

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

3130
const { CI, NPM } = constants
3231

@@ -47,25 +46,17 @@ async function install(
4746
await arb2.reify()
4847
}
4948

50-
type NpmFixOptions = {
51-
cwd?: string | undefined
52-
rangeStyle?: RangeStyle | undefined
53-
spinner?: Spinner | undefined
54-
test?: boolean | undefined
55-
testScript?: string | undefined
56-
}
57-
5849
export async function npmFix(
5950
_pkgEnvDetails: EnvDetails,
60-
options?: NpmFixOptions | undefined
61-
) {
62-
const {
63-
cwd = process.cwd(),
51+
{
52+
autoMerge,
53+
cwd,
54+
rangeStyle,
6455
spinner,
65-
test = false,
66-
testScript = 'test'
67-
} = { __proto__: null, ...options } as NpmFixOptions
68-
56+
test,
57+
testScript
58+
}: NormalizedFixOptions
59+
) {
6960
spinner?.start()
7061

7162
const arb = new SafeArborist({
@@ -158,7 +149,12 @@ export async function npmFix(
158149
let saved = false
159150
let installed = false
160151
try {
161-
updatePackageJsonFromNode(editablePkgJson, arb.idealTree!, node)
152+
updatePackageJsonFromNode(
153+
editablePkgJson,
154+
arb.idealTree!,
155+
node,
156+
rangeStyle
157+
)
162158
// eslint-disable-next-line no-await-in-loop
163159
await editablePkgJson.save()
164160
saved = true
@@ -177,7 +173,15 @@ export async function npmFix(
177173
// Lazily access constants.ENV[CI].
178174
if (constants.ENV[CI]) {
179175
// eslint-disable-next-line no-await-in-loop
180-
await openGitHubPullRequest(name, targetVersion, cwd)
176+
const prResponse = await openGitHubPullRequest(
177+
name,
178+
targetVersion,
179+
cwd
180+
)
181+
if (autoMerge) {
182+
// eslint-disable-next-line no-await-in-loop
183+
await enableAutoMerge(prResponse.data)
184+
}
181185
}
182186
} catch {
183187
spinner?.error(`Reverting ${fixSpec}`)

src/commands/fix/open-pr.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import { spawn } from '@socketsecurity/registry/lib/spawn'
55

66
import constants from '../../constants'
77

8+
import type { components } from '@octokit/openapi-types'
9+
import type { OctokitResponse } from '@octokit/types'
10+
11+
type PullsCreateResponseData = components['schemas']['pull-request']
12+
813
const {
914
GITHUB_ACTIONS,
1015
GITHUB_REF_NAME,
@@ -79,11 +84,44 @@ function getOctokit() {
7984
return _octokit
8085
}
8186

87+
export async function enableAutoMerge(
88+
prResponseData: PullsCreateResponseData
89+
): Promise<void> {
90+
const octokit = getOctokit()
91+
const { node_id: prId, number: prNumber } = prResponseData
92+
93+
try {
94+
await octokit.graphql(
95+
`
96+
mutation EnableAutoMerge($pullRequestId: ID!) {
97+
enablePullRequestAutoMerge(input: {
98+
pullRequestId: $pullRequestId,
99+
mergeMethod: SQUASH
100+
}) {
101+
pullRequest {
102+
number
103+
autoMergeRequest {
104+
enabledAt
105+
}
106+
}
107+
}
108+
}
109+
`,
110+
{
111+
pullRequestId: prId
112+
}
113+
)
114+
logger.info(`Auto-merge enabled for PR #${prNumber}`)
115+
} catch (e) {
116+
logger.error(`Failed to enable auto-merge for PR #${prNumber}:`, e)
117+
}
118+
}
119+
82120
export async function openGitHubPullRequest(
83121
name: string,
84122
targetVersion: string,
85123
cwd = process.cwd()
86-
) {
124+
): Promise<OctokitResponse<PullsCreateResponseData>> {
87125
// Lazily access constants.ENV[GITHUB_ACTIONS].
88126
if (constants.ENV[GITHUB_ACTIONS]) {
89127
// Lazily access constants.ENV[SOCKET_SECURITY_GITHUB_PAT].
@@ -116,7 +154,7 @@ export async function openGitHubPullRequest(
116154
await spawn('git', ['push', '--set-upstream', 'origin', branch], { cwd })
117155
}
118156
const octokit = getOctokit()
119-
await octokit.pulls.create({
157+
return await octokit.pulls.create({
120158
owner,
121159
repo,
122160
title: commitMsg,

src/commands/fix/pnpm-fix.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
readPackageJson
99
} from '@socketsecurity/registry/lib/packages'
1010

11-
import { openGitHubPullRequest } from './open-pr'
11+
import { enableAutoMerge, openGitHubPullRequest } from './open-pr'
1212
import constants from '../../constants'
1313
import {
1414
SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES,
@@ -24,7 +24,7 @@ import { getAlertsMapFromPnpmLockfile } from '../../utils/pnpm-lock-yaml'
2424
import { getCveInfoByAlertsMap } from '../../utils/socket-package-alert'
2525
import { runAgentInstall } from '../optimize/run-agent'
2626

27-
import type { RangeStyle } from './types'
27+
import type { NormalizedFixOptions } from './types'
2828
import type { StringKeyValueObject } from '../../types'
2929
import type { EnvDetails } from '../../utils/package-environment'
3030
import type { PackageJson } from '@socketsecurity/registry/lib/packages'
@@ -48,25 +48,17 @@ async function install(
4848
})
4949
}
5050

51-
type PnpmFixOptions = {
52-
cwd?: string | undefined
53-
rangeStyle?: RangeStyle | undefined
54-
spinner?: Spinner | undefined
55-
test?: boolean | undefined
56-
testScript?: string | undefined
57-
}
58-
5951
export async function pnpmFix(
6052
pkgEnvDetails: EnvDetails,
61-
options?: PnpmFixOptions
62-
) {
63-
const {
64-
cwd = process.cwd(),
53+
{
54+
autoMerge,
55+
cwd,
56+
rangeStyle,
6557
spinner,
66-
test = false,
67-
testScript = 'test'
68-
} = { __proto__: null, ...options } as PnpmFixOptions
69-
58+
test,
59+
testScript
60+
}: NormalizedFixOptions
61+
) {
7062
const lockfile = await readWantedLockfile(cwd, { ignoreIncompatible: false })
7163
if (!lockfile) {
7264
return
@@ -185,7 +177,12 @@ export async function pnpmFix(
185177
let installed = false
186178
try {
187179
editablePkgJson.update(updateData)
188-
updatePackageJsonFromNode(editablePkgJson, arb.actualTree!, node)
180+
updatePackageJsonFromNode(
181+
editablePkgJson,
182+
arb.actualTree!,
183+
node,
184+
rangeStyle
185+
)
189186
// eslint-disable-next-line no-await-in-loop
190187
await editablePkgJson.save()
191188
saved = true
@@ -206,7 +203,15 @@ export async function pnpmFix(
206203
// Lazily access constants.ENV[CI].
207204
if (constants.ENV[CI]) {
208205
// eslint-disable-next-line no-await-in-loop
209-
await openGitHubPullRequest(name, targetVersion, cwd)
206+
const prResponse = await openGitHubPullRequest(
207+
name,
208+
targetVersion,
209+
cwd
210+
)
211+
if (autoMerge) {
212+
// eslint-disable-next-line no-await-in-loop
213+
await enableAutoMerge(prResponse.data)
214+
}
210215
}
211216
} catch {
212217
spinner?.error(`Reverting ${fixSpec}`)

0 commit comments

Comments
 (0)