@@ -19,6 +19,7 @@ public class Ado : NotificationsBase, IAdo {
19
19
// https://github.com/MicrosoftDocs/azure-devops-docs/issues/5890#issuecomment-539632059
20
20
private const int MAX_SYSTEM_TITLE_LENGTH = 128 ;
21
21
private const string TITLE_FIELD = "System.Title" ;
22
+ private static List < string > DEFAULT_REGRESSION_IGNORE_STATES = new ( ) { "New" , "Commited" , "Active" } ;
22
23
23
24
public Ado ( ILogger < Ado > logTracer , IOnefuzzContext context ) : base ( logTracer , context ) {
24
25
}
@@ -56,7 +57,7 @@ public async Async.Task<OneFuzzResultVoid> NotifyAdo(AdoTemplate config, Contain
56
57
_logTracer . LogEvent ( adoEventType ) ;
57
58
58
59
try {
59
- await ProcessNotification ( _context , container , filename , config , report , _logTracer , notificationInfo ) ;
60
+ await ProcessNotification ( _context , container , filename , config , report , _logTracer , notificationInfo , isRegression : reportable is RegressionReport ) ;
60
61
} catch ( Exception e )
61
62
when ( e is VssUnauthorizedException || e is VssAuthenticationException || e is VssServiceException ) {
62
63
if ( config . AdoFields . TryGetValue ( "System.AssignedTo" , out var assignedTo ) ) {
@@ -298,7 +299,7 @@ private static async Async.Task<Dictionary<string, WorkItemField2>> GetValidFiel
298
299
. ToDictionary ( field => field . ReferenceName . ToLowerInvariant ( ) ) ;
299
300
}
300
301
301
- private static async Async . Task ProcessNotification ( IOnefuzzContext context , Container container , string filename , AdoTemplate config , Report report , ILogger logTracer , IList < ( string , string ) > notificationInfo , Renderer ? renderer = null ) {
302
+ private static async Async . Task ProcessNotification ( IOnefuzzContext context , Container container , string filename , AdoTemplate config , Report report , ILogger logTracer , IList < ( string , string ) > notificationInfo , Renderer ? renderer = null , bool isRegression = false ) {
302
303
if ( ! config . AdoFields . TryGetValue ( TITLE_FIELD , out var issueTitle ) ) {
303
304
issueTitle = "{{ report.crash_site }} - {{ report.executable }}" ;
304
305
}
@@ -311,7 +312,7 @@ private static async Async.Task ProcessNotification(IOnefuzzContext context, Con
311
312
312
313
var renderedConfig = RenderAdoTemplate ( logTracer , renderer , config , instanceUrl ) ;
313
314
var ado = new AdoConnector ( renderedConfig , project ! , client , instanceUrl , logTracer , await GetValidFields ( client , project ) ) ;
314
- await ado . Process ( notificationInfo ) ;
315
+ await ado . Process ( notificationInfo , isRegression ) ;
315
316
}
316
317
317
318
public static RenderedAdoTemplate RenderAdoTemplate ( ILogger logTracer , Renderer renderer , AdoTemplate original , Uri instanceUrl ) {
@@ -352,7 +353,8 @@ public static RenderedAdoTemplate RenderAdoTemplate(ILogger logTracer, Renderer
352
353
original . OnDuplicate . SetState ,
353
354
onDuplicateAdoFields ,
354
355
original . OnDuplicate . Comment != null ? Render ( renderer , original . OnDuplicate . Comment , instanceUrl , logTracer ) : null ,
355
- onDuplicateUnless
356
+ onDuplicateUnless ,
357
+ original . OnDuplicate . RegressionIgnoreStates
356
358
) ;
357
359
358
360
return new RenderedAdoTemplate (
@@ -598,7 +600,7 @@ private async Async.Task<WorkItem> CreateNew() {
598
600
return ( taskType , document ) ;
599
601
}
600
602
601
- public async Async . Task Process ( IList < ( string , string ) > notificationInfo ) {
603
+ public async Async . Task Process ( IList < ( string , string ) > notificationInfo , bool isRegression ) {
602
604
var updated = false ;
603
605
WorkItem ? oldestWorkItem = null ;
604
606
await foreach ( var workItem in ExistingWorkItems ( notificationInfo ) ) {
@@ -612,6 +614,13 @@ public async Async.Task Process(IList<(string, string)> notificationInfo) {
612
614
continue ;
613
615
}
614
616
617
+ var regressionStatesToIgnore = _config . OnDuplicate . RegressionIgnoreStates != null ? _config . OnDuplicate . RegressionIgnoreStates : DEFAULT_REGRESSION_IGNORE_STATES ;
618
+ if ( isRegression ) {
619
+ var state = ( string ) workItem . Fields [ "System.State" ] ;
620
+ if ( regressionStatesToIgnore . Contains ( state , StringComparer . InvariantCultureIgnoreCase ) )
621
+ continue ;
622
+ }
623
+
615
624
using ( _logTracer . BeginScope ( "Non-duplicate work item" ) ) {
616
625
_logTracer . AddTags ( new List < ( string , string ) > { ( "NonDuplicateWorkItemId" , $ "{ workItem . Id } ") } ) ;
617
626
_logTracer . LogInformation ( "Found matching non-duplicate work item" ) ;
@@ -621,30 +630,32 @@ public async Async.Task Process(IList<(string, string)> notificationInfo) {
621
630
updated = true ;
622
631
}
623
632
624
- if ( ! updated ) {
625
- if ( oldestWorkItem != null ) {
626
- // We have matching work items but all are duplicates
627
- _logTracer . AddTags ( notificationInfo ) ;
628
- _logTracer . LogInformation ( $ "All matching work items were duplicates, re-opening the oldest one") ;
629
- var stateChanged = await UpdateExisting ( oldestWorkItem , notificationInfo ) ;
630
- if ( stateChanged ) {
631
- // add a comment if we re-opened the bug
632
- _ = await _client . AddCommentAsync (
633
- new CommentCreate ( ) {
634
- Text =
635
- "This work item was re-opened because OneFuzz could only find related work items that are marked as duplicate."
636
- } ,
637
- _project ,
638
- ( int ) oldestWorkItem . Id ! ) ;
639
- }
640
- } else {
641
- // We never saw a work item like this before, it must be new
642
- var entry = await CreateNew ( ) ;
643
- var adoEventType = "AdoNewItem" ;
644
- _logTracer . AddTags ( notificationInfo ) ;
645
- _logTracer . AddTag ( "WorkItemId" , entry . Id . HasValue ? entry . Id . Value . ToString ( ) : "" ) ;
646
- _logTracer . LogEvent ( adoEventType ) ;
633
+ if ( updated || isRegression ) {
634
+ return ;
635
+ }
636
+
637
+ if ( oldestWorkItem != null ) {
638
+ // We have matching work items but all are duplicates
639
+ _logTracer . AddTags ( notificationInfo ) ;
640
+ _logTracer . LogInformation ( $ "All matching work items were duplicates, re-opening the oldest one") ;
641
+ var stateChanged = await UpdateExisting ( oldestWorkItem , notificationInfo ) ;
642
+ if ( stateChanged ) {
643
+ // add a comment if we re-opened the bug
644
+ _ = await _client . AddCommentAsync (
645
+ new CommentCreate ( ) {
646
+ Text =
647
+ "This work item was re-opened because OneFuzz could only find related work items that are marked as duplicate."
648
+ } ,
649
+ _project ,
650
+ ( int ) oldestWorkItem . Id ! ) ;
647
651
}
652
+ } else {
653
+ // We never saw a work item like this before, it must be new
654
+ var entry = await CreateNew ( ) ;
655
+ var adoEventType = "AdoNewItem" ;
656
+ _logTracer . AddTags ( notificationInfo ) ;
657
+ _logTracer . AddTag ( "WorkItemId" , entry . Id . HasValue ? entry . Id . Value . ToString ( ) : "" ) ;
658
+ _logTracer . LogEvent ( adoEventType ) ;
648
659
}
649
660
}
650
661
0 commit comments