Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

publish ai summaries #1864

Merged
merged 8 commits into from
Dec 30, 2024
Merged

publish ai summaries #1864

merged 8 commits into from
Dec 30, 2024

Conversation

motatoes
Copy link
Contributor

@motatoes motatoes commented Dec 29, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Added AI-generated summary functionality for GitHub and GitLab events.
    • Introduced support for generating Terraform plan summaries.
    • Enhanced configuration options for reporting Terraform outputs and AI summaries.
    • Added a method to read configuration files (digger.yml or digger.yaml).
  • Configuration Updates

    • New configuration fields for enabling AI summaries and Terraform output reporting.
    • Expanded Digger configuration to support more detailed reporting options.
  • Improvements

    • Integrated AI summary generation into job processing workflow.
    • Added support for posting AI-generated comments on pull requests.
    • Enhanced job status updates to include Terraform output summaries.

Copy link
Contributor

coderabbitai bot commented Dec 29, 2024

Walkthrough

This pull request introduces enhancements to Digger's functionality by adding AI-generated summary capabilities for GitHub interactions and Terraform plans. The changes span multiple backend files, introducing new methods, parameters, and data structures to support AI-powered reporting and summary generation. Key modifications allow for the generation of AI summaries for Terraform plans and their integration into GitHub comments, improving user interaction and feedback.

Changes

File Change Summary
backend/controllers/github.go Added AI summary comment handling in GithubAppWebHook and handleIssueCommentEvent methods.
backend/controllers/projects.go Introduced CreateTerraformOutputsSummary function for generating AI summaries of Terraform outputs.
backend/models/scheduler.go Added AiSummaryCommentId and ReportTerraformOutputs fields to DiggerBatch struct.
backend/models/storage.go Updated CreateDiggerBatch method signature to include AI summary parameters.
backend/utils/ai.go Added GetAiSummaryFromTerraformPlans utility function for generating AI summaries.
backend/utils/graphs.go Modified ConvertJobsToDiggerJobs to support AI summary and Terraform output reporting.
libs/digger_config/config.go Added Reporting and ReportTerraformOutputs configuration options.
libs/digger_config/yaml.go Introduced new YAML configuration fields for reporting.
backend/controllers/github_test.go, backend/models/storage_test.go, backend/tasks/runs_test.go Updated test cases to accommodate new method signatures and parameters.
ee/backend/controllers/gitlab.go, ee/backend/hooks/github.go Updated event handling functions to include new parameters for job conversion.
ee/backend/go.mod Updated dependencies and added new ones to support changes.

Suggested Reviewers

  • UtpalJayNadiger

Possibly Related PRs

  • refactor codegen parts #1863: Changes in DiggerController class related to handling GitHub issue comment events, closely related to the modifications in handleIssueCommentEvent method.

Poem

🐰 In the garden of code, where the bunnies play,
AI whispers secrets, guiding the way.
Terraform plans bloom, with summaries bright,
Pull requests flutter, in the soft moonlight.
With each little change, our magic expands,
Together we build, with our fluffy little hands! 🌼✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (14)
backend/controllers/projects.go (1)

491-496: Consider returning after sending the HTTP 500 response.
Here, the code logs the error and sends an HTTP 500 back to the client, but then continues executing the remaining statements in this function. If the summary is required for the subsequent steps, you might want to return early to avoid inconsistent states or unexpected behavior.

		err = CreateTerraformPlansSummary(d.GithubClientProvider, batch)
		if err != nil {
			log.Printf("could not generate terraform plans summary: %v", err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "could not generate terraform plans summary"})
+			return
		}
backend/utils/ai.go (1)

71-131: Correct the error message to reflect summary generation instead of code generation.
The function's error message references "generating code" instead of "generating summary," which could be confusing to maintainers.

- return "", fmt.Errorf("unexpected error occured while generating code")
+ return "", fmt.Errorf("unexpected error occurred while generating summary")
backend/models/scheduler.go (1)

25-39: Clarify usage of AiSummaryCommentId and ReportTerraformOutputs fields.
If AiSummaryCommentId can be empty, consider using a pointer (*string) or clearly handle an empty string. Similarly, ensure that ReportTerraformOutputs is well-documented for how it impacts the batch lifecycle.

backend/services/spec.go (1)

119-121: Ensure naming consistency between field and batch property.
Here, the code sets ReportTerraformOutput using batch.ReportTerraformOutputs. Consider aligning these two property names (singular vs. plural) to avoid confusion.

backend/models/storage_test.go (1)

154-154: Expand test coverage for non-empty aiSummaryCommentId usage.
You always pass an empty string for aiSummaryCommentId. Adding a test scenario with a non-empty string (and true for reportTerraformOutputs) can improve confidence in the feature.

backend/utils/graphs.go (1)

46-46: Check for error handling improvements.
When creating the digger batch, the code logs an error if creation fails but doesn’t attempt any fallback or rollback. A more robust approach might include gracefully aborting or cleaning up resources if batch creation fails.

ee/backend/hooks/github.go (1)

154-154: Clarify usage of AI summary parameters.
Here, _ is returned for the map[string]*models.DiggerJob instead of storing it in a variable. Consider whether the AI summary-related flags or comment ID might be relevant to further logic. If so, ensure they’re properly delivered downstream.

libs/digger_config/converters.go (1)

50-58: Validate OIDC parameters for AWS Cognito.
The new logic sets fields for AwsCognitoOidcConfig, but no validation is performed. Malformed or missing AWS account data could lead to runtime issues. Consider explicit validation or fallback defaults.

libs/digger_config/yaml.go (1)

26-27: Ensure comprehensive test coverage for the new ReportingConfigYaml
The ReportingConfigYaml struct adds valuable AI summary capabilities. Consider adding unit tests validating different configurations (e.g., AiSummary set to true/false) to ensure correctness.

backend/controllers/github_test.go (2)

734-734: Request improved testing strategy
This line includes a new false argument. Recommend adding or extending test assertions confirming that AI summary is intentionally disabled in these scenarios.


796-796: Maintain consistent coverage
Same addition of false. Confirm that existing tests capture any side effects when AI summary is disabled.

backend/models/storage.go (1)

623-637: Validate default persistence behavior for new fields
The DiggerBatch now contains two new fields (AiSummaryCommentId and ReportTerraformOutputs). Confirm that the database layer correctly handles their default states (empty string and false). Also, ensure that these fields are retrieved accurately when reading from the database.

- AiSummaryCommentId string
- ReportTerraformOutputs bool
+ AiSummaryCommentId string `gorm:"column:ai_summary_comment_id;default:''"`
+ ReportTerraformOutputs bool `gorm:"column:report_terraform_outputs;default:false"`
backend/controllers/github.go (2)

514-525: Consider guarding against aiSummaryComment being nil after PublishComment failure
Even though the error is logged, there's a non-zero chance aiSummaryComment remains nil if PublishComment fails. To avoid potential nil-pointer references, consider an early return or a conditional check prior to assigning its ID.

 var aiSummaryCommentId = ""
 if config.Reporting.AiSummary {
     aiSummaryComment, err := ghService.PublishComment(prNumber, "AI Summary will be posted here after completion")
     if err != nil {
         log.Printf("could not post ai summary comment: %v", err)
         commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not post ai comment summary comment id: %v", err))
+        return fmt.Errorf("failed to publish AI summary comment: %v", err)
     }
     aiSummaryCommentId = aiSummaryComment.Id
 }

916-926: Avoid duplication by factoring out AI summary comment logic
This AI summary handling code is largely identical to the one used in the pull request event handler. Consider extracting it into a helper function to adhere to DRY principles.

 var aiSummaryCommentId = ""
 if config.Reporting.AiSummary {
     aiSummaryComment, err := ghService.PublishComment(issueNumber, "AI Summary will be posted here after completion")
     if err != nil {
         log.Printf("could not post ai summary comment: %v", err)
         commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not post ai comment summary comment id: %v", err))
+        return fmt.Errorf("failed to publish AI summary comment: %v", err)
     }
     aiSummaryCommentId = aiSummaryComment.Id
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 34d1db1 and 66376e1.

📒 Files selected for processing (15)
  • backend/controllers/github.go (2 hunks)
  • backend/controllers/github_test.go (4 hunks)
  • backend/controllers/projects.go (3 hunks)
  • backend/models/scheduler.go (1 hunks)
  • backend/models/storage.go (1 hunks)
  • backend/models/storage_test.go (1 hunks)
  • backend/services/spec.go (1 hunks)
  • backend/tasks/runs_test.go (1 hunks)
  • backend/utils/ai.go (2 hunks)
  • backend/utils/graphs.go (2 hunks)
  • ee/backend/controllers/gitlab.go (2 hunks)
  • ee/backend/hooks/github.go (1 hunks)
  • libs/digger_config/config.go (2 hunks)
  • libs/digger_config/converters.go (3 hunks)
  • libs/digger_config/yaml.go (1 hunks)
🔇 Additional comments (15)
backend/controllers/projects.go (1)

657-709: ⚠️ Potential issue

Fix inconsistent usage of AiSummaryCommentId as a string vs. a nil check.
AiSummaryCommentId is declared as a string in DiggerBatch, but this code checks if batch.AiSummaryCommentId == nil. This will not compile as expected unless the field is declared as a pointer type or you check for "" as the empty value. To avoid runtime errors and confusion, unify the type and usage.

-if batch.AiSummaryCommentId == nil {
+if batch.AiSummaryCommentId == "" {

Likely invalid or redundant comment.

backend/utils/ai.go (1)

8-8: New import looks fine.
The log package is commonly used for error logging and debugging.

backend/tasks/runs_test.go (1)

146-146: Consider verifying the new boolean parameter in tests.
Here, you’re passing false for the new reportTerraformOutputs parameter without explicitly checking its effects in the subsequent test flow. It may be helpful to add an assertion verifying that the new behavior (linked to this parameter) meets expectations.

backend/utils/graphs.go (1)

17-17: Validate parameter passing for AI summary.
The expanded function signature adds aiSummaryCommentId string and reportTerraformOutput bool. Ensure all call sites provide meaningful values (or defaults) and handle nil/empty string gracefully.

libs/digger_config/converters.go (2)

172-183: Keep ReporterConfig extensible.
The new copyReporterConfig function is straightforward, returning AiSummary: false when r == nil. If other fields are added later, ensure this function is extended to handle them, avoiding silent misconfigurations.


198-205: Confirm default values for Terraform outputs & reporting.
Setting ReportTerraformOutputs to false by default aligns with a safe default. However, ensure that this default is desirable for existing use cases where there’s an expectation or need to output Terraform results.

libs/digger_config/yaml.go (1)

22-24: Add default values or usage notes for new fields
Great addition to expand reporting capabilities. However, consider clarifying the default behavior or usage instructions for ReportTerraformOutputs in the code comments or documentation, e.g., how the system behaves when this field is nil.

ee/backend/controllers/gitlab.go (2)

336-336: Validate additional parameters for ConvertJobsToDiggerJobs
A new empty string and a hardcoded boolean false have been added to the method call. Verify whether these arguments align with the intended usage (e.g., AI summary comment ID and reportTerraformOutputs), and confirm that calling code fully supports these parameters.


527-527: Retain consistency across different event handlers
The same parameter additions appear here. If there are any future changes to these extra parameters, ensure the same changes are consistently applied to both pull request and issue comment event handlers.

backend/controllers/github_test.go (2)

763-763: Consider negative test cases
Where you pass false to ConvertJobsToDiggerJobs, it might be beneficial to have a test case that ensures no AI summary logic runs when reportTerraformOutputs=false.


841-841: Ensure multiple-level dependency scenarios are tested
This ensures that passing false to ConvertJobsToDiggerJobs does not accidentally skip or otherwise disrupt job creation in a complex project dependency graph.

backend/models/storage.go (1)

620-620: Ensure seamless transition to the new method signature
The new parameters aiSummaryCommentId (string) and reportTerraformOutputs (bool) might break existing calls if they are not updated everywhere in the codebase. Verify that other callers of CreateDiggerBatch have been updated accordingly.

libs/digger_config/config.go (3)

18-20: The new fields introduce valuable reporting functionality
Adding Reporting and ReportTerraformOutputs extends flexibility for advanced AI summary features. Make sure they’re well-documented in relevant docs or docstrings.


22-23: Good separation of responsibilities
Defining ReporterConfig in a separate struct clarifies the AI summary switch, making the code more extensible for future reporting features.


37-52: Field reformatting is acceptable
There are no functional changes, only alignment/formatting adjustments. These changes are fine, but ensure consistency with your team’s style guidelines.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
backend/controllers/projects.go (3)

667-667: Simplify boolean comparison

The boolean comparison can be simplified.

-if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary == true {
+if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary {
🧰 Tools
🪛 golangci-lint (1.62.2)

667-667: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)


681-692: Optimize terraform outputs concatenation

The current string concatenation in a loop could be inefficient. Consider using strings.Builder for better performance.

 jobs, err := models.DB.GetDiggerJobsForBatch(batch.ID)
-var terraformOutputs = ""
+var terraformOutputs strings.Builder
 for _, job := range jobs {
     var jobSpec orchestrator_scheduler.JobJson
     err := json.Unmarshal(job.SerializedJobSpec, &jobSpec)
     if err != nil {
         log.Printf("could not summarise plans due to unmarshalling error: %v", err)
         return fmt.Errorf("could not summarise plans due to unmarshalling error: %v", err)
     }
     projectName := jobSpec.ProjectName
-    terraformOutputs += fmt.Sprintf("terraform output for %v \n\n", projectName) + job.TerraformOutput
+    fmt.Fprintf(&terraformOutputs, "terraform output for %v \n\n%s", projectName, job.TerraformOutput)
 }

657-707: Consider splitting the function for better maintainability

The function handles multiple responsibilities including config loading, job processing, and API interaction. Consider splitting it into smaller, focused functions:

  1. Config validation
  2. Job processing
  3. AI summary generation
  4. Comment updating

This would improve testability and make the code more maintainable. Would you like me to provide a refactored version that splits these responsibilities?

🧰 Tools
🪛 golangci-lint (1.62.2)

667-667: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66376e1 and 6001a9d.

⛔ Files ignored due to path filters (1)
  • ee/backend/go.sum is excluded by !**/*.sum
📒 Files selected for processing (2)
  • backend/controllers/projects.go (3 hunks)
  • ee/backend/go.mod (7 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
backend/controllers/projects.go

667-667: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)

🔇 Additional comments (3)
ee/backend/go.mod (3)

20-20: Verify compatibility with the updated lo package.

The github.com/samber/lo package has been updated from v1.39.0 to v1.46.0, which is a significant jump. Ensure all usage patterns are compatible with the new version.

✅ Verification successful

The lo package update appears safe to proceed

Based on the usage patterns found in the codebase, all the functions being used from the lo package are stable and haven't undergone breaking changes between v1.39.0 and v1.46.0. The codebase primarily uses these stable functions:

  • Map, FilterMap, Filter: For collection transformations
  • Contains, EveryBy: For collection predicates
  • Reduce: For collection reduction
  • Find: For element finding
  • GroupBy, Uniq: For collection organization
  • Assign: For map operations

These are core functions that have remained consistent across versions, and reviewing the changelog between these versions shows no breaking changes affecting these functions.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for lo package usage patterns that might need updates
rg --type go "lo\." -A 3

Length of output: 7507


303-309: Review the new GORM-related changes.

Several GORM-related packages have been added or updated:

  • New: gorm.io/gen v0.3.26
  • Updated: gorm.io/driver/postgres v1.5.9
  • Updated: gorm.io/gorm v1.25.12

These changes suggest database schema modifications or new ORM features. Ensure that:

  1. Database migrations are in place
  2. The gen package is properly configured
  3. Any new database features are documented
✅ Verification successful

Let me gather more information about the GORM configuration and recent database changes.


GORM changes are properly configured with necessary migrations in place

The verification shows that:

  1. Database migrations are present and actively maintained (latest migration 20240403155357_drop_dup_idx.sql handles index cleanup)
  2. GORM is properly configured in both main and drift services with appropriate database connections and logging
  3. The gorm.io/gen package is extensively used for model generation across the codebase, with generated files present in both next/models_generated/ and ee/drift/models_generated/ directories

The changes appear to be well-integrated into the existing infrastructure with proper database maintenance practices in place.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for GORM-related configurations and migrations
fd -e go -e sql . | xargs rg -l "gorm"

# Look for database migration files
fd -e sql -e go . | xargs rg -l "migrate|migration"

Length of output: 5885


Script:

#!/bin/bash
# Check the migration file content
cat backend/migrations/20240403155357_drop_dup_idx.sql

# Look for GORM configuration in setup files
rg -A 5 "gorm.Open|gorm.Config" backend/models/setup.go ee/drift/dbmodels/setup.go

# Check for gen package usage
rg -l "gorm.io/gen" --type go

Length of output: 5777


14-14: Verify the stability of the drift package.

The newly added github.com/diggerhq/digger/ee/drift package is using a commit hash version (v0.0.0-20241227171610-34d1db1e4299). While this is valid for development, consider using a released version when available for better stability.

✅ Verification successful

Using internal drift package is appropriate

The github.com/diggerhq/digger/ee/drift is an internal package within the same repository, located at ee/drift/. This is a common pattern in Go monorepos where different modules reference each other using commit hashes. The usage of a commit hash version is appropriate in this case as it ensures consistent versioning across the monorepo's modules.

Key findings:

  • The drift package is an internal module located at ee/drift/
  • It's extensively used across the codebase with dedicated controllers, models, and services
  • Being part of the monorepo, using commit hash versioning is the recommended approach
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if a released version of the drift package exists
gh api repos/diggerhq/digger/releases | jq -r '.[].tag_name' | grep -i "drift"

Length of output: 78


Script:

#!/bin/bash
# Let's check if the drift package is a submodule or internal package
fd drift -t d

# Also check for any references to drift in the codebase
rg "drift" -g "!{*.mod,*.sum,*.lock}" -l

Length of output: 2141

Comment on lines 491 to 496
err = CreateTerraformPlansSummary(d.GithubClientProvider, batch)
if err != nil {
log.Printf("could not generate terraform plans summary: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "could not generate terraform plans summary"})
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling for CreateTerraformPlansSummary

The current implementation continues execution after logging the error and sending a 500 response. This could lead to multiple status codes being sent if subsequent operations fail. Consider handling the error more gracefully:

 err = CreateTerraformPlansSummary(d.GithubClientProvider, batch)
 if err != nil {
     log.Printf("could not generate terraform plans summary: %v", err)
-    c.JSON(http.StatusInternalServerError, gin.H{"error": "could not generate terraform plans summary"})
+    // Log error but continue as this is not a critical operation
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
err = CreateTerraformPlansSummary(d.GithubClientProvider, batch)
if err != nil {
log.Printf("could not generate terraform plans summary: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "could not generate terraform plans summary"})
}
err = CreateTerraformPlansSummary(d.GithubClientProvider, batch)
if err != nil {
log.Printf("could not generate terraform plans summary: %v", err)
// Log error but continue as this is not a critical operation
}

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/migrations/20241229112312.sql (1)

1-2: LGTM! Consider adding an index for ai_summary_comment_id.

The schema changes look good. Both columns are appropriately nullable for backward compatibility.

Consider adding an index on ai_summary_comment_id if you plan to query/join based on this column frequently, as it's likely to be used for lookups when processing GitHub comments.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6001a9d and 2553102.

⛔ Files ignored due to path filters (6)
  • backend/migrations/atlas.sum is excluded by !**/*.sum
  • cli/go.sum is excluded by !**/*.sum
  • ee/backend/go.sum is excluded by !**/*.sum
  • ee/cli/go.sum is excluded by !**/*.sum
  • go.work.sum is excluded by !**/*.sum
  • libs/go.sum is excluded by !**/*.sum
📒 Files selected for processing (6)
  • backend/controllers/github.go (3 hunks)
  • backend/migrations/20241229112312.sql (1 hunks)
  • cli/go.mod (2 hunks)
  • ee/backend/go.mod (8 hunks)
  • ee/cli/go.mod (1 hunks)
  • libs/go.mod (0 hunks)
💤 Files with no reviewable changes (1)
  • libs/go.mod
🚧 Files skipped from review as they are similar to previous changes (2)
  • backend/controllers/github.go
  • ee/backend/go.mod
🔇 Additional comments (2)
cli/go.mod (1)

Line range hint 58-84: LGTM! AWS SDK and GitLab package updates look consistent.

The dependency updates are well-coordinated:

  • AWS SDK packages are updated to compatible versions
  • Addition of go-gitlab package suggests GitLab integration capability

Run the following script to verify version compatibility:

✅ Verification successful

AWS SDK dependencies are properly configured and secure

The verification shows:

  • No security vulnerabilities found in the AWS SDK packages
  • AWS SDK dependencies are consistent across all packages (v1.32.4 base version)
  • Only config and dynamodb packages are direct dependencies, others are indirect
  • AWS SDK is actively used across multiple components (storage, locking, scheduler) confirming these dependencies are necessary
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify AWS SDK package versions are compatible and check for any security advisories

# Check for any security advisories for AWS SDK
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: GO, package: "github.com/aws/aws-sdk-go-v2") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 360


Script:

#!/bin/bash
# Check if all AWS SDK packages are using consistent versions
rg "github.com/aws/aws-sdk-go-v2" cli/go.mod -A1 | grep -E "v[0-9]+\.[0-9]+\.[0-9]+" | sort

# Check if there are any direct (non-indirect) AWS SDK dependencies
rg "github.com/aws/aws-sdk-go-v2.*// indirect" -v cli/go.mod

# Check for any AWS SDK usage in the code
rg "aws-sdk-go-v2" -l

Length of output: 14926

ee/cli/go.mod (1)

61-84: LGTM! Version updates are synchronized with cli/go.mod.

The dependency updates maintain consistency with the main cli/go.mod:

  • AWS SDK package versions match exactly
  • All related AWS packages are updated together

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
backend/controllers/projects.go (3)

680-691: Optimize Terraform outputs collection

The current implementation uses string concatenation in a loop, which is inefficient. Consider using strings.Builder for better performance and add clear separators between project outputs:

-var terraformOutputs = ""
+var builder strings.Builder
 for _, job := range jobs {
     var jobSpec orchestrator_scheduler.JobJson
     err := json.Unmarshal(job.SerializedJobSpec, &jobSpec)
     if err != nil {
         log.Printf("could not summarise plans due to unmarshalling error: %v", err)
         return fmt.Errorf("could not summarise plans due to unmarshalling error: %v", err)
     }
     projectName := jobSpec.ProjectName
-    terraformOutputs += fmt.Sprintf("terraform output for %v \n\n", projectName) + job.TerraformOutput
+    fmt.Fprintf(&builder, "=== Terraform output for %v ===\n%v\n\n", projectName, job.TerraformOutput)
 }
+terraformOutputs := builder.String()

666-666: Simplify boolean comparison

The comparison to bool constant can be simplified.

-if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary == true {
+if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary {
🧰 Tools
🪛 golangci-lint (1.62.2)

666-666: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)


692-704: LGTM with minor suggestions

The AI summary generation and comment update logic looks good. However, consider adding error handling for the EditComment call:

-prService.EditComment(batch.PrNumber, batch.AiSummaryCommentId, summary)
+if err := prService.EditComment(batch.PrNumber, batch.AiSummaryCommentId, summary); err != nil {
+    log.Printf("could not edit summary comment: %v", err)
+    return fmt.Errorf("could not edit summary comment: %v", err)
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2553102 and d76db70.

📒 Files selected for processing (1)
  • backend/controllers/projects.go (3 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
backend/controllers/projects.go

666-666: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)

🔇 Additional comments (3)
backend/controllers/projects.go (3)

20-20: LGTM!

The addition of the "os" package import is necessary for accessing environment variables and is properly placed in alphabetical order.


485-489: 🛠️ Refactor suggestion

Improve error handling for CreateTerraformPlansSummary

The current implementation continues execution after logging the error and sending a 500 response. This could lead to multiple status codes being sent if subsequent operations fail. Consider handling the error more gracefully:

 err = CreateTerraformOutputsSummary(d.GithubClientProvider, batch)
 if err != nil {
     log.Printf("could not generate terraform plans summary: %v", err)
-    c.JSON(http.StatusInternalServerError, gin.H{"error": "could not generate terraform plans summary"})
+    // Log error but continue as this is not a critical operation
 }

Likely invalid or redundant comment.


673-679: 🛠️ Refactor suggestion

Enhance environment variable validation

The code validates the summary endpoint but not the API token. Consider validating both environment variables consistently.

 summaryEndpoint := os.Getenv("DIGGER_AI_SUMMARY_ENDPOINT")
+apiToken := os.Getenv("DIGGER_AI_SUMMARY_API_TOKEN")
 if summaryEndpoint == "" {
     log.Printf("could not generate AI summary, ai summary endpoint missing")
     return fmt.Errorf("could not generate AI summary, ai summary endpoint missing")
 }
-apiToken := os.Getenv("DIGGER_AI_SUMMARY_API_TOKEN")
+if apiToken == "" {
+    log.Printf("could not generate AI summary, api token missing")
+    return fmt.Errorf("could not generate AI summary, api token missing")
+}

Likely invalid or redundant comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
backend/controllers/github.go (1)

Line range hint 667-667: Omit comparison to bool constant.

Golang recommends comparing boolean variables directly, without == true.

-	if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary == true {
+	if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d76db70 and e9e2c78.

📒 Files selected for processing (3)
  • backend/controllers/github.go (4 hunks)
  • backend/controllers/projects.go (3 hunks)
  • libs/digger_config/digger_config.go (1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
backend/controllers/projects.go

667-667: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)

libs/digger_config/digger_config.go

38-38: ineffectual assignment to err

(ineffassign)

🔇 Additional comments (2)
backend/controllers/projects.go (1)

485-489: 🛠️ Refactor suggestion

Return or handle errors after creating Terraform outputs summary.

The code logs the error but continues execution. If the summary generation is critical, consider returning or otherwise handling the error to avoid silently failing this step.

Example fix:

 err = CreateTerraformOutputsSummary(d.GithubClientProvider, batch)
 if err != nil {
-    log.Printf("could not generate terraform plans summary: %v", err)
-}
+    log.Printf("could not generate terraform plans summary: %v", err)
+    c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to generate terraform plans summary"})
+    return
 }

Likely invalid or redundant comment.

backend/controllers/github.go (1)

599-602: Looks good.

This block properly handles errors from loading Digger config and logs any failures. No action needed here.

diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
if err != nil {
// if file doesn't exist look for digger.yaml instead
diggerYmlBytes, err = os.ReadFile(path.Join(dir, "digger.yaml"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle error after reading secondary file.

The error assigned to err here is never checked. If reading digger.yaml also fails, the error will be silently ignored. Consider returning the error in this scenario to avoid unexpected behavior.

Apply this diff to ensure we don't ignore the second read error:

 func ReadDiggerYmlFileContents(dir string) (string, error) {
     var diggerYmlBytes []byte
     diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
     if err != nil {
         // if file doesn't exist look for digger.yaml instead
-        diggerYmlBytes, err = os.ReadFile(path.Join(dir, "digger.yaml"))
+        diggerYmlBytes, err = os.ReadFile(path.Join(dir, "digger.yaml"))
+        if err != nil {
+            return "", err
+        }
     }
     diggerYmlStr := string(diggerYmlBytes)
     return diggerYmlStr, nil
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
diggerYmlBytes, err = os.ReadFile(path.Join(dir, "digger.yaml"))
func ReadDiggerYmlFileContents(dir string) (string, error) {
var diggerYmlBytes []byte
diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
if err != nil {
// if file doesn't exist look for digger.yaml instead
diggerYmlBytes, err = os.ReadFile(path.Join(dir, "digger.yaml"))
if err != nil {
return "", err
}
}
diggerYmlStr := string(diggerYmlBytes)
return diggerYmlStr, nil
}
🧰 Tools
🪛 golangci-lint (1.62.2)

38-38: ineffectual assignment to err

(ineffassign)

Comment on lines 921 to 930
var aiSummaryCommentId = ""
if config.Reporting.AiSummary {
aiSummaryComment, err := ghService.PublishComment(issueNumber, "AI Summary will be posted here after completion")
if err != nil {
log.Printf("could not post ai summary comment: %v", err)
commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not post ai comment summary comment id: %v", err))
}
aiSummaryCommentId = aiSummaryComment.Id
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Check for nil after failing to publish the AI summary comment.

Similarly to the earlier comment, if PublishComment fails, referencing aiSummaryComment.Id may cause a panic.

Proposed fix:

 var aiSummaryCommentId = ""
 if config.Reporting.AiSummary {
     aiSummaryComment, err := ghService.PublishComment(issueNumber, "AI Summary will be posted here after completion")
     if err != nil {
         log.Printf("could not post ai summary comment: %v", err)
         commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not post ai comment summary comment id: %v", err))
+        return
     }
     aiSummaryCommentId = aiSummaryComment.Id
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 513 to 523

var aiSummaryCommentId = ""
if config.Reporting.AiSummary {
aiSummaryComment, err := ghService.PublishComment(prNumber, "AI Summary will be posted here after completion")
if err != nil {
log.Printf("could not post ai summary comment: %v", err)
commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not post ai comment summary comment id: %v", err))
}
aiSummaryCommentId = aiSummaryComment.Id
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Check for nil after failing to publish the AI summary comment.

If PublishComment fails, we log the error but still proceed to use aiSummaryComment.Id, which may cause a nil pointer dereference. Consider returning early when an error occurs.

Proposed fix:

 var aiSummaryCommentId = ""
 if config.Reporting.AiSummary {
     aiSummaryComment, err := ghService.PublishComment(prNumber, "AI Summary will be posted here after completion")
     if err != nil {
         log.Printf("could not post ai summary comment: %v", err)
         commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not post ai comment summary comment id: %v", err))
+        return
     }
     aiSummaryCommentId = aiSummaryComment.Id
 }

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
backend/controllers/projects.go (3)

485-489: Enhance error handling with more context

The error handling could be more descriptive to aid in debugging.

 err = CreateTerraformOutputsSummary(d.GithubClientProvider, batch)
 if err != nil {
-    log.Printf("could not generate terraform plans summary: %v", err)
+    log.Printf("could not generate terraform plans summary for batch %v: %v", batch.ID, err)
 }

685-695: Optimize string concatenation for better performance

Using string concatenation in a loop can be inefficient. Consider using strings.Builder for better performance.

-var terraformOutputs = "## AI Summary for terraform runs\n\n"
+var builder strings.Builder
+builder.WriteString("## AI Summary for terraform runs\n\n")
 for _, job := range jobs {
     var jobSpec orchestrator_scheduler.JobJson
     err := json.Unmarshal(job.SerializedJobSpec, &jobSpec)
     if err != nil {
         log.Printf("could not summarise plans due to unmarshalling error: %v", err)
         return fmt.Errorf("could not summarise plans due to unmarshalling error: %v", err)
     }
     projectName := jobSpec.ProjectName
-    terraformOutputs += fmt.Sprintf("terraform output for %v \n\n", projectName) + job.TerraformOutput
+    fmt.Fprintf(&builder, "terraform output for %v \n\n%v", projectName, job.TerraformOutput)
 }
+terraformOutputs := builder.String()

665-665: Simplify boolean comparison

The boolean comparison can be simplified.

-if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary == true {
+if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary {
🧰 Tools
🪛 golangci-lint (1.62.2)

665-665: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9e2c78 and af9d4eb.

📒 Files selected for processing (1)
  • backend/controllers/projects.go (3 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
backend/controllers/projects.go

665-665: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)

🔇 Additional comments (1)
backend/controllers/projects.go (1)

672-678: Enhance environment variable validation

The code validates the summary endpoint but not the API token. Consider validating both environment variables consistently.

 summaryEndpoint := os.Getenv("DIGGER_AI_SUMMARY_ENDPOINT")
+apiToken := os.Getenv("DIGGER_AI_SUMMARY_API_TOKEN")
 if summaryEndpoint == "" {
     log.Printf("could not generate AI summary, ai summary endpoint missing")
     return fmt.Errorf("could not generate AI summary, ai summary endpoint missing")
 }
-apiToken := os.Getenv("DIGGER_AI_SUMMARY_API_TOKEN")
+if apiToken == "" {
+    log.Printf("could not generate AI summary, api token missing")
+    return fmt.Errorf("could not generate AI summary, api token missing")
+}

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
backend/controllers/projects.go (4)

665-665: Simplify boolean comparison

The boolean comparison can be simplified.

-if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary == true {
+if batch.Status == orchestrator_scheduler.BatchJobSucceeded && config.Reporting.AiSummary {
🧰 Tools
🪛 golangci-lint (1.62.2)

665-665: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)


669-669: Standardize error message formatting

The error messages in EditComment/PublishComment calls have inconsistent formatting. Some have extra newlines, some don't. Consider standardizing the format.

-":x: could not generate AI summary \n\n could not communicate with github"
-":x: could not generate AI summary \n\n could not communicate with github"
-":x: could not generate AI summary \n\n comment ID is missing "
-":x: could not generate AI summary \n\n error fetching jobs "
-":x: could not generate AI summary \n\n error fetching job spec"
-":x: could not generate AI summary \n\n error generating summary from plans"
+":x: Could not generate AI summary\n\nReason: Could not communicate with GitHub"
+":x: Could not generate AI summary\n\nReason: Could not communicate with GitHub"
+":x: Could not generate AI summary\n\nReason: Comment ID is missing"
+":x: Could not generate AI summary\n\nReason: Error fetching jobs"
+":x: Could not generate AI summary\n\nReason: Error fetching job spec"
+":x: Could not generate AI summary\n\nReason: Error generating summary from plans"

Also applies to: 675-675, 682-682, 690-690, 700-700, 709-709


655-716: Consider breaking down the function for better maintainability

The function has high cyclomatic complexity with multiple nested conditions and error handling. Consider breaking it down into smaller, focused functions:

  1. validateConfiguration
  2. validateEnvironment
  3. collectTerraformOutputs
  4. generateAndPostSummary

Here's a sketch of how it could be refactored:

func validateConfiguration(batch *models.DiggerBatch) (*digger_config.DiggerConfig, error) {
    // Handle digger config loading and validation
}

func validateEnvironment() (string, string, error) {
    // Handle environment variables validation
}

func collectTerraformOutputs(batchID uint) (string, error) {
    // Handle collecting terraform outputs
}

func generateAndPostSummary(prService ci.PullRequestService, summary string, batch *models.DiggerBatch) error {
    // Handle posting the summary
}

func CreateTerraformOutputsSummary(gh utils.GithubClientProvider, batch *models.DiggerBatch) error {
    config, err := validateConfiguration(batch)
    if err != nil {
        return err
    }

    if batch.Status != orchestrator_scheduler.BatchJobSucceeded || !config.Reporting.AiSummary {
        return nil
    }

    summaryEndpoint, apiToken, err := validateEnvironment()
    if err != nil {
        return err
    }

    terraformOutputs, err := collectTerraformOutputs(batch.ID)
    if err != nil {
        return err
    }

    prService, err := GetPrServiceFromBatch(batch, gh)
    if err != nil {
        return err
    }

    summary, err := utils.GetAiSummaryFromTerraformPlans(terraformOutputs, summaryEndpoint, apiToken)
    if err != nil {
        return err
    }

    return generateAndPostSummary(prService, summary, batch)
}
🧰 Tools
🪛 golangci-lint (1.62.2)

665-665: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)


694-705: Enhance terraform outputs formatting

The current formatting of terraform outputs could be improved for better readability.

-var terraformOutputs = "## AI Summary for terraform runs\n\n"
+var terraformOutputs = "## AI Summary for Terraform Runs\n\n"
 for _, job := range jobs {
     // ... job spec unmarshaling ...
     projectName := jobSpec.ProjectName
-    terraformOutputs += fmt.Sprintf("terraform output for %v \n\n", projectName) + job.TerraformOutput
+    terraformOutputs += fmt.Sprintf("### Terraform Output: %s\n\n```hcl\n%s\n```\n\n", projectName, job.TerraformOutput)
 }
libs/digger_config/digger_config.go (3)

33-45: Consider aligning with existing file handling patterns.

While the implementation is functionally correct, consider these improvements for better consistency and maintainability:

  1. Use the existing isFileExists helper function to check file existence.
  2. Align the implementation with retrieveConfigFile function's pattern.
  3. Make the error message more specific about which file failed.
 func ReadDiggerYmlFileContents(dir string) (string, error) {
-	var diggerYmlBytes []byte
-	diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
-	if err != nil {
-		// if file doesn't exist look for digger.yaml instead
-		diggerYmlBytes, err = os.ReadFile(path.Join(dir, "digger.yaml"))
-		if err != nil {
-			return "", fmt.Errorf("could not read the file both digger.yml and digger.yaml are missing: %v", err)
-		}
-	}
-	diggerYmlStr := string(diggerYmlBytes)
-	return diggerYmlStr, nil
+	ymlPath := path.Join(dir, "digger.yml")
+	yamlPath := path.Join(dir, "digger.yaml")
+	
+	if isFileExists(ymlPath) {
+		diggerYmlBytes, err := os.ReadFile(ymlPath)
+		if err != nil {
+			return "", fmt.Errorf("failed to read digger.yml: %v", err)
+		}
+		return string(diggerYmlBytes), nil
+	}
+	
+	if isFileExists(yamlPath) {
+		diggerYmlBytes, err := os.ReadFile(yamlPath)
+		if err != nil {
+			return "", fmt.Errorf("failed to read digger.yaml: %v", err)
+		}
+		return string(diggerYmlBytes), nil
+	}
+	
+	return "", fmt.Errorf("neither digger.yml nor digger.yaml exists in directory: %s", dir)
 }

33-45: Consider consolidating configuration file handling logic.

The new ReadDiggerYmlFileContents function partially duplicates logic from retrieveConfigFile. Consider refactoring to share common functionality:

  1. Extract the file existence checking logic into a shared helper.
  2. Use retrieveConfigFile to get the correct filename, then read its contents.

Example approach:

// Helper function to consolidate file handling logic
func getDiggerConfigPath(dir string) (string, error) {
    configPath, err := retrieveConfigFile(dir)
    if err != nil {
        return "", err
    }
    if configPath == "" {
        return "", fmt.Errorf("neither digger.yml nor digger.yaml exists in directory: %s", dir)
    }
    return configPath, nil
}

func ReadDiggerYmlFileContents(dir string) (string, error) {
    configPath, err := getDiggerConfigPath(dir)
    if err != nil {
        return "", err
    }
    
    data, err := os.ReadFile(configPath)
    if err != nil {
        return "", fmt.Errorf("failed to read %s: %v", configPath, err)
    }
    return string(data), nil
}

33-45: Enhance error handling with error wrapping.

While the error handling is functional, consider using error wrapping to preserve the error chain for better debugging:

 func ReadDiggerYmlFileContents(dir string) (string, error) {
 	var diggerYmlBytes []byte
 	diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
 	if err != nil {
 		// if file doesn't exist look for digger.yaml instead
 		diggerYmlBytes, err = os.ReadFile(path.Join(dir, "digger.yaml"))
 		if err != nil {
-			return "", fmt.Errorf("could not read the file both digger.yml and digger.yaml are missing: %v", err)
+			return "", fmt.Errorf("could not read configuration files: %w", err)
 		}
 	}
 	diggerYmlStr := string(diggerYmlBytes)
 	return diggerYmlStr, nil
 }

This change:

  1. Uses %w instead of %v to wrap the original error
  2. Preserves the full error chain for better debugging
  3. Allows upstream code to use errors.Is and errors.As for error handling
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af9d4eb and 69b2db3.

📒 Files selected for processing (2)
  • backend/controllers/projects.go (3 hunks)
  • libs/digger_config/digger_config.go (1 hunks)
🧰 Additional context used
📓 Learnings (1)
backend/controllers/projects.go (1)
Learnt from: motatoes
PR: diggerhq/digger#1864
File: backend/controllers/projects.go:672-678
Timestamp: 2024-12-30T09:19:58.162Z
Learning: In file `backend/controllers/projects.go`, the user clarified that the AI summary token is considered non-critical, so they prefer not to validate it.
🪛 golangci-lint (1.62.2)
backend/controllers/projects.go

665-665: S1002: should omit comparison to bool constant, can be simplified to config.Reporting.AiSummary

(gosimple)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
backend/controllers/github.go (1)

513-524: 🛠️ Refactor suggestion

Apply the same refactoring to handlePullRequestEvent.

The same issues exist here as in handleIssueCommentEvent. Use the extracted helper function here as well.

🧹 Nitpick comments (2)
backend/controllers/github.go (2)

785-788: Enhance error handling for terraform generation.

The error handling could be more informative and follow Go's error handling best practices.

 if err != nil {
-    log.Printf("terraform generation failed: %v", err)
-    return err
+    log.Printf("Terraform generation failed for project: %v, error: %v", projectName, err)
+    return fmt.Errorf("terraform generation failed: %w", err)
 }

599-603: Enhance error handling for configuration file reading.

The error handling could be more informative by including the directory context and wrapping the error.

 diggerYmlStr, err = dg_configuration.ReadDiggerYmlFileContents(dir)
 if err != nil {
-    log.Printf("could not load digger config: %v", err)
-    return err
+    log.Printf("could not load digger config from directory %s: %v", dir, err)
+    return fmt.Errorf("failed to read digger.yml from %s: %w", dir, err)
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69b2db3 and c08f33c.

📒 Files selected for processing (1)
  • backend/controllers/github.go (4 hunks)

Comment on lines +922 to +932
var aiSummaryCommentId = ""
if config.Reporting.AiSummary {
aiSummaryComment, err := ghService.PublishComment(issueNumber, "AI Summary will be posted here after completion")
if err != nil {
log.Printf("could not post ai summary comment: %v", err)
commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not post ai comment summary comment id: %v", err))
return fmt.Errorf("could not post ai summary comment: %v", err)
}
aiSummaryCommentId = aiSummaryComment.Id
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated AI summary initialization logic.

The AI summary initialization logic is duplicated between handleIssueCommentEvent and handlePullRequestEvent. Consider extracting this into a shared helper function.

+func initializeAISummary(config *dg_configuration.DiggerConfig, ghService *dg_github.GithubService, issueNumber int) (string, error) {
+    if !config.Reporting.AiSummary {
+        return "", nil
+    }
+    aiSummaryComment, err := ghService.PublishComment(issueNumber, "AI Summary will be posted here after completion")
+    if err != nil {
+        return "", fmt.Errorf("could not post ai summary comment: %w", err)
+    }
+    return aiSummaryComment.Id, nil
+}

Then use it in both handlers:

-var aiSummaryCommentId = ""
-if config.Reporting.AiSummary {
-    aiSummaryComment, err := ghService.PublishComment(issueNumber, "AI Summary will be posted here after completion")
-    if err != nil {
-        log.Printf("could not post ai summary comment: %v", err)
-        commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not post ai comment summary comment id: %v", err))
-        return fmt.Errorf("could not post ai summary comment: %v", err)
-    }
-    aiSummaryCommentId = aiSummaryComment.Id
-}
+aiSummaryCommentId, err := initializeAISummary(config, ghService, issueNumber)
+if err != nil {
+    log.Printf("could not initialize ai summary: %v", err)
+    commentReporterManager.UpdateComment(fmt.Sprintf(":x: could not initialize ai summary: %v", err))
+    return fmt.Errorf("could not initialize ai summary: %w", err)
+}

Committable suggestion skipped: line range outside the PR's diff.

@motatoes motatoes merged commit 9599562 into develop Dec 30, 2024
11 checks passed
motatoes added a commit that referenced this pull request Jan 2, 2025
* add flag to ignore all external directories per project (#1851)

* add flag to ignore all external directories per project

* revert includeparentblocks flag (#1852)

* improve efficiency in terragrunt generation (#1854)

* improve efficiency in terragrunt generation

* Update action.yml (#1856)

* handle crashes in goroutine events (#1857)

* fix/recover from webhook goroutines (#1858)

* handle crashes in goroutine events

* include stacktrace in errors

* wip generation of terraform code from application code (#1855)

* terraform code generation demo


---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: incorrect comment in backend/migrations (#1860)

* Update setup-opentofu to fix issues with 1.6.x downloads (#1861)

* restructure docs to have no columns (#1862)

* Create curl_bootstrap.sh

* refactor codegen parts (#1863)

* refactor codegen parts

* publish ai summaries (#1864)

* publish ai summaries

* add a header for summary comment (#1865)

* fix heading (#1866)

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Aldo <82811+aldoborrero@users.noreply.github.com>
Co-authored-by: Hugo Samayoa <htplbc@gmail.com>
This was referenced Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant