Skip to content

Commit 34d1db1

Browse files
authored
refactor codegen parts (#1863)
* refactor codegen parts
1 parent 7706260 commit 34d1db1

File tree

2 files changed

+156
-150
lines changed

2 files changed

+156
-150
lines changed

backend/controllers/github.go

+154-148
Original file line numberDiff line numberDiff line change
@@ -767,154 +767,8 @@ func handleIssueCommentEvent(gh utils.GithubClientProvider, payload *github.Issu
767767

768768
// terraform code generator
769769
if os.Getenv("DIGGER_GENERATION_ENABLED") == "1" {
770-
if strings.HasPrefix(*payload.Comment.Body, "digger generate") {
771-
projectName := ci.ParseProjectName(*payload.Comment.Body)
772-
if projectName == "" {
773-
commentReporterManager.UpdateComment(fmt.Sprintf(":x: generate requires argument -p <project_name>: %v", err))
774-
log.Printf("missing project in command: %v", *payload.Comment.Body)
775-
return fmt.Errorf("generate requires argument -p <project_name>: %v", err)
776-
}
777-
778-
project := config.GetProject(projectName)
779-
if project == nil {
780-
commentReporterManager.UpdateComment(fmt.Sprintf("could not find project %v in digger.yml", projectName))
781-
log.Printf("could not find project %v in digger.yml", projectName)
782-
return fmt.Errorf("could not find project %v in digger.yml", projectName)
783-
}
784-
785-
commentReporterManager.UpdateComment(fmt.Sprintf(":white_check_mark: Successfully loaded project"))
786-
787-
generationEndpoint := os.Getenv("DIGGER_GENERATION_ENDPOINT")
788-
if generationEndpoint == "" {
789-
commentReporterManager.UpdateComment(fmt.Sprintf(":x: server does not have generation endpoint configured, please verify"))
790-
log.Printf("server does not have generation endpoint configured, please verify")
791-
return fmt.Errorf("server does not have generation endpoint configured, please verify")
792-
}
793-
webhookSecret := os.Getenv("DIGGER_GENERATION_WEBHOOK_SECRET")
794-
795-
// Get all code content from the repository at a specific commit
796-
getCodeFromCommit := func(ghService *dg_github.GithubService, repoOwner, repoName string, commitSha *string, projectDir string) (string, error) {
797-
const MaxPatchSize = 1024 * 1024 // 1MB limit
798-
799-
// Get the commit's changes compared to default branch
800-
comparison, _, err := ghService.Client.Repositories.CompareCommits(
801-
context.Background(),
802-
repoOwner,
803-
repoName,
804-
defaultBranch,
805-
*commitSha,
806-
nil,
807-
)
808-
if err != nil {
809-
return "", fmt.Errorf("error comparing commits: %v", err)
810-
}
811-
812-
var appCode strings.Builder
813-
for _, file := range comparison.Files {
814-
if file.Patch == nil {
815-
continue // Skip files without patches
816-
}
817-
log.Printf("Processing patch for file: %s", *file.Filename)
818-
if *file.Additions > 0 {
819-
lines := strings.Split(*file.Patch, "\n")
820-
for _, line := range lines {
821-
if strings.HasPrefix(line, "+") && !strings.HasPrefix(line, "+++") {
822-
appCode.WriteString(strings.TrimPrefix(line, "+"))
823-
appCode.WriteString("\n")
824-
}
825-
}
826-
}
827-
appCode.WriteString("\n")
828-
}
829-
830-
if appCode.Len() == 0 {
831-
return "", fmt.Errorf("no code changes found in commit %s. Please ensure the PR contains added or modified code", *commitSha)
832-
}
833-
834-
return appCode.String(), nil
835-
}
836-
837-
appCode, err := getCodeFromCommit(ghService, repoOwner, repoName, commitSha, project.Dir)
838-
if err != nil {
839-
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to get code content: %v", err))
840-
log.Printf("Error getting code content: %v", err)
841-
return fmt.Errorf("error getting code content: %v", err)
842-
}
843-
844-
commentReporterManager.UpdateComment(fmt.Sprintf(":white_check_mark: Successfully loaded code from commit"))
845-
846-
log.Printf("the app code is: %v", appCode)
847-
848-
commentReporterManager.UpdateComment(fmt.Sprintf("Generating terraform..."))
849-
terraformCode, err := utils.GenerateTerraformCode(appCode, generationEndpoint, webhookSecret)
850-
if err != nil {
851-
commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not generate terraform code: %v", err))
852-
log.Printf("could not generate terraform code: %v", err)
853-
return fmt.Errorf("could not generate terraform code: %v", err)
854-
}
855-
856-
commentReporterManager.UpdateComment(fmt.Sprintf(":white_check_mark: Generated terraform"))
857-
858-
// comment terraform code to project dir
859-
//project.Dir
860-
log.Printf("terraform code is %v", terraformCode)
861-
862-
baseTree, _, err := ghService.Client.Git.GetTree(context.Background(), repoOwner, repoName, *commitSha, false)
863-
if err != nil {
864-
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to get base tree: %v", err))
865-
log.Printf("Error getting base tree: %v", err)
866-
return fmt.Errorf("error getting base tree: %v", err)
867-
}
868-
869-
// Create a new tree with the new file
870-
treeEntries := []*github.TreeEntry{
871-
{
872-
Path: github.String(filepath.Join(project.Dir, fmt.Sprintf("generated_%v.tf", issueNumber))),
873-
Mode: github.String("100644"),
874-
Type: github.String("blob"),
875-
Content: github.String(terraformCode),
876-
},
877-
}
878-
879-
newTree, _, err := ghService.Client.Git.CreateTree(context.Background(), repoOwner, repoName, *baseTree.SHA, treeEntries)
880-
if err != nil {
881-
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to create new tree: %v", err))
882-
log.Printf("Error creating new tree: %v", err)
883-
return fmt.Errorf("error creating new tree: %v", err)
884-
}
885-
886-
// Create the commit
887-
commitMsg := fmt.Sprintf("Add generated Terraform code for %v", projectName)
888-
commit := &github.Commit{
889-
Message: &commitMsg,
890-
Tree: newTree,
891-
Parents: []*github.Commit{{SHA: commitSha}},
892-
}
893-
894-
newCommit, _, err := ghService.Client.Git.CreateCommit(context.Background(), repoOwner, repoName, commit, nil)
895-
if err != nil {
896-
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to commit Terraform file: %v", err))
897-
log.Printf("Error committing Terraform file: %v", err)
898-
return fmt.Errorf("error committing Terraform file: %v", err)
899-
}
900-
901-
// Update the reference to point to the new commit
902-
ref := &github.Reference{
903-
Ref: github.String(fmt.Sprintf("refs/heads/%s", *branch)),
904-
Object: &github.GitObject{
905-
SHA: newCommit.SHA,
906-
},
907-
}
908-
_, _, err = ghService.Client.Git.UpdateRef(context.Background(), repoOwner, repoName, ref, false)
909-
if err != nil {
910-
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to update branch reference: %v", err))
911-
log.Printf("Error updating branch reference: %v", err)
912-
return fmt.Errorf("error updating branch reference: %v", err)
913-
}
914-
915-
commentReporterManager.UpdateComment(":white_check_mark: Successfully generated and committed Terraform code")
916-
return nil
917-
}
770+
err = GenerateTerraformFromCode(payload, commentReporterManager, config, defaultBranch, ghService, repoOwner, repoName, commitSha, issueNumber, branch)
771+
return err
918772
}
919773

920774
commentIdStr := strconv.FormatInt(userCommentId, 10)
@@ -1120,6 +974,158 @@ func handleIssueCommentEvent(gh utils.GithubClientProvider, payload *github.Issu
1120974
return nil
1121975
}
1122976

977+
func GenerateTerraformFromCode(payload *github.IssueCommentEvent, commentReporterManager utils.CommentReporterManager, config *dg_configuration.DiggerConfig, defaultBranch string, ghService *dg_github.GithubService, repoOwner string, repoName string, commitSha *string, issueNumber int, branch *string) error {
978+
if strings.HasPrefix(*payload.Comment.Body, "digger generate") {
979+
projectName := ci.ParseProjectName(*payload.Comment.Body)
980+
if projectName == "" {
981+
commentReporterManager.UpdateComment(fmt.Sprintf(":x: generate requires argument -p <project_name>"))
982+
log.Printf("missing project in command: %v", *payload.Comment.Body)
983+
return fmt.Errorf("generate requires argument -p <project_name>")
984+
}
985+
986+
project := config.GetProject(projectName)
987+
if project == nil {
988+
commentReporterManager.UpdateComment(fmt.Sprintf("could not find project %v in digger.yml", projectName))
989+
log.Printf("could not find project %v in digger.yml", projectName)
990+
return fmt.Errorf("could not find project %v in digger.yml", projectName)
991+
}
992+
993+
commentReporterManager.UpdateComment(fmt.Sprintf(":white_check_mark: Successfully loaded project"))
994+
995+
generationEndpoint := os.Getenv("DIGGER_GENERATION_ENDPOINT")
996+
if generationEndpoint == "" {
997+
commentReporterManager.UpdateComment(fmt.Sprintf(":x: server does not have generation endpoint configured, please verify"))
998+
log.Printf("server does not have generation endpoint configured, please verify")
999+
return fmt.Errorf("server does not have generation endpoint configured, please verify")
1000+
}
1001+
apiToken := os.Getenv("DIGGER_GENERATION_API_TOKEN")
1002+
1003+
// Get all code content from the repository at a specific commit
1004+
getCodeFromCommit := func(ghService *dg_github.GithubService, repoOwner, repoName string, commitSha *string, projectDir string) (string, error) {
1005+
const MaxPatchSize = 1024 * 1024 // 1MB limit
1006+
1007+
// Get the commit's changes compared to default branch
1008+
comparison, _, err := ghService.Client.Repositories.CompareCommits(
1009+
context.Background(),
1010+
repoOwner,
1011+
repoName,
1012+
defaultBranch,
1013+
*commitSha,
1014+
nil,
1015+
)
1016+
if err != nil {
1017+
return "", fmt.Errorf("error comparing commits: %v", err)
1018+
}
1019+
1020+
var appCode strings.Builder
1021+
for _, file := range comparison.Files {
1022+
if file.Patch == nil {
1023+
continue // Skip files without patches
1024+
}
1025+
log.Printf("Processing patch for file: %s", *file.Filename)
1026+
if *file.Additions > 0 {
1027+
lines := strings.Split(*file.Patch, "\n")
1028+
for _, line := range lines {
1029+
if strings.HasPrefix(line, "+") && !strings.HasPrefix(line, "+++") {
1030+
appCode.WriteString(strings.TrimPrefix(line, "+"))
1031+
appCode.WriteString("\n")
1032+
}
1033+
}
1034+
}
1035+
appCode.WriteString("\n")
1036+
}
1037+
1038+
if appCode.Len() == 0 {
1039+
return "", fmt.Errorf("no code changes found in commit %s. Please ensure the PR contains added or modified code", *commitSha)
1040+
}
1041+
1042+
return appCode.String(), nil
1043+
}
1044+
1045+
appCode, err := getCodeFromCommit(ghService, repoOwner, repoName, commitSha, project.Dir)
1046+
if err != nil {
1047+
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to get code content: %v", err))
1048+
log.Printf("Error getting code content: %v", err)
1049+
return fmt.Errorf("error getting code content: %v", err)
1050+
}
1051+
1052+
commentReporterManager.UpdateComment(fmt.Sprintf(":white_check_mark: Successfully loaded code from commit"))
1053+
1054+
log.Printf("the app code is: %v", appCode)
1055+
1056+
commentReporterManager.UpdateComment(fmt.Sprintf("Generating terraform..."))
1057+
terraformCode, err := utils.GenerateTerraformCode(appCode, generationEndpoint, apiToken)
1058+
if err != nil {
1059+
commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not generate terraform code: %v", err))
1060+
log.Printf("could not generate terraform code: %v", err)
1061+
return fmt.Errorf("could not generate terraform code: %v", err)
1062+
}
1063+
1064+
commentReporterManager.UpdateComment(fmt.Sprintf(":white_check_mark: Generated terraform"))
1065+
1066+
// comment terraform code to project dir
1067+
//project.Dir
1068+
log.Printf("terraform code is %v", terraformCode)
1069+
1070+
baseTree, _, err := ghService.Client.Git.GetTree(context.Background(), repoOwner, repoName, *commitSha, false)
1071+
if err != nil {
1072+
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to get base tree: %v", err))
1073+
log.Printf("Error getting base tree: %v", err)
1074+
return fmt.Errorf("error getting base tree: %v", err)
1075+
}
1076+
1077+
// Create a new tree with the new file
1078+
treeEntries := []*github.TreeEntry{
1079+
{
1080+
Path: github.String(filepath.Join(project.Dir, fmt.Sprintf("generated_%v.tf", issueNumber))),
1081+
Mode: github.String("100644"),
1082+
Type: github.String("blob"),
1083+
Content: github.String(terraformCode),
1084+
},
1085+
}
1086+
1087+
newTree, _, err := ghService.Client.Git.CreateTree(context.Background(), repoOwner, repoName, *baseTree.SHA, treeEntries)
1088+
if err != nil {
1089+
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to create new tree: %v", err))
1090+
log.Printf("Error creating new tree: %v", err)
1091+
return fmt.Errorf("error creating new tree: %v", err)
1092+
}
1093+
1094+
// Create the commit
1095+
commitMsg := fmt.Sprintf("Add generated Terraform code for %v", projectName)
1096+
commit := &github.Commit{
1097+
Message: &commitMsg,
1098+
Tree: newTree,
1099+
Parents: []*github.Commit{{SHA: commitSha}},
1100+
}
1101+
1102+
newCommit, _, err := ghService.Client.Git.CreateCommit(context.Background(), repoOwner, repoName, commit, nil)
1103+
if err != nil {
1104+
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to commit Terraform file: %v", err))
1105+
log.Printf("Error committing Terraform file: %v", err)
1106+
return fmt.Errorf("error committing Terraform file: %v", err)
1107+
}
1108+
1109+
// Update the reference to point to the new commit
1110+
ref := &github.Reference{
1111+
Ref: github.String(fmt.Sprintf("refs/heads/%s", *branch)),
1112+
Object: &github.GitObject{
1113+
SHA: newCommit.SHA,
1114+
},
1115+
}
1116+
_, _, err = ghService.Client.Git.UpdateRef(context.Background(), repoOwner, repoName, ref, false)
1117+
if err != nil {
1118+
commentReporterManager.UpdateComment(fmt.Sprintf(":x: Failed to update branch reference: %v", err))
1119+
log.Printf("Error updating branch reference: %v", err)
1120+
return fmt.Errorf("error updating branch reference: %v", err)
1121+
}
1122+
1123+
commentReporterManager.UpdateComment(":white_check_mark: Successfully generated and committed Terraform code")
1124+
return nil
1125+
}
1126+
return nil
1127+
}
1128+
11231129
func TriggerDiggerJobs(ciBackend ci_backends.CiBackend, repoFullName string, repoOwner string, repoName string, batchId *uuid.UUID, prNumber int, prService ci.PullRequestService, gh utils.GithubClientProvider) error {
11241130
_, err := models.DB.GetDiggerBatch(batchId)
11251131
if err != nil {

backend/utils/ai.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"net/http"
99
)
1010

11-
func GenerateTerraformCode(appCode string, generationEndpoint string, webhookSecret string) (string, error) {
11+
func GenerateTerraformCode(appCode string, generationEndpoint string, apiToken string) (string, error) {
1212

1313
payload := map[string]string{
1414
"code": appCode,
@@ -28,7 +28,7 @@ func GenerateTerraformCode(appCode string, generationEndpoint string, webhookSec
2828

2929
// Set headers
3030
req.Header.Set("Content-Type", "application/json")
31-
req.Header.Set("X-Webhook-Secret", webhookSecret) // Replace with your webhook secret
31+
req.Header.Set("Authorization", "Bearer "+apiToken)
3232

3333
// Make the request
3434
client := &http.Client{}

0 commit comments

Comments
 (0)