Skip to content

Commit

Permalink
Merge pull request #1027 from solidify/feature/git-branch-links
Browse files Browse the repository at this point in the history
Rename 'Commit' > 'Development Link' in preparation for more general solution for development links
  • Loading branch information
Alexander-Hjelm authored Apr 18, 2024
2 parents a303469 + 6145d05 commit 4591dd6
Show file tree
Hide file tree
Showing 18 changed files with 108 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/WorkItemMigrator/JiraExport/JiraCommandLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private bool ExecuteMigration(CommandOption user, CommandOption password, Comman
AttachmentsDir = Path.Combine(migrationWorkspace, config.AttachmentsFolder),
JQL = config.Query,
UsingJiraCloud = config.UsingJiraCloud,
IncludeCommits = config.IncludeCommits,
IncludeDevelopmentLinks = config.IncludeDevelopmentLinks,
RepositoryMap = config.RepositoryMap
};

Expand Down
11 changes: 0 additions & 11 deletions src/WorkItemMigrator/JiraExport/JiraCommit.cs

This file was deleted.

26 changes: 26 additions & 0 deletions src/WorkItemMigrator/JiraExport/JiraDevelopmentLink.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;

namespace JiraExport
{
public class JiraDevelopmentLink
{
public enum DevelopmentLinkType
{
Commit,
Branch
}

public string Repository { get; private set; }
public string Id { get; private set; }
public DateTime AuthorTimestamp { get; private set; }
public DevelopmentLinkType Type { get; private set; }

public JiraDevelopmentLink(string repository, string id, DateTime authorTimestamp, DevelopmentLinkType type)
{
Repository = repository;
Id = id;
AuthorTimestamp = authorTimestamp;
Type = type;
}
}
}
28 changes: 22 additions & 6 deletions src/WorkItemMigrator/JiraExport/JiraItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,16 @@ private static List<JiraRevision> BuildRevisions(JiraItem jiraItem, IJiraProvide
listOfRevisions.AddRange(commentRevisions);

var settings = jiraProvider.GetSettings();
if (settings.IncludeCommits)
if (settings.IncludeDevelopmentLinks)
{
if (settings.RepositoryMap == null)
{
Logger.Log(LogLevel.Warning, $"IncludeCommits was 'true' in the config, but no RepositoryMap was specified in the config. " +
Logger.Log(LogLevel.Warning, $"IncludeDevelopmentLinks was 'true' in the config, but no RepositoryMap was specified in the config. " +
$"Please add a RepositoryMap in order to migrate git artifact links. Git artifacts will be skipped for now...");
}
else
{
// Get development links: commits
var commitRepositories = jiraProvider.GetCommitRepositories(jiraItem.Id);
foreach (var respository in commitRepositories)
{
Expand All @@ -122,21 +123,36 @@ private static List<JiraRevision> BuildRevisions(JiraItem jiraItem, IJiraProvide
{
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));
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 } };
var jiraDevelopmentLink = new JiraDevelopmentLink(
repositoryName,
commit.SelectToken("id").ToString(),
commitCreatedOn,
JiraDevelopmentLink.DevelopmentLinkType.Commit
);
var commitRevision = new JiraRevision(jiraItem)
{
Time = commitCreatedOn,
Author = commitAuthor,
Fields = new Dictionary<string, object>(),
DevelopmentLink = new RevisionAction<JiraDevelopmentLink>()
{
ChangeType = RevisionChangeType.Added,
Value = jiraDevelopmentLink
}
};
listOfRevisions.Add(commitRevision);
}
}
Expand Down
19 changes: 10 additions & 9 deletions src/WorkItemMigrator/JiraExport/JiraMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,18 @@ internal Dictionary<string, FieldMapping<JiraRevision>> InitializeFieldMappings(
return mappingPerWiType;
}

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

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

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

var respositoryOverride = _config
.RepositoryMap
Expand All @@ -213,13 +213,14 @@ internal WiCommit MapCommit(JiraRevision jiraRevision)
respositoryTarget = respositoryOverride;
}

var commit = new WiCommit()
var developmentLink = new WiDevelopmentLink()
{
Id = jiraCommit.Id,
Id = jiraDevelopmentLink.Id,
Repository = respositoryTarget,
Type = jiraDevelopmentLink.Type.ToString()
};

return commit;
return developmentLink;
}

internal List<WiLink> MapLinks(JiraRevision r)
Expand Down Expand Up @@ -348,7 +349,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);
var developmentLink = MapDevelopmentLink(r);

return new WiRevision()
{
Expand All @@ -360,7 +361,7 @@ internal WiRevision MapRevision(JiraRevision r)
Fields = fields,
Links = links,
AttachmentReferences = attachments.Any(),
Commit = commit
DevelopmentLink = developmentLink
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/WorkItemMigrator/JiraExport/JiraRevision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +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 RevisionAction<JiraDevelopmentLink> DevelopmentLink { get; set; }
public JiraItem ParentItem { get; private set; }
public int Index { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion src/WorkItemMigrator/JiraExport/JiraSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class JiraSettings
public string AttachmentsDir { get; set; }
public string JQL { get; set; }
public bool UsingJiraCloud { get; set; }
public bool IncludeCommits { get; set; }
public bool IncludeDevelopmentLinks { get; set; }
public RepositoryMap RepositoryMap { get; set; }

public JiraSettings(string userID, string pass, string token, string url, string project)
Expand Down
2 changes: 1 addition & 1 deletion src/WorkItemMigrator/JiraExport/jira-export.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
<Compile Include="IJiraProvider.cs" />
<Compile Include="IJiraServiceWrapper.cs" />
<Compile Include="JiraCommandLine.cs" />
<Compile Include="JiraCommit.cs" />
<Compile Include="JiraDevelopmentLink.cs" />
<Compile Include="JiraServiceWrapper.cs" />
<Compile Include="JiraMapper.cs" />
<Compile Include="JiraAttachment.cs" />
Expand Down
4 changes: 2 additions & 2 deletions src/WorkItemMigrator/Migration.Common/Config/ConfigJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ public class ConfigJson
[JsonProperty(PropertyName = "sleep-time-between-revision-import-milliseconds")]
public int SleepTimeBetweenRevisionImportMilliseconds { get; set; } = 0;

[JsonProperty(PropertyName = "include-commits")]
public bool IncludeCommits { get; set; } = false;
[JsonProperty(PropertyName = "include-development-links")]
public bool IncludeDevelopmentLinks { get; set; } = false;

[JsonProperty(PropertyName = "include-jira-css-styles")]
public bool IncludeJiraCssStyles { get; set; } = false;
Expand Down
3 changes: 2 additions & 1 deletion src/WorkItemMigrator/Migration.WIContract/WiCommit.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
namespace Migration.WIContract
{
public class WiCommit
public class WiDevelopmentLink
{
public string Id { get; set; }
public string Repository { get; set; }
public string Type { get; set; }

public override string ToString()
{
Expand Down
2 changes: 1 addition & 1 deletion src/WorkItemMigrator/Migration.WIContract/WiRevision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +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; }
public WiDevelopmentLink DevelopmentLink { get; set; }

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

// rev with a commit won't have meaningful information, skip saving fields
if (rev.Commit != null)
// rev with a development link won't have meaningful information, skip saving fields
if (rev.DevelopmentLink != null)
{
if (settings.IncludeCommits)
if (settings.IncludeDevelopmentLinks)
{
_witClientUtils.SaveWorkItemArtifacts(rev, wi, settings);
}
Expand Down
2 changes: 1 addition & 1 deletion src/WorkItemMigrator/WorkItemImport/ImportCommandLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private bool ExecuteMigration(CommandOption token, CommandOption url, CommandOpt
IgnoreFailedLinks = config.IgnoreFailedLinks,
ProcessTemplate = config.ProcessTemplate,
IncludeLinkComments = config.IncludeLinkComments,
IncludeCommits = config.IncludeCommits,
IncludeDevelopmentLinks = config.IncludeDevelopmentLinks,
FieldMap = config.FieldMap,
SuppressNotifications = config.SuppressNotifications
};
Expand Down
2 changes: 1 addition & 1 deletion src/WorkItemMigrator/WorkItemImport/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ 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; }
public bool IncludeDevelopmentLinks { get; internal set; }
public FieldMap FieldMap { get; internal set; }
public bool SuppressNotifications { get; internal set; }
}
Expand Down
25 changes: 21 additions & 4 deletions src/WorkItemMigrator/WorkItemImport/WitClient/JsonPatchDocUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.VisualStudio.Services.WebApi.Patch;
using Microsoft.VisualStudio.Services.WebApi.Patch.Json;
using System;
using System.Web;

namespace WorkItemImport.WitClient
{
Expand Down Expand Up @@ -33,11 +34,17 @@ public static JsonPatchOperation CreateJsonFieldPatchOp(Operation op, string key
};
}

public static JsonPatchOperation CreateJsonArtifactLinkPatchOp(Operation op, string projectId, string repositoryId, string commitId)
public static JsonPatchOperation CreateJsonArtifactLinkPatchOp(
Operation op,
string projectId,
string repositoryId,
string developmentLinkId,
string type
)
{
if (string.IsNullOrEmpty(commitId))
if (string.IsNullOrEmpty(developmentLinkId))
{
throw new ArgumentException(nameof(commitId));
throw new ArgumentException(nameof(developmentLinkId));
}

if (string.IsNullOrEmpty(projectId))
Expand All @@ -50,14 +57,24 @@ public static JsonPatchOperation CreateJsonArtifactLinkPatchOp(Operation op, str
throw new ArgumentException(nameof(repositoryId));
}

string url;
if (type == "Commit")
{
url = $"vstfs:///Git/Commit/{projectId}%2F{repositoryId}%2F{developmentLinkId}";
}
else
{
throw new ArgumentException(nameof(type));
}

return new JsonPatchOperation()
{
Operation = op,
Path = "/relations/-",
Value = new PatchOperationValue
{
Rel = "ArtifactLink",
Url = $"vstfs:///Git/Commit/{projectId}%2F{repositoryId}%2F{commitId}",
Url = url,
Attributes = new Attributes
{
Name = "Fixed in Commit"
Expand Down
12 changes: 9 additions & 3 deletions src/WorkItemMigrator/WorkItemImport/WitClient/WitClientUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -687,17 +687,23 @@ public void SaveWorkItemArtifacts(WiRevision rev, WorkItem wi, Settings settings
throw new ArgumentException(nameof(wi));
}

if (rev.Commit == null)
if (rev.DevelopmentLink == null)
{
return;
}

Guid projectId = _witClientWrapper.GetProject(settings.Project).Id;
Guid repositoryId = _witClientWrapper.GetRepository(settings.Project, rev.Commit.Repository).Id;
Guid repositoryId = _witClientWrapper.GetRepository(settings.Project, rev.DevelopmentLink.Repository).Id;

var patchDocument = new JsonPatchDocument
{
JsonPatchDocUtils.CreateJsonArtifactLinkPatchOp(Operation.Add, projectId.ToString(), repositoryId.ToString(), rev.Commit.Id),
JsonPatchDocUtils.CreateJsonArtifactLinkPatchOp(
Operation.Add,
projectId.ToString(),
repositoryId.ToString(),
rev.DevelopmentLink.Id,
rev.DevelopmentLink.Type
),
JsonPatchDocUtils.CreateJsonFieldPatchOp(Operation.Add, WiFieldReference.ChangedDate, rev.Time),
JsonPatchDocUtils.CreateJsonFieldPatchOp(Operation.Add, WiFieldReference.ChangedBy, rev.Author)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void When_calling_create_json_field_patch_op_with_empty_args_Then_an_exce
public void When_calling_create_json_artifact_link_field_patch_op_with_empty_args_Then_an_exception_is_thrown()
{
Assert.That(
() => JsonPatchDocUtils.CreateJsonArtifactLinkPatchOp(Operation.Add, null, null, null),
() => JsonPatchDocUtils.CreateJsonArtifactLinkPatchOp(Operation.Add, null, null, null, null),
Throws.InstanceOf<ArgumentException>());
}

Expand All @@ -61,7 +61,7 @@ public void When_calling_create_json_artifact_link_field_patch_op_Then_a_correct
string projectId = Guid.NewGuid().ToString();
string repositoryId = Guid.NewGuid().ToString();
string commitId = Guid.NewGuid().ToString();
JsonPatchOperation jsonPatchOp = JsonPatchDocUtils.CreateJsonArtifactLinkPatchOp(Operation.Add, projectId, repositoryId, commitId);
JsonPatchOperation jsonPatchOp = JsonPatchDocUtils.CreateJsonArtifactLinkPatchOp(Operation.Add, projectId, repositoryId, commitId, "Commit");
PatchOperationValue artifactLink = jsonPatchOp.Value as PatchOperationValue;

Assert.Multiple(() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1176,10 +1176,11 @@ public void When_calling_save_workitem_artifacts_with_populated_workitem_Then_wo

WiRevision revision = new WiRevision
{
Commit = new WiCommit
DevelopmentLink = new WiDevelopmentLink
{
Repository = "repository",
Id = "1234567890"
Id = "1234567890",
Type = "Commit"
}
};

Expand All @@ -1200,7 +1201,7 @@ public void When_calling_save_workitem_artifacts_with_populated_workitem_Then_wo
{
Assert.That(updatedWI.Relations.First().Rel, Is.EqualTo("ArtifactLink"));
Assert.That(updatedWI.Relations.First().Url, Is.EqualTo($"vstfs:///Git/Commit/" +
$"{witClientWrapper.projectId}%2F{witClientWrapper.repositoryId}%2F{revision.Commit.Id}"));
$"{witClientWrapper.projectId}%2F{witClientWrapper.repositoryId}%2F{revision.DevelopmentLink.Id}"));
});
}

Expand Down

0 comments on commit 4591dd6

Please sign in to comment.