fix(featuredetection): add ReleaseFeatures method
Signed-off-by: Babak K. Shandiz <babakks@github.com>
This commit is contained in:
parent
20c7bdc2a4
commit
26552f3489
3 changed files with 156 additions and 0 deletions
|
|
@ -24,6 +24,10 @@ func (md *DisabledDetectorMock) SearchFeatures() (SearchFeatures, error) {
|
|||
return advancedIssueSearchNotSupported, nil
|
||||
}
|
||||
|
||||
func (md *DisabledDetectorMock) ReleaseFeatures() (ReleaseFeatures, error) {
|
||||
return ReleaseFeatures{}, nil
|
||||
}
|
||||
|
||||
type EnabledDetectorMock struct{}
|
||||
|
||||
func (md *EnabledDetectorMock) IssueFeatures() (IssueFeatures, error) {
|
||||
|
|
@ -46,6 +50,12 @@ func (md *EnabledDetectorMock) SearchFeatures() (SearchFeatures, error) {
|
|||
return advancedIssueSearchNotSupported, nil
|
||||
}
|
||||
|
||||
func (md *EnabledDetectorMock) ReleaseFeatures() (ReleaseFeatures, error) {
|
||||
return ReleaseFeatures{
|
||||
ImmutableReleases: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type AdvancedIssueSearchDetectorMock struct {
|
||||
EnabledDetectorMock
|
||||
searchFeatures SearchFeatures
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ type Detector interface {
|
|||
RepositoryFeatures() (RepositoryFeatures, error)
|
||||
ProjectsV1() gh.ProjectsV1Support
|
||||
SearchFeatures() (SearchFeatures, error)
|
||||
ReleaseFeatures() (ReleaseFeatures, error)
|
||||
}
|
||||
|
||||
type IssueFeatures struct {
|
||||
|
|
@ -93,6 +94,10 @@ var advancedIssueSearchSupportedAsOnlyBackend = SearchFeatures{
|
|||
AdvancedIssueSearchAPIOptIn: false,
|
||||
}
|
||||
|
||||
type ReleaseFeatures struct {
|
||||
ImmutableReleases bool
|
||||
}
|
||||
|
||||
type detector struct {
|
||||
host string
|
||||
httpClient *http.Client
|
||||
|
|
@ -358,6 +363,36 @@ func (d *detector) SearchFeatures() (SearchFeatures, error) {
|
|||
return feature, nil
|
||||
}
|
||||
|
||||
func (d *detector) ReleaseFeatures() (ReleaseFeatures, error) {
|
||||
// TODO: immutableReleaseFullSupport
|
||||
// Once all supported GHES versions fully support immutable releases, we can
|
||||
// remove this function, of course, unless there will be other release-related
|
||||
// features that are not available on all GH hosts.
|
||||
|
||||
var releaseFeatureDetection struct {
|
||||
Release struct {
|
||||
Fields []struct {
|
||||
Name string
|
||||
} `graphql:"fields"`
|
||||
} `graphql:"Release: __type(name: \"Release\")"`
|
||||
}
|
||||
|
||||
gql := api.NewClientFromHTTP(d.httpClient)
|
||||
if err := gql.Query(d.host, "Release_fields", &releaseFeatureDetection, nil); err != nil {
|
||||
return ReleaseFeatures{}, err
|
||||
}
|
||||
|
||||
for _, field := range releaseFeatureDetection.Release.Fields {
|
||||
if field.Name == "immutable" {
|
||||
return ReleaseFeatures{
|
||||
ImmutableReleases: true,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return ReleaseFeatures{}, nil
|
||||
}
|
||||
|
||||
func resolveEnterpriseVersion(httpClient *http.Client, host string) (*version.Version, error) {
|
||||
var metaResponse struct {
|
||||
InstalledVersion string `json:"installed_version"`
|
||||
|
|
|
|||
|
|
@ -585,3 +585,114 @@ func TestAdvancedIssueSearchSupport(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseFeatures(t *testing.T) {
|
||||
withImmutableReleaseSupport := `{"data":{"Release":{"fields":[{"name":"author"},{"name":"name"},{"name":"immutable"}]}}}`
|
||||
withoutImmutableReleaseSupport := `{"data":{"Release":{"fields":[{"name":"author"},{"name":"name"}]}}}`
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
hostname string
|
||||
httpStubs func(*httpmock.Registry)
|
||||
wantFeatures ReleaseFeatures
|
||||
}{
|
||||
{
|
||||
// This is not a real case as `github.com` supports immutable releases.
|
||||
name: "github.com, immutable releases unsupported",
|
||||
hostname: "github.com",
|
||||
httpStubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.GraphQL(`query Release_fields\b`),
|
||||
httpmock.StringResponse(withoutImmutableReleaseSupport),
|
||||
)
|
||||
},
|
||||
wantFeatures: ReleaseFeatures{
|
||||
ImmutableReleases: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "github.com, immutable releases supported",
|
||||
hostname: "github.com",
|
||||
httpStubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.GraphQL(`query Release_fields\b`),
|
||||
httpmock.StringResponse(withImmutableReleaseSupport),
|
||||
)
|
||||
},
|
||||
wantFeatures: ReleaseFeatures{
|
||||
ImmutableReleases: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
// This is not a real case as `github.com` supports immutable releases.
|
||||
name: "ghec data residency (ghe.com), immutable releases unsupported",
|
||||
hostname: "stampname.ghe.com",
|
||||
httpStubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.GraphQL(`query Release_fields\b`),
|
||||
httpmock.StringResponse(withoutImmutableReleaseSupport),
|
||||
)
|
||||
},
|
||||
wantFeatures: ReleaseFeatures{
|
||||
ImmutableReleases: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ghec data residency (ghe.com), immutable releases supported",
|
||||
hostname: "stampname.ghe.com",
|
||||
httpStubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.GraphQL(`query Release_fields\b`),
|
||||
httpmock.StringResponse(withImmutableReleaseSupport),
|
||||
)
|
||||
},
|
||||
wantFeatures: ReleaseFeatures{
|
||||
ImmutableReleases: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GHE, immutable releases unsupported",
|
||||
hostname: "git.my.org",
|
||||
httpStubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.GraphQL(`query Release_fields\b`),
|
||||
httpmock.StringResponse(withoutImmutableReleaseSupport),
|
||||
)
|
||||
},
|
||||
wantFeatures: ReleaseFeatures{
|
||||
ImmutableReleases: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GHE, immutable releases supported",
|
||||
hostname: "git.my.org",
|
||||
httpStubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.GraphQL(`query Release_fields\b`),
|
||||
httpmock.StringResponse(withImmutableReleaseSupport),
|
||||
)
|
||||
},
|
||||
wantFeatures: ReleaseFeatures{
|
||||
ImmutableReleases: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
reg := &httpmock.Registry{}
|
||||
if tt.httpStubs != nil {
|
||||
tt.httpStubs(reg)
|
||||
}
|
||||
httpClient := &http.Client{}
|
||||
httpmock.ReplaceTripper(httpClient, reg)
|
||||
|
||||
detector := NewDetector(httpClient, tt.hostname)
|
||||
|
||||
features, err := detector.ReleaseFeatures()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.wantFeatures, features)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue