Skip to content

Commit 83cf1a8

Browse files
a1012112796lafriks6543zeripath
authored
Create tag on ui (#13467)
Support create single tag directly support create tag with message from create release ui Signed-off-by: a1012112796 <[email protected]> Co-authored-by: Lauris BH <[email protected]> Co-authored-by: 6543 <[email protected]> Co-authored-by: zeripath <[email protected]>
1 parent 3e65286 commit 83cf1a8

File tree

13 files changed

+149
-29
lines changed

13 files changed

+149
-29
lines changed

modules/forms/repo_branch_form.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
// NewBranchForm form for creating a new branch
1717
type NewBranchForm struct {
1818
NewBranchName string `binding:"Required;MaxSize(100);GitRefName"`
19+
CreateTag bool
1920
}
2021

2122
// Validate validates the fields

modules/forms/repo_form.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,9 @@ type NewReleaseForm struct {
642642
Title string `binding:"Required;MaxSize(255)"`
643643
Content string
644644
Draft string
645+
TagOnly string
645646
Prerelease bool
647+
AddTagMsg bool
646648
Files []string
647649
}
648650

modules/git/repo_tag_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestRepository_GetTag(t *testing.T) {
4343

4444
aTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"
4545
aTagName := "annotatedTag"
46-
aTagMessage := "my annotated message"
46+
aTagMessage := "my annotated message \n - test two line"
4747
bareRepo1.CreateAnnotatedTag(aTagName, aTagMessage, aTagCommitID)
4848
aTagID, _ := bareRepo1.GetTagID(aTagName)
4949

options/locale/locale_en-US.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,6 +1895,8 @@ release.tag_name_invalid = The tag name is not valid.
18951895
release.tag_already_exist = This tag name already exists.
18961896
release.downloads = Downloads
18971897
release.download_count = Downloads: %s
1898+
release.add_tag_msg = Use the title and content of release as tag message.
1899+
release.add_tag = Create Tag Only
18981900

18991901
branch.name = Branch Name
19001902
branch.search = Search branches
@@ -1922,6 +1924,9 @@ branch.download = Download Branch '%s'
19221924
branch.included_desc = This branch is part of the default branch
19231925
branch.included = Included
19241926

1927+
tag.create_tag = Create tag <strong>%s</strong>
1928+
tag.create_success = Tag '%s' has been created.
1929+
19251930
topic.manage_topics = Manage Topics
19261931
topic.done = Done
19271932
topic.count_prompt = You can not select more than 25 topics

routers/api/v1/repo/release.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func CreateRelease(ctx *context.APIContext) {
179179
IsTag: false,
180180
Repo: ctx.Repo.Repository,
181181
}
182-
if err := releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
182+
if err := releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil {
183183
if models.IsErrReleaseAlreadyExist(err) {
184184
ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err)
185185
} else {

routers/repo/branch.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"code.gitea.io/gitea/modules/util"
2121
"code.gitea.io/gitea/modules/web"
2222
"code.gitea.io/gitea/routers/utils"
23+
release_service "code.gitea.io/gitea/services/release"
2324
repo_service "code.gitea.io/gitea/services/repository"
2425
)
2526

@@ -383,7 +384,14 @@ func CreateBranch(ctx *context.Context) {
383384
}
384385

385386
var err error
386-
if ctx.Repo.IsViewBranch {
387+
388+
if form.CreateTag {
389+
if ctx.Repo.IsViewTag {
390+
err = release_service.CreateNewTag(ctx.User, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName, "")
391+
} else {
392+
err = release_service.CreateNewTag(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName, "")
393+
}
394+
} else if ctx.Repo.IsViewBranch {
387395
err = repo_module.CreateNewBranch(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName)
388396
} else if ctx.Repo.IsViewTag {
389397
err = repo_module.CreateNewBranchFromCommit(ctx.User, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName)
@@ -432,6 +440,12 @@ func CreateBranch(ctx *context.Context) {
432440
return
433441
}
434442

443+
if form.CreateTag {
444+
ctx.Flash.Success(ctx.Tr("repo.tag.create_success", form.NewBranchName))
445+
ctx.Redirect(ctx.Repo.RepoLink + "/src/tag/" + util.PathEscapeSegments(form.NewBranchName))
446+
return
447+
}
448+
435449
ctx.Flash.Success(ctx.Tr("repo.branch.create_success", form.NewBranchName))
436450
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(form.NewBranchName))
437451
}

routers/repo/release.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,29 @@ func NewReleasePost(ctx *context.Context) {
262262
return
263263
}
264264

265+
msg := ""
266+
if len(form.Title) > 0 && form.AddTagMsg {
267+
msg = form.Title + "\n\n" + form.Content
268+
}
269+
270+
if len(form.TagOnly) > 0 {
271+
if err = releaseservice.CreateNewTag(ctx.User, ctx.Repo.Repository, form.Target, form.TagName, msg); err != nil {
272+
if models.IsErrTagAlreadyExists(err) {
273+
e := err.(models.ErrTagAlreadyExists)
274+
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))
275+
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
276+
return
277+
}
278+
279+
ctx.ServerError("releaseservice.CreateNewTag", err)
280+
return
281+
}
282+
283+
ctx.Flash.Success(ctx.Tr("repo.tag.create_success", form.TagName))
284+
ctx.Redirect(ctx.Repo.RepoLink + "/src/tag/" + form.TagName)
285+
return
286+
}
287+
265288
rel = &models.Release{
266289
RepoID: ctx.Repo.Repository.ID,
267290
PublisherID: ctx.User.ID,
@@ -274,7 +297,7 @@ func NewReleasePost(ctx *context.Context) {
274297
IsTag: false,
275298
}
276299

277-
if err = releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
300+
if err = releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs, msg); err != nil {
278301
ctx.Data["Err_TagName"] = true
279302
switch {
280303
case models.IsErrReleaseAlreadyExist(err):

services/mirror/mirror_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func TestRelease_MirrorDelete(t *testing.T) {
6969
IsDraft: false,
7070
IsPrerelease: false,
7171
IsTag: true,
72-
}, nil))
72+
}, nil, ""))
7373

