Skip to content

Commit

Permalink
Merge pull request #830 from solidify/feature/git-artifact-linking-su…
Browse files Browse the repository at this point in the history
…pport

Feature/git artifact linking support
  • Loading branch information
Alexander-Hjelm authored Aug 21, 2023
2 parents 8cad1d4 + dca8f7f commit c661636
Show file tree
Hide file tree
Showing 27 changed files with 348 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/WorkItemMigrator/JiraExport/IJiraProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ public interface IJiraProvider
string GetCustomId(string propertyName);
Task<List<RevisionAction<JiraAttachment>>> DownloadAttachments(JiraRevision rev);

IEnumerable<JObject> GetCommitRepositories(string issueId);
}
}
4 changes: 3 additions & 1 deletion src/WorkItemMigrator/JiraExport/JiraCommandLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ private void ExecuteMigration(CommandOption user, CommandOption password, Comman
UserMappingFile = config.UserMappingFile != null ? Path.Combine(migrationWorkspace, config.UserMappingFile) : string.Empty,
AttachmentsDir = Path.Combine(migrationWorkspace, config.AttachmentsFolder),
JQL = config.Query,
UsingJiraCloud = config.UsingJiraCloud
UsingJiraCloud = config.UsingJiraCloud,
IncludeCommits = config.IncludeCommits,
RepositoryMap = config.RepositoryMap
};

var jiraServiceWrapper = new JiraServiceWrapper(jiraSettings);
Expand Down
11 changes: 11 additions & 0 deletions src/WorkItemMigrator/JiraExport/JiraCommit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace JiraExport
{
public class JiraCommit
{
public string Repository { get; set; }
public string Id { get; set; }
public DateTime AuthorTimestamp { get; set; }
}
}
33 changes: 33 additions & 0 deletions src/WorkItemMigrator/JiraExport/JiraItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,38 @@ private static List<JiraRevision> BuildRevisions(JiraItem jiraItem, IJiraProvide

List<JiraRevision> commentRevisions = BuildCommentRevisions(jiraItem, jiraProvider);
listOfRevisions.AddRange(commentRevisions);

var settings = jiraProvider.GetSettings();
if (settings.IncludeCommits)
{
var commitRepositories = jiraProvider.GetCommitRepositories(jiraItem.Id);
foreach (var respository in commitRepositories)
{
var commits = respository.SelectTokens(".commits[*]");
foreach (JToken commit in commits)
{
var commitCreatedOn = commit.ExValue<DateTime>("$.authorTimestamp");
var commitAuthor = GetAuthor(commit as JObject);
var jiraCommit = commit.ToObject<JiraCommit>();
var repositoryName = respository.SelectToken("$.name").Value<string>();
if (string.IsNullOrEmpty(repositoryName))
{
continue;
}

var hasRespositoryTarget = settings.RepositoryMap.Repositories.Exists(r => r.Source == repositoryName && !string.IsNullOrEmpty(r.Target));
if (!hasRespositoryTarget)
{
continue;
}

jiraCommit.Repository = repositoryName;
var commitRevision = new JiraRevision(jiraItem) { Time = commitCreatedOn, Author = commitAuthor, Fields = new Dictionary<string, object>(), Commit = new RevisionAction<JiraCommit>() { ChangeType = RevisionChangeType.Added, Value = jiraCommit } };
listOfRevisions.Add(commitRevision);
}
}
}

listOfRevisions.Sort();

foreach (var revAndI in listOfRevisions.Select((r, i) => (r, i)))
Expand Down Expand Up @@ -524,6 +556,7 @@ private static string[] ParseCustomField(string fieldName, JToken value, IJiraPr

public string Key { get { return RemoteIssue.ExValue<string>("$.key"); } }
public string Type { get { return RemoteIssue.ExValue<string>("$.fields.issuetype.name")?.Trim(); } }
public string Id { get { return RemoteIssue.ExValue<string>("$.id"); } }
public string EpicParent
{
get
Expand Down
39 changes: 37 additions & 2 deletions src/WorkItemMigrator/JiraExport/JiraMapper.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

using Common.Config;

using Migration.Common;
Expand Down Expand Up @@ -55,6 +54,7 @@ internal WiItem Map(JiraItem issue)
return null;
}
}

return wiItem;
}

Expand Down Expand Up @@ -180,6 +180,39 @@ internal Dictionary<string, FieldMapping<JiraRevision>> InitializeFieldMappings(
return mappingPerWiType;
}

internal WiCommit MapCommit(JiraRevision jiraRevision)
{
if (jiraRevision == null)
throw new ArgumentNullException(nameof(jiraRevision));

if (jiraRevision.Commit == null)
{
return null;
}

var jiraCommit = jiraRevision.Commit.Value;
var respositoryTarget = jiraCommit.Repository;

var respositoryOverride = _config
.RepositoryMap
.Repositories?
.Find(r => r.Source == respositoryTarget)?
.Target;

if (!string.IsNullOrEmpty(respositoryOverride))
{
respositoryTarget = respositoryOverride;
}

var commit = new WiCommit()
{
Id = jiraCommit.Id,
Repository = respositoryTarget,
};

return commit;
}

internal List<WiLink> MapLinks(JiraRevision r)
{
if (r == null)
Expand Down Expand Up @@ -303,6 +336,7 @@ internal WiRevision MapRevision(JiraRevision r)
List<WiAttachment> attachments = MapAttachments(r);
List<WiField> fields = MapFields(r);
List<WiLink> links = MapLinks(r);
var commit = MapCommit(r);

return new WiRevision()
{
Expand All @@ -313,7 +347,8 @@ internal WiRevision MapRevision(JiraRevision r)
Attachments = attachments,
Fields = fields,
Links = links,
AttachmentReferences = attachments.Any()
AttachmentReferences = attachments.Any(),
Commit = commit
};
}

Expand Down
6 changes: 6 additions & 0 deletions src/WorkItemMigrator/JiraExport/JiraProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -441,5 +441,11 @@ private string GetItemFromFieldCache(string propertyName, ILookup<string, string
}
return customId;
}

public IEnumerable<JObject> GetCommitRepositories(string issueId)
{
var response = (JObject)_jiraServiceWrapper.RestClient.ExecuteRequestAsync(Method.GET, $"/rest/dev-status/latest/issue/detail?issueId={issueId}&applicationType=stash&dataType=repository").Result;
return response.SelectTokens("$.detail[*].repositories[*]").Cast<JObject>();
}
}
}
1 change: 1 addition & 0 deletions src/WorkItemMigrator/JiraExport/JiraRevision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class JiraRevision : ISourceRevision, IComparable<JiraRevision>
public List<RevisionAction<JiraLink>> LinkActions { get; set; }

public List<RevisionAction<JiraAttachment>> AttachmentActions { get; set; }
public RevisionAction<JiraCommit> Commit { get; set; }
public JiraItem ParentItem { get; private set; }
public int Index { get; set; }

Expand Down
4 changes: 4 additions & 0 deletions src/WorkItemMigrator/JiraExport/JiraSettings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

using Migration.Common.Config;

