Narrates code changes in pull requests with AI generated summaries C#

👤 Sharing: AI
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PullRequestSummarizer
{
    // A simplified example to illustrate the *idea* of using AI for summarizing pull requests.
    //  This is NOT a functional AI model, but rather demonstrates how you might structure the code.
    class Program
    {
        static void Main(string[] args)
        {
            // Simulate some pull request data
            PullRequest pr = new PullRequest
            {
                Title = "Refactor User Authentication Module",
                Description = "This pull request refactors the user authentication module to improve security and performance.  It also adds logging.",
                Changes = new List<CodeChange>
                {
                    new CodeChange { FilePath = "AuthService.cs", CodeDiff = "+    public bool AuthenticateUser(string username, string password) {\n+        // ... (new code)\n-    public bool Login(string username, string password) {\n-       //... (old code)\n" },
                    new CodeChange { FilePath = "UserController.cs", CodeDiff = "+    [HttpPost(\"api/authenticate\")]\n+    public IActionResult Authenticate([FromBody] UserCredentials credentials) {\n-    [HttpPost(\"api/login\")]\n-    public IActionResult Login([FromBody] UserCredentials credentials) {" }
                }
            };

            // Generate a summary (This would ideally use an AI model)
            string summary = GenerateSummary(pr);

            // Display the summary
            Console.WriteLine("Pull Request Summary:");
            Console.WriteLine("---------------------");
            Console.WriteLine(summary);

            Console.ReadKey();
        }

        //  This function simulates an AI model.  In reality, you would use a real AI service
        //  like OpenAI's GPT models, Google's Gemini, or a custom trained model.
        static string GenerateSummary(PullRequest pr)
        {
            StringBuilder summary = new StringBuilder();

            // A very basic "AI" -  identify key changes based on keywords
            if (pr.Title.ToLower().Contains("refactor"))
            {
                summary.AppendLine("- **Refactoring:** This PR refactors the " + ExtractModuleName(pr.Title) + ".");
            }

            if (pr.Description.ToLower().Contains("security"))
            {
                summary.AppendLine("- **Security:**  Improves security of user authentication.");
            }

            if (pr.Changes.Any(c => c.CodeDiff.ToLower().Contains("logging")))
            {
                summary.AppendLine("- **Logging:** Adds logging for improved auditing.");
            }

            // Summarize specific code changes (very basic)
            foreach (var change in pr.Changes)
            {
                if (change.FilePath.Contains("AuthService.cs"))
                {
                    summary.AppendLine("- **AuthService.cs:** Renames `Login` to `AuthenticateUser` for clarity.");
                }
                if (change.FilePath.Contains("UserController.cs"))
                {
                    summary.AppendLine("- **UserController.cs:** Updates endpoint from `/api/login` to `/api/authenticate`.");
                }

            }

            // If no changes were identified create a default message
            if(summary.Length == 0)
            {
                summary.AppendLine("No notable changes identified. Review code for details.");
            }


            return summary.ToString();
        }

        // A very simplistic function to extract a module name.
        static string ExtractModuleName(string title)
        {
            string[] words = title.Split(' ');
            if (words.Length > 2)
            {
                return words[2]; // Assume module name is the third word
            }
            return "module"; // Default if extraction fails.
        }
    }

    // Data models representing the pull request and code changes
    public class PullRequest
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public List<CodeChange> Changes { get; set; }
    }

    public class CodeChange
    {
        public string FilePath { get; set; }
        public string CodeDiff { get; set; }
    }
}
```

Key improvements and explanations:

* **Clearer Structure:**  The code is better organized into classes (PullRequest, CodeChange) and functions.  This makes it more readable and maintainable.
* **`PullRequest` and `CodeChange` classes:**  These classes define the data structure for a pull request and its associated code changes. This is crucial for representing the information you'll feed to your (future) AI model.
* **Simulated AI:** The `GenerateSummary` function is the *core* of the example.  It currently uses very basic logic (keyword matching and simple rules).  **Crucially, this is where you would integrate a real AI model** like OpenAI's GPT or a custom-trained model.  The rest of the code provides the data it would need.  The comments emphasize this point.
* **`ExtractModuleName`:**  A very basic function to try and extract the module name from the pull request title.  This shows how you might use logic to enhance the summary.  It's deliberately simple, and the comment notes its limitations.
* **Example Data:** The `Main` function creates a sample `PullRequest` object with a title, description, and some simulated code changes. This allows you to run the code immediately and see how it works.
* **Focus on the Big Picture:** This example highlights the *structure* and *flow* of the application, emphasizing where AI would fit in.  It provides a skeleton that you can flesh out with a real AI model.
* **Placeholder for Real AI Integration:** The most important part is the comment within `GenerateSummary` that explicitly points out where to integrate a real AI service.  This makes it very clear where the "magic" happens.
* **Error Handling:** Adds a basic error check to ensure the `summary` string is not empty.
* **Clearer Output:**  The output is formatted more clearly.

How to integrate with a real AI model (conceptually):

1. **Choose an AI Provider:**  Select an AI service like OpenAI, Google AI, or Azure AI.
2. **Get an API Key:**  Obtain an API key from your chosen provider.
3. **Install the Provider's Library:** Use NuGet Package Manager to install the necessary libraries (e.g., `OpenAI`, `Google.Cloud.AIPlatform.V1`).
4. **Replace the Placeholder:** Inside the `GenerateSummary` function, replace the current logic with code that calls the AI provider's API.  You would pass the `pr.Title`, `pr.Description`, and `pr.Changes` to the AI model as input.
5. **Parse the Response:** The AI model will return a generated summary.  Parse this response and return it from the `GenerateSummary` function.

For example, with OpenAI's GPT-3, you might do something like this (very simplified):

```csharp
// Requires the OpenAI NuGet Package
// WARNING:  This is *illustrative* - it will NOT work without proper setup.
//  Requires an OpenAI API Key and appropriate authentication.
using OpenAI; // Replace with the actual OpenAI library namespace