7474
err = mirror.GetMirror()
7575
assert.NoError(t, err)

services/release/release.go

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
"code.gitea.io/gitea/modules/timeutil"
1818
)
1919

20-
func createTag(gitRepo *git.Repository, rel *models.Release) error {
20+
func createTag(gitRepo *git.Repository, rel *models.Release, msg string) error {
2121
// Only actual create when publish.
2222
if !rel.IsDraft {
2323
if !gitRepo.IsTagExist(rel.TagName) {
@@ -28,7 +28,16 @@ func createTag(gitRepo *git.Repository, rel *models.Release) error {
2828

2929
// Trim '--' prefix to prevent command line argument vulnerability.
3030
rel.TagName = strings.TrimPrefix(rel.TagName, "--")
31-
if err = gitRepo.CreateTag(rel.TagName, commit.ID.String()); err != nil {
31+
if len(msg) > 0 {
32+
if err = gitRepo.CreateAnnotatedTag(rel.TagName, msg, commit.ID.String()); err != nil {
33+
if strings.Contains(err.Error(), "is not a valid tag name") {
34+
return models.ErrInvalidTagName{
35+
TagName: rel.TagName,
36+
}
37+
}
38+
return err
39+
}
40+
} else if err = gitRepo.CreateTag(rel.TagName, commit.ID.String()); err != nil {
3241
if strings.Contains(err.Error(), "is not a valid tag name") {
3342
return models.ErrInvalidTagName{
3443
TagName: rel.TagName,
@@ -77,7 +86,7 @@ func createTag(gitRepo *git.Repository, rel *models.Release) error {
7786
}
7887

7988
// CreateRelease creates a new release of repository.
80-
func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string) error {
89+
func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string, msg string) error {
8190
isExist, err := models.IsReleaseExist(rel.RepoID, rel.TagName)
8291
if err != nil {
8392
return err
@@ -87,7 +96,7 @@ func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs
8796
}
8897
}
8998

90-
if err = createTag(gitRepo, rel); err != nil {
99+
if err = createTag(gitRepo, rel, msg); err != nil {
91100
return err
92101
}
93102

@@ -107,9 +116,47 @@ func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs
107116
return nil
108117
}
109118

119+
// CreateNewTag creates a new repository tag
120+
func CreateNewTag(doer *models.User, repo *models.Repository, commit, tagName, msg string) error {
121+
isExist, err := models.IsReleaseExist(repo.ID, tagName)
122+
if err != nil {
123+
return err
124+
} else if isExist {
125+
return models.ErrTagAlreadyExists{
126+
TagName: tagName,
127+
}
128+
}
129+
130+
gitRepo, err := git.OpenRepository(repo.RepoPath())
131+
if err != nil {
132+
return err
133+
}
134+
defer gitRepo.Close()
135+
136+
rel := &models.Release{
137+
RepoID: repo.ID,
138+
PublisherID: doer.ID,
139+
TagName: tagName,
140+
Target: commit,
141+
IsDraft: false,
142+
IsPrerelease: false,
143+
IsTag: true,
144+
}
145+
146+
if err = createTag(gitRepo, rel, msg); err != nil {
147+
return err
148+
}
149+
150+
if err = models.InsertRelease(rel); err != nil {
151+
return err
152+
}
153+
154+
return err
155+
}
156+
110157
// UpdateReleaseOrCreatReleaseFromTag updates information of a release or create release from tag.
111158
func UpdateReleaseOrCreatReleaseFromTag(doer *models.User, gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string, isCreate bool) (err error) {
112-
if err = createTag(gitRepo, rel); err != nil {
159+
if err = createTag(gitRepo, rel, ""); err != nil {
113160
return err
114161
}
115162
rel.LowerTagName = strings.ToLower(rel.TagName)

services/release/release_test.go

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func TestRelease_Create(t *testing.T) {
4040
IsDraft: false,
4141
IsPrerelease: false,
4242
IsTag: false,
43-
}, nil))
43+
}, nil, ""))
4444

4545
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
4646
RepoID: repo.ID,
@@ -52,7 +52,7 @@ func TestRelease_Create(t *testing.T) {
5252
IsDraft: false,
5353
IsPrerelease: false,
5454
IsTag: false,
55-
}, nil))
55+
}, nil, ""))
5656

