Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ All notable changes to `src-cli` are documented in this file.

### Added

- When used with Sourcegraph 3.18 or later, campaigns can now be created on GitLab. [#231](https://github.com/sourcegraph/src-cli/pull/231)

### Changed

### Fixed
Expand Down
53 changes: 50 additions & 3 deletions cmd/src/actions_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,15 @@ fragment repositoryFields on Repository {
}

// Skip repos from unsupported code hosts but don't report them explicitly.
if !includeUnsupported && strings.ToLower(repo.ExternalRepository.ServiceType) != "github" && strings.ToLower(repo.ExternalRepository.ServiceType) != "bitbucketserver" {
unsupported = append(unsupported, repo.Name)
continue
if !includeUnsupported {
ok, err := isCodeHostSupportedForCampaigns(repo.ExternalRepository.ServiceType)
if err != nil {
return nil, errors.Wrap(err, "failed code host check")
}
if !ok {
unsupported = append(unsupported, repo.Name)
continue
}
}

if repo.DefaultBranch == nil || repo.DefaultBranch.Name == "" {
Expand Down Expand Up @@ -517,3 +523,44 @@ func askForConfirmation(s string) (bool, error) {

return false, nil
}

type minimumVersionDate struct {
version string
date string
}

// codeHostCampaignVersions contains the minimum Sourcegraph version and build
// date required for the given code host kind. If a code host is present with a
// value of nil, this means that any Sourcegraph version will pass the check.
var codeHostCampaignVersions = map[string]*minimumVersionDate{
"github": nil,
"bitbucketserver": nil,
"gitlab": {
version: "3.18.0",
date: "2020-07-14",
},
}

func isCodeHostSupportedForCampaigns(kind string) (bool, error) {
// TODO(LawnGnome): this is a temporary hack; I intend to improve our
// testing story including mocking requests to Sourcegraph as part of
// https://github.com/sourcegraph/sourcegraph/issues/12333
return isCodeHostSupportedForCampaignsImpl(kind, getSourcegraphVersion)
}

func isCodeHostSupportedForCampaignsImpl(kind string, getVersion func() (string, error)) (bool, error) {
mvd, ok := codeHostCampaignVersions[strings.ToLower(kind)]
if !ok {
return false, nil
}
if mvd == nil {
return true, nil
}

ver, err := getVersion()
if err != nil {
return false, errors.Wrap(err, "getting Sourcegraph version")
}

return sourcegraphVersionCheck(ver, fmt.Sprintf(">= %s", mvd.version), mvd.date)
}
83 changes: 83 additions & 0 deletions cmd/src/actions_exec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package main

import (
"testing"

"github.com/pkg/errors"
)

func TestCodeHostSupported(t *testing.T) {
t.Run("error from getSourcegraphVersion", func(t *testing.T) {
want := errors.New("foo")
if _, have := isCodeHostSupportedForCampaignsImpl("GITLAB", func() (string, error) {
return "", want
}); !errors.Is(have, want) {
t.Errorf("unexpected error: have %+v; want %+v", have, want)
}
})

t.Run("error from sourcegraphVersionCheck", func(t *testing.T) {
if _, err := isCodeHostSupportedForCampaignsImpl("GITLAB", func() (string, error) {
return "x.y.z", nil
}); err == nil {
t.Error("unexpected nil error")
}
})

t.Run("no errors", func(t *testing.T) {
for name, tc := range map[string]struct {
want bool
kind string
version string
}{
"GitHub": {
want: true,
kind: "GITHUB",
version: "1.2.3",
},
"BitBucket": {
want: true,
kind: "BITBUCKETSERVER",
version: "1.2.3",
},
"GitLab with old semver version": {
want: false,
kind: "GITLAB",
version: "1.2.3",
},
"GitLab with old dev version": {
want: false,
kind: "GITLAB",
version: "68956_2019-07-21_c3a5992",
},
"GitLab with new semver version": {
want: true,
kind: "GITLAB",
version: "3.18.0",
},
"GitLab with new dev version": {
want: true,
kind: "GITLAB",
version: "68956_2020-07-21_c3a5992",
},
"unknown kind": {
want: false,
kind: "CODE HOSTS R US",
version: "3.18.0",
},
} {
t.Run(name, func(t *testing.T) {
have, err := isCodeHostSupportedForCampaignsImpl(tc.kind, func() (string, error) {
return tc.version, nil
})
if err != nil {
t.Errorf("unexpected non-nil error: %+v", err)
}

if have != tc.want {
t.Errorf("unexpected support status: have %v; want %v", have, tc.want)
}
})
}
})
}