* Add API for Repo Advanced Settings of wiki and issue tracker Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Add some integration tests for tracker and wiki settings through API * Should return StatusUnprocessableEntity in case of invalid API values. * Add tests for invalid URLs for external tracker and wiki. * Do not set inital values if they are default of type * Make issue tracker and wiki units separate structures in Repository API structure. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix comment of structures Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Rewrite API to use struct for setting tracker and wiki settings. * LetOnlyContributorsTrackTime -> AllowOnlyContributorsToTrackTimetags/v1.10.0-rc1
@@ -23,12 +23,35 @@ func getRepoEditOptionFromRepo(repo *models.Repository) *api.EditRepoOption { | |||
website := repo.Website | |||
private := repo.IsPrivate | |||
hasIssues := false | |||
if _, err := repo.GetUnit(models.UnitTypeIssues); err == nil { | |||
var internalTracker *api.InternalTracker | |||
var externalTracker *api.ExternalTracker | |||
if unit, err := repo.GetUnit(models.UnitTypeIssues); err == nil { | |||
config := unit.IssuesConfig() | |||
hasIssues = true | |||
internalTracker = &api.InternalTracker{ | |||
EnableTimeTracker: config.EnableTimetracker, | |||
AllowOnlyContributorsToTrackTime: config.AllowOnlyContributorsToTrackTime, | |||
EnableIssueDependencies: config.EnableDependencies, | |||
} | |||
} else if unit, err := repo.GetUnit(models.UnitTypeExternalTracker); err == nil { | |||
config := unit.ExternalTrackerConfig() | |||
hasIssues = true | |||
externalTracker = &api.ExternalTracker{ | |||
ExternalTrackerURL: config.ExternalTrackerURL, | |||
ExternalTrackerFormat: config.ExternalTrackerFormat, | |||
ExternalTrackerStyle: config.ExternalTrackerStyle, | |||
} | |||
} | |||
hasWiki := false | |||
var externalWiki *api.ExternalWiki | |||
if _, err := repo.GetUnit(models.UnitTypeWiki); err == nil { | |||
hasWiki = true | |||
} else if unit, err := repo.GetUnit(models.UnitTypeExternalWiki); err == nil { | |||
hasWiki = true | |||
config := unit.ExternalWikiConfig() | |||
externalWiki = &api.ExternalWiki{ | |||
ExternalWikiURL: config.ExternalWikiURL, | |||
} | |||
} | |||
defaultBranch := repo.DefaultBranch | |||
hasPullRequests := false | |||
@@ -53,7 +76,10 @@ func getRepoEditOptionFromRepo(repo *models.Repository) *api.EditRepoOption { | |||
Website: &website, | |||
Private: &private, | |||
HasIssues: &hasIssues, | |||
ExternalTracker: externalTracker, | |||
InternalTracker: internalTracker, | |||
HasWiki: &hasWiki, | |||
ExternalWiki: externalWiki, | |||
DefaultBranch: &defaultBranch, | |||
HasPullRequests: &hasPullRequests, | |||
IgnoreWhitespaceConflicts: &ignoreWhitespaceConflicts, | |||
@@ -143,6 +169,84 @@ func TestAPIRepoEdit(t *testing.T) { | |||
assert.Equal(t, *repoEditOption.Archived, *repo1editedOption.Archived) | |||
assert.Equal(t, *repoEditOption.Private, *repo1editedOption.Private) | |||
assert.Equal(t, *repoEditOption.HasWiki, *repo1editedOption.HasWiki) | |||
//Test editing repo1 to use internal issue and wiki (default) | |||
*repoEditOption.HasIssues = true | |||
repoEditOption.ExternalTracker = nil | |||
repoEditOption.InternalTracker = &api.InternalTracker{ | |||
EnableTimeTracker: false, | |||
AllowOnlyContributorsToTrackTime: false, | |||
EnableIssueDependencies: false, | |||
} | |||
*repoEditOption.HasWiki = true | |||
repoEditOption.ExternalWiki = nil | |||
url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2) | |||
req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) | |||
resp = session.MakeRequest(t, req, http.StatusOK) | |||
DecodeJSON(t, resp, &repo) | |||
assert.NotNil(t, repo) | |||
// check repo1 was written to database | |||
repo1edited = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) | |||
repo1editedOption = getRepoEditOptionFromRepo(repo1edited) | |||
assert.Equal(t, *repo1editedOption.HasIssues, true) | |||
assert.Nil(t, repo1editedOption.ExternalTracker) | |||
assert.Equal(t, *repo1editedOption.InternalTracker, *repoEditOption.InternalTracker) | |||
assert.Equal(t, *repo1editedOption.HasWiki, true) | |||
assert.Nil(t, repo1editedOption.ExternalWiki) | |||
//Test editing repo1 to use external issue and wiki | |||
repoEditOption.ExternalTracker = &api.ExternalTracker{ | |||
ExternalTrackerURL: "http://www.somewebsite.com", | |||
ExternalTrackerFormat: "http://www.somewebsite.com/{user}/{repo}?issue={index}", | |||
ExternalTrackerStyle: "alphanumeric", | |||
} | |||
repoEditOption.ExternalWiki = &api.ExternalWiki{ | |||
ExternalWikiURL: "http://www.somewebsite.com", | |||
} | |||
req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) | |||
resp = session.MakeRequest(t, req, http.StatusOK) | |||
DecodeJSON(t, resp, &repo) | |||
assert.NotNil(t, repo) | |||
// check repo1 was written to database | |||
repo1edited = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) | |||
repo1editedOption = getRepoEditOptionFromRepo(repo1edited) | |||
assert.Equal(t, *repo1editedOption.HasIssues, true) | |||
assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker) | |||
assert.Equal(t, *repo1editedOption.HasWiki, true) | |||
assert.Equal(t, *repo1editedOption.ExternalWiki, *repoEditOption.ExternalWiki) | |||
// Do some tests with invalid URL for external tracker and wiki | |||
repoEditOption.ExternalTracker.ExternalTrackerURL = "htp://www.somewebsite.com" | |||
req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) | |||
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity) | |||
repoEditOption.ExternalTracker.ExternalTrackerURL = "http://www.somewebsite.com" | |||
repoEditOption.ExternalTracker.ExternalTrackerFormat = "http://www.somewebsite.com/{user/{repo}?issue={index}" | |||
req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) | |||
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity) | |||
repoEditOption.ExternalTracker.ExternalTrackerFormat = "http://www.somewebsite.com/{user}/{repo}?issue={index}" | |||
repoEditOption.ExternalWiki.ExternalWikiURL = "htp://www.somewebsite.com" | |||
req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) | |||
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity) | |||
//Test small repo change through API with issue and wiki option not set; They shall not be touched. | |||
*repoEditOption.Description = "small change" | |||
repoEditOption.HasIssues = nil | |||
repoEditOption.ExternalTracker = nil | |||
repoEditOption.HasWiki = nil | |||
repoEditOption.ExternalWiki = nil | |||
req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) | |||
resp = session.MakeRequest(t, req, http.StatusOK) | |||
DecodeJSON(t, resp, &repo) | |||
assert.NotNil(t, repo) | |||
// check repo1 was written to database | |||
repo1edited = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) | |||
repo1editedOption = getRepoEditOptionFromRepo(repo1edited) | |||
assert.Equal(t, *repo1editedOption.Description, *repoEditOption.Description) | |||
assert.Equal(t, *repo1editedOption.HasIssues, true) | |||
assert.NotNil(t, *repo1editedOption.ExternalTracker) | |||
assert.Equal(t, *repo1editedOption.HasWiki, true) | |||
assert.NotNil(t, *repo1editedOption.ExternalWiki) | |||
// reset repo in db | |||
url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2) | |||
req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption) |
@@ -275,12 +275,35 @@ func (repo *Repository) innerAPIFormat(e Engine, mode AccessMode, isParent bool) | |||
} | |||
} | |||
hasIssues := false | |||
if _, err := repo.getUnit(e, UnitTypeIssues); err == nil { | |||
var externalTracker *api.ExternalTracker | |||
var internalTracker *api.InternalTracker | |||
if unit, err := repo.getUnit(e, UnitTypeIssues); err == nil { | |||
config := unit.IssuesConfig() | |||
hasIssues = true | |||
internalTracker = &api.InternalTracker{ | |||
EnableTimeTracker: config.EnableTimetracker, | |||
AllowOnlyContributorsToTrackTime: config.AllowOnlyContributorsToTrackTime, | |||
EnableIssueDependencies: config.EnableDependencies, | |||
} | |||
} else if unit, err := repo.getUnit(e, UnitTypeExternalTracker); err == nil { | |||
config := unit.ExternalTrackerConfig() | |||
hasIssues = true | |||
externalTracker = &api.ExternalTracker{ | |||
ExternalTrackerURL: config.ExternalTrackerURL, | |||
ExternalTrackerFormat: config.ExternalTrackerFormat, | |||
ExternalTrackerStyle: config.ExternalTrackerStyle, | |||
} | |||
} | |||
hasWiki := false | |||
var externalWiki *api.ExternalWiki | |||
if _, err := repo.getUnit(e, UnitTypeWiki); err == nil { | |||
hasWiki = true | |||
} else if unit, err := repo.getUnit(e, UnitTypeExternalWiki); err == nil { | |||
hasWiki = true | |||
config := unit.ExternalWikiConfig() | |||
externalWiki = &api.ExternalWiki{ | |||
ExternalWikiURL: config.ExternalWikiURL, | |||
} | |||
} | |||
hasPullRequests := false | |||
ignoreWhitespaceConflicts := false | |||
@@ -324,7 +347,10 @@ func (repo *Repository) innerAPIFormat(e Engine, mode AccessMode, isParent bool) | |||
Updated: repo.UpdatedUnix.AsTime(), | |||
Permissions: permission, | |||
HasIssues: hasIssues, | |||
ExternalTracker: externalTracker, | |||
InternalTracker: internalTracker, | |||
HasWiki: hasWiki, | |||
ExternalWiki: externalWiki, | |||
HasPullRequests: hasPullRequests, | |||
IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts, | |||
AllowMerge: allowMerge, |
@@ -15,6 +15,35 @@ type Permission struct { | |||
Pull bool `json:"pull"` | |||
} | |||
// InternalTracker represents settings for internal tracker | |||
// swagger:model | |||
type InternalTracker struct { | |||
// Enable time tracking (Built-in issue tracker) | |||
EnableTimeTracker bool `json:"enable_time_tracker"` | |||
// Let only contributors track time (Built-in issue tracker) | |||
AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"` | |||
// Enable dependencies for issues and pull requests (Built-in issue tracker) | |||
EnableIssueDependencies bool `json:"enable_issue_dependencies"` | |||
} | |||
// ExternalTracker represents settings for external tracker | |||
// swagger:model | |||
type ExternalTracker struct { | |||
// URL of external issue tracker. | |||
ExternalTrackerURL string `json:"external_tracker_url"` | |||
// External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index. | |||
ExternalTrackerFormat string `json:"external_tracker_format"` | |||
// External Issue Tracker Number Format, either `numeric` or `alphanumeric` | |||
ExternalTrackerStyle string `json:"external_tracker_style"` | |||
} | |||
// ExternalWiki represents setting for external wiki | |||
// swagger:model | |||
type ExternalWiki struct { | |||
// URL of external wiki. | |||
ExternalWikiURL string `json:"external_wiki_url"` | |||
} | |||
// Repository represents a repository | |||
type Repository struct { | |||
ID int64 `json:"id"` | |||
@@ -42,17 +71,20 @@ type Repository struct { | |||
// swagger:strfmt date-time | |||
Created time.Time `json:"created_at"` | |||
// swagger:strfmt date-time | |||
Updated time.Time `json:"updated_at"` | |||
Permissions *Permission `json:"permissions,omitempty"` | |||
HasIssues bool `json:"has_issues"` | |||
HasWiki bool `json:"has_wiki"` | |||
HasPullRequests bool `json:"has_pull_requests"` | |||
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` | |||
AllowMerge bool `json:"allow_merge_commits"` | |||
AllowRebase bool `json:"allow_rebase"` | |||
AllowRebaseMerge bool `json:"allow_rebase_explicit"` | |||
AllowSquash bool `json:"allow_squash_merge"` | |||
AvatarURL string `json:"avatar_url"` | |||
Updated time.Time `json:"updated_at"` | |||
Permissions *Permission `json:"permissions,omitempty"` | |||
HasIssues bool `json:"has_issues"` | |||
InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` | |||
ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` | |||
HasWiki bool `json:"has_wiki"` | |||
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` | |||
HasPullRequests bool `json:"has_pull_requests"` | |||
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` | |||
AllowMerge bool `json:"allow_merge_commits"` | |||
AllowRebase bool `json:"allow_rebase"` | |||
AllowRebaseMerge bool `json:"allow_rebase_explicit"` | |||
AllowSquash bool `json:"allow_squash_merge"` | |||
AvatarURL string `json:"avatar_url"` | |||
} | |||
// CreateRepoOption options when creating repository | |||
@@ -95,8 +127,14 @@ type EditRepoOption struct { | |||
Private *bool `json:"private,omitempty"` | |||
// either `true` to enable issues for this repository or `false` to disable them. | |||
HasIssues *bool `json:"has_issues,omitempty"` | |||
// set this structure to configure internal issue tracker (requires has_issues) | |||
InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` | |||
// set this structure to use external issue tracker (requires has_issues) | |||
ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` | |||
// either `true` to enable the wiki for this repository or `false` to disable it. | |||
HasWiki *bool `json:"has_wiki,omitempty"` | |||
// set this structure to use external wiki instead of internal (requires has_wiki) | |||
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` | |||
// sets the default branch for this repository. | |||
DefaultBranch *string `json:"default_branch,omitempty"` | |||
// either `true` to allow pull requests, or `false` to prevent pull request. |
@@ -19,6 +19,7 @@ import ( | |||
"code.gitea.io/gitea/modules/setting" | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/util" | |||
"code.gitea.io/gitea/modules/validation" | |||
"code.gitea.io/gitea/routers/api/v1/convert" | |||
mirror_service "code.gitea.io/gitea/services/mirror" | |||
) | |||
@@ -669,27 +670,56 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { | |||
units = append(units, *unit) | |||
} | |||
} else if *opts.HasIssues { | |||
// We don't currently allow setting individual issue settings through the API, | |||
// only can enable/disable issues, so when enabling issues, | |||
// we either get the existing config which means it was already enabled, | |||
// or create a new config since it doesn't exist. | |||
unit, err := repo.GetUnit(models.UnitTypeIssues) | |||
var config *models.IssuesConfig | |||
if err != nil { | |||
// Unit type doesn't exist so we make a new config file with default values | |||
config = &models.IssuesConfig{ | |||
EnableTimetracker: true, | |||
AllowOnlyContributorsToTrackTime: true, | |||
EnableDependencies: true, | |||
if opts.ExternalTracker != nil { | |||
// Check that values are valid | |||
if !validation.IsValidExternalURL(opts.ExternalTracker.ExternalTrackerURL) { | |||
err := fmt.Errorf("External tracker URL not valid") | |||
ctx.Error(http.StatusUnprocessableEntity, "Invalid external tracker URL", err) | |||
return err | |||
} | |||
if len(opts.ExternalTracker.ExternalTrackerFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(opts.ExternalTracker.ExternalTrackerFormat) { | |||
err := fmt.Errorf("External tracker URL format not valid") | |||
ctx.Error(http.StatusUnprocessableEntity, "Invalid external tracker URL format", err) | |||
return err | |||
} | |||
units = append(units, models.RepoUnit{ | |||
RepoID: repo.ID, | |||
Type: models.UnitTypeExternalTracker, | |||
Config: &models.ExternalTrackerConfig{ | |||
ExternalTrackerURL: opts.ExternalTracker.ExternalTrackerURL, | |||
ExternalTrackerFormat: opts.ExternalTracker.ExternalTrackerFormat, | |||
ExternalTrackerStyle: opts.ExternalTracker.ExternalTrackerStyle, | |||
}, | |||
}) | |||
} else { | |||
config = unit.IssuesConfig() | |||
// Default to built-in tracker | |||
var config *models.IssuesConfig | |||
if opts.InternalTracker != nil { | |||
config = &models.IssuesConfig{ | |||
EnableTimetracker: opts.InternalTracker.EnableTimeTracker, | |||
AllowOnlyContributorsToTrackTime: opts.InternalTracker.AllowOnlyContributorsToTrackTime, | |||
EnableDependencies: opts.InternalTracker.EnableIssueDependencies, | |||
} | |||
} else if unit, err := repo.GetUnit(models.UnitTypeIssues); err != nil { | |||
// Unit type doesn't exist so we make a new config file with default values | |||
config = &models.IssuesConfig{ | |||
EnableTimetracker: true, | |||
AllowOnlyContributorsToTrackTime: true, | |||
EnableDependencies: true, | |||
} | |||
} else { | |||
config = unit.IssuesConfig() | |||
} | |||
units = append(units, models.RepoUnit{ | |||
RepoID: repo.ID, | |||
Type: models.UnitTypeIssues, | |||
Config: config, | |||
}) | |||
} | |||
units = append(units, models.RepoUnit{ | |||
RepoID: repo.ID, | |||
Type: models.UnitTypeIssues, | |||
Config: config, | |||
}) | |||
} | |||
if opts.HasWiki == nil { | |||
@@ -700,16 +730,30 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { | |||
units = append(units, *unit) | |||
} | |||
} else if *opts.HasWiki { | |||
// We don't currently allow setting individual wiki settings through the API, | |||
// only can enable/disable the wiki, so when enabling the wiki, | |||
// we either get the existing config which means it was already enabled, | |||
// or create a new config since it doesn't exist. | |||
config := &models.UnitConfig{} | |||
units = append(units, models.RepoUnit{ | |||
RepoID: repo.ID, | |||
Type: models.UnitTypeWiki, | |||
Config: config, | |||
}) | |||
if opts.ExternalWiki != nil { | |||
// Check that values are valid | |||
if !validation.IsValidExternalURL(opts.ExternalWiki.ExternalWikiURL) { | |||
err := fmt.Errorf("External wiki URL not valid") | |||
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid external wiki URL") | |||
return err | |||
} | |||
units = append(units, models.RepoUnit{ | |||
RepoID: repo.ID, | |||
Type: models.UnitTypeExternalWiki, | |||
Config: &models.ExternalWikiConfig{ | |||
ExternalWikiURL: opts.ExternalWiki.ExternalWikiURL, | |||
}, | |||
}) | |||
} else { | |||
config := &models.UnitConfig{} | |||
units = append(units, models.RepoUnit{ | |||
RepoID: repo.ID, | |||
Type: models.UnitTypeWiki, | |||
Config: config, | |||
}) | |||
} | |||
} | |||
if opts.HasPullRequests == nil { |
@@ -8469,6 +8469,12 @@ | |||
"type": "string", | |||
"x-go-name": "Description" | |||
}, | |||
"external_tracker": { | |||
"$ref": "#/definitions/ExternalTracker" | |||
}, | |||
"external_wiki": { | |||
"$ref": "#/definitions/ExternalWiki" | |||
}, | |||
"has_issues": { | |||
"description": "either `true` to enable issues for this repository or `false` to disable them.", | |||
"type": "boolean", | |||
@@ -8489,6 +8495,9 @@ | |||
"type": "boolean", | |||
"x-go-name": "IgnoreWhitespaceConflicts" | |||
}, | |||
"internal_tracker": { | |||
"$ref": "#/definitions/InternalTracker" | |||
}, | |||
"name": { | |||
"description": "name of the repository", | |||
"type": "string", | |||
@@ -8644,6 +8653,40 @@ | |||
}, | |||
"x-go-package": "code.gitea.io/gitea/modules/structs" | |||
}, | |||
"ExternalTracker": { | |||
"description": "ExternalTracker represents settings for external tracker", | |||
"type": "object", | |||
"properties": { | |||
"external_tracker_format": { | |||
"description": "External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index.", | |||
"type": "string", | |||
"x-go-name": "ExternalTrackerFormat" | |||
}, | |||
"external_tracker_style": { | |||
"description": "External Issue Tracker Number Format, either `numeric` or `alphanumeric`", | |||
"type": "string", | |||
"x-go-name": "ExternalTrackerStyle" | |||
}, | |||
"external_tracker_url": { | |||
"description": "URL of external issue tracker.", | |||
"type": "string", | |||
"x-go-name": "ExternalTrackerURL" | |||
} | |||
}, | |||
"x-go-package": "code.gitea.io/gitea/modules/structs" | |||
}, | |||
"ExternalWiki": { | |||
"description": "ExternalWiki represents setting for external wiki", | |||
"type": "object", | |||
"properties": { | |||
"external_wiki_url": { | |||
"description": "URL of external wiki.", | |||
"type": "string", | |||
"x-go-name": "ExternalWikiURL" | |||
} | |||
}, | |||
"x-go-package": "code.gitea.io/gitea/modules/structs" | |||
}, | |||
"FileCommitResponse": { | |||
"type": "object", | |||
"title": "FileCommitResponse contains information generated from a Git commit for a repo's file.", | |||
@@ -9008,6 +9051,28 @@ | |||
}, | |||
"x-go-package": "code.gitea.io/gitea/modules/structs" | |||
}, | |||
"InternalTracker": { | |||
"description": "InternalTracker represents settings for internal tracker", | |||
"type": "object", | |||
"properties": { | |||
"allow_only_contributors_to_track_time": { | |||
"description": "Let only contributors track time (Built-in issue tracker)", | |||
"type": "boolean", | |||
"x-go-name": "AllowOnlyContributorsToTrackTime" | |||
}, | |||
"enable_issue_dependencies": { | |||
"description": "Enable dependencies for issues and pull requests (Built-in issue tracker)", | |||
"type": "boolean", | |||
"x-go-name": "EnableIssueDependencies" | |||
}, | |||
"enable_time_tracker": { | |||
"description": "Enable time tracking (Built-in issue tracker)", | |||
"type": "boolean", | |||
"x-go-name": "EnableTimeTracker" | |||
} | |||
}, | |||
"x-go-package": "code.gitea.io/gitea/modules/structs" | |||
}, | |||
"Issue": { | |||
"description": "Issue represents an issue in a repository", | |||
"type": "object", | |||
@@ -9863,6 +9928,12 @@ | |||
"type": "boolean", | |||
"x-go-name": "Empty" | |||
}, | |||
"external_tracker": { | |||
"$ref": "#/definitions/ExternalTracker" | |||
}, | |||
"external_wiki": { | |||
"$ref": "#/definitions/ExternalWiki" | |||
}, | |||
"fork": { | |||
"type": "boolean", | |||
"x-go-name": "Fork" | |||
@@ -9901,6 +9972,9 @@ | |||
"type": "boolean", | |||
"x-go-name": "IgnoreWhitespaceConflicts" | |||
}, | |||
"internal_tracker": { | |||
"$ref": "#/definitions/InternalTracker" | |||
}, | |||
"mirror": { | |||
"type": "boolean", | |||
"x-go-name": "Mirror" |