From 545984309c4ccddf9d29b8d46850abbb42eae5ab Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 4 Sep 2026 14:57:44 -0400 Subject: [PATCH 1/3] Support tags with replaceable text Currently small in scope, this adds a way to map a label to a tag, including some replacement text. For now, this handles monthly highlights. Update the config with new label -> tag mapping for spotlight projects and monthly highlights. So we don't have to change the config every month, this maps a general "Highlight" label to a "Highlight-" tag in Azure DevOps. --- .../GitHubObjects/StoryPointSize.cs | 17 +++++++++++++++++ .../BuildExtendedPropertiesTests.cs | 13 ++++++++----- .../Quest2GitHub/Models/WorkItemProperties.cs | 3 ++- quest-config.json | 18 ++++++++++++++++-- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/DotNet.DocsTools/GitHubObjects/StoryPointSize.cs b/DotNet.DocsTools/GitHubObjects/StoryPointSize.cs index eaf20e69..50f063e7 100644 --- a/DotNet.DocsTools/GitHubObjects/StoryPointSize.cs +++ b/DotNet.DocsTools/GitHubObjects/StoryPointSize.cs @@ -98,6 +98,23 @@ private StoryPointSize(int CalendarYear, string Month, string Size, int? Priorit public string Size { get; } public int? Priority { get; } + public string FullMonthText => Month switch + { + "Jan" => "January", + "Feb" => "February", + "Mar" => "March", + "Apr" => "April", + "May" => "May", + "Jun" => "June", + "Jul" => "July", + "Aug" => "August", + "Sep" => "September", + "Oct" => "October", + "Nov" => "November", + "Dec" => "December", + _ => Month + }; + public bool IsPastIteration { get diff --git a/actions/sequester/Quest2GitHub.Tests/BuildExtendedPropertiesTests.cs b/actions/sequester/Quest2GitHub.Tests/BuildExtendedPropertiesTests.cs index d944c256..c715b998 100644 --- a/actions/sequester/Quest2GitHub.Tests/BuildExtendedPropertiesTests.cs +++ b/actions/sequester/Quest2GitHub.Tests/BuildExtendedPropertiesTests.cs @@ -26,6 +26,7 @@ public class BuildExtendedPropertiesTests [ new () { Label = ":checkered_flag: Release: .NET 9", Tag = "new-feature" }, new () { Label = labelForTag, Tag = "content-curation" }, + new () { Label = labelWithReplacement, Tag = "Highlight-$FullMonthText$" } ]; private static ParentForLabel[] _parentMap = @@ -41,6 +42,8 @@ public class BuildExtendedPropertiesTests private const string labelWithParent = "user-feedback"; private const string labelWithoutParent = "bug"; + private const string labelWithReplacement = ":sparkler: Highlight :sparkler:"; + private const string PastProject = """ { @@ -256,13 +259,13 @@ public class BuildExtendedPropertiesTests }, "labels": { "nodes": [ - { - "name": "{{labelForTag}}", - "id": "MDU6TGFiZWwzMDkwMTEzMzI1" - }, { "name": "{{labelWithoutTag}}", "id": "LA_kwDOFn2dfM8AAAABK0cMjA" + }, + { + "name": "{{labelWithReplacement}}", + "id": "NA" } ] }, @@ -665,7 +668,7 @@ public static void BuildExtensionForFutureProjectWithTag() Assert.Equal(2, extendedProperties.Priority); Assert.Equal(ExpectedFutureProject, extendedProperties.IterationPath); Assert.Equal("New", extendedProperties.WorkItemState); - Assert.Equal(["content-curation"], extendedProperties.Tags); + Assert.Equal(["Highlight-March"], extendedProperties.Tags); Assert.Equal(33, extendedProperties.ParentNodeId); } diff --git a/actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs b/actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs index c5a05917..1818ebfc 100644 --- a/actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs +++ b/actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs @@ -182,12 +182,13 @@ month descending private static IEnumerable WorkItemTagsForIssue(QuestIssueOrPullRequest issue, IEnumerable tags, string copilotTag) { + string? sprint = LatestStoryPointSize(issue)?.FullMonthText?.ToString(); foreach (var label in issue.Labels) { var tag = tags.FirstOrDefault(t => t.Label == label.Name); if (tag.Tag is not null) { - yield return tag.Tag; + yield return (sprint is not null) ? tag.Tag.Replace("$FullMonthText$", sprint) : tag.Tag; } } // Add custom tag if one of the assignees is "Copilot": diff --git a/quest-config.json b/quest-config.json index 0ea8482e..a7757464 100644 --- a/quest-config.json +++ b/quest-config.json @@ -6,5 +6,19 @@ }, "ImportTriggerLabel": ":world_map: reQUEST", "ImportedLabel": ":pushpin: seQUESTered", - "DefaultParentNode": 405108 -} \ No newline at end of file + "DefaultParentNode": 405108, + "WorkItemTags": [ + { + "Label": ":sparkler: Highlight :sparkler:", + "Tag": "Highlight-$FullMonthText$" + }, + { + "Label": ":mag_right: AISDLC :mag:", + "Tag": "SP-AISDLC" + }, + { + "Label": ":mag_right: AIPlatform :mag:", + "Tag": "SP-AIPlatform" + } + ] +} From f0c93a18ba2273239b216d6444bfecebbe01c24b Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 4 Sep 2026 15:07:52 -0400 Subject: [PATCH 2/3] Refactor FullMonthText to use get accessor Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../GitHubObjects/StoryPointSize.cs | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/DotNet.DocsTools/GitHubObjects/StoryPointSize.cs b/DotNet.DocsTools/GitHubObjects/StoryPointSize.cs index 50f063e7..4b82f885 100644 --- a/DotNet.DocsTools/GitHubObjects/StoryPointSize.cs +++ b/DotNet.DocsTools/GitHubObjects/StoryPointSize.cs @@ -98,22 +98,18 @@ private StoryPointSize(int CalendarYear, string Month, string Size, int? Priorit public string Size { get; } public int? Priority { get; } - public string FullMonthText => Month switch + public string FullMonthText { - "Jan" => "January", - "Feb" => "February", - "Mar" => "March", - "Apr" => "April", - "May" => "May", - "Jun" => "June", - "Jul" => "July", - "Aug" => "August", - "Sep" => "September", - "Oct" => "October", - "Nov" => "November", - "Dec" => "December", - _ => Month - }; + get + { + if (!TryGetMonthOrdinal(Month, out int ordinal)) + { + return Month; + } + + return System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(ordinal); + } + } public bool IsPastIteration { From 285229ea7c3dc319d3c2c41409a303fa5094c12b Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 4 Sep 2026 15:10:56 -0400 Subject: [PATCH 3/3] respond to feedback. --- actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs b/actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs index 1818ebfc..7a16050a 100644 --- a/actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs +++ b/actions/sequester/Quest2GitHub/Models/WorkItemProperties.cs @@ -186,9 +186,9 @@ private static IEnumerable WorkItemTagsForIssue(QuestIssueOrPullRequest foreach (var label in issue.Labels) { var tag = tags.FirstOrDefault(t => t.Label == label.Name); - if (tag.Tag is not null) + if ((tag.Tag is not null) && (sprint is not null)) { - yield return (sprint is not null) ? tag.Tag.Replace("$FullMonthText$", sprint) : tag.Tag; + yield return tag.Tag.Replace("$FullMonthText$", sprint); } } // Add custom tag if one of the assignees is "Copilot":