From a9869bf3731658378f1edf1be1186e957468bec3 Mon Sep 17 00:00:00 2001 From: spaeps <1037160+spaeps@users.noreply.github.com> Date: Wed, 2 Oct 2019 09:20:30 +0200 Subject: [PATCH 1/5] [arc-green] white on hover for active menu items (#8344) * [arc-green] white on hover for active menu items Actually, hovered active menu elements are in an unreadable black text colour. This should be changed to white. * [arc-green] white on hover for active menu items Actually, hovered active menu elements are in an unreadable black text colour. This should be changed to white. Now editing less files and commiting with `make css`. --- public/css/theme-arc-green.css | 2 +- public/less/themes/arc-green.less | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/public/css/theme-arc-green.css b/public/css/theme-arc-green.css index 938904c0bc216..28a127a3dd7b1 100644 --- a/public/css/theme-arc-green.css +++ b/public/css/theme-arc-green.css @@ -42,7 +42,7 @@ a:hover{color:#a0cc75} .ui.attached.table{border:1px solid #304251;background:#304251} .feeds .list ul li:not(:last-child){border-bottom:1px solid #333640} .feeds .list ul li.private{background:#353945;border:1px solid #333640} -.ui.secondary.menu .dropdown.item:hover,.ui.secondary.menu .link.item:hover,.ui.secondary.menu a.item:hover{color:#fff} +.ui.secondary.menu .active.item:hover,.ui.secondary.menu .dropdown.item:hover,.ui.secondary.menu .link.item:hover,.ui.secondary.menu a.item:hover{color:#fff} .ui.menu .ui.dropdown .menu>.item{background:#2c303a!important;color:#9e9e9e!important} .ui.secondary.menu .dropdown.item>.menu,.ui.text.menu .dropdown.item>.menu{border:1px solid #434444} footer{background:#2e323e;border-top:1px solid #313131} diff --git a/public/less/themes/arc-green.less b/public/less/themes/arc-green.less index cff51f0908f9d..27c32728a2f61 100644 --- a/public/less/themes/arc-green.less +++ b/public/less/themes/arc-green.less @@ -225,6 +225,7 @@ a:hover { .ui.secondary.menu .dropdown.item:hover, .ui.secondary.menu .link.item:hover, +.ui.secondary.menu .active.item:hover, .ui.secondary.menu a.item:hover { color: #ffffff; } From 68b1381b5ce3dd28777a3fd379283eb3bb2931ba Mon Sep 17 00:00:00 2001 From: David Svantesson Date: Wed, 2 Oct 2019 11:30:41 +0200 Subject: [PATCH 2/5] Api: advanced settings for repository (external wiki, issue tracker etc.) (#7756) * Add API for Repo Advanced Settings of wiki and issue tracker Signed-off-by: David Svantesson * 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 * Fix comment of structures Signed-off-by: David Svantesson * Rewrite API to use struct for setting tracker and wiki settings. * LetOnlyContributorsTrackTime -> AllowOnlyContributorsToTrackTime --- integrations/api_repo_edit_test.go | 106 ++++++++++++++++++++++++++++- models/repo.go | 28 +++++++- modules/structs/repo.go | 60 +++++++++++++--- routers/api/v1/repo/repo.go | 100 +++++++++++++++++++-------- templates/swagger/v1_json.tmpl | 74 ++++++++++++++++++++ 5 files changed, 327 insertions(+), 41 deletions(-) diff --git a/integrations/api_repo_edit_test.go b/integrations/api_repo_edit_test.go index 1231201b978fe..c1b513d0753c1 100644 --- a/integrations/api_repo_edit_test.go +++ b/integrations/api_repo_edit_test.go @@ -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) diff --git a/models/repo.go b/models/repo.go index eb7f286fec40a..69f32ae4a521a 100644 --- a/models/repo.go +++ b/models/repo.go @@ -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, diff --git a/modules/structs/repo.go b/modules/structs/repo.go index d94980fca4c7e..87396d6ce99a9 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -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. diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 513e7a37b3560..d8b06862a5ea6 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -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 { diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index fcc26f5c54bcd..d8750d8bcce46 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -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" From 808a477e3e6f8f148d7e8fbd54e078314db8092c Mon Sep 17 00:00:00 2001 From: Aam Surganda Date: Wed, 2 Oct 2019 19:58:40 +0700 Subject: [PATCH 3/5] Change general form binding to gogs form (#8334) --- routers/repo/webhook.go | 13 +++++-------- routers/routes/routes.go | 8 ++++---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 0711270cb9fd7..48b4e7afff66e 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -198,20 +198,17 @@ func WebHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { } // GogsHooksNewPost response for creating webhook -func GogsHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { - newGenericWebhookPost(ctx, form, models.GOGS) +func GogsHooksNewPost(ctx *context.Context, form auth.NewGogshookForm) { + newGogsWebhookPost(ctx, form, models.GOGS) } -func newGenericWebhookPost(ctx *context.Context, form auth.NewWebhookForm, kind models.HookTaskType) { +// newGogsWebhookPost response for creating gogs hook +func newGogsWebhookPost(ctx *context.Context, form auth.NewGogshookForm, kind models.HookTaskType) { ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} - - ctx.Data["HookType"] = "gitea" - if kind == models.GOGS { - ctx.Data["HookType"] = "gogs" - } + ctx.Data["HookType"] = "gogs" orCtx, err := getOrgRepoCtx(ctx) if err != nil { diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 5262d4ad5cf7f..11f2029226a7a 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -444,7 +444,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/delete", admin.DeleteDefaultWebhook) m.Get("/:type/new", repo.WebhooksNew) m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) - m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.GogsHooksNewPost) + m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) m.Post("/dingtalk/new", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) @@ -452,7 +452,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/msteams/new", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) m.Get("/:id", repo.WebHooksEdit) m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) - m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.GogsHooksEditPost) + m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost) m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) @@ -585,7 +585,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/delete", org.DeleteWebhook) m.Get("/:type/new", repo.WebhooksNew) m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) - m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.GogsHooksNewPost) + m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) m.Post("/dingtalk/new", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) @@ -647,7 +647,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/delete", repo.DeleteWebhook) m.Get("/:type/new", repo.WebhooksNew) m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) - m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.GogsHooksNewPost) + m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) m.Post("/dingtalk/new", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) From 15214fcbf2401a4647a0400e446739ec308e15cc Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 2 Oct 2019 13:01:01 +0000 Subject: [PATCH 4/5] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index e464b016b1b55..ca38757e1c7fe 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -1325,6 +1325,7 @@ settings.protect_merge_whitelist_committers_desc=ホワイトリストに登録 settings.protect_merge_whitelist_users=マージ・ホワイトリストに含むユーザー: settings.protect_merge_whitelist_teams=マージ・ホワイトリストに含むチーム: settings.protect_check_status_contexts=ステータスチェックを有効にする +settings.protect_check_status_contexts_desc=マージの前にステータスチェックがパスしていることを必須にします。 このルールの対象ブランチへのマージが可能となるまでに、事前にパスしている必要があるステータスチェックを選んでください。 有効にする場合は、まずコミットを別のブランチにプッシュし、ステータスチェックがパスしたあと、このルールの対象ブランチにマージするか、直接プッシュするようにします。 条件が選択されていない場合は、最後のコミットが成功していることが必須条件となります。 settings.protect_check_status_contexts_list=1週間の間にこのリポジトリにあったステータスチェック settings.protect_required_approvals=必要な承認数: settings.protect_required_approvals_desc=ホワイトリストに登録したユーザーやチームがレビューを行い、肯定的なレビューの数を満たしたプルリクエストしかマージできないようにします。 From ea7dc3bb54aec01a0fc501cdb1d47390858c46d0 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Wed, 2 Oct 2019 18:47:10 -0300 Subject: [PATCH 5/5] Extend time window for TestAPILFSLocksLogged --- integrations/api_repo_lfs_locks_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/api_repo_lfs_locks_test.go b/integrations/api_repo_lfs_locks_test.go index 6c0aeb1152950..4fe92b33b5f3b 100644 --- a/integrations/api_repo_lfs_locks_test.go +++ b/integrations/api_repo_lfs_locks_test.go @@ -126,7 +126,7 @@ func TestAPILFSLocksLogged(t *testing.T) { assert.Len(t, lfsLocks.Locks, test.totalCount) for i, lock := range lfsLocks.Locks { assert.EqualValues(t, test.locksOwners[i].DisplayName(), lock.Owner.Name) - assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 3*time.Second) + assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 10*time.Second) assert.EqualValues(t, lock.LockedAt.Format(time.RFC3339), lock.LockedAt.Format(time.RFC3339Nano)) //locked at should be rounded to second }