feat: update gitea vendor
runner nix smoke / nix label and flake smoke (push) Failing after 1m28s

This commit is contained in:
2026-09-26 21:18:24 +00:00
parent c439c1b948
commit d9b2a4e787
3538 changed files with 116131 additions and 44340 deletions
+46 -19
View File
@@ -10,12 +10,13 @@ import (
"slices"
"strings"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/util"
"gitea.dev/models/db"
issues_model "gitea.dev/models/issues"
repo_model "gitea.dev/models/repo"
user_model "gitea.dev/models/user"
"gitea.dev/modules/container"
"gitea.dev/modules/git"
"gitea.dev/modules/util"
)
// GenerateReleaseNotesOptions describes how to build release notes content.
@@ -25,27 +26,32 @@ type GenerateReleaseNotesOptions struct {
PreviousTag string
}
// GenerateReleaseNotes builds the markdown snippet for release notes.
// GenerateReleaseNotes builds the Markdown snippet for release notes.
func GenerateReleaseNotes(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, opts GenerateReleaseNotesOptions) (string, error) {
headCommit, err := resolveHeadCommit(gitRepo, opts.TagName, opts.TagTarget)
if err != nil {
return "", err
}
if opts.PreviousTag == "" {
// no previous tag, usually due to there is no tag in the repo, use the same content as GitHub
content := fmt.Sprintf("**Full Changelog**: %s/commits/tag/%s\n", repo.HTMLURL(ctx), util.PathEscapeSegments(opts.TagName))
return content, nil
isFirstRelease, err := repoReleaseIsEmpty(ctx, repo.ID)
if err != nil {
return "", fmt.Errorf("repoReleaseIsEmpty: %w", err)
}
baseCommit, err := gitRepo.GetCommit(opts.PreviousTag)
if err != nil {
var baseCommitID git.RefName
if opts.PreviousTag != "" {
baseCommit, err := gitRepo.GetCommit(opts.PreviousTag)
if err != nil {
return "", util.ErrorWrapTranslatable(util.ErrNotExist, "repo.release.generate_notes_tag_not_found", opts.PreviousTag)
}
baseCommitID = baseCommit.ID.RefName()
} else if !isFirstRelease {
return "", util.ErrorWrapTranslatable(util.ErrNotExist, "repo.release.generate_notes_tag_not_found", opts.TagName)
}
commits, err := gitRepo.CommitsBetweenIDs(headCommit.ID.String(), baseCommit.ID.String())
commits, err := gitRepo.CommitsBetween(headCommit.ID.RefName(), baseCommitID, -1)
if err != nil {
return "", fmt.Errorf("CommitsBetweenIDs: %w", err)
return "", fmt.Errorf("CommitsBetween: %w", err)
}
prs, err := collectPullRequestsFromCommits(ctx, repo.ID, commits)
@@ -58,10 +64,27 @@ func GenerateReleaseNotes(ctx context.Context, repo *repo_model.Repository, gitR
return "", err
}
content := buildReleaseNotesContent(ctx, repo, opts.TagName, opts.PreviousTag, prs, contributors, newContributors)
fullChangelogURL := ""
if isFirstRelease {
// Keep the first-release changelog link aligned with GitHub, while collecting PRs from full history.
fullChangelogURL = fmt.Sprintf("%s/commits/tag/%s", repo.HTMLURL(ctx), util.PathEscapeSegments(opts.TagName))
}
content := buildReleaseNotesContent(ctx, repo, opts.TagName, opts.PreviousTag, prs, contributors, newContributors, fullChangelogURL)
return content, nil
}
func repoReleaseIsEmpty(ctx context.Context, repoID int64) (bool, error) {
count, err := db.Count[repo_model.Release](ctx, repo_model.FindReleasesOptions{
RepoID: repoID,
IncludeDrafts: false,
})
if err != nil {
return false, err
}
return count == 0, nil
}
func resolveHeadCommit(gitRepo *git.Repository, tagName, tagTarget string) (*git.Commit, error) {
ref := tagName
if !gitRepo.IsTagExist(tagName) {
@@ -107,7 +130,7 @@ func collectPullRequestsFromCommits(ctx context.Context, repoID int64, commits [
return prs, nil
}
func buildReleaseNotesContent(ctx context.Context, repo *repo_model.Repository, tagName, baseRef string, prs []*issues_model.PullRequest, contributors []*user_model.User, newContributors []*issues_model.PullRequest) string {
func buildReleaseNotesContent(ctx context.Context, repo *repo_model.Repository, tagName, baseRef string, prs []*issues_model.PullRequest, contributors []*user_model.User, newContributors []*issues_model.PullRequest, fullChangelogURL string) string {
var builder strings.Builder
builder.WriteString("## What's Changed\n")
@@ -136,8 +159,12 @@ func buildReleaseNotesContent(ctx context.Context, repo *repo_model.Repository,
}
builder.WriteString("**Full Changelog**: ")
compareURL := fmt.Sprintf("%s/compare/%s...%s", repo.HTMLURL(ctx), util.PathEscapeSegments(baseRef), util.PathEscapeSegments(tagName))
fmt.Fprintf(&builder, "[%s...%s](%s)", baseRef, tagName, compareURL)
if fullChangelogURL != "" {
builder.WriteString(fullChangelogURL)
} else {
compareURL := fmt.Sprintf("%s/compare/%s...%s", repo.HTMLURL(ctx), util.PathEscapeSegments(baseRef), util.PathEscapeSegments(tagName))
fmt.Fprintf(&builder, "[%s...%s](%s)", baseRef, tagName, compareURL)
}
builder.WriteByte('\n')
return builder.String()
}
@@ -6,13 +6,13 @@ package release
import (
"testing"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
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/gitrepo"
"code.gitea.io/gitea/modules/timeutil"
"gitea.dev/models/db"
issues_model "gitea.dev/models/issues"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"gitea.dev/modules/gitrepo"
"gitea.dev/modules/timeutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -21,13 +21,14 @@ import (
func TestGenerateReleaseNotes(t *testing.T) {
unittest.PrepareTestEnv(t)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
require.NoError(t, err)
t.Run("ChangeLogsWithPRs", func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
require.NoError(t, err)
t.Cleanup(func() { gitRepo.Close() })
mergedCommit := "90c1019714259b24fb81711d4416ac0f18667dfa"
createMergedPullRequest(t, repo, mergedCommit, 5)
createMergedPullRequest(t, repo, mergedCommit, 5, "Release notes test pull request")
content, err := GenerateReleaseNotes(t.Context(), repo, gitRepo, GenerateReleaseNotesOptions{
TagName: "v1.2.0",
@@ -50,16 +51,51 @@ func TestGenerateReleaseNotes(t *testing.T) {
})
t.Run("NoPreviousTag", func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
require.NoError(t, err)
t.Cleanup(func() { gitRepo.Close() })
createMergedPullRequest(t, repo, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", 5, "Initial tag PR 1")
createMergedPullRequest(t, repo, "27566bd5738fc8b4e3fef3c5e72cce608537bd95", 4, "Initial tag PR 2")
createMergedPullRequest(t, repo, "5099b81332712fe655e34e8dd63574f503f61811", 8, "Initial tag PR 3")
content, err := GenerateReleaseNotes(t.Context(), repo, gitRepo, GenerateReleaseNotesOptions{
TagName: "v1.2.0",
TagTarget: "DefaultBranch",
TagName: "v0.1.0",
TagTarget: repo.DefaultBranch,
})
require.NoError(t, err)
assert.Equal(t, "**Full Changelog**: https://try.gitea.io/user2/repo1/commits/tag/v1.2.0\n", content)
assert.Contains(t, content, "## What's Changed\n")
assert.Contains(t, content, "* Initial tag PR 1 in [#")
assert.Contains(t, content, "* Initial tag PR 2 in [#")
assert.Contains(t, content, "* Initial tag PR 3 in [#")
assert.Contains(t, content, "\n## Contributors\n")
assert.Contains(t, content, "* @user5\n")
assert.Contains(t, content, "* @user4\n")
assert.Contains(t, content, "* @user8\n")
assert.Contains(t, content, "\n## New Contributors\n")
assert.Contains(t, content, "* @user5 made their first contribution in [#")
assert.Contains(t, content, "* @user4 made their first contribution in [#")
assert.Contains(t, content, "* @user8 made their first contribution in [#")
assert.Contains(t, content, "**Full Changelog**: https://try.gitea.io/user2/repo16/commits/tag/v0.1.0\n")
})
t.Run("EmptyPreviousTagWithExistingTags", func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
require.NoError(t, err)
t.Cleanup(func() { gitRepo.Close() })
_, err = GenerateReleaseNotes(t.Context(), repo, gitRepo, GenerateReleaseNotesOptions{
TagName: "v1.2.0",
TagTarget: repo.DefaultBranch,
})
require.Error(t, err)
})
}
func createMergedPullRequest(t *testing.T, repo *repo_model.Repository, mergeCommit string, posterID int64) *issues_model.PullRequest {
func createMergedPullRequest(t *testing.T, repo *repo_model.Repository, mergeCommit string, posterID int64, title string) *issues_model.PullRequest {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: posterID})
issue := &issues_model.Issue{
@@ -67,7 +103,7 @@ func createMergedPullRequest(t *testing.T, repo *repo_model.Repository, mergeCom
Repo: repo,
Poster: user,
PosterID: user.ID,
Title: "Release notes test pull request",
Title: title,
Content: "content",
}
@@ -9,21 +9,23 @@ import (
"fmt"
"strings"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
notify_service "code.gitea.io/gitea/services/notify"
"gitea.dev/models/db"
git_model "gitea.dev/models/git"
repo_model "gitea.dev/models/repo"
user_model "gitea.dev/models/user"
"gitea.dev/modules/container"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/gitrepo"
"gitea.dev/modules/graceful"
"gitea.dev/modules/log"
"gitea.dev/modules/repository"
"gitea.dev/modules/setting"
"gitea.dev/modules/storage"
"gitea.dev/modules/timeutil"
"gitea.dev/modules/util"
"gitea.dev/services/context/upload"
notify_service "gitea.dev/services/notify"
)
// ErrInvalidTagName represents a "InvalidTagName" kind of error.
@@ -319,13 +321,17 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo
}
for uuid, newName := range editAttachments {
if !deletedUUIDs.Contains(uuid) {
if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{
UUID: uuid,
Name: newName,
}, "name"); err != nil {
return err
}
if deletedUUIDs.Contains(uuid) {
continue
}
if err = upload.Verify(nil, newName, setting.Repository.Release.AllowedTypes); err != nil {
return err
}
if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{
UUID: uuid,
Name: newName,
}, "name"); err != nil {
return err
}
}
}
@@ -8,13 +8,17 @@ import (
"testing"
"time"
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/gitrepo"
"code.gitea.io/gitea/services/attachment"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"gitea.dev/modules/gitrepo"
"gitea.dev/modules/setting"
"gitea.dev/modules/test"
"gitea.dev/modules/timeutil"
"gitea.dev/services/attachment"
"gitea.dev/services/context/upload"
_ "code.gitea.io/gitea/models/actions"
_ "gitea.dev/models/actions"
"github.com/stretchr/testify/assert"
)
@@ -138,6 +142,12 @@ func TestRelease_Update(t *testing.T) {
assert.NoError(t, err)
defer gitRepo.Close()
// Advance a mocked clock between create and update instead of sleeping, so the
// timestamp-sensitive assertions below stay deterministic.
fakeNow := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
defer timeutil.MockSet(fakeNow)()
advance := func() { fakeNow = fakeNow.Add(time.Second); timeutil.MockSet(fakeNow) }
// Test a changed release
assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{
RepoID: repo.ID,
@@ -155,7 +165,7 @@ func TestRelease_Update(t *testing.T) {
release, err := repo_model.GetRelease(t.Context(), repo.ID, "v1.1.1")
assert.NoError(t, err)
releaseCreatedUnix := release.CreatedUnix
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
advance()
release.Note = "Changed note"
assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, nil))
release, err = repo_model.GetReleaseByID(t.Context(), release.ID)
@@ -179,7 +189,7 @@ func TestRelease_Update(t *testing.T) {
release, err = repo_model.GetRelease(t.Context(), repo.ID, "v1.2.1")
assert.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
advance()
release.Title = "Changed title"
assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, nil))
release, err = repo_model.GetReleaseByID(t.Context(), release.ID)
@@ -203,7 +213,7 @@ func TestRelease_Update(t *testing.T) {
release, err = repo_model.GetRelease(t.Context(), repo.ID, "v1.3.1")
assert.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
advance()
release.Title = "Changed title"
release.Note = "Changed note"
assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, nil))
@@ -263,6 +273,17 @@ func TestRelease_Update(t *testing.T) {
assert.Equal(t, release.ID, release.Attachments[0].ReleaseID)
assert.Equal(t, "test2.txt", release.Attachments[0].Name)
defer test.MockVariableValue(&setting.Repository.Release.AllowedTypes, ".zip")()
err = UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, map[string]string{
attach.UUID: "test.exe",
})
assert.Error(t, err)
assert.True(t, upload.IsErrFileTypeForbidden(err))
release.Attachments = nil
assert.NoError(t, repo_model.GetReleaseAttachments(t.Context(), release))
assert.Len(t, release.Attachments, 1)
assert.Equal(t, "test2.txt", release.Attachments[0].Name)
// delete the attachment
assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, []string{attach.UUID}, nil))
release.Attachments = nil
@@ -280,6 +301,12 @@ func TestRelease_createTag(t *testing.T) {
assert.NoError(t, err)
defer gitRepo.Close()
// Advance a mocked clock between create and update instead of sleeping, so the
// timestamp-sensitive assertions below stay deterministic.
fakeNow := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
defer timeutil.MockSet(fakeNow)()
advance := func() { fakeNow = fakeNow.Add(time.Second); timeutil.MockSet(fakeNow) }
// Test a changed release
release := &repo_model.Release{
RepoID: repo.ID,
@@ -298,7 +325,7 @@ func TestRelease_createTag(t *testing.T) {
assert.NoError(t, err)
assert.NotEmpty(t, release.CreatedUnix)
releaseCreatedUnix := release.CreatedUnix
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
advance()
release.Note = "Changed note"
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
@@ -321,7 +348,7 @@ func TestRelease_createTag(t *testing.T) {
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
advance()
release.Title = "Changed title"
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
@@ -344,7 +371,7 @@ func TestRelease_createTag(t *testing.T) {
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
advance()
release.Title = "Changed title"
release.Note = "Changed note"
_, err = createTag(t.Context(), gitRepo, release, "")
+6 -6
View File
@@ -8,12 +8,12 @@ import (
"errors"
"fmt"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/queue"
repo_module "code.gitea.io/gitea/modules/repository"
"gitea.dev/models/db"
repo_model "gitea.dev/models/repo"
"gitea.dev/modules/graceful"
"gitea.dev/modules/log"
"gitea.dev/modules/queue"
repo_module "gitea.dev/modules/repository"
"xorm.io/builder"
)