@@ -363,8 +363,7 @@ func (svc *Service) ResolveNamespace(ctx context.Context, namespace string) (str
363363}
364364
365365func (svc * Service ) ResolveRepositories (ctx context.Context , spec * CampaignSpec ) ([]* graphql.Repository , error ) {
366- final := []* graphql.Repository {}
367- seen := map [string ]struct {}{}
366+ seen := map [string ]* graphql.Repository {}
368367 unsupported := UnsupportedRepoSet {}
369368
370369 // TODO: this could be trivially parallelised in the future.
@@ -375,11 +374,12 @@ func (svc *Service) ResolveRepositories(ctx context.Context, spec *CampaignSpec)
375374 }
376375
377376 for _ , repo := range repos {
378- if _ , ok := seen [repo .ID ]; ! ok {
379- if repo .DefaultBranch == nil {
380- continue
381- }
382- seen [repo .ID ] = struct {}{}
377+ if ! repo .HasBranch () {
378+ continue
379+ }
380+
381+ if other , ok := seen [repo .ID ]; ! ok {
382+ seen [repo .ID ] = repo
383383 switch st := strings .ToLower (repo .ExternalRepository .ServiceType ); st {
384384 case "github" , "gitlab" , "bitbucketserver" :
385385 default :
@@ -388,12 +388,20 @@ func (svc *Service) ResolveRepositories(ctx context.Context, spec *CampaignSpec)
388388 continue
389389 }
390390 }
391-
392- final = append (final , repo )
391+ } else {
392+ // If we've already seen this repository, we overwrite the
393+ // Commit/Branch fields with the latest value we have
394+ other .Commit = repo .Commit
395+ other .Branch = repo .Branch
393396 }
394397 }
395398 }
396399
400+ final := make ([]* graphql.Repository , 0 , len (seen ))
401+ for _ , repo := range seen {
402+ final = append (final , repo )
403+ }
404+
397405 if unsupported .hasUnsupported () && ! svc .allowUnsupported {
398406 return final , unsupported
399407 }
@@ -404,6 +412,12 @@ func (svc *Service) ResolveRepositories(ctx context.Context, spec *CampaignSpec)
404412func (svc * Service ) ResolveRepositoriesOn (ctx context.Context , on * OnQueryOrRepository ) ([]* graphql.Repository , error ) {
405413 if on .RepositoriesMatchingQuery != "" {
406414 return svc .resolveRepositorySearch (ctx , on .RepositoriesMatchingQuery )
415+ } else if on .Repository != "" && on .Branch != "" {
416+ repo , err := svc .resolveRepositoryNameAndBranch (ctx , on .Repository , on .Branch )
417+ if err != nil {
418+ return nil , err
419+ }
420+ return []* graphql.Repository {repo }, nil
407421 } else if on .Repository != "" {
408422 repo , err := svc .resolveRepositoryName (ctx , on .Repository )
409423 if err != nil {
@@ -418,7 +432,7 @@ func (svc *Service) ResolveRepositoriesOn(ctx context.Context, on *OnQueryOrRepo
418432}
419433
420434const repositoryNameQuery = `
421- query Repository($name: String!) {
435+ query Repository($name: String!, $queryCommit: Boolean!, $rev: String! ) {
422436 repository(name: $name) {
423437 ...repositoryFields
424438 }
@@ -428,7 +442,9 @@ query Repository($name: String!) {
428442func (svc * Service ) resolveRepositoryName (ctx context.Context , name string ) (* graphql.Repository , error ) {
429443 var result struct { Repository * graphql.Repository }
430444 if ok , err := svc .client .NewRequest (repositoryNameQuery , map [string ]interface {}{
431- "name" : name ,
445+ "name" : name ,
446+ "queryCommit" : false ,
447+ "rev" : "" ,
432448 }).Do (ctx , & result ); err != nil || ! ok {
433449 return nil , err
434450 }
@@ -438,10 +454,36 @@ func (svc *Service) resolveRepositoryName(ctx context.Context, name string) (*gr
438454 return result .Repository , nil
439455}
440456
457+ func (svc * Service ) resolveRepositoryNameAndBranch (ctx context.Context , name , branch string ) (* graphql.Repository , error ) {
458+ var result struct { Repository * graphql.Repository }
459+ if ok , err := svc .client .NewRequest (repositoryNameQuery , map [string ]interface {}{
460+ "name" : name ,
461+ "queryCommit" : true ,
462+ "rev" : branch ,
463+ }).Do (ctx , & result ); err != nil || ! ok {
464+ return nil , err
465+ }
466+ if result .Repository == nil {
467+ return nil , errors .New ("no repository found" )
468+ }
469+ if result .Repository .Commit .OID == "" {
470+ return nil , fmt .Errorf ("no branch matching %q found for repository %s" , branch , name )
471+ }
472+
473+ result .Repository .Branch = graphql.Branch {
474+ Name : branch ,
475+ Target : result .Repository .Commit ,
476+ }
477+
478+ return result .Repository , nil
479+ }
480+
441481// TODO: search result alerts.
442482const repositorySearchQuery = `
443483query ChangesetRepos(
444484 $query: String!,
485+ $queryCommit: Boolean!,
486+ $rev: String!,
445487) {
446488 search(query: $query, version: V2) {
447489 results {
@@ -471,7 +513,9 @@ func (svc *Service) resolveRepositorySearch(ctx context.Context, query string) (
471513 }
472514 }
473515 if ok , err := svc .client .NewRequest (repositorySearchQuery , map [string ]interface {}{
474- "query" : setDefaultQueryCount (query ),
516+ "query" : setDefaultQueryCount (query ),
517+ "queryCommit" : false ,
518+ "rev" : "" ,
475519 }).Do (ctx , & result ); err != nil || ! ok {
476520 return nil , err
477521 }
0 commit comments