From 35bcd667b23de29a7b0d0bf1090fb10961d3aca3 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Fri, 8 Nov 2024 10:53:06 +0800 Subject: [PATCH] Fix broken releases when re-pushing tags (#32435) Fix #32427 --- services/repository/push.go | 19 +++++++----- tests/integration/repo_tag_test.go | 47 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/services/repository/push.go b/services/repository/push.go index 36c7927ab6..06ad65e48f 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -318,9 +318,10 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo } releases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{ - RepoID: repo.ID, - TagNames: tags, - IncludeTags: true, + RepoID: repo.ID, + TagNames: tags, + IncludeDrafts: true, + IncludeTags: true, }) if err != nil { return fmt.Errorf("db.Find[repo_model.Release]: %w", err) @@ -407,13 +408,17 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo newReleases = append(newReleases, rel) } else { - rel.Title = parts[0] - rel.Note = note rel.Sha1 = commit.ID.String() rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix()) rel.NumCommits = commitsCount - if rel.IsTag && author != nil { - rel.PublisherID = author.ID + if rel.IsTag { + rel.Title = parts[0] + rel.Note = note + if author != nil { + rel.PublisherID = author.ID + } + } else { + rel.IsDraft = false } if err = repo_model.UpdateRelease(ctx, rel); err != nil { return fmt.Errorf("Update: %w", err) diff --git a/tests/integration/repo_tag_test.go b/tests/integration/repo_tag_test.go index d649f041cc..0cd49ee4cd 100644 --- a/tests/integration/repo_tag_test.go +++ b/tests/integration/repo_tag_test.go @@ -4,17 +4,20 @@ package integration import ( + "fmt" "net/http" "net/url" "testing" "code.gitea.io/gitea/models" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" + api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/services/release" "code.gitea.io/gitea/tests" @@ -117,3 +120,47 @@ func TestCreateNewTagProtected(t *testing.T) { assert.NoError(t, err) } } + +func TestRepushTag(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + session := loginUser(t, owner.LowerName) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + httpContext := NewAPITestContext(t, owner.Name, repo.Name) + + dstPath := t.TempDir() + + u.Path = httpContext.GitPath() + u.User = url.UserPassword(owner.Name, userPassword) + + doGitClone(dstPath, u)(t) + + // create and push a tag + _, _, err := git.NewCommand(git.DefaultContext, "tag", "v2.0").RunStdString(&git.RunOpts{Dir: dstPath}) + assert.NoError(t, err) + _, _, err = git.NewCommand(git.DefaultContext, "push", "origin", "--tags", "v2.0").RunStdString(&git.RunOpts{Dir: dstPath}) + assert.NoError(t, err) + // create a release for the tag + createdRelease := createNewReleaseUsingAPI(t, token, owner, repo, "v2.0", "", "Release of v2.0", "desc") + assert.False(t, createdRelease.IsDraft) + // delete the tag + _, _, err = git.NewCommand(git.DefaultContext, "push", "origin", "--delete", "v2.0").RunStdString(&git.RunOpts{Dir: dstPath}) + assert.NoError(t, err) + // query the release by API and it should be a draft + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, "v2.0")) + resp := MakeRequest(t, req, http.StatusOK) + var respRelease *api.Release + DecodeJSON(t, resp, &respRelease) + assert.True(t, respRelease.IsDraft) + // re-push the tag + _, _, err = git.NewCommand(git.DefaultContext, "push", "origin", "--tags", "v2.0").RunStdString(&git.RunOpts{Dir: dstPath}) + assert.NoError(t, err) + // query the release by API and it should not be a draft + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, "v2.0")) + resp = MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &respRelease) + assert.False(t, respRelease.IsDraft) + }) +}