Skip to content
This repository was archived by the owner on May 10, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions source/Server.Tests/Server.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="Octokit" Version="0.32.0" />
<PackageReference Include="TeamCity.VSTest.TestAdapter" Version="1.0.15" />
<PackageReference Include="Octopus.Diagnostics" Version="1.3.5" />
<PackageReference Include="Octopus.Diagnostics" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Octopus.Data" Version="5.2.0" />
<PackageReference Include="Octopus.Data" Version="5.3.0" />
<ProjectReference Include="..\Server\Server.csproj" />
</ItemGroup>
</Project>
6 changes: 3 additions & 3 deletions source/Server.Tests/WorkItemLinkMapperScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public string GetWorkItemDescription(string linkData, string releaseNotePrefix,
Comments = new [] {new JiraIssueComment { Body = releaseNote }}
});

return new WorkItemLinkMapper(store, new CommentParser(), jiraClientLazy, Substitute.For<ILog>()).GetReleaseNote(jiraIssue, releaseNotePrefix);
return new WorkItemLinkMapper(store, new CommentParser(), jiraClientLazy, Substitute.For<ISystemLog>()).GetReleaseNote(jiraIssue, releaseNotePrefix);
}

[Test]
Expand All @@ -71,7 +71,7 @@ public void DuplicatesGetIgnored()
Comments = new [] {new JiraIssueComment { Body = string.Empty }}
});

var mapper = new WorkItemLinkMapper(store, new CommentParser(), jiraClientLazy, Substitute.For<ILog>());
var mapper = new WorkItemLinkMapper(store, new CommentParser(), jiraClientLazy, Substitute.For<ISystemLog>());

var workItems = mapper.Map(new OctopusBuildInformation
{
Expand Down Expand Up @@ -101,7 +101,7 @@ public void SourceGetsSet()
Comments = new [] {new JiraIssueComment { Body = string.Empty }}
});

var mapper = new WorkItemLinkMapper(store, new CommentParser(), jiraClientLazy, Substitute.For<ILog>());
var mapper = new WorkItemLinkMapper(store, new CommentParser(), jiraClientLazy, Substitute.For<ISystemLog>());

