aboutsummaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorJakobDev <jakobdev@gmx.de>2023-03-28 20:22:07 +0200
committerGitHub <noreply@github.com>2023-03-28 14:22:07 -0400
commitf384b13f1cd44be3a87df5553a0099390dacd010 (patch)
tree08b2744df3a8792ef2f50e4d559d55e4a349c198 /routers
parent5cd1d6c93ba9b8399f826e671b8940eb5294b872 (diff)
downloadgitea-f384b13f1cd44be3a87df5553a0099390dacd010.tar.gz
gitea-f384b13f1cd44be3a87df5553a0099390dacd010.zip
Implement Issue Config (#20956)
Closes #20955 This PR adds the possibility to disable blank Issues, when the Repo has templates. This can be done by creating the file `.gitea/issue_config.yaml` with the content `blank_issues_enabled` in the Repo.
Diffstat (limited to 'routers')
-rw-r--r--routers/api/v1/api.go2
-rw-r--r--routers/api/v1/repo/repo.go55
-rw-r--r--routers/api/v1/swagger/repo.go14
-rw-r--r--routers/web/repo/issue.go14
-rw-r--r--routers/web/repo/view.go3
5 files changed, 83 insertions, 5 deletions
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 7d1980baeb..8b13f5492c 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -1169,6 +1169,8 @@ func Routes(ctx gocontext.Context) *web.Route {
}, reqAdmin())
}, reqAnyRepoReader())
m.Get("/issue_templates", context.ReferencesGitRepo(), repo.GetIssueTemplates)
+ m.Get("/issue_config", context.ReferencesGitRepo(), repo.GetIssueConfig)
+ m.Get("/issue_config/validate", context.ReferencesGitRepo(), repo.ValidateIssueConfig)
m.Get("/languages", reqRepoReader(unit.TypeCode), repo.GetLanguages)
}, repoAssignment())
})
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 4f43b10259..60e71495e8 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -1144,3 +1144,58 @@ func GetIssueTemplates(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, ctx.IssueTemplatesFromDefaultBranch())
}
+
+// GetIssueConfig returns the issue config for a repo
+func GetIssueConfig(ctx *context.APIContext) {
+ // swagger:operation GET /repos/{owner}/{repo}/issue_config repository repoGetIssueConfig
+ // ---
+ // summary: Returns the issue config for a repo
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/RepoIssueConfig"
+ issueConfig, _ := ctx.IssueConfigFromDefaultBranch()
+ ctx.JSON(http.StatusOK, issueConfig)
+}
+
+// ValidateIssueConfig returns validation errors for the issue config
+func ValidateIssueConfig(ctx *context.APIContext) {
+ // swagger:operation GET /repos/{owner}/{repo}/issue_config/validate repository repoValidateIssueConfig
+ // ---
+ // summary: Returns the validation information for a issue config
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/RepoIssueConfigValidation"
+ _, err := ctx.IssueConfigFromDefaultBranch()
+
+ if err == nil {
+ ctx.JSON(http.StatusOK, api.IssueConfigValidation{Valid: true, Message: ""})
+ } else {
+ ctx.JSON(http.StatusOK, api.IssueConfigValidation{Valid: false, Message: err.Error()})
+ }
+}
diff --git a/routers/api/v1/swagger/repo.go b/routers/api/v1/swagger/repo.go
index bd867213a6..e0418e99dc 100644
--- a/routers/api/v1/swagger/repo.go
+++ b/routers/api/v1/swagger/repo.go
@@ -386,3 +386,17 @@ type swaggerRepoCollaboratorPermission struct {
// in:body
Body api.RepoCollaboratorPermission `json:"body"`
}
+
+// RepoIssueConfig
+// swagger:response RepoIssueConfig
+type swaggerRepoIssueConfig struct {
+ // in:body
+ Body api.IssueConfig `json:"body"`
+}
+
+// RepoIssueConfigValidation
+// swagger:response RepoIssueConfigValidation
+type swaggerRepoIssueConfigValidation struct {
+ // in:body
+ Body api.IssueConfigValidation `json:"body"`
+}
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 00551a8848..612222598f 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -435,7 +435,7 @@ func Issues(ctx *context.Context) {
}
ctx.Data["Title"] = ctx.Tr("repo.issues")
ctx.Data["PageIsIssueList"] = true
- ctx.Data["NewIssueChooseTemplate"] = len(ctx.IssueTemplatesFromDefaultBranch()) > 0
+ ctx.Data["NewIssueChooseTemplate"] = ctx.HasIssueTemplatesOrContactLinks()
}
issues(ctx, ctx.FormInt64("milestone"), ctx.FormInt64("project"), util.OptionalBoolOf(isPullList))
@@ -848,7 +848,7 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles
func NewIssue(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.issues.new")
ctx.Data["PageIsIssueList"] = true
- ctx.Data["NewIssueChooseTemplate"] = len(ctx.IssueTemplatesFromDefaultBranch()) > 0
+ ctx.Data["NewIssueChooseTemplate"] = ctx.HasIssueTemplatesOrContactLinks()
ctx.Data["RequireTribute"] = true
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
title := ctx.FormString("title")
@@ -946,12 +946,16 @@ func NewIssueChooseTemplate(ctx *context.Context) {
ctx.Flash.Warning(renderErrorOfTemplates(ctx, errs), true)
}
- if len(issueTemplates) == 0 {
+ if !ctx.HasIssueTemplatesOrContactLinks() {
// The "issues/new" and "issues/new/choose" share the same query parameters "project" and "milestone", if no template here, just redirect to the "issues/new" page with these parameters.
ctx.Redirect(fmt.Sprintf("%s/issues/new?%s", ctx.Repo.Repository.Link(), ctx.Req.URL.RawQuery), http.StatusSeeOther)
return
}
+ issueConfig, err := ctx.IssueConfigFromDefaultBranch()
+ ctx.Data["IssueConfig"] = issueConfig
+ ctx.Data["IssueConfigError"] = err // ctx.Flash.Err makes problems here
+
ctx.Data["milestone"] = ctx.FormInt64("milestone")
ctx.Data["project"] = ctx.FormInt64("project")
@@ -1086,7 +1090,7 @@ func NewIssuePost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CreateIssueForm)
ctx.Data["Title"] = ctx.Tr("repo.issues.new")
ctx.Data["PageIsIssueList"] = true
- ctx.Data["NewIssueChooseTemplate"] = len(ctx.IssueTemplatesFromDefaultBranch()) > 0
+ ctx.Data["NewIssueChooseTemplate"] = ctx.HasIssueTemplatesOrContactLinks()
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled
upload.AddUploadContext(ctx, "comment")
@@ -1280,7 +1284,7 @@ func ViewIssue(ctx *context.Context) {
return
}
ctx.Data["PageIsIssueList"] = true
- ctx.Data["NewIssueChooseTemplate"] = len(ctx.IssueTemplatesFromDefaultBranch()) > 0
+ ctx.Data["NewIssueChooseTemplate"] = ctx.HasIssueTemplatesOrContactLinks()
}
if issue.IsPull && !ctx.Repo.CanRead(unit.TypeIssues) {
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 4d49ab6359..ce60d91150 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -348,6 +348,9 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
if ctx.Repo.TreePath == ".editorconfig" {
_, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit)
ctx.Data["FileError"] = editorconfigErr
+ } else if ctx.Repo.IsIssueConfig(ctx.Repo.TreePath) {
+ _, issueConfigErr := ctx.Repo.GetIssueConfig(ctx.Repo.TreePath, ctx.Repo.Commit)
+ ctx.Data["FileError"] = issueConfigErr
}
isDisplayingSource := ctx.FormString("display") == "source"