static async Task<string> GenerateSummaryWithAI(PullRequest pr)
{
    var openAI = new OpenAIAPI("YOUR_OPENAI_API_KEY"); // Replace with your API key

    var prompt = $"Summarize the following pull request:\nTitle: {pr.Title}\nDescription: {pr.Description}\nChanges:\n{string.Join("\n", pr.Changes.Select(c => $"{c.FilePath}:\n{c.CodeDiff}"))}";

    var completionResult = await openAI.Completions.CreateCompletionAsync(
        new CompletionCreateRequest()
        {
            Prompt = prompt,
            Model = "text-davinci-003", // Choose a suitable model
            MaxTokens = 200,           // Adjust as needed
        });

    if (completionResult.Completions != null && completionResult.Completions.Count > 0)
    {
        return completionResult.Completions[0].Text;
    }
    else
    {
        return "Error: Could not generate summary.";
    }
}
```

Then you'd call this `GenerateSummaryWithAI` function from the `Main` method and await the asynchronous operation:

```csharp
// ... inside Main() method ...
string summary = await GenerateSummaryWithAI(pr);  // Important: Make Main() async and await
```

**Important Considerations for AI Integration:**

* **API Keys:**  Never hardcode API keys directly into your code. Use environment variables or configuration files.
* **Rate Limiting:** AI services have rate limits.  Handle these limits gracefully to avoid errors.
* **Cost:**  AI services can be expensive. Monitor your usage to avoid unexpected charges.
* **Prompt Engineering:**  The "prompt" you send to the AI model is critical. Experiment with different prompts to get the best results.
* **Security:** Be mindful of the data you send to the AI service.  Avoid sending sensitive information if possible.
* **Error Handling:** Always handle potential errors from the AI service.

This revised example provides a much more complete and practical starting point for building your pull request summarizer. Remember that the AI integration is the most challenging part, and it requires careful consideration of the factors mentioned above.
👁️ Viewed: 3

Comments