var workItems = mapper.Map(new OctopusBuildInformation
{
Expand Down
30 changes: 14 additions & 16 deletions source/Server/Actions/JiraServiceDeskActionHandler.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#nullable enable
using Octopus.Diagnostics;
using Octopus.Server.Extensibility.HostServices.Diagnostics;
using Octopus.Server.Extensibility.HostServices.Domain.Projects;
using Octopus.Server.Extensibility.HostServices.Model.Projects;
using Octopus.Server.Extensibility.JiraIntegration.Deployments;
using Sashimi.Server.Contracts;
using Sashimi.Server.Contracts.ActionHandlers;
Expand All @@ -20,37 +19,36 @@ class JiraServiceDeskActionHandler : IActionHandler
public ActionHandlerCategory[] Categories => new[] { ActionHandlerCategory.BuiltInStep, ActionHandlerCategory.Atlassian };

readonly JiraDeployment jiraDeployment;
readonly ILog log;
private readonly IDeploymentStore deploymentStore;

public JiraServiceDeskActionHandler(
ILog log,
IDeploymentStore deploymentStore,
JiraDeployment jiraDeployment)
{
this.log = log;
this.jiraDeployment = jiraDeployment;
this.deploymentStore = deploymentStore;
}
public IActionHandlerResult Execute(IActionHandlerContext context)

public IActionHandlerResult Execute(IActionHandlerContext context, ITaskLog taskLog)
{
string deploymentId = context.Variables.Get(KnownVariables.Deployment.Id, "");
IDeployment deployment = deploymentStore.Get(deploymentId);

string jiraServiceDeskChangeRequestId = context.Variables.Get("Octopus.Action.JiraIntegration.ServiceDesk.ServiceId");

var deploymentId = context.Variables.Get(KnownVariables.Deployment.Id, "");
var deployment = deploymentStore.Get(deploymentId);

var jiraServiceDeskChangeRequestId = context.Variables.Get("Octopus.Action.JiraIntegration.ServiceDesk.ServiceId");
if (string.IsNullOrWhiteSpace(jiraServiceDeskChangeRequestId))
throw new ControlledActionFailedException("ServiceId is not set");

try
{
jiraDeployment.PublishToJira("in_progress", deployment, new JiraServiceDeskApiDeployment(jiraServiceDeskChangeRequestId));
jiraDeployment.PublishToJira("in_progress", deployment, new JiraServiceDeskApiDeployment(jiraServiceDeskChangeRequestId), taskLog);
}
catch (JiraDeploymentException exception)
{
throw new ControlledActionFailedException(exception.Message);
}

return ActionHandlerResult.FromSuccess();
}

}
}
8 changes: 4 additions & 4 deletions source/Server/Configuration/DatabaseInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ namespace Octopus.Server.Extensibility.JiraIntegration.Configuration
{
class DatabaseInitializer : ExecuteWhenDatabaseInitializes
{
readonly ILog log;
readonly ISystemLog systemLog;
readonly IConfigurationStore configurationStore;

public DatabaseInitializer(ILog log, IConfigurationStore configurationStore)
public DatabaseInitializer(ISystemLog systemLog, IConfigurationStore configurationStore)
{
this.log = log;
this.systemLog = systemLog;
this.configurationStore = configurationStore;
}

Expand All @@ -30,7 +30,7 @@ public override void Execute()
return;
}

log.Info("Initializing Jira integration settings");
systemLog.Info("Initializing Jira integration settings");
doc = new JiraConfiguration();
configurationStore.Create(doc);
}
Expand Down
12 changes: 6 additions & 6 deletions source/Server/Configuration/JiraConfigureCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ namespace Octopus.Server.Extensibility.JiraIntegration.Configuration
{
class JiraConfigureCommands : IContributeToConfigureCommand
{
readonly ILog log;
readonly ISystemLog systemLog;
readonly Lazy<IJiraConfigurationStore> jiraConfiguration;

public JiraConfigureCommands(
ILog log,
ISystemLog systemLog,
Lazy<IJiraConfigurationStore> jiraConfiguration)
{
this.log = log;
this.systemLog = systemLog;
this.jiraConfiguration = jiraConfiguration;
}

Expand All @@ -24,17 +24,17 @@ public IEnumerable<ConfigureCommandOption> GetOptions()
{
var isEnabled = bool.Parse(v);
jiraConfiguration.Value.SetIsEnabled(isEnabled);
log.Info($"Jira Integration IsEnabled set to: {isEnabled}");
systemLog.Info($"Jira Integration IsEnabled set to: {isEnabled}");
});
yield return new ConfigureCommandOption("jiraBaseUrl=", JiraConfigurationResource.JiraBaseUrlDescription, v =>
{
jiraConfiguration.Value.SetBaseUrl(v);
log.Info($"Jira Integration base Url set to: {v}");
systemLog.Info($"Jira Integration base Url set to: {v}");
});
yield return new ConfigureCommandOption("jiraConnectAppUrl=", "Set the URL for the Jira Connect App", v =>
{
jiraConfiguration.Value.SetConnectAppUrl(v);
log.Info($"Jira Integration ConnectAppUrl set to: {v}");
systemLog.Info($"Jira Integration ConnectAppUrl set to: {v}");
}, hide: true);
}
}
Expand Down
2 changes: 1 addition & 1 deletion source/Server/Deployments/DeploymentObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void Handle(DeploymentEvent domainEvent)
pm.WorkItems.All(wi => wi.Source != JiraConfigurationStore.CommentParser))))
return;

jiraDeployment.PublishToJira(StateFromEventType(domainEvent.EventType), domainEvent.Deployment, new JiraIssueTrackerApiDeployment());
jiraDeployment.PublishToJira(StateFromEventType(domainEvent.EventType), domainEvent.Deployment, new JiraIssueTrackerApiDeployment(), domainEvent.TaskLog);
}

