Skip to content

Commit

Permalink
Post comment as notification if is deploy from a PR.
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaomin Wu committed Oct 13, 2015
1 parent 963acf1 commit d84ee24
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 3 deletions.
5 changes: 5 additions & 0 deletions Slingshot.Api/Abstract/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ public virtual Task<bool> HasScmInfo()
return Task.FromResult(false);
}

public virtual Task WritePullRequestComment(string prId, string comment)
{
return Task.FromResult(new object());
}

/// <summary>
/// <para>Pubic repo should always return true, private repo and use`s access token has access to the repo, return true</para>
/// <para>All other case return false, e.g:</para>
Expand Down
1 change: 1 addition & 0 deletions Slingshot.Api/App_Start/WebApiConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public static void Register(HttpConfiguration config)
config.Routes.MapHttpRoute("post-deployments", "api/deployments/{subscriptionId}", new { controller = "ARM", action = "Deploy" }, new { verb = new HttpMethodConstraint("POST") });
config.Routes.MapHttpRoute("get-deployments-status", "api/deployments/{subscriptionId}/rg/{resourceGroup}", new { controller = "ARM", action = "GetDeploymentStatus" }, new { verb = new HttpMethodConstraint("GET") });
config.Routes.MapHttpRoute("get-scmdeployments-status", "api/deployments/{subscriptionId}/rg/{resourceGroup}/scm", new { controller = "ARM", action = "GetScmDeploymentStatus" }, new { verb = new HttpMethodConstraint("GET") });
config.Routes.MapHttpRoute("post-deployments-notification", "api/deploymentsnotification", new { controller = "ARM", action = "DeploymentNotification" }, new { verb = new HttpMethodConstraint("POST") });

config.Routes.MapHttpRoute("get", "api/{*path}", new { controller = "ARM", action = "Get" }, new { verb = new HttpMethodConstraint("GET", "HEAD") });

Expand Down
26 changes: 24 additions & 2 deletions Slingshot.Api/Concrete/BitbucketRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -212,6 +210,30 @@ public override async Task<bool> HasAccess()
return false;
}

public override async Task WritePullRequestComment(string prId, string comment)
{
if (await this.HasScmInfo() == false)
{
throw new InvalidOperationException("User credential is required to post any comments for a Pull Requests.");
}

try
{
SourceControlInfo info = await this.GetScmInfo();
string repoToken = info.token;

using (HttpClient client = CreateHttpClient(accessToken: repoToken))
{
var repoInfoUrl = string.Format(CultureInfo.InvariantCulture, Constants.Repository.BitbucketApiPullRequestCommentsFormat, UserName, RepositoryName, prId);
await client.PostAsJsonAsync(repoInfoUrl, new { content = comment });
}
}
catch (Exception ex)
{
throw new InvalidOperationException(string.Format("Failed to create comment on Pull Request: {0}. {1}", prId, ex.Message));
}
}

/// <summary>
/// Caller need to make sure there is access token when run against private repo, otherwise error will be thrown
/// </summary>
Expand Down
32 changes: 31 additions & 1 deletion Slingshot.Api/Controllers/ARMController.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Routing;
using Microsoft.Azure.Management.Resources;
Expand All @@ -18,7 +20,6 @@
using Slingshot.Concrete;
using Slingshot.Helpers;
using Slingshot.Models;
using System.Web;

namespace Slingshot.Controllers
{
Expand Down Expand Up @@ -395,6 +396,35 @@ public async Task<HttpResponseMessage> GetTemplate(string repositoryUrl)
return response;
}

[Authorize]
[HttpPost]
public async Task DeploymentNotification(DeploymentNotificationInputs inputs)
{
string repositoryUrl = HttpUtility.UrlDecode(inputs.deployInputs.repoUrl);
string token = GetTokenFromHeader();
Repository repo = Repository.CreateRepositoryObj(repositoryUrl, Request.RequestUri.Host, token);
var queryStrings = HttpUtility.ParseQueryString(repositoryUrl);
if (queryStrings["pr"] != null)
{
// if deployment is come from a pull request, post a comment back to the pull request.
string siteUrl = inputs.siteUrl;
StringBuilder pullRequestComment = new StringBuilder();
pullRequestComment.AppendFormat(CultureInfo.InvariantCulture, "A [website]({0}) has been deployed to Azure from this pull request", siteUrl);

bool isManualIntegration = true;
if (inputs.deployInputs.parameters["isManualIntegration"] != null &&
inputs.deployInputs.parameters["isManualIntegration"]["value"] != null &&
bool.TryParse(inputs.deployInputs.parameters["isManualIntegration"]["value"].ToString(), out isManualIntegration) &&
!isManualIntegration)
{
pullRequestComment.Append(" with continuous deployment enabled");
}

pullRequestComment.AppendFormat(". {0}", siteUrl);
await repo.WritePullRequestComment(queryStrings["pr"], pullRequestComment.ToString());
}
}

private async Task<string> GenerateResourceGroupName(string token, Repository repo, SubscriptionInfo[] subscriptions)
{
if (!string.IsNullOrEmpty(repo.RepositoryName))
Expand Down
1 change: 1 addition & 0 deletions Slingshot.Api/Helpers/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class Repository
public const string BitbucketApiRepoInfoFormat = "https://api.bitbucket.org/2.0/repositories/{0}/{1}";
public const string BitbucketRawFileWebFormat = "https://bitbucket.org/{0}/{1}/raw/{2}/{3}";
public const string BitbucketApiMainBranchInfoFormat = "https://bitbucket.org/api/1.0/repositories/{0}/{1}/main-branch";
public const string BitbucketApiPullRequestCommentsFormat = "https://bitbucket.org/api/1.0/repositories/{0}/{1}/pullrequests/{2}/comments";
public const string BitbucketApiRawFile = "https://bitbucket.org/api/1.0/repositories/{0}/{1}/raw/{2}/{3}";
}

Expand Down
13 changes: 13 additions & 0 deletions Slingshot.Api/Models/DeploymentNotificationInputs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Slingshot.Models
{
public class DeploymentNotificationInputs
{
public string siteUrl { get; set; }
public DeployInputs deployInputs { get; set; }
}
}
1 change: 1 addition & 0 deletions Slingshot.Api/Slingshot.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
<Compile Include="Helpers\Constants.cs" />
<Compile Include="Helpers\Utils.cs" />
<Compile Include="Models\CreateDeploymentResponse.cs" />
<Compile Include="Models\DeploymentNotificationInputs.cs" />
<Compile Include="Models\Inputs.cs" />
<Compile Include="Models\SourceControlInfo.cs" />
<Compile Include="Models\Subscriptions.cs" />
Expand Down
11 changes: 11 additions & 0 deletions Slingshot.Api/ng/Scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,17 @@ function IsSiteLocationParam(paramName) {
if (result.data.status === 4) {
formData.deploymentSucceeded = true;
telemetry.logDeploySucceeded(formData.repositoryUrl);

// once deployment is successfully done
// make a "fire and forget" request to see if there is any post deployment action need to be done
$http({
method: "post",
url: "api/deploymentsnotification",
data: {
siteUrl: $scope.formData.siteUrl,
deployInputs: $scope.formData.deployPayload
}
});
}
else if (result.data.status === 3) {
formData.errorMesg = "Failed to acquire content from your repository.";
Expand Down

0 comments on commit d84ee24

Please sign in to comment.