Skip to content

Commit

Permalink
Outdated packages have been updated. Refactoring for .NET 8 has been …
Browse files Browse the repository at this point in the history
…completed. Improvements were made to enhance code readability. Models were consolidated into a single file.
  • Loading branch information
cenksari committed Oct 12, 2024
1 parent 62082ab commit 3e4e751
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 91 deletions.
29 changes: 29 additions & 0 deletions src/Summarize.PR/Models/GithubRepositoryModels.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Summarize.PR.Models;

public record Review(string body);

public record CommitChanges
{
public required string CommitSHA { get; set; }
public required string RepositoryName { get; set; }
public required string RepositoryAccount { get; set; }
}

public record CommitComment
{
public required string Comment { get; set; }
public required string PullRequestId { get; set; }
public required string RepositoryName { get; set; }
public required string RepositoryAccount { get; set; }
}

public record Settings
{
public required string PAT { get; set; }
public required string APIKey { get; set; }
public required string ModelId { get; set; }
public required string CommitSHA { get; set; }
public required string PullRequestId { get; set; }
public required string RepositoryName { get; set; }
public required string RepositoryAccount { get; set; }
}
96 changes: 54 additions & 42 deletions src/Summarize.PR/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,79 @@
using Azure.AI.Inference;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;

using Summarize.PR.Models;
using Summarize.PR.Repository.GitHub;

IConfigurationRoot config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();

Settings settings = config.Get<Settings>()
?? throw new Exception("Invalid Configuration");
?? throw new Exception("Invalid configuration.");

if (!string.IsNullOrEmpty(settings.CommitSHA))
{
System.Console.WriteLine($"Repository account: {settings.RepositoryAccount}");
System.Console.WriteLine($"Repository name: {settings.RepositoryName}");
System.Console.WriteLine($"Commit: {settings.CommitSHA}");
System.Console.WriteLine($"Model: {settings.ModelId}");
Console.WriteLine($"Repository account: {settings.RepositoryAccount}");
Console.WriteLine($"Repository name: {settings.RepositoryName}");
Console.WriteLine($"Commit: {settings.CommitSHA}");
Console.WriteLine($"Model: {settings.ModelId}");

IChatClient client = new ChatCompletionsClient(
endpoint: new("https://models.inference.ai.azure.com"),
credential: new AzureKeyCredential(settings.APIKey)
).AsChatClient(settings.ModelId);

IChatClient client = new ChatCompletionsClient(
endpoint: new Uri("https://models.inference.ai.azure.com"),
credential: new AzureKeyCredential(settings.APIKey)
).AsChatClient(settings.ModelId);
List<ChatMessage> messages = [
new(
Microsoft.Extensions.AI.ChatRole.System,
@"
You are a software developer. You describe code changes for commits.
Your descriptions are simple and clear so that they help developers to understand changes.
Because you describe briefly, if there is more than 7 file changes, just describe 7 files.
You do descriptions in an order.
"
)
];

var messages = new List<ChatMessage>(){
new(
Microsoft.Extensions.AI.ChatRole.System,
$$"""
You are a software developer. You describe code changes for commits.
Your descriptions are simple and clear so that they help developers to understand changes.
Because you describe briefly, if there is more than 7 file changes, just describe 7 files.
You do descriptions in an order.
"""
)
};
GitHubRepository repository = new(settings.PAT);

var repository = new GitHubRepository(settings.PAT);
CommitChanges commitChanges = new()
{
CommitSHA = settings.CommitSHA,
RepositoryName = settings.RepositoryName,
RepositoryAccount = settings.RepositoryAccount
};

var diff = await repository.GetCommitChanges(
settings.RepositoryAccount,
settings.RepositoryName,
settings.CommitSHA);
string diff = await repository.GetCommitChangesAsync(commitChanges);

messages.Add(new ChatMessage()
{
Role = Microsoft.Extensions.AI.ChatRole.User,
Text = $$"""
messages.Add(new()
{
Role = Microsoft.Extensions.AI.ChatRole.User,
Text = $$"""
Describe the following commit and group descriptions per file.
<code>
{{diff}}
</code>
""",
});
});

var result = await client.CompleteAsync(messages);
ChatCompletion? result = await client.CompleteAsync(messages);

await repository.PostComment(result.Message.Text,
settings.RepositoryAccount,
settings.RepositoryName,
settings.PullRequestId);
CommitComment commitComment = new()
{
Comment = result.Message.Text ?? "",
PullRequestId = settings.PullRequestId,
RepositoryName = settings.RepositoryName,
RepositoryAccount = settings.RepositoryAccount,
};

System.Console.WriteLine("Commit changes are summarized");
}else{
System.Console.WriteLine("Commit SHA is not provided, summarization is skipped");
await repository.PostCommentAsync(commitComment);

Console.WriteLine("Commit changes are summarized.");
}
else
{
Console.WriteLine("Commit SHA is not provided, summarization is skipped.");
}
88 changes: 51 additions & 37 deletions src/Summarize.PR/Repository/GitHub/GitHubRepository.cs
Original file line number Diff line number Diff line change
@@ -1,43 +1,57 @@
namespace Summarize.PR.Repository.GitHub;

using Summarize.PR.Models;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

public class GitHubRepository
{
private readonly HttpClient _client;

public GitHubRepository(string token)
{
_client = new HttpClient();
//User-Agent should be defined or actions worker does not allow for a request
_client.DefaultRequestHeaders.Add("User-Agent", "SummarizePRAction");
_client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.diff");
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Trim());
}

public async Task<string> GetCommitChanges(string repositoryAccount, string repositoryName, string commitSHA)
{
var response = await _client.GetAsync($"https://api.github.com/repos/{repositoryAccount}/{repositoryName}/commits/{commitSHA}");
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();

return result;
}

public async Task PostComment(string comment, string repositoryAccount, string repositoryName, string pullRequestId)
{

var result = await _client.PostAsJsonAsync<Review>($"https://api.github.com/repos/{repositoryAccount}/{repositoryName}/issues/{pullRequestId}/comments", new Review
{
Body = comment
});

result.EnsureSuccessStatusCode();
}
}

file class Review
{
public string Body { get; set; }
private readonly HttpClient _client;

// The HttpClient is injected through the constructor (HttpClientFactory pattern),
// and the GitHub token is used to set up authorization headers.
public GitHubRepository(string token)
{
_client = new HttpClient();

// Set User-Agent and Accept headers.
// These headers are necessary for the GitHub API to recognize the request.
_client.DefaultRequestHeaders.Add("User-Agent", "SummarizePRAction");
_client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.diff");

// Authorization header with the Bearer token for authentication.
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Trim());
}

/// <summary>
/// Fetches the commit changes from the GitHub API using the commit SHA.
/// </summary>
/// <param name="commitChanges">Commit changes model.</param>
public async Task<string> GetCommitChangesAsync(CommitChanges commitChanges)
{
// Build the request URL using string interpolation and send GET request to GitHub API.
using var response = await _client.GetAsync($"repos/{commitChanges.RepositoryAccount}/{commitChanges.RepositoryName}/commits/{commitChanges.CommitSHA}");

// Ensure the response is successful (throws an exception if the status code is not 2xx).
response.EnsureSuccessStatusCode();

// Read and return the response content as a string (the diff of the commit).
return await response.Content.ReadAsStringAsync();
}

/// <summary>
/// Posts a comment on a GitHub pull request.
/// </summary>
/// <param name="commitComment">Commit comment model</param>
public async Task PostCommentAsync(CommitComment commitComment)
{
// Create a new review object with the comment body.
Review review = new(commitComment.Comment);

// Send a POST request to GitHub API with the review object in JSON format.
using var response = await _client.PostAsJsonAsync($"repos/{commitComment.RepositoryAccount}/{commitComment.RepositoryName}/issues/{commitComment.PullRequestId}/comments", review);

// Ensure the response is successful.
response.EnsureSuccessStatusCode();
}
}
10 changes: 0 additions & 10 deletions src/Summarize.PR/Settings.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/Summarize.PR/Summarize.PR.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.AI" Version="9.0.0-preview.9.24507.7" />
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="9.0.0-preview.9.24507.7" />
<PackageReference Include="Microsoft.Extensions.AI.AzureAIInference" Version="9.0.0-preview.9.24507.7" />
Expand Down

0 comments on commit 3e4e751

Please sign in to comment.