diff --git a/models/repo/topic.go b/models/repo/topic.go index b71f43bc880..79b13e320da 100644 --- a/models/repo/topic.go +++ b/models/repo/topic.go @@ -366,7 +366,7 @@ func syncTopicsInRepository(sess db.Engine, repoID int64) error { topicNames := make([]string, 0, 25) if err := sess.Table("topic").Cols("name"). Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id"). - Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil { + Where("repo_topic.repo_id = ?", repoID).Asc("topic.name").Find(&topicNames); err != nil { return err } diff --git a/modules/markup/markdown/goldmark.go b/modules/markup/markdown/goldmark.go index 1db3cbad7e1..3dc5530e008 100644 --- a/modules/markup/markdown/goldmark.go +++ b/modules/markup/markdown/goldmark.go @@ -85,9 +85,11 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa // 2. If they're not wrapped with a link they need a link wrapper // Check if the destination is a real link - link := v.Destination - if len(link) > 0 && !markup.IsLink(link) { - v.Destination = []byte(giteautil.URLJoin(ctx.Links.ResolveMediaLink(ctx.IsWiki), string(link))) + if len(v.Destination) > 0 && !markup.IsLink(v.Destination) { + v.Destination = []byte(giteautil.URLJoin( + ctx.Links.ResolveMediaLink(ctx.IsWiki), + strings.TrimLeft(string(v.Destination), "/"), + )) } parent := n.Parent() @@ -103,7 +105,7 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa // Duplicate the current image node image := ast.NewImage(ast.NewLink()) - image.Destination = link + image.Destination = v.Destination image.Title = v.Title for _, attr := range v.Attributes() { image.SetAttribute(attr.Name, attr.Value) diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 1edfb3e6644..bdf4011fa24 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -580,6 +580,8 @@ https://example.com/file.bin [[local link|file.bin]] [[remote link|https://example.com]] ![local image](image.jpg) +![local image](path/file) +![local image](/path/file) ![remote image](https://example.com/image.jpg) [[local image|image.jpg]] [[remote link|https://example.com/image.jpg]] @@ -609,6 +611,8 @@ mail@domain.com local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -634,6 +638,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -661,6 +667,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -688,6 +696,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -715,6 +725,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -742,6 +754,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -770,6 +784,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -798,6 +814,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -826,6 +844,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -854,6 +874,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -883,6 +905,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
@@ -912,6 +936,8 @@ space

local link
remote link
local image
+local image
+local image
remote image
local image
remote link
diff --git a/modules/repository/repo.go b/modules/repository/repo.go index 5af69763d15..5352da0378d 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -508,6 +508,18 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re return nil } +// shortRelease to reduce load memory, this struct can replace repo_model.Release +type shortRelease struct { + ID int64 + TagName string + Sha1 string + IsTag bool +} + +func (shortRelease) TableName() string { + return "release" +} + // pullMirrorReleaseSync is a pull-mirror specific tag<->release table // synchronization which overwrites all Releases from the repository tags. This // can be relied on since a pull-mirror is always identical to its @@ -521,16 +533,20 @@ func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, git return fmt.Errorf("unable to GetTagInfos in pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) } err = db.WithTx(ctx, func(ctx context.Context) error { - // - // clear out existing releases - // - if _, err := db.DeleteByBean(ctx, &repo_model.Release{RepoID: repo.ID}); err != nil { - return fmt.Errorf("unable to clear releases for pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) + dbReleases, err := db.Find[shortRelease](ctx, repo_model.FindReleasesOptions{ + RepoID: repo.ID, + IncludeDrafts: true, + IncludeTags: true, + }) + if err != nil { + return fmt.Errorf("unable to FindReleases in pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) } + + inserts, deletes, updates := calcSync(tags, dbReleases) // // make release set identical to upstream tags // - for _, tag := range tags { + for _, tag := range inserts { release := repo_model.Release{ RepoID: repo.ID, TagName: tag.Name, @@ -547,6 +563,25 @@ func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, git return fmt.Errorf("unable insert tag %s for pull-mirror Repo[%d:%s/%s]: %w", tag.Name, repo.ID, repo.OwnerName, repo.Name, err) } } + + // only delete tags releases + if len(deletes) > 0 { + if _, err := db.GetEngine(ctx).Where("repo_id=?", repo.ID). + In("id", deletes). + Delete(&repo_model.Release{}); err != nil { + return fmt.Errorf("unable to delete tags for pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) + } + } + + for _, tag := range updates { + if _, err := db.GetEngine(ctx).Where("repo_id = ? AND lower_tag_name = ?", repo.ID, strings.ToLower(tag.Name)). + Cols("sha1"). + Update(&repo_model.Release{ + Sha1: tag.Object.String(), + }); err != nil { + return fmt.Errorf("unable to update tag %s for pull-mirror Repo[%d:%s/%s]: %w", tag.Name, repo.ID, repo.OwnerName, repo.Name, err) + } + } return nil }) if err != nil { @@ -556,3 +591,32 @@ func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, git log.Trace("pullMirrorReleaseSync: done rebuilding %d releases", numTags) return nil } + +func calcSync(destTags []*git.Tag, dbTags []*shortRelease) ([]*git.Tag, []int64, []*git.Tag) { + destTagMap := make(map[string]*git.Tag) + for _, tag := range destTags { + destTagMap[tag.Name] = tag + } + dbTagMap := make(map[string]*shortRelease) + for _, rel := range dbTags { + dbTagMap[rel.TagName] = rel + } + + inserted := make([]*git.Tag, 0, 10) + updated := make([]*git.Tag, 0, 10) + for _, tag := range destTags { + rel := dbTagMap[tag.Name] + if rel == nil { + inserted = append(inserted, tag) + } else if rel.Sha1 != tag.Object.String() { + updated = append(updated, tag) + } + } + deleted := make([]int64, 0, 10) + for _, tag := range dbTags { + if destTagMap[tag.TagName] == nil && tag.IsTag { + deleted = append(deleted, tag.ID) + } + } + return inserted, deleted, updated +} diff --git a/modules/repository/repo_test.go b/modules/repository/repo_test.go new file mode 100644 index 00000000000..68980f92f94 --- /dev/null +++ b/modules/repository/repo_test.go @@ -0,0 +1,76 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repository + +import ( + "testing" + + "code.gitea.io/gitea/modules/git" + + "github.com/stretchr/testify/assert" +) + +func Test_calcSync(t *testing.T) { + gitTags := []*git.Tag{ + /*{ + Name: "v0.1.0-beta", //deleted tag + Object: git.MustIDFromString(""), + }, + { + Name: "v0.1.1-beta", //deleted tag but release should not be deleted because it's a release + Object: git.MustIDFromString(""), + }, + */ + { + Name: "v1.0.0", // keep as before + Object: git.MustIDFromString("1006e6e13c73ad3d9e2d5682ad266b5016523485"), + }, + { + Name: "v1.1.0", // retagged with new commit id + Object: git.MustIDFromString("bbdb7df30248e7d4a26a909c8d2598a152e13868"), + }, + { + Name: "v1.2.0", // new tag + Object: git.MustIDFromString("a5147145e2f24d89fd6d2a87826384cc1d253267"), + }, + } + + dbReleases := []*shortRelease{ + { + ID: 1, + TagName: "v0.1.0-beta", + Sha1: "244758d7da8dd1d9e0727e8cb7704ed4ba9a17c3", + IsTag: true, + }, + { + ID: 2, + TagName: "v0.1.1-beta", + Sha1: "244758d7da8dd1d9e0727e8cb7704ed4ba9a17c3", + IsTag: false, + }, + { + ID: 3, + TagName: "v1.0.0", + Sha1: "1006e6e13c73ad3d9e2d5682ad266b5016523485", + }, + { + ID: 4, + TagName: "v1.1.0", + Sha1: "53ab18dcecf4152b58328d1f47429510eb414d50", + }, + } + + inserts, deletes, updates := calcSync(gitTags, dbReleases) + if assert.EqualValues(t, 1, len(inserts), "inserts") { + assert.EqualValues(t, *gitTags[2], *inserts[0], "inserts equal") + } + + if assert.EqualValues(t, 1, len(deletes), "deletes") { + assert.EqualValues(t, 1, deletes[0], "deletes equal") + } + + if assert.EqualValues(t, 1, len(updates), "updates") { + assert.EqualValues(t, *gitTags[1], *updates[0], "updates equal") + } +} diff --git a/services/auth/sspi.go b/services/auth/sspi.go index 57ba0462c57..0e974fde8f3 100644 --- a/services/auth/sspi.go +++ b/services/auth/sspi.go @@ -11,7 +11,6 @@ import ( "sync" "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/avatars" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -167,12 +166,9 @@ func (s *SSPI) shouldAuthenticate(req *http.Request) (shouldAuth bool) { func (s *SSPI) newUser(ctx context.Context, username string, cfg *sspi.Source) (*user_model.User, error) { email := gouuid.New().String() + "@localhost.localdomain" user := &user_model.User{ - Name: username, - Email: email, - Passwd: gouuid.New().String(), - Language: cfg.DefaultLanguage, - UseCustomAvatar: true, - Avatar: avatars.DefaultAvatarLink(), + Name: username, + Email: email, + Language: cfg.DefaultLanguage, } emailNotificationPreference := user_model.EmailNotificationsDisabled overwriteDefault := &user_model.CreateUserOverwriteOptions{ diff --git a/web_src/css/modules/animations.css b/web_src/css/modules/animations.css index cac824d87d6..87eb6a75cf0 100644 --- a/web_src/css/modules/animations.css +++ b/web_src/css/modules/animations.css @@ -22,7 +22,7 @@ height: min(4em, 66.6%); aspect-ratio: 1; transform: translate(-50%, -50%); - animation: isloadingspin 500ms infinite linear; + animation: isloadingspin 1000ms infinite linear; border-width: 4px; border-style: solid; border-color: var(--color-secondary) var(--color-secondary) var(--color-secondary-dark-8) var(--color-secondary-dark-8);