namespace JiraExport
{
public class JiraSettings
Expand All @@ -14,6 +16,8 @@ public class JiraSettings
public string AttachmentsDir { get; set; }
public string JQL { get; set; }
public bool UsingJiraCloud { get; set; }
public bool IncludeCommits { get; set; }
public RepositoryMap RepositoryMap { get; set; }

public JiraSettings(string userID, string pass, string url, string project)
{
Expand Down
1 change: 1 addition & 0 deletions src/WorkItemMigrator/JiraExport/jira-export.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
<Compile Include="IJiraProvider.cs" />
<Compile Include="IJiraServiceWrapper.cs" />
<Compile Include="JiraCommandLine.cs" />
<Compile Include="JiraCommit.cs" />
<Compile Include="JiraServiceWrapper.cs" />
<Compile Include="JiraMapper.cs" />
<Compile Include="JiraAttachment.cs" />
Expand Down
8 changes: 7 additions & 1 deletion src/WorkItemMigrator/Migration.Common/Config/ConfigJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public class ConfigJson
[JsonProperty(PropertyName = "process-template")]
public string ProcessTemplate { get; set; } = "Scrum";

[JsonProperty(PropertyName = "repository-map")]
public RepositoryMap RepositoryMap { get; set; }

[JsonProperty(PropertyName = "type-map", Required = Required.Always)]
public TypeMap TypeMap { get; set; }

Expand All @@ -63,13 +66,16 @@ public class ConfigJson
[JsonProperty(PropertyName = "rendered-fields")]
public string[] RenderedFields { get; set; } = new string[] { "description", "comment" };


[JsonProperty(PropertyName = "using-jira-cloud")]
public bool UsingJiraCloud { get; set; } = true;

[JsonProperty(PropertyName = "include-link-comments")]
public bool IncludeLinkComments { get; set; } = true;

[JsonProperty(PropertyName = "sleep-time-between-revision-import-milliseconds")]
public int SleepTimeBetweenRevisionImportMilliseconds { get; set; } = 0;

[JsonProperty(PropertyName = "include-commits")]
public bool IncludeCommits { get; set; } = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ public ConfigJson DeserializeText(string input)
}
result.TypeMap.Types.AddRange(types);

if(obj.ContainsKey("repository-map"))
{
var repositories = obj.SelectToken("repository-map.repository").Select(li => li.ToObject<Repository>()).ToList();
if (result.RepositoryMap.Repositories == null)
{
result.RepositoryMap.Repositories = new List<Repository>();
}
result.RepositoryMap.Repositories.AddRange(repositories);
}
}
catch (Exception)
{
Expand Down
13 changes: 13 additions & 0 deletions src/WorkItemMigrator/Migration.Common/Config/Repository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Newtonsoft.Json;

namespace Migration.Common.Config
{
public class Repository
{
[JsonProperty("target", Required = Required.Always)]
public string Target { get; set; }

[JsonProperty("source", Required = Required.Always)]
public string Source { get; set; }
}
}
9 changes: 9 additions & 0 deletions src/WorkItemMigrator/Migration.Common/Config/RepositoryMap.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;

namespace Migration.Common.Config
{
public class RepositoryMap
{
public List<Repository> Repositories { get; set; }
}
}
2 changes: 2 additions & 0 deletions src/WorkItemMigrator/Migration.Common/Migration.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
<Compile Include="Config\Link.cs" />
<Compile Include="Config\LinkMap.cs" />
<Compile Include="Config\Mapping.cs" />
<Compile Include="Config\RepositoryMap.cs" />
<Compile Include="Config\Repository.cs" />
<Compile Include="Config\Value.cs" />
<Compile Include="Config\Type.cs" />
<Compile Include="Config\TypeMap.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<ItemGroup>
<Compile Include="WiAttachment.cs" />
<Compile Include="WiField.cs" />
<Compile Include="WiCommit.cs" />
<Compile Include="WiItem.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WiItemProvider.cs" />
Expand Down
13 changes: 13 additions & 0 deletions src/WorkItemMigrator/Migration.WIContract/WiCommit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Migration.WIContract
{
public class WiCommit
{
public string Id { get; set; }
public string Repository { get; set; }

public override string ToString()
{
return $"[{Repository}]{Id}";
}
}
}
1 change: 1 addition & 0 deletions src/WorkItemMigrator/Migration.WIContract/WiRevision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public WiRevision()
public List<WiField> Fields { get; set; }
public List<WiLink> Links { get; set; }
public List<WiAttachment> Attachments { get; set; }
public WiCommit Commit { get; set; }

[DefaultValue(false)]
public bool AttachmentReferences { get; set; } = false;
Expand Down
14 changes: 12 additions & 2 deletions src/WorkItemMigrator/WorkItemImport/Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,18 @@ public bool ImportRevision(WiRevision rev, WorkItem wi, Settings settings)
}
}

_witClientUtils.SaveWorkItemFields(wi);
// rev with a commit won't have meaningful information, skip saving fields
if (rev.Commit != null)
{
if (settings.IncludeCommits)
{
_witClientUtils.SaveWorkItemArtifacts(rev, wi, settings);
}
}
else
{
_witClientUtils.SaveWorkItemFields(wi);
}

if (wi.Id.HasValue)
{
Expand Down Expand Up @@ -579,7 +590,6 @@ private bool ApplyAndSaveLinks(WiRevision rev, WorkItem wi, bool addLinkComments

return success;
}

#endregion
}
}
3 changes: 2 additions & 1 deletion src/WorkItemMigrator/WorkItemImport/ImportCommandLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ private void ExecuteMigration(CommandOption token, CommandOption url, CommandOpt
BaseIterationPath = config.BaseIterationPath ?? string.Empty, // Root iteration path that will prefix each iteration
IgnoreFailedLinks = config.IgnoreFailedLinks,
ProcessTemplate = config.ProcessTemplate,
IncludeLinkComments = config.IncludeLinkComments
IncludeLinkComments = config.IncludeLinkComments,
IncludeCommits = config.IncludeCommits
};

// initialize Azure DevOps/TFS connection. Creates/fetches project, fills area and iteration caches.
Expand Down
1 change: 1 addition & 0 deletions src/WorkItemMigrator/WorkItemImport/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public Settings(string account, string project, string pat)
public bool IgnoreFailedLinks { get; internal set; }
public string ProcessTemplate { get; internal set; }
public bool IncludeLinkComments { get; internal set; }
public bool IncludeCommits { get; internal set; }
}
}
Loading

0 comments on commit c661636

Please sign in to comment.