@@ -19,6 +19,7 @@ public class Ado : NotificationsBase, IAdo {
1919 // https://github.com/MicrosoftDocs/azure-devops-docs/issues/5890#issuecomment-539632059
2020 private const int MAX_SYSTEM_TITLE_LENGTH = 128 ;
2121 private const string TITLE_FIELD = "System.Title" ;
22+ private static List < string > DEFAULT_REGRESSION_IGNORE_STATES = new ( ) { "New" , "Commited" , "Active" } ;
2223
2324 public Ado ( ILogger < Ado > logTracer , IOnefuzzContext context ) : base ( logTracer , context ) {
2425 }
@@ -56,7 +57,7 @@ public async Async.Task<OneFuzzResultVoid> NotifyAdo(AdoTemplate config, Contain
5657 _logTracer . LogEvent ( adoEventType ) ;
5758
5859 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 ) ;
6061 } catch ( Exception e )
6162 when ( e is VssUnauthorizedException || e is VssAuthenticationException || e is VssServiceException ) {
6263 if ( config . AdoFields . TryGetValue ( "System.AssignedTo" , out var assignedTo ) ) {
@@ -298,7 +299,7 @@ private static async Async.Task<Dictionary<string, WorkItemField2>> GetValidFiel
298299 . ToDictionary ( field => field . ReferenceName . ToLowerInvariant ( ) ) ;
299300 }
300301
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 ) {
302303 if ( ! config . AdoFields . TryGetValue ( TITLE_FIELD , out var issueTitle ) ) {
303304 issueTitle = "{{ report.crash_site }} - {{ report.executable }}" ;
304305 }
@@ -311,7 +312,7 @@ private static async Async.Task ProcessNotification(IOnefuzzContext context, Con
311312
312313 var renderedConfig = RenderAdoTemplate ( logTracer , renderer , config , instanceUrl ) ;
313314 var ado = new AdoConnector ( renderedConfig , project ! , client , instanceUrl , logTracer , await GetValidFields ( client , project ) ) ;
314- await ado . Process ( notificationInfo ) ;
315+ await ado . Process ( notificationInfo , isRegression ) ;
315316 }
316317
317318 public static RenderedAdoTemplate RenderAdoTemplate ( ILogger logTracer , Renderer renderer , AdoTemplate original , Uri instanceUrl ) {
@@ -352,7 +353,8 @@ public static RenderedAdoTemplate RenderAdoTemplate(ILogger logTracer, Renderer
352353 original . OnDuplicate . SetState ,
353354 onDuplicateAdoFields ,
354355 original . OnDuplicate . Comment != null ? Render ( renderer , original . OnDuplicate . Comment , instanceUrl , logTracer ) : null ,
355- onDuplicateUnless
356+ onDuplicateUnless ,
357+ original . OnDuplicate . RegressionIgnoreStates
356358 ) ;
357359
358360 return new RenderedAdoTemplate (
@@ -598,7 +600,7 @@ private async Async.Task<WorkItem> CreateNew() {
598600 return ( taskType , document ) ;
599601 }
600602
601- public async Async . Task Process ( IList < ( string , string ) > notificationInfo ) {
603+ public async Async . Task Process ( IList < ( string , string ) > notificationInfo , bool isRegression ) {
602604 var updated = false ;
603605 WorkItem ? oldestWorkItem = null ;
604606 await foreach ( var workItem in ExistingWorkItems ( notificationInfo ) ) {
@@ -612,6 +614,13 @@ public async Async.Task Process(IList<(string, string)> notificationInfo) {
612614 continue ;
613615 }
614616
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+
615624 using ( _logTracer . BeginScope ( "Non-duplicate work item" ) ) {
616625 _logTracer . AddTags ( new List < ( string , string ) > { ( "NonDuplicateWorkItemId" , $ "{ workItem . Id } ") } ) ;
617626 _logTracer . LogInformation ( "Found matching non-duplicate work item" ) ;
@@ -621,30 +630,32 @@ public async Async.Task Process(IList<(string, string)> notificationInfo) {
621630 updated = true ;
622631 }
623632
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 ! ) ;
647651 }
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 ) ;
648659 }
649660 }
650661
0 commit comments