Skip to content

Commit b2a9ea0

Browse files
committed
Optimize release creation and update
Minimize posibility of race conditions
1 parent 8b78ce7 commit b2a9ea0

File tree

3 files changed

+76
-71
lines changed

3 files changed

+76
-71
lines changed

models/release.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,17 @@ func createTag(gitRepo *git.Repository, rel *Release) error {
140140
}
141141
return err
142142
}
143-
} else {
144-
commit, err := gitRepo.GetTagCommit(rel.TagName)
145-
if err != nil {
146-
return fmt.Errorf("GetTagCommit: %v", err)
147-
}
143+
}
144+
commit, err := gitRepo.GetTagCommit(rel.TagName)
145+
if err != nil {
146+
return fmt.Errorf("GetTagCommit: %v", err)
147+
}
148148

149-
rel.Sha1 = commit.ID.String()
150-
rel.NumCommits, err = commit.CommitsCount()
151-
if err != nil {
152-
return fmt.Errorf("CommitsCount: %v", err)
153-
}
149+
rel.Sha1 = commit.ID.String()
150+
rel.CreatedUnix = commit.Author.When.Unix()
151+
rel.NumCommits, err = commit.CommitsCount()
152+
if err != nil {
153+
return fmt.Errorf("CommitsCount: %v", err)
154154
}
155155
}
156156
return nil

routers/api/v1/repo/release.go

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -63,29 +63,47 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
6363
}
6464
rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName)
6565
if err != nil {
66-
if models.IsErrReleaseNotExist(err) {
67-
ctx.Status(404)
66+
if !models.IsErrReleaseNotExist(err) {
67+
ctx.Handle(500, "GetRelease", err)
68+
return
69+
}
70+
rel = &models.Release{
71+
RepoID: ctx.Repo.Repository.ID,
72+
PublisherID: ctx.User.ID,
73+
Publisher: ctx.User,
74+
TagName: form.TagName,
75+
Target: form.Target,
76+
Title: form.Title,
77+
Note: form.Note,
78+
IsDraft: form.IsDraft,
79+
IsPrerelease: form.IsPrerelease,
80+
IsTag: false,
81+
}
82+
if err := models.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
83+
if models.IsErrReleaseAlreadyExist(err) {
84+
ctx.Status(409)
85+
} else {
86+
ctx.Error(500, "CreateRelease", err)
87+
}
88+
return
89+
}
90+
} else {
91+
if !rel.IsTag {
92+
ctx.Status(409)
6893
return
6994
}
70-
ctx.Handle(500, "GetRelease", err)
71-
return
72-
}
73-
74-
if !rel.IsTag {
75-
ctx.Status(409)
76-
return
77-
}
7895

79-
rel.Title = form.Title
80-
rel.Note = form.Note
81-
rel.IsDraft = form.IsDraft
82-
rel.IsPrerelease = form.IsPrerelease
83-
rel.PublisherID = ctx.User.ID
84-
rel.IsTag = false
96+
rel.Title = form.Title
97+
rel.Note = form.Note
98+
rel.IsDraft = form.IsDraft
99+
rel.IsPrerelease = form.IsPrerelease
100+
rel.PublisherID = ctx.User.ID
101+
rel.IsTag = false
85102

86-
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
87-
ctx.Handle(500, "UpdateRelease", err)
88-
return
103+
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
104+
ctx.Handle(500, "UpdateRelease", err)
105+
return
106+
}
89107
}
90108
ctx.JSON(201, rel.APIFormat())
91109
}

routers/repo/release.go

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -146,64 +146,28 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
146146
return
147147
}
148148

149-
var tagCreatedUnix int64
150-
tag, err := ctx.Repo.GitRepo.GetTag(form.TagName)
151-
if err == nil {
152-
commit, err := tag.Commit()
153-
if err == nil {
154-
tagCreatedUnix = commit.Author.When.Unix()
155-
}
156-
}
157-
158-
commit, err := ctx.Repo.GitRepo.GetBranchCommit(form.Target)
159-
if err != nil {
160-
ctx.Handle(500, "GetBranchCommit", err)
161-
return
162-
}
163-
164-
commitsCount, err := commit.CommitsCount()
165-
if err != nil {
166-
ctx.Handle(500, "CommitsCount", err)
167-
return
168-
}
169-
170-
rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName)
171-
if err != nil && !models.IsErrReleaseNotExist(err) {
172-
ctx.Handle(500, "GetRelease", err)
173-
return
174-
}
175-
176149
var attachmentUUIDs []string
177150
if setting.AttachmentEnabled {
178151
attachmentUUIDs = form.Files
179152
}
180153

181-
if rel != nil && rel.IsTag {
182-
rel.Title = form.Title
183-
rel.Note = form.Content
184-
rel.IsDraft = len(form.Draft) > 0
185-
rel.IsPrerelease = form.Prerelease
186-
rel.PublisherID = ctx.User.ID
187-
rel.IsTag = false
188-
189-
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
190-
ctx.Data["Err_TagName"] = true
191-
ctx.Handle(500, "UpdateRelease", err)
154+
rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName)
155+
if err != nil {
156+
if !models.IsErrReleaseNotExist(err) {
157+
ctx.Handle(500, "GetRelease", err)
192158
return
193159
}
194-
} else {
160+
195161
rel := &models.Release{
196162
RepoID: ctx.Repo.Repository.ID,
197163
PublisherID: ctx.User.ID,
198164
Title: form.Title,
199165
TagName: form.TagName,
200166
Target: form.Target,
201-
Sha1: commit.ID.String(),
202-
NumCommits: commitsCount,
203167
Note: form.Content,
204168
IsDraft: len(form.Draft) > 0,
205169
IsPrerelease: form.Prerelease,
206-
CreatedUnix: tagCreatedUnix,
170+
IsTag: false,
207171
}
208172

209173
if err = models.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
@@ -218,6 +182,25 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
218182
}
219183
return
220184
}
185+
} else {
186+
if !rel.IsTag {
187+
ctx.Data["Err_TagName"] = true
188+
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_already_exist"), tplReleaseNew, &form)
189+
return
190+
}
191+
192+
rel.Title = form.Title
193+
rel.Note = form.Content
194+
rel.IsDraft = len(form.Draft) > 0
195+
rel.IsPrerelease = form.Prerelease
196+
rel.PublisherID = ctx.User.ID
197+
rel.IsTag = false
198+
199+
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
200+
ctx.Data["Err_TagName"] = true
201+
ctx.Handle(500, "UpdateRelease", err)
202+
return
203+
}
221204
}
222205
log.Trace("Release created: %s/%s:%s", ctx.User.LowerName, ctx.Repo.Repository.Name, form.TagName)
223206

@@ -268,6 +251,10 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
268251
}
269252
return
270253
}
254+
if rel.IsTag {
255+
ctx.Handle(404, "GetRelease", err)
256+
return
257+
}
271258
ctx.Data["tag_name"] = rel.TagName
272259
ctx.Data["tag_target"] = rel.Target
273260
ctx.Data["title"] = rel.Title

0 commit comments

Comments
 (0)