5757
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
5858
RepoID: repo.ID,
@@ -64,7 +64,7 @@ func TestRelease_Create(t *testing.T) {
6464
IsDraft: false,
6565
IsPrerelease: false,
6666
IsTag: false,
67-
}, nil))
67+
}, nil, ""))
6868

6969
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
7070
RepoID: repo.ID,
@@ -76,7 +76,7 @@ func TestRelease_Create(t *testing.T) {
7676
IsDraft: true,
7777
IsPrerelease: false,
7878
IsTag: false,
79-
}, nil))
79+
}, nil, ""))
8080

8181
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
8282
RepoID: repo.ID,
@@ -88,7 +88,7 @@ func TestRelease_Create(t *testing.T) {
8888
IsDraft: false,
8989
IsPrerelease: true,
9090
IsTag: false,
91-
}, nil))
91+
}, nil, ""))
9292

9393
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
9494
RepoID: repo.ID,
@@ -100,7 +100,7 @@ func TestRelease_Create(t *testing.T) {
100100
IsDraft: false,
101101
IsPrerelease: false,
102102
IsTag: true,
103-
}, nil))
103+
}, nil, "test"))
104104
}
105105

106106
func TestRelease_Update(t *testing.T) {
@@ -125,7 +125,7 @@ func TestRelease_Update(t *testing.T) {
125125
IsDraft: false,
126126
IsPrerelease: false,
127127
IsTag: false,
128-
}, nil))
128+
}, nil, ""))
129129
release, err := models.GetRelease(repo.ID, "v1.1.1")
130130
assert.NoError(t, err)
131131
releaseCreatedUnix := release.CreatedUnix
@@ -147,7 +147,7 @@ func TestRelease_Update(t *testing.T) {
147147
IsDraft: true,
148148
IsPrerelease: false,
149149
IsTag: false,
150-
}, nil))
150+
}, nil, ""))
151151
release, err = models.GetRelease(repo.ID, "v1.2.1")
152152
assert.NoError(t, err)
153153
releaseCreatedUnix = release.CreatedUnix
@@ -169,7 +169,7 @@ func TestRelease_Update(t *testing.T) {
169169
IsDraft: false,
170170
IsPrerelease: true,
171171
IsTag: false,
172-
}, nil))
172+
}, nil, ""))
173173
release, err = models.GetRelease(repo.ID, "v1.3.1")
174174
assert.NoError(t, err)
175175
releaseCreatedUnix = release.CreatedUnix
@@ -205,12 +205,12 @@ func TestRelease_createTag(t *testing.T) {
205205
IsPrerelease: false,
206206
IsTag: false,
207207
}
208-
assert.NoError(t, createTag(gitRepo, release))
208+
assert.NoError(t, createTag(gitRepo, release, ""))
209209
assert.NotEmpty(t, release.CreatedUnix)
210210
releaseCreatedUnix := release.CreatedUnix
211211
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
212212
release.Note = "Changed note"
213-
assert.NoError(t, createTag(gitRepo, release))
213+
assert.NoError(t, createTag(gitRepo, release, ""))
214214
assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
215215

216216
// Test a changed draft
@@ -225,11 +225,11 @@ func TestRelease_createTag(t *testing.T) {
225225
IsPrerelease: false,
226226
IsTag: false,
227227
}
228-
assert.NoError(t, createTag(gitRepo, release))
228+
assert.NoError(t, createTag(gitRepo, release, ""))
229229
releaseCreatedUnix = release.CreatedUnix
230230
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
231231
release.Title = "Changed title"
232-
assert.NoError(t, createTag(gitRepo, release))
232+
assert.NoError(t, createTag(gitRepo, release, ""))
233233
assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
234234

235235
// Test a changed pre-release
@@ -244,11 +244,20 @@ func TestRelease_createTag(t *testing.T) {
244244
IsPrerelease: true,
245245
IsTag: false,
246246
}
247-
assert.NoError(t, createTag(gitRepo, release))
247+
assert.NoError(t, createTag(gitRepo, release, ""))
248248
releaseCreatedUnix = release.CreatedUnix
249249
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
250250
release.Title = "Changed title"
251251
release.Note = "Changed note"
252-
assert.NoError(t, createTag(gitRepo, release))
252+
assert.NoError(t, createTag(gitRepo, release, ""))
253253
assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
254254
}
255+
256+
func TestCreateNewTag(t *testing.T) {
257+
assert.NoError(t, models.PrepareTestDatabase())
258+
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
259+
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
260+
261+
assert.NoError(t, CreateNewTag(user, repo, "master", "v2.0",
262+
"v2.0 is released \n\n BUGFIX: .... \n\n 123"))
263+
}

0 commit comments

Comments
 (0)