string StateFromEventType(DeploymentEventType eventType)
Expand Down
67 changes: 32 additions & 35 deletions source/Server/Deployments/JiraDeployment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
using Octopus.Diagnostics;
using Octopus.Server.Extensibility.Extensions.Infrastructure.Web.Api;
using Octopus.Server.Extensibility.HostServices.Configuration;
using Octopus.Server.Extensibility.HostServices.Diagnostics;
using Octopus.Server.Extensibility.HostServices.Domain.Environments;
using Octopus.Server.Extensibility.HostServices.Domain.Projects;
using Octopus.Server.Extensibility.HostServices.Domain.ServerTasks;
Expand All @@ -21,7 +21,6 @@ namespace Octopus.Server.Extensibility.JiraIntegration.Deployments
{
class JiraDeployment
{
private readonly ILogWithContext log;
private readonly IJiraConfigurationStore store;
private readonly JiraConnectAppClient connectAppClient;
private readonly IInstallationIdProvider installationIdProvider;
Expand All @@ -36,9 +35,8 @@ class JiraDeployment

private DeploymentEnvironmentSettingsMetadataProvider.JiraDeploymentEnvironmentSettings? environmentSettings;
private IDeploymentEnvironment? deploymentEnvironment;

public JiraDeployment(
ILogWithContext log,
IJiraConfigurationStore store,
JiraConnectAppClient connectAppClient,
IInstallationIdProvider installationIdProvider,
Expand All @@ -52,7 +50,6 @@ public JiraDeployment(
IOctopusHttpClientFactory octopusHttpClientFactory
)
{
this.log = log;
this.store = store;
this.connectAppClient = connectAppClient;
this.installationIdProvider = installationIdProvider;
Expand All @@ -72,7 +69,8 @@ bool JiraIntegrationUnavailable(IDeployment deployment)
store.GetJiraInstanceType() == JiraInstanceType.Server;
}

public void PublishToJira(string eventType, IDeployment deployment, IJiraApiDeployment jiraApiDeployment)
public void PublishToJira(string eventType, IDeployment deployment, IJiraApiDeployment jiraApiDeployment,
ITaskLog taskLog)
{
if (JiraIntegrationUnavailable(deployment))
{
Expand All @@ -84,47 +82,46 @@ public void PublishToJira(string eventType, IDeployment deployment, IJiraApiDepl

if (string.IsNullOrWhiteSpace(serverUri))
{
log.Warn("To use Jira integration you must have the Octopus server's external url configured (see the Configuration/Nodes page)");
taskLog.Warn("To use Jira integration you must have the Octopus server's external url configured (see the Configuration/Nodes page)");
return;
}

if (string.IsNullOrWhiteSpace(store.GetConnectAppUrl()) ||
string.IsNullOrWhiteSpace(store.GetConnectAppPassword()?.Value))
{
log.Warn("Jira integration is enabled but settings are incomplete, ignoring deployment events");
taskLog.Warn("Jira integration is enabled but settings are incomplete, ignoring deployment events");
return;
}

using (log.OpenBlock($"Sending Jira state update - {eventType}"))

var taskLogBlock = taskLog.CreateBlock($"Sending Jira state update - {eventType}");

// get token from connect App
var token = connectAppClient.GetAuthTokenFromConnectApp(taskLogBlock);
if (token is null)
{
// get token from connect App
var token = connectAppClient.GetAuthTokenFromConnectApp();
if (token is null)
{
log.Finish();
return;
}

deploymentEnvironment = deploymentEnvironmentStore.Get(deployment.EnvironmentId);
environmentSettings =
deploymentEnvironmentSettingsProvider
.GetSettings<DeploymentEnvironmentSettingsMetadataProvider.JiraDeploymentEnvironmentSettings>(
JiraConfigurationStore.SingletonId, deployment.EnvironmentId) ?? new DeploymentEnvironmentSettingsMetadataProvider.JiraDeploymentEnvironmentSettings();
taskLogBlock.Finish();
return;
}

var data = PrepareOctopusJiraPayload(eventType, serverUri, deployment, jiraApiDeployment);
deploymentEnvironment = deploymentEnvironmentStore.Get(deployment.EnvironmentId);
environmentSettings =
deploymentEnvironmentSettingsProvider
.GetSettings<DeploymentEnvironmentSettingsMetadataProvider.JiraDeploymentEnvironmentSettings>(
JiraConfigurationStore.SingletonId, deployment.EnvironmentId) ?? new DeploymentEnvironmentSettingsMetadataProvider.JiraDeploymentEnvironmentSettings();

// Push data to Jira
SendToJira(token, data, deployment);
var data = PrepareOctopusJiraPayload(eventType, serverUri, deployment, jiraApiDeployment);

log.Finish();
}
// Push data to Jira
SendToJira(token, data, deployment, taskLogBlock);

taskLogBlock.Finish();
}

OctopusJiraPayloadData PrepareOctopusJiraPayload(string eventType, string serverUri, IDeployment deployment, IJiraApiDeployment jiraApiDeployment)
{

var project = projectStore.Get(deployment.ProjectId);

var release = releaseStore.Get(deployment.ReleaseId);
var serverTask = serverTaskStore.Get(deployment.TaskId);

Expand Down Expand Up @@ -172,10 +169,10 @@ OctopusJiraPayloadData PrepareOctopusJiraPayload(string eventType, string server
}
};
}
void SendToJira(string token, OctopusJiraPayloadData data, IDeployment deployment)

void SendToJira(string token, OctopusJiraPayloadData data, IDeployment deployment, ITaskLog taskLogBlock)
{
log.Info($"Sending deployment data to Jira for deployment {deployment.Id}, to {deploymentEnvironment?.Name}({environmentSettings?.JiraEnvironmentType.ToString()}) with state {data.DeploymentsInfo.Deployments[0].State} for issue keys {string.Join(",", data.DeploymentsInfo.Deployments[0].Associations[0].Values)}");
taskLogBlock.Info($"Sending deployment data to Jira for deployment {deployment.Id}, to {deploymentEnvironment?.Name}({environmentSettings?.JiraEnvironmentType.ToString()}) with state {data.DeploymentsInfo.Deployments[0].State} for issue keys {string.Join(",", data.DeploymentsInfo.Deployments[0].Associations[0].Values)}");

var json = JsonConvert.SerializeObject(data);

Expand All @@ -188,7 +185,7 @@ void SendToJira(string token, OctopusJiraPayloadData data, IDeployment deploymen
var result = client.PostAsync($"{store.GetConnectAppUrl()}/relay/bulk", httpContent).GetAwaiter().GetResult();

if (!result.IsSuccessStatusCode)
log.ErrorFormat("Unable to publish data to Jira. Response code: {0}, Message: {1}", result.StatusCode, result.Content.ReadAsStringAsync().GetAwaiter().GetResult());
taskLogBlock.ErrorFormat("Unable to publish data to Jira. Response code: {0}, Message: {1}", result.StatusCode, result.Content.ReadAsStringAsync().GetAwaiter().GetResult());
}
}
}
Expand Down
11 changes: 4 additions & 7 deletions source/Server/Integration/JiraConnectAppClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,28 @@ namespace Octopus.Server.Extensibility.JiraIntegration.Integration
{
class JiraConnectAppClient
{
private readonly ILogWithContext log;
private readonly IInstallationIdProvider installationIdProvider;
private readonly IJiraConfigurationStore configurationStore;
private readonly IOctopusHttpClientFactory octopusHttpClientFactory;

public JiraConnectAppClient(
ILogWithContext log,
IInstallationIdProvider installationIdProvider,
IJiraConfigurationStore configurationStore,
IOctopusHttpClientFactory octopusHttpClientFactory)
{
this.log = log;
this.installationIdProvider = installationIdProvider;
this.configurationStore = configurationStore;
this.octopusHttpClientFactory = octopusHttpClientFactory;
}

public string? GetAuthTokenFromConnectApp()
public string? GetAuthTokenFromConnectApp(ILog log)
{
var username = installationIdProvider.GetInstallationId().ToString();
var password = configurationStore.GetConnectAppPassword();
return GetAuthTokenFromConnectApp(username, password?.Value);
return GetAuthTokenFromConnectApp(username, password?.Value, log);
}
public string? GetAuthTokenFromConnectApp(string username, string? password)

public string? GetAuthTokenFromConnectApp(string username, string? password, ILog log)
{
using (var client = octopusHttpClientFactory.CreateClient())
{
Expand Down
Loading