Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move create release from models to a standalone package #7539

Merged
merged 13 commits into from
Sep 15, 2019
124 changes: 11 additions & 113 deletions models/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,43 +112,20 @@ func IsReleaseExist(repoID int64, tagName string) (bool, error) {
return x.Get(&Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)})
}

func createTag(gitRepo *git.Repository, rel *Release) error {
// Only actual create when publish.
if !rel.IsDraft {
if !gitRepo.IsTagExist(rel.TagName) {
commit, err := gitRepo.GetCommit(rel.Target)
if err != nil {
return fmt.Errorf("GetCommit: %v", err)
}

// Trim '--' prefix to prevent command line argument vulnerability.
rel.TagName = strings.TrimPrefix(rel.TagName, "--")
if err = gitRepo.CreateTag(rel.TagName, commit.ID.String()); err != nil {
if strings.Contains(err.Error(), "is not a valid tag name") {
return ErrInvalidTagName{rel.TagName}
}
return err
}
rel.LowerTagName = strings.ToLower(rel.TagName)
}
commit, err := gitRepo.GetTagCommit(rel.TagName)
if err != nil {
return fmt.Errorf("GetTagCommit: %v", err)
}
// InsertRelease inserts a release
func InsertRelease(rel *Release) error {
_, err := x.Insert(rel)
return err
}

rel.Sha1 = commit.ID.String()
rel.CreatedUnix = timeutil.TimeStamp(commit.Author.When.Unix())
rel.NumCommits, err = commit.CommitsCount()
if err != nil {
return fmt.Errorf("CommitsCount: %v", err)
}
} else {
rel.CreatedUnix = timeutil.TimeStampNow()
}
return nil
// UpdateRelease updates all columns of a release
func UpdateRelease(rel *Release) error {
_, err := x.ID(rel.ID).AllCols().Update(rel)
return err
}

func addReleaseAttachments(releaseID int64, attachmentUUIDs []string) (err error) {
// AddReleaseAttachments adds a release attachments
func AddReleaseAttachments(releaseID int64, attachmentUUIDs []string) (err error) {
// Check attachments
var attachments = make([]*Attachment, 0)
for _, uuid := range attachmentUUIDs {
Expand All @@ -173,51 +150,6 @@ func addReleaseAttachments(releaseID int64, attachmentUUIDs []string) (err error
return
}

// CreateRelease creates a new release of repository.
func CreateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []string) error {
isExist, err := IsReleaseExist(rel.RepoID, rel.TagName)
if err != nil {
return err
} else if isExist {
return ErrReleaseAlreadyExist{rel.TagName}
}

if err = createTag(gitRepo, rel); err != nil {
return err
}
rel.LowerTagName = strings.ToLower(rel.TagName)

_, err = x.InsertOne(rel)
if err != nil {
return err
}

err = addReleaseAttachments(rel.ID, attachmentUUIDs)
if err != nil {
return err
}

if !rel.IsDraft {
if err := rel.LoadAttributes(); err != nil {
log.Error("LoadAttributes: %v", err)
} else {
mode, _ := AccessLevel(rel.Publisher, rel.Repo)
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleasePublished,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: rel.Publisher.APIFormat(),
}); err != nil {
log.Error("PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}
}
}

return nil
}

// GetRelease returns release by given ID.
func GetRelease(repoID int64, tagName string) (*Release, error) {
isExist, err := IsReleaseExist(repoID, tagName)
Expand Down Expand Up @@ -385,40 +317,6 @@ func SortReleases(rels []*Release) {
sort.Sort(sorter)
}

// UpdateRelease updates information of a release.
func UpdateRelease(doer *User, gitRepo *git.Repository, rel *Release, attachmentUUIDs []string) (err error) {
if err = createTag(gitRepo, rel); err != nil {
return err
}
rel.LowerTagName = strings.ToLower(rel.TagName)

_, err = x.ID(rel.ID).AllCols().Update(rel)
if err != nil {
return err
}

err = rel.loadAttributes(x)
if err != nil {
return err
}

err = addReleaseAttachments(rel.ID, attachmentUUIDs)

mode, _ := AccessLevel(doer, rel.Repo)
if err1 := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseUpdated,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
}); err1 != nil {
log.Error("PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}

return err
}

// DeleteReleaseByID deletes a release and corresponding Git tag by given ID.
func DeleteReleaseByID(id int64, doer *User, delTag bool) error {
rel, err := GetReleaseByID(id)
Expand Down
6 changes: 6 additions & 0 deletions models/repo_mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
return parseRemoteUpdateOutput(output), true
}

// RunMirrorSync will invoke Mirror's runSync
func RunMirrorSync(mirror *Mirror) bool {
_, ok := mirror.runSync()
return ok
}

func getMirrorByRepoID(e Engine, repoID int64) (*Mirror, error) {
m := &Mirror{RepoID: repoID}
has, err := e.Get(m)
Expand Down
7 changes: 4 additions & 3 deletions routers/api/v1/repo/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
releaseservice "code.gitea.io/gitea/services/release"
)

// GetRelease get a single release of a repository
Expand Down Expand Up @@ -168,7 +169,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
IsTag: false,
Repo: ctx.Repo.Repository,
}
if err := models.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
if err := releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
if models.IsErrReleaseAlreadyExist(err) {
ctx.Status(409)
} else {
Expand All @@ -191,7 +192,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
rel.Repo = ctx.Repo.Repository
rel.Publisher = ctx.User

if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.ServerError("UpdateRelease", err)
return
}
Expand Down Expand Up @@ -262,7 +263,7 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
if form.IsPrerelease != nil {
rel.IsPrerelease = *form.IsPrerelease
}
if err := models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
if err := releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.Error(500, "UpdateRelease", err)
return
}
Expand Down
7 changes: 4 additions & 3 deletions routers/repo/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
releaseservice "code.gitea.io/gitea/services/release"
)

const (
Expand Down Expand Up @@ -175,7 +176,7 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
IsTag: false,
}

if err = models.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
if err = releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.Data["Err_TagName"] = true
switch {
case models.IsErrReleaseAlreadyExist(err):
Expand All @@ -202,7 +203,7 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
rel.PublisherID = ctx.User.ID
rel.IsTag = false

if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.Data["Err_TagName"] = true
ctx.ServerError("UpdateRelease", err)
return
Expand Down Expand Up @@ -281,7 +282,7 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
rel.Note = form.Content
rel.IsDraft = len(form.Draft) > 0
rel.IsPrerelease = form.Prerelease
if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.ServerError("UpdateRelease", err)
return
}
Expand Down
132 changes: 132 additions & 0 deletions services/release/release.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package release

import (
"fmt"
"strings"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
)

func createTag(gitRepo *git.Repository, rel *models.Release) error {
// Only actual create when publish.
if !rel.IsDraft {
if !gitRepo.IsTagExist(rel.TagName) {
commit, err := gitRepo.GetCommit(rel.Target)
if err != nil {
return fmt.Errorf("GetCommit: %v", err)
}

// Trim '--' prefix to prevent command line argument vulnerability.
rel.TagName = strings.TrimPrefix(rel.TagName, "--")
if err = gitRepo.CreateTag(rel.TagName, commit.ID.String()); err != nil {
if strings.Contains(err.Error(), "is not a valid tag name") {
return models.ErrInvalidTagName{
TagName: rel.TagName,
}
}
return err
}
rel.LowerTagName = strings.ToLower(rel.TagName)
}
commit, err := gitRepo.GetTagCommit(rel.TagName)
if err != nil {
return fmt.Errorf("GetTagCommit: %v", err)
}

rel.Sha1 = commit.ID.String()
rel.CreatedUnix = timeutil.TimeStamp(commit.Author.When.Unix())
rel.NumCommits, err = commit.CommitsCount()
if err != nil {
return fmt.Errorf("CommitsCount: %v", err)
}
} else {
rel.CreatedUnix = timeutil.TimeStampNow()
}
return nil
}

// CreateRelease creates a new release of repository.
func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string) error {
isExist, err := models.IsReleaseExist(rel.RepoID, rel.TagName)
if err != nil {
return err
} else if isExist {
return models.ErrReleaseAlreadyExist{
TagName: rel.TagName,
}
}

if err = createTag(gitRepo, rel); err != nil {
return err
}

rel.LowerTagName = strings.ToLower(rel.TagName)
if err = models.InsertRelease(rel); err != nil {
return err
}

if err = models.AddReleaseAttachments(rel.ID, attachmentUUIDs); err != nil {
return err
}

if !rel.IsDraft {
if err := rel.LoadAttributes(); err != nil {
log.Error("LoadAttributes: %v", err)
} else {
mode, _ := models.AccessLevel(rel.Publisher, rel.Repo)
if err := models.PrepareWebhooks(rel.Repo, models.HookEventRelease, &api.ReleasePayload{
Action: api.HookReleasePublished,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: rel.Publisher.APIFormat(),
}); err != nil {
log.Error("PrepareWebhooks: %v", err)
} else {
go models.HookQueue.Add(rel.Repo.ID)
}
}
}

return nil
}

// UpdateRelease updates information of a release.
func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string) (err error) {
if err = createTag(gitRepo, rel); err != nil {
return err
}
rel.LowerTagName = strings.ToLower(rel.TagName)

if err = models.UpdateRelease(rel); err != nil {
return err
}

if err = rel.LoadAttributes(); err != nil {
return err
}

err = models.AddReleaseAttachments(rel.ID, attachmentUUIDs)

// even if attachments added failed, hooks will be still triggered
mode, _ := models.AccessLevel(doer, rel.Repo)
if err1 := models.PrepareWebhooks(rel.Repo, models.HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseUpdated,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
}); err1 != nil {
log.Error("PrepareWebhooks: %v", err)
} else {
go models.HookQueue.Add(rel.Repo.ID)
}

return err
}
Loading