Skip to content

Commit

Permalink
Added app insights. Error handling fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
goncalvesj committed Aug 23, 2023
1 parent 011a3bf commit b55e309
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
<RootNamespace>AzDevOps_GitHub_Workflow</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.16.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.11.0" />
<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.205.1" />
Expand Down
54 changes: 22 additions & 32 deletions AzDevOps-GitHub-Workflow/Functions/CloseIssue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class CloseIssue
{
private readonly ILogger _logger;
private readonly IAzDOClientService _azdoClient;

private static readonly Regex pattern = new(@"\[(AB#)(\d+)\]", RegexOptions.Compiled, TimeSpan.FromMilliseconds(100));

public CloseIssue(ILoggerFactory loggerFactory, IAzDOClientService azdoClient)
{
Expand All @@ -24,44 +24,34 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Fun
{
_logger.LogInformation("HTTP trigger started");

try
{
var content = await req.ReadFromJsonAsync<GitHubRoot>();
var content = await req.ReadFromJsonAsync<GitHubRoot>();

if (content != null && content.Issue.State == "closed")
{
var issue = content.Issue.Body;

var pattern = @"\[(AB#)(\d+)\]";
if (content != null && content.Issue.State == "closed")
{
var issue = content.Issue.Body;

var matches = Regex.Matches(issue, pattern, RegexOptions.None, TimeSpan.FromMilliseconds(100));
//var pattern = @"\[(AB#)(\d+)\]";
//var matches = Regex.Matches(issue, pattern, RegexOptions.None, TimeSpan.FromMilliseconds(100));

for (int i = 0; i < matches.Count; i++)
{
Match match = matches[i];
var workItem = await _azdoClient.UpdateWorkItemStatus(Convert.ToInt32(match.Groups[2].Value));
_logger.LogInformation("Data: {workItem}", workItem.Url);
}
var matches = pattern.Matches(issue);

var successResponse = req.CreateResponse(HttpStatusCode.OK);
await successResponse.WriteAsJsonAsync(new { message = "Tasks closed successfully" });
return successResponse;
for (int i = 0; i < matches.Count; i++)
{
Match match = matches[i];
var workItem = await _azdoClient.UpdateWorkItemStatus(Convert.ToInt32(match.Groups[2].Value));
_logger.LogInformation("Data: {workItem}", workItem.Url);
}

var message = "Issue not found or status is not closed";
_logger.LogInformation("Message: {message}", message);
var successResponse = req.CreateResponse(HttpStatusCode.OK);
await successResponse.WriteAsJsonAsync(new { message = "Tasks closed successfully" });
return successResponse;
}

var response = req.CreateResponse(HttpStatusCode.BadRequest);
await response.WriteAsJsonAsync(new { error = message });
return response;
var message = "Issue not found or status is not closed";
_logger.LogInformation("Message: {message}", message);

}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating issue");
var errorResponse = req.CreateResponse(HttpStatusCode.InternalServerError);
await errorResponse.WriteAsJsonAsync(new { error = "Error creating issue" });
return errorResponse;
}
var response = req.CreateResponse(HttpStatusCode.BadRequest);
await response.WriteAsJsonAsync(new { error = message });
return response;
}
}
81 changes: 36 additions & 45 deletions AzDevOps-GitHub-Workflow/Functions/CreateIssue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,59 +23,50 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Fun
{
_logger.LogInformation("HTTP trigger started");

try
{
var content = await req.ReadFromJsonAsync<AzDORoot>();
var content = await req.ReadFromJsonAsync<AzDORoot>();

var systemTags = content?.Resource?.Fields?.SystemTags;
if (string.IsNullOrEmpty(systemTags))
{
var message = "SystemTags field not found";
_logger.LogInformation("Message: {message}", message);
var systemTags = content?.Resource?.Fields?.SystemTags;
if (string.IsNullOrEmpty(systemTags))
{
var message = "SystemTags field not found";
_logger.LogInformation("Message: {message}", message);

var response = req.CreateResponse(HttpStatusCode.BadRequest);
await response.WriteAsJsonAsync(new { error = message });
return response;
}
var response = req.CreateResponse(HttpStatusCode.BadRequest);
await response.WriteAsJsonAsync(new { error = message });
return response;
}

var tags = systemTags.Split(';');
var owner = tags.FirstOrDefault(t => t.Trim().StartsWith("owner:", StringComparison.OrdinalIgnoreCase))?.Split(':')[1]?.Trim();
var repo = tags.FirstOrDefault(t => t.Trim().StartsWith("repo:", StringComparison.OrdinalIgnoreCase))?.Split(':')[1]?.Trim();
var tags = systemTags.Split(';');
var owner = tags.FirstOrDefault(t => t.Trim().StartsWith("owner:", StringComparison.OrdinalIgnoreCase))?.Split(':')[1]?.Trim();
var repo = tags.FirstOrDefault(t => t.Trim().StartsWith("repo:", StringComparison.OrdinalIgnoreCase))?.Split(':')[1]?.Trim();

if (string.IsNullOrEmpty(owner) || string.IsNullOrEmpty(repo))
{
var message = "Invalid owner or repo tag";
_logger.LogInformation("Message: {message}", message);
if (string.IsNullOrEmpty(owner) || string.IsNullOrEmpty(repo))
{
var message = "Invalid owner or repo tag";
_logger.LogInformation("Message: {message}", message);

var response = req.CreateResponse(HttpStatusCode.BadRequest);
await response.WriteAsJsonAsync(new { error = message });
return response;
}
var response = req.CreateResponse(HttpStatusCode.BadRequest);
await response.WriteAsJsonAsync(new { error = message });
return response;
}

var newIssue = new NewIssue(content?.Resource.Fields.SystemTitle)
{
Body = $"Azure Boards WorkItem: AB#{content?.Resource.Id}"
};
var newIssue = new NewIssue(content?.Resource.Fields.SystemTitle)
{
Body = $"Azure Boards WorkItem: AB#{content?.Resource.Id}"
};

var issue = await _githubClient.CreateGitHubIssue(owner, repo, newIssue);
var issue = await _githubClient.CreateGitHubIssue(owner, repo, newIssue);

var successResponse = req.CreateResponse(HttpStatusCode.OK);
await successResponse.WriteAsJsonAsync(new
{
issue.Id,
issue.Number,
issue.Title,
issue.HtmlUrl
});
_logger.LogInformation("GH Issue created successfully");
return successResponse;
}
catch (Exception ex)
var successResponse = req.CreateResponse(HttpStatusCode.OK);
await successResponse.WriteAsJsonAsync(new
{
_logger.LogError(ex, "Error creating issue");
var errorResponse = req.CreateResponse(HttpStatusCode.InternalServerError);
await errorResponse.WriteAsJsonAsync(new { error = "Error creating issue" });
return errorResponse;
}
issue.Id,
issue.Number,
issue.Title,
issue.HtmlUrl
});

_logger.LogInformation("GH Issue created successfully");
return successResponse;
}
}
38 changes: 3 additions & 35 deletions AzDevOps-GitHub-Workflow/Functions/GithubModels.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
using System.Text.Json.Serialization;

namespace AzDO.GH.Function.Models;

public record Body(
[property: JsonPropertyName("from")] string From
);

public record Changes(
[property: JsonPropertyName("body")] Body Body
);

public record Issue(
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("repository_url")] string RepositoryUrl,
Expand All @@ -21,7 +12,6 @@ public record Issue(
[property: JsonPropertyName("node_id")] string NodeId,
[property: JsonPropertyName("number")] int Number,
[property: JsonPropertyName("title")] string Title,
[property: JsonPropertyName("user")] User User,
[property: JsonPropertyName("labels")] IReadOnlyList<object> Labels,
[property: JsonPropertyName("state")] string State,
[property: JsonPropertyName("locked")] bool Locked,
Expand All @@ -31,38 +21,16 @@ public record Issue(
[property: JsonPropertyName("comments")] int Comments,
[property: JsonPropertyName("created_at")] DateTime CreatedAt,
[property: JsonPropertyName("updated_at")] DateTime UpdatedAt,
[property: JsonPropertyName("closed_at")] object ClosedAt,
[property: JsonPropertyName("closed_at")] DateTime ClosedAt,
[property: JsonPropertyName("author_association")] string AuthorAssociation,
[property: JsonPropertyName("active_lock_reason")] object ActiveLockReason,
[property: JsonPropertyName("body")] string Body,
[property: JsonPropertyName("timeline_url")] string TimelineUrl,
[property: JsonPropertyName("performed_via_github_app")] object PerformedViaGithubApp,
[property: JsonPropertyName("state_reason")] object StateReason
[property: JsonPropertyName("state_reason")] string StateReason
);

public record GitHubRoot(
[property: JsonPropertyName("action")] string Action,
[property: JsonPropertyName("issue")] Issue Issue,
[property: JsonPropertyName("changes")] Changes Changes
);

public record User(
[property: JsonPropertyName("login")] string Login,
[property: JsonPropertyName("id")] int Id,
[property: JsonPropertyName("node_id")] string NodeId,
[property: JsonPropertyName("avatar_url")] string AvatarUrl,
[property: JsonPropertyName("gravatar_id")] string GravatarId,
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("html_url")] string HtmlUrl,
[property: JsonPropertyName("followers_url")] string FollowersUrl,
[property: JsonPropertyName("following_url")] string FollowingUrl,
[property: JsonPropertyName("gists_url")] string GistsUrl,
[property: JsonPropertyName("starred_url")] string StarredUrl,
[property: JsonPropertyName("subscriptions_url")] string SubscriptionsUrl,
[property: JsonPropertyName("organizations_url")] string OrganizationsUrl,
[property: JsonPropertyName("repos_url")] string ReposUrl,
[property: JsonPropertyName("events_url")] string EventsUrl,
[property: JsonPropertyName("received_events_url")] string ReceivedEventsUrl,
[property: JsonPropertyName("type")] string Type,
[property: JsonPropertyName("site_admin")] bool SiteAdmin
[property: JsonPropertyName("issue")] Issue Issue
);
3 changes: 3 additions & 0 deletions AzDevOps-GitHub-Workflow/Functions/Program.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using AzDO.GH.Function;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
services.AddTransient<IGitHubClientService, GitHubClientService>();
services.AddTransient<IAzDOClientService, AzDOClientService>();
})
Expand Down

0 comments on commit b55e309

Please sign in to comment.