mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
### **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> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-54c17cef859f033fc84a59da2e977235ebc494943710c25d132e310ec500c5ef">+754/-2</a> </td> </tr> <tr> <td><strong>package-lock.json</strong><dd><code>Refresh package lock with lint and formatting tools</code> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-75446c74353509ca0232d6a1350aef075ced8f72bd568e9bafa09cf255683142">+743/-0</a> </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> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-4edec169b0f8d3312edaf35b5cc8521fe1edfa163ce174f60eff51906896601f">+34/-17</a> </td> </tr> <tr> <td><strong>package.json</strong><dd><code>Introduce formatting commands and pre-commit hooks</code> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-53ddfb1f8a02f1231d3d15a2e694ffe1407d2cc01d3e685de5653b67fec571c7">+18/-1</a> </td> </tr> <tr> <td><strong>package.json</strong><dd><code>Integrate pre-commit hook and formatting configurations</code> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-b0d32af9c2caaba1377ec3e924eb553105cdc86e244018ffc6a866c530523599">+20/-3</a> </td> </tr> <tr> <td><strong>settings.json</strong><dd><code>Enhance VSCode settings for auto-format and lint fixes</code> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-a5de3e5871ffcc383a2294845bd3df25d3eeff6c29ad46e3a396577c413bf357">+13/-1</a> </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> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-0947e2727d6bad8cd0ac4122f5314bb5b04e337393075bc4b5ef143b17fcbd5b">+32/-0</a> </td> </tr> <tr> <td><strong>.prettierrc</strong><dd><code>Update prettier config with extended formatting rules</code> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-ce5b7ae243151fb6eb3db1799b95d5c50ce2fe5080e8365c7834f81e8a44aade">+10/-4</a> </td> </tr> <tr> <td><strong>.prettierrc</strong><dd><code>Update prettier settings for consistent code style</code> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-e169a799a8a22863b844d1c816ebb5798c0bcf8151503b0329bf60a2b3050b03">+10/-4</a> </td> </tr> <tr> <td><strong>.prettierrc</strong><dd><code>Add new prettier configuration file</code> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-7058ba9d421d7fa280582bcc9a2053e64ec0b2bb700ae46cb7073f295d154713">+10/-0</a> </td> </tr> <tr> <td><strong>.prettierignore</strong><dd><code>Extend ignore rules with node_modules and dist folders</code> </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1499/files#diff-a33307d68affc99ba88b1b79308f622350c8306bdeac2368b70d99ce72a7c8fa">+3/-1</a> </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> </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> </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>
164 lines
5.4 KiB
TypeScript
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`)
|
|
}
|
|
}
|
|
}
|