Sync releases table with tags on push and for mirrors (#2459)
* Sync releases table with tags on push and for mirrors * Code style fixes * Fix api to return only releases * Optimize release creation and update Minimize posibility of race conditions * Fix release lower tag name updating * handle tag reference update by addionally comparing commit id
This commit is contained in:
parent
8b6236d67b
commit
7a0297819d
10 changed files with 370 additions and 122 deletions
|
@ -5,8 +5,6 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
api "code.gitea.io/sdk/gitea"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
|
@ -36,6 +34,7 @@ func GetRelease(ctx *context.APIContext) {
|
|||
func ListReleases(ctx *context.APIContext) {
|
||||
releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{
|
||||
IncludeDrafts: ctx.Repo.AccessMode >= models.AccessModeWrite,
|
||||
IncludeTags: false,
|
||||
}, 1, 2147483647)
|
||||
if err != nil {
|
||||
ctx.Error(500, "GetReleasesByRepoID", err)
|
||||
|
@ -62,43 +61,49 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
|
|||
ctx.Status(404)
|
||||
return
|
||||
}
|
||||
tag, err := ctx.Repo.GitRepo.GetTag(form.TagName)
|
||||
rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName)
|
||||
if err != nil {
|
||||
ctx.Error(500, "GetTag", err)
|
||||
return
|
||||
}
|
||||
commit, err := tag.Commit()
|
||||
if err != nil {
|
||||
ctx.Error(500, "Commit", err)
|
||||
return
|
||||
}
|
||||
commitsCount, err := commit.CommitsCount()
|
||||
if err != nil {
|
||||
ctx.Error(500, "CommitsCount", err)
|
||||
return
|
||||
}
|
||||
rel := &models.Release{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
PublisherID: ctx.User.ID,
|
||||
Publisher: ctx.User,
|
||||
TagName: form.TagName,
|
||||
LowerTagName: strings.ToLower(form.TagName),
|
||||
Target: form.Target,
|
||||
Title: form.Title,
|
||||
Sha1: commit.ID.String(),
|
||||
NumCommits: commitsCount,
|
||||
Note: form.Note,
|
||||
IsDraft: form.IsDraft,
|
||||
IsPrerelease: form.IsPrerelease,
|
||||
CreatedUnix: commit.Author.When.Unix(),
|
||||
}
|
||||
if err := models.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
|
||||
if models.IsErrReleaseAlreadyExist(err) {
|
||||
ctx.Status(409)
|
||||
} else {
|
||||
ctx.Error(500, "CreateRelease", err)
|
||||
if !models.IsErrReleaseNotExist(err) {
|
||||
ctx.Handle(500, "GetRelease", err)
|
||||
return
|
||||
}
|
||||
rel = &models.Release{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
PublisherID: ctx.User.ID,
|
||||
Publisher: ctx.User,
|
||||
TagName: form.TagName,
|
||||
Target: form.Target,
|
||||
Title: form.Title,
|
||||
Note: form.Note,
|
||||
IsDraft: form.IsDraft,
|
||||
IsPrerelease: form.IsPrerelease,
|
||||
IsTag: false,
|
||||
}
|
||||
if err := models.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
|
||||
if models.IsErrReleaseAlreadyExist(err) {
|
||||
ctx.Status(409)
|
||||
} else {
|
||||
ctx.Error(500, "CreateRelease", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if !rel.IsTag {
|
||||
ctx.Status(409)
|
||||
return
|
||||
}
|
||||
|
||||
rel.Title = form.Title
|
||||
rel.Note = form.Note
|
||||
rel.IsDraft = form.IsDraft
|
||||
rel.IsPrerelease = form.IsPrerelease
|
||||
rel.PublisherID = ctx.User.ID
|
||||
rel.IsTag = false
|
||||
|
||||
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
|
||||
ctx.Handle(500, "UpdateRelease", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.JSON(201, rel.APIFormat())
|
||||
}
|
||||
|
@ -111,11 +116,12 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
|
|||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
rel, err := models.GetReleaseByID(id)
|
||||
if err != nil {
|
||||
if err != nil && !models.IsErrReleaseNotExist(err) {
|
||||
ctx.Error(500, "GetReleaseByID", err)
|
||||
return
|
||||
}
|
||||
if rel.RepoID != ctx.Repo.Repository.ID {
|
||||
if err != nil && models.IsErrReleaseNotExist(err) ||
|
||||
rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.Status(404)
|
||||
return
|
||||
}
|
||||
|
@ -162,12 +168,13 @@ func DeleteRelease(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
release, err := models.GetReleaseByID(id)
|
||||
if err != nil {
|
||||
rel, err := models.GetReleaseByID(id)
|
||||
if err != nil && !models.IsErrReleaseNotExist(err) {
|
||||
ctx.Error(500, "GetReleaseByID", err)
|
||||
return
|
||||
}
|
||||
if release.RepoID != ctx.Repo.Repository.ID {
|
||||
if err != nil && models.IsErrReleaseNotExist(err) ||
|
||||
rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.Status(404)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ func Releases(ctx *context.Context) {
|
|||
|
||||
opts := models.FindReleasesOptions{
|
||||
IncludeDrafts: ctx.Repo.IsWriter(),
|
||||
IncludeTags: true,
|
||||
}
|
||||
|
||||
releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts, page, limit)
|
||||
|
@ -145,57 +146,61 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
|
|||
return
|
||||
}
|
||||
|
||||
var tagCreatedUnix int64
|
||||
tag, err := ctx.Repo.GitRepo.GetTag(form.TagName)
|
||||
if err == nil {
|
||||
commit, err := tag.Commit()
|
||||
if err == nil {
|
||||
tagCreatedUnix = commit.Author.When.Unix()
|
||||
}
|
||||
}
|
||||
|
||||
commit, err := ctx.Repo.GitRepo.GetBranchCommit(form.Target)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetBranchCommit", err)
|
||||
return
|
||||
}
|
||||
|
||||
commitsCount, err := commit.CommitsCount()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "CommitsCount", err)
|
||||
return
|
||||
}
|
||||
|
||||
rel := &models.Release{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
PublisherID: ctx.User.ID,
|
||||
Title: form.Title,
|
||||
TagName: form.TagName,
|
||||
Target: form.Target,
|
||||
Sha1: commit.ID.String(),
|
||||
NumCommits: commitsCount,
|
||||
Note: form.Content,
|
||||
IsDraft: len(form.Draft) > 0,
|
||||
IsPrerelease: form.Prerelease,
|
||||
CreatedUnix: tagCreatedUnix,
|
||||
}
|
||||
|
||||
var attachmentUUIDs []string
|
||||
if setting.AttachmentEnabled {
|
||||
attachmentUUIDs = form.Files
|
||||
}
|
||||
|
||||
if err = models.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
|
||||
ctx.Data["Err_TagName"] = true
|
||||
switch {
|
||||
case models.IsErrReleaseAlreadyExist(err):
|
||||
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_already_exist"), tplReleaseNew, &form)
|
||||
case models.IsErrInvalidTagName(err):
|
||||
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_invalid"), tplReleaseNew, &form)
|
||||
default:
|
||||
ctx.Handle(500, "CreateRelease", err)
|
||||
rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName)
|
||||
if err != nil {
|
||||
if !models.IsErrReleaseNotExist(err) {
|
||||
ctx.Handle(500, "GetRelease", err)
|
||||
return
|
||||
}
|
||||
|
||||
rel := &models.Release{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
PublisherID: ctx.User.ID,
|
||||
Title: form.Title,
|
||||
TagName: form.TagName,
|
||||
Target: form.Target,
|
||||
Note: form.Content,
|
||||
IsDraft: len(form.Draft) > 0,
|
||||
IsPrerelease: form.Prerelease,
|
||||
IsTag: false,
|
||||
}
|
||||
|
||||
if err = models.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
|
||||
ctx.Data["Err_TagName"] = true
|
||||
switch {
|
||||
case models.IsErrReleaseAlreadyExist(err):
|
||||
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_already_exist"), tplReleaseNew, &form)
|
||||
case models.IsErrInvalidTagName(err):
|
||||
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_invalid"), tplReleaseNew, &form)
|
||||
default:
|
||||
ctx.Handle(500, "CreateRelease", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if !rel.IsTag {
|
||||
ctx.Data["Err_TagName"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_already_exist"), tplReleaseNew, &form)
|
||||
return
|
||||
}
|
||||
|
||||
rel.Title = form.Title
|
||||
rel.Note = form.Content
|
||||
rel.IsDraft = len(form.Draft) > 0
|
||||
rel.IsPrerelease = form.Prerelease
|
||||
rel.PublisherID = ctx.User.ID
|
||||
rel.IsTag = false
|
||||
|
||||
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
|
||||
ctx.Data["Err_TagName"] = true
|
||||
ctx.Handle(500, "UpdateRelease", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Release created: %s/%s:%s", ctx.User.LowerName, ctx.Repo.Repository.Name, form.TagName)
|
||||
|
||||
|
@ -246,6 +251,10 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
|
|||
}
|
||||
return
|
||||
}
|
||||
if rel.IsTag {
|
||||
ctx.Handle(404, "GetRelease", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["tag_name"] = rel.TagName
|
||||
ctx.Data["tag_target"] = rel.Target
|
||||
ctx.Data["title"] = rel.Title
|
||||
|
@ -275,8 +284,7 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
|
|||
|
||||
// DeleteRelease delete a release
|
||||
func DeleteRelease(ctx *context.Context) {
|
||||
delTag := ctx.QueryBool("delTag")
|
||||
if err := models.DeleteReleaseByID(ctx.QueryInt64("id"), ctx.User, delTag); err != nil {
|
||||
if err := models.DeleteReleaseByID(ctx.QueryInt64("id"), ctx.User, true); err != nil {
|
||||
ctx.Flash.Error("DeleteReleaseByID: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.release.deletion_success"))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue