codeflash-internal/js/cf-api/endpoints/create-pr.ts
Sarthak Agarwal 1cb2051b15
consistency in formatting across ide & js projs (#1499)
### **PR Type**
- Enhancement



___

### **Description**
- Add pre-commit hook integration and formatting commands

- Introduce lint-staged and simple-git-hooks into package scripts

- Update prettier configuration and ignore files for consistency

- Refresh dependency lock files with new tooling entries


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Dependencies</strong></td><td><details><summary>2
files</summary><table>
<tr>
<td><strong>package-lock.json</strong><dd><code>Update dependency lock
with new tooling entries</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-54c17cef859f033fc84a59da2e977235ebc494943710c25d132e310ec500c5ef">+754/-2</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>package-lock.json</strong><dd><code>Refresh package lock
with lint and formatting tools</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-75446c74353509ca0232d6a1350aef075ced8f72bd568e9bafa09cf255683142">+743/-0</a>&nbsp;
</td>

</tr>
</table></details></td></tr><tr><td><strong>Configuration
changes</strong></td><td><details><summary>4 files</summary><table>
<tr>
<td><strong>package.json</strong><dd><code>Add formatting, lint and
pre-commit hook scripts</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-4edec169b0f8d3312edaf35b5cc8521fe1edfa163ce174f60eff51906896601f">+34/-17</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>package.json</strong><dd><code>Introduce formatting commands
and pre-commit hooks</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-53ddfb1f8a02f1231d3d15a2e694ffe1407d2cc01d3e685de5653b67fec571c7">+18/-1</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>package.json</strong><dd><code>Integrate pre-commit hook and
formatting configurations</code>&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-b0d32af9c2caaba1377ec3e924eb553105cdc86e244018ffc6a866c530523599">+20/-3</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>settings.json</strong><dd><code>Enhance VSCode settings for
auto-format and lint fixes</code>&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-a5de3e5871ffcc383a2294845bd3df25d3eeff6c29ad46e3a396577c413bf357">+13/-1</a>&nbsp;
&nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>7
files</summary><table>
<tr>
<td><strong>.editorconfig</strong><dd><code>Add consistent editor
settings for file formatting</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-0947e2727d6bad8cd0ac4122f5314bb5b04e337393075bc4b5ef143b17fcbd5b">+32/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>.prettierrc</strong><dd><code>Update prettier config with
extended formatting rules</code>&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-ce5b7ae243151fb6eb3db1799b95d5c50ce2fe5080e8365c7834f81e8a44aade">+10/-4</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>.prettierrc</strong><dd><code>Update prettier settings for
consistent code style</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-e169a799a8a22863b844d1c816ebb5798c0bcf8151503b0329bf60a2b3050b03">+10/-4</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>.prettierrc</strong><dd><code>Add new prettier configuration
file</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-7058ba9d421d7fa280582bcc9a2053e64ec0b2bb700ae46cb7073f295d154713">+10/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>.prettierignore</strong><dd><code>Extend ignore rules with
node_modules and dist folders</code>&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-a33307d68affc99ba88b1b79308f622350c8306bdeac2368b70d99ce72a7c8fa">+3/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>.prettierignore</strong><dd><code>Add ignore patterns for
node_modules and dist directories</code></dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-8f0741d174231baef1746c1fdb003dc727bb4416e16e99166edc020670861c1d">+2/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>.prettierignore</strong><dd><code>Update ignore file to
include node_modules and dist folders</code></dd></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-e84a66c182e9d121fc156f4b50d606f385b591ed493f8c284628451d58907875">+2/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Additional
files</strong></td><td><details><summary>1 files</summary><table>
<tr>
  <td><strong>package-lock.json</strong></td>
<td><a
href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-0214c85d1717ad8b736e0296bb8cbf50db2aed068f31316d3c39904824a14f8e">+1026/-52</a></td>

</tr>
</table></details></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-04 23:52:45 +00:00

164 lines
5.4 KiB
TypeScript

import { fileDiffsToMap, isDiffContentsWellFormed } from "../diff_utils.js"
import { type FileDiffContent } from "code-suggester/build/src/types.js"
import { userNickname } from "../auth0-mgmt.js"
import {
addLabelToPullRequest,
getInstallationOctokitByOwner,
isUserCollaborator,
} from "../github/github-utils.js"
import { buildPrTitle } from "../github/pr-changes-utils.js"
import { githubApp } from "../github/github-app.js"
import {
assignReviewer,
createNewBranchFromDiffContents,
createStandalonePullRequest,
} from "../github/create-pr-from-diffcontents.js"
import { posthog } from "../analytics.js"
import { PrismaClient } from "@prisma/client"
import { Request, Response } from "express"
const prisma = new PrismaClient()
export async function createPr(req: Request, res: Response): Promise<void> {
try {
const {
owner,
repo,
baseBranch,
diffContents,
prCommentFields,
existingTests,
generatedTests,
coverage,
} = req.body
const userId = (req as any).userId
//traceId is optional to allow for backwards compatibility, can make this required in the future
const traceId = req.body.traceId || ""
//coveragePct is optional to allow for backwards compatibility, can make this required in the future
if (!repo || !owner || !baseBranch || !isDiffContentsWellFormed(diffContents)) {
res.status(400).send("Missing or malformed fields")
return
}
const nickname: string | null = await userNickname(userId)
if (nickname == null) {
res.status(401).send("Unauthorized") // Error getting user nickname
return
}
const installationOctokit = await getInstallationOctokitByOwner(githubApp, owner, repo)
if (installationOctokit instanceof Error) {
res.status(401).send(installationOctokit.message)
return
}
const isCollaborator = await isUserCollaborator(installationOctokit, owner, repo, nickname)
if (!isCollaborator) {
console.log(`${nickname} is not a collaborator on ${owner}/${repo}`)
res.status(401).send("Unauthorized") // User is not a collaborator
return
}
console.log(`${nickname} is a collaborator on ${owner}/${repo}`)
const diffContentsMap: Map<string, FileDiffContent> = fileDiffsToMap(diffContents)
// Generate a Base36-encoded timestamp
const timestamp = Date.now() // Current timestamp in milliseconds
const encodedTimestamp = timestamp.toString(36) // e.g., 'kf12oi0'
// If you change this, please also change the regex in github-app.ts in the pull_request.closed event
const newBranchName = `codeflash/optimize-${prCommentFields.function_name}-${encodedTimestamp}`
const commitMessage =
buildPrTitle(prCommentFields.function_name, prCommentFields.speedup_pct) +
`\n${prCommentFields.optimization_explanation}`
const branchCreated = await createNewBranchFromDiffContents(
installationOctokit,
owner,
repo,
newBranchName,
baseBranch,
diffContentsMap,
commitMessage,
)
if (!branchCreated) {
throw new Error(`Failed to create branch ${newBranchName}`)
}
const newPrData = await createStandalonePullRequest(
installationOctokit,
owner,
repo,
newBranchName,
baseBranch,
prCommentFields,
existingTests,
generatedTests,
coverage,
)
await addLabelToPullRequest(installationOctokit, owner, repo, newPrData.data.number)
// Assign the user who initiated the create-pr as the reviewer
await assignReviewer(installationOctokit, owner, repo, newPrData.data.number, nickname)
// Respond with the new PR details
console.log(`Created new PR #${newPrData.data.number} with branch ${newPrData.data.head.ref}`)
posthog.capture({
distinctId: userId,
event: `cfapi-create-pr-success-standalone-pr-created`,
properties: {
owner,
repo,
newPrNumber: newPrData.data.number,
newPrBranch: newPrData.data.head.ref,
PRURL: newPrData.data.html_url,
},
})
if (traceId !== "") {
let pull_request_db = await prisma.optimization_features.findUnique({
where: {
trace_id: traceId,
},
select: {
pull_request: true,
},
})
if (pull_request_db) {
// the trace_id is not in the database then ignore it, because it should already exist by this stage.
if (pull_request_db.pull_request === null || pull_request_db.pull_request === undefined) {
pull_request_db.pull_request = {}
}
;(pull_request_db.pull_request as any).new_pr_url = newPrData.data.html_url
await prisma.optimization_features.update({
where: {
trace_id: traceId,
},
data: {
pull_request: pull_request_db.pull_request,
},
})
}
}
res.json(newPrData.data.number)
} catch (error) {
console.log(`Error in /cfapi/create-pr: ${error}`)
if (error instanceof Error) {
console.log(`Error message: ${error.message}`)
console.log(`Error stack: ${error.stack}`)
posthog.capture({
distinctId: (req as any).userId,
event: `cfapi-create-pr-failed-error-creating-standalone-pr`,
properties: {
error: error.message,
},
})
res.status(500).send(`Error creating pull request: ${error.message}`)
} else {
res.status(500).send(`Error creating pull request`)
}
}
}