Skip to content

Commit 6f55645

Browse files
committed
feat: automatic generation of release notes
dummy commit fix cs fix fix remove test file
1 parent 1da1e64 commit 6f55645

File tree

8 files changed

+639
-0
lines changed

8 files changed

+639
-0
lines changed

options/locale/locale_en-US.ini

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,6 +2751,14 @@ release.add_tag_msg = Use the title and content of release as tag message.
27512751
release.add_tag = Create Tag Only
27522752
release.releases_for = Releases for %s
27532753
release.tags_for = Tags for %s
2754+
release.generate_notes = Generate release notes
2755+
release.generate_notes_desc = Automatically add merged pull requests and a changelog link for this release.
2756+
release.previous_tag = Previous tag
2757+
release.previous_tag_auto = Auto
2758+
release.generate_notes_tag_not_found = Tag "%s" does not exist in this repository.
2759+
release.generate_notes_no_base_tag = No previous tag found to generate release notes.
2760+
release.generate_notes_target_not_found = The release target "%s" cannot be found.
2761+
release.generate_notes_missing_tag = Enter a tag name to generate release notes.
27542762
27552763
branch.name = Branch Name
27562764
branch.already_exists = A branch named "%s" already exists.

routers/web/repo/release.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"code.gitea.io/gitea/models/unit"
1919
user_model "code.gitea.io/gitea/models/user"
2020
"code.gitea.io/gitea/modules/git"
21+
"code.gitea.io/gitea/modules/log"
2122
"code.gitea.io/gitea/modules/markup/markdown"
2223
"code.gitea.io/gitea/modules/optional"
2324
"code.gitea.io/gitea/modules/setting"
@@ -390,6 +391,45 @@ func NewRelease(ctx *context.Context) {
390391
ctx.HTML(http.StatusOK, tplReleaseNew)
391392
}
392393

394+
// GenerateReleaseNotes builds release notes content for the given tag and base.
395+
func GenerateReleaseNotes(ctx *context.Context) {
396+
form := web.GetForm(ctx).(*forms.GenerateReleaseNotesForm)
397+
398+
if ctx.HasError() {
399+
ctx.JSONError(ctx.GetErrMsg())
400+
return
401+
}
402+
403+
result, err := release_service.GenerateReleaseNotes(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, release_service.GenerateReleaseNotesOptions{
404+
TagName: form.TagName,
405+
Target: form.Target,
406+
PreviousTag: form.PreviousTag,
407+
})
408+
if err != nil {
409+
var tagErr release_service.ErrReleaseNotesTagNotFound
410+
var targetErr release_service.ErrReleaseNotesTargetNotFound
411+
switch {
412+
case release_service.IsErrReleaseNotesNoBaseTag(err):
413+
ctx.JSONError(ctx.Tr("repo.release.generate_notes_no_base_tag"))
414+
case errors.As(err, &tagErr):
415+
ctx.JSONError(ctx.Tr("repo.release.generate_notes_tag_not_found", tagErr.TagName))
416+
case errors.As(err, &targetErr):
417+
ctx.JSONError(ctx.Tr("repo.release.generate_notes_target_not_found", targetErr.Ref))
418+
default:
419+
log.Error("GenerateReleaseNotes: %v", err)
420+
ctx.JSON(http.StatusInternalServerError, map[string]any{
421+
"errorMessage": ctx.Tr("error.occurred"),
422+
})
423+
}
424+
return
425+
}
426+
427+
ctx.JSON(http.StatusOK, map[string]any{
428+
"content": result.Content,
429+
"previous_tag": result.PreviousTag,
430+
})
431+
}
432+
393433
// NewReleasePost response for creating a release
394434
func NewReleasePost(ctx *context.Context) {
395435
newReleaseCommon(ctx)

routers/web/web.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,7 @@ func registerWebRoutes(m *web.Router) {
14061406
m.Group("/releases", func() {
14071407
m.Get("/new", repo.NewRelease)
14081408
m.Post("/new", web.Bind(forms.NewReleaseForm{}), repo.NewReleasePost)
1409+
m.Post("/generate-notes", web.Bind(forms.GenerateReleaseNotesForm{}), repo.GenerateReleaseNotes)
14091410
m.Post("/delete", repo.DeleteRelease)
14101411
m.Post("/attachments", repo.UploadReleaseAttachment)
14111412
m.Post("/attachments/remove", repo.DeleteAttachment)

services/forms/repo_form.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,19 @@ func (f *NewReleaseForm) Validate(req *http.Request, errs binding.Errors) bindin
638638
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
639639
}
640640

641+
// GenerateReleaseNotesForm retrieves release notes recommendations.
642+
type GenerateReleaseNotesForm struct {
643+
TagName string `form:"tag_name" binding:"Required;GitRefName;MaxSize(255)"`
644+
Target string `form:"tag_target" binding:"MaxSize(255)"`
645+
PreviousTag string `form:"previous_tag" binding:"MaxSize(255)"`
646+
}
647+
648+
// Validate validates the fields
649+
func (f *GenerateReleaseNotesForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
650+
ctx := context.GetValidateContext(req)
651+
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
652+
}
653+
641654
// EditReleaseForm form for changing release
642655
type EditReleaseForm struct {
643656
Title string `form:"title" binding:"Required;MaxSize(255)"`

0 commit comments

Comments
 (0)