Skip to content

Commit a1c01b2

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: (23 commits) [skip ci] Updated translations via Crowdin Update tool dependencies (go-gitea#33907) Move hooks function to gitrepo and reduce expose repopath (go-gitea#33890) Replace text-align classes with tailwind (go-gitea#33905) Simplify secure context check (go-gitea#33906) Update JS and PY deps, misc tweaks (go-gitea#33903) Refactor functions to reduce repopath expose (go-gitea#33892) Move git references checking to gitrepo packages to reduce expose of repository path (go-gitea#33891) [skip ci] Updated translations via Crowdin Add missing translation (go-gitea#33900) Give organisation members access to organisation feeds (go-gitea#33508) Add lock for a repository pull mirror (go-gitea#33876) Fix cannot delete runners via the modal dialog (go-gitea#33895) Add file tree to file view page (go-gitea#32721) [skip ci] Updated translations via Crowdin Feature: Ephemeral action runners (go-gitea#33570) Add abstraction layer to delete repository from disk (go-gitea#33879) Make SearchMode have default value and add comments (go-gitea#33863) Fix maven panic when no package exists (go-gitea#33888) Add old svg class name to git entry icon (go-gitea#33884) ... # Conflicts: # templates/repo/wiki/revision.tmpl
2 parents ec05550 + 9ebae4a commit a1c01b2

File tree

156 files changed

+2817
-1905
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+2817
-1905
lines changed

.eslintrc.cjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ module.exports = {
104104
'@vitest/no-disabled-tests': [0],
105105
'@vitest/no-done-callback': [0],
106106
'@vitest/no-duplicate-hooks': [0],
107-
'@vitest/no-focused-tests': [0],
107+
'@vitest/no-focused-tests': [2],
108108
'@vitest/no-hooks': [0],
109109
'@vitest/no-identical-title': [2],
110110
'@vitest/no-interpolation-in-snapshots': [0],
@@ -155,7 +155,7 @@ module.exports = {
155155
'eslint-plugin-vue-scoped-css',
156156
],
157157
extends: [
158-
'plugin:vue/vue3-recommended',
158+
'plugin:vue/recommended',
159159
'plugin:vue-scoped-css/vue3-recommended',
160160
],
161161
rules: {

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ COMMA := ,
2626
XGO_VERSION := go-1.24.x
2727

2828
AIR_PACKAGE ?= github.com/air-verse/air@v1
29-
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.1.2
29+
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.2.1
3030
GOFUMPT_PACKAGE ?= mvdan.cc/[email protected]
31-
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/[email protected].5
31+
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/[email protected].7
3232
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/[email protected]
3333
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/[email protected]
3434
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/[email protected]

models/actions/runner.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ type ActionRunner struct {
5757

5858
// Store labels defined in state file (default: .runner file) of `act_runner`
5959
AgentLabels []string `xorm:"TEXT"`
60+
// Store if this is a runner that only ever get one single job assigned
61+
Ephemeral bool `xorm:"ephemeral NOT NULL DEFAULT false"`
6062

6163
Created timeutil.TimeStamp `xorm:"created"`
6264
Updated timeutil.TimeStamp `xorm:"updated"`

models/git/commit_status.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,8 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error {
453453
return fmt.Errorf("NewCommitStatus[nil, %s]: no repository specified", opts.SHA)
454454
}
455455

456-
repoPath := opts.Repo.RepoPath()
457456
if opts.Creator == nil {
458-
return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", repoPath, opts.SHA)
457+
return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", opts.Repo.FullName(), opts.SHA)
459458
}
460459

461460
ctx, committer, err := db.TxContext(ctx)
@@ -477,13 +476,13 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error {
477476
opts.CommitStatus.CreatorID = opts.Creator.ID
478477
opts.CommitStatus.RepoID = opts.Repo.ID
479478
opts.CommitStatus.Index = idx
480-
log.Debug("NewCommitStatus[%s, %s]: %d", repoPath, opts.SHA, opts.CommitStatus.Index)
479+
log.Debug("NewCommitStatus[%s, %s]: %d", opts.Repo.FullName(), opts.SHA, opts.CommitStatus.Index)
481480

482481
opts.CommitStatus.ContextHash = hashCommitStatusContext(opts.CommitStatus.Context)
483482

484483
// Insert new CommitStatus
485484
if _, err = db.GetEngine(ctx).Insert(opts.CommitStatus); err != nil {
486-
return fmt.Errorf("insert CommitStatus[%s, %s]: %w", repoPath, opts.SHA, err)
485+
return fmt.Errorf("insert CommitStatus[%s, %s]: %w", opts.Repo.FullName(), opts.SHA, err)
487486
}
488487

489488
return committer.Commit()

models/migrations/migrations.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ func prepareMigrationTasks() []*migration {
375375
newMigration(312, "Add DeleteBranchAfterMerge to AutoMerge", v1_24.AddDeleteBranchAfterMergeForAutoMerge),
376376
newMigration(313, "Move PinOrder from issue table to a new table issue_pin", v1_24.MovePinOrderToTableIssuePin),
377377
newMigration(314, "Update OwnerID as zero for repository level action tables", v1_24.UpdateOwnerIDOfRepoLevelActionsTables),
378+
newMigration(315, "Add Ephemeral to ActionRunner", v1_24.AddEphemeralToActionRunner),
378379
}
379380
return preparedMigrations
380381
}

models/migrations/v1_24/v315.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_24 //nolint
5+
6+
import (
7+
"xorm.io/xorm"
8+
)
9+
10+
func AddEphemeralToActionRunner(x *xorm.Engine) error {
11+
type ActionRunner struct {
12+
Ephemeral bool `xorm:"ephemeral NOT NULL DEFAULT false"`
13+
}
14+
15+
return x.Sync(new(ActionRunner))
16+
}

models/unittest/fixtures_loader.go

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@ import (
1212
"slices"
1313
"strings"
1414

15+
"code.gitea.io/gitea/models/db"
16+
1517
"gopkg.in/yaml.v3"
1618
"xorm.io/xorm"
1719
"xorm.io/xorm/schemas"
1820
)
1921

20-
type fixtureItem struct {
21-
tableName string
22+
type FixtureItem struct {
23+
fileFullPath string
24+
tableName string
25+
2226
tableNameQuoted string
2327
sqlInserts []string
2428
sqlInsertArgs [][]any
@@ -27,10 +31,11 @@ type fixtureItem struct {
2731
}
2832

2933
type fixturesLoaderInternal struct {
34+
xormEngine *xorm.Engine
35+
xormTableNames map[string]bool
3036
db *sql.DB
3137
dbType schemas.DBType
32-
files []string
33-
fixtures map[string]*fixtureItem
38+
fixtures map[string]*FixtureItem
3439
quoteObject func(string) string
3540
paramPlaceholder func(idx int) string
3641
}
@@ -59,29 +64,27 @@ func (f *fixturesLoaderInternal) preprocessFixtureRow(row []map[string]any) (err
5964
return nil
6065
}
6166

62-
func (f *fixturesLoaderInternal) prepareFixtureItem(file string) (_ *fixtureItem, err error) {
63-
fixture := &fixtureItem{}
64-
fixture.tableName, _, _ = strings.Cut(filepath.Base(file), ".")
67+
func (f *fixturesLoaderInternal) prepareFixtureItem(fixture *FixtureItem) (err error) {
6568
fixture.tableNameQuoted = f.quoteObject(fixture.tableName)
6669

6770
if f.dbType == schemas.MSSQL {
6871
fixture.mssqlHasIdentityColumn, err = f.mssqlTableHasIdentityColumn(f.db, fixture.tableName)
6972
if err != nil {
70-
return nil, err
73+
return err
7174
}
7275
}
7376

74-
data, err := os.ReadFile(file)
77+
data, err := os.ReadFile(fixture.fileFullPath)
7578
if err != nil {
76-
return nil, fmt.Errorf("failed to read file %q: %w", file, err)
79+
return fmt.Errorf("failed to read file %q: %w", fixture.fileFullPath, err)
7780
}
7881

7982
var rows []map[string]any
8083
if err = yaml.Unmarshal(data, &rows); err != nil {
81-
return nil, fmt.Errorf("failed to unmarshal yaml data from %q: %w", file, err)
84+
return fmt.Errorf("failed to unmarshal yaml data from %q: %w", fixture.fileFullPath, err)
8285
}
8386
if err = f.preprocessFixtureRow(rows); err != nil {
84-
return nil, fmt.Errorf("failed to preprocess fixture rows from %q: %w", file, err)
87+
return fmt.Errorf("failed to preprocess fixture rows from %q: %w", fixture.fileFullPath, err)
8588
}
8689

8790
var sqlBuf []byte
@@ -107,16 +110,14 @@ func (f *fixturesLoaderInternal) prepareFixtureItem(file string) (_ *fixtureItem
107110
sqlBuf = sqlBuf[:0]
108111
sqlArguments = sqlArguments[:0]
109112
}
110-
return fixture, nil
113+
return nil
111114
}
112115

113-
func (f *fixturesLoaderInternal) loadFixtures(tx *sql.Tx, file string) (err error) {
114-
fixture := f.fixtures[file]
115-
if fixture == nil {
116-
if fixture, err = f.prepareFixtureItem(file); err != nil {
116+
func (f *fixturesLoaderInternal) loadFixtures(tx *sql.Tx, fixture *FixtureItem) (err error) {
117+
if fixture.tableNameQuoted == "" {
118+
if err = f.prepareFixtureItem(fixture); err != nil {
117119
return err
118120
}
119-
f.fixtures[file] = fixture
120121
}
121122

122123
_, err = tx.Exec(fmt.Sprintf("DELETE FROM %s", fixture.tableNameQuoted)) // sqlite3 doesn't support truncate
@@ -147,15 +148,26 @@ func (f *fixturesLoaderInternal) Load() error {
147148
}
148149
defer func() { _ = tx.Rollback() }()
149150

150-
for _, file := range f.files {
151-
if err := f.loadFixtures(tx, file); err != nil {
152-
return fmt.Errorf("failed to load fixtures from %s: %w", file, err)
151+
for _, fixture := range f.fixtures {
152+
if !f.xormTableNames[fixture.tableName] {
153+
continue
154+
}
155+
if err := f.loadFixtures(tx, fixture); err != nil {
156+
return fmt.Errorf("failed to load fixtures from %s: %w", fixture.fileFullPath, err)
153157
}
154158
}
155-
return tx.Commit()
159+
if err = tx.Commit(); err != nil {
160+
return err
161+
}
162+
for xormTableName := range f.xormTableNames {
163+
if f.fixtures[xormTableName] == nil {
164+
_, _ = f.xormEngine.Exec("DELETE FROM `" + xormTableName + "`")
165+
}
166+
}
167+
return nil
156168
}
157169

158-
func FixturesFileFullPaths(dir string, files []string) ([]string, error) {
170+
func FixturesFileFullPaths(dir string, files []string) (map[string]*FixtureItem, error) {
159171
if files != nil && len(files) == 0 {
160172
return nil, nil // load nothing
161173
}
@@ -169,20 +181,25 @@ func FixturesFileFullPaths(dir string, files []string) ([]string, error) {
169181
files = append(files, e.Name())
170182
}
171183
}
172-
for i, file := range files {
173-
if !filepath.IsAbs(file) {
174-
files[i] = filepath.Join(dir, file)
184+
fixtureItems := map[string]*FixtureItem{}
185+
for _, file := range files {
186+
fileFillPath := file
187+
if !filepath.IsAbs(fileFillPath) {
188+
fileFillPath = filepath.Join(dir, file)
175189
}
190+
tableName, _, _ := strings.Cut(filepath.Base(file), ".")
191+
fixtureItems[tableName] = &FixtureItem{fileFullPath: fileFillPath, tableName: tableName}
176192
}
177-
return files, nil
193+
return fixtureItems, nil
178194
}
179195

180196
func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, error) {
181-
files, err := FixturesFileFullPaths(opts.Dir, opts.Files)
197+
fixtureItems, err := FixturesFileFullPaths(opts.Dir, opts.Files)
182198
if err != nil {
183199
return nil, fmt.Errorf("failed to get fixtures files: %w", err)
184200
}
185-
f := &fixturesLoaderInternal{db: x.DB().DB, dbType: x.Dialect().URI().DBType, files: files, fixtures: map[string]*fixtureItem{}}
201+
202+
f := &fixturesLoaderInternal{xormEngine: x, db: x.DB().DB, dbType: x.Dialect().URI().DBType, fixtures: fixtureItems}
186203
switch f.dbType {
187204
case schemas.SQLITE:
188205
f.quoteObject = func(s string) string { return fmt.Sprintf(`"%s"`, s) }
@@ -197,5 +214,12 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er
197214
f.quoteObject = func(s string) string { return fmt.Sprintf("[%s]", s) }
198215
f.paramPlaceholder = func(idx int) string { return "?" }
199216
}
217+
218+
xormBeans, _ := db.NamesToBean()
219+
f.xormTableNames = map[string]bool{}
220+
for _, bean := range xormBeans {
221+
f.xormTableNames[db.TableName(bean)] = true
222+
}
223+
200224
return f, nil
201225
}

models/user/setting_keys.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const (
1010
SettingsKeyDiffWhitespaceBehavior = "diff.whitespace_behaviour"
1111
// SettingsKeyShowOutdatedComments is the setting key wether or not to show outdated comments in PRs
1212
SettingsKeyShowOutdatedComments = "comment_code.show_outdated"
13+
1314
// UserActivityPubPrivPem is user's private key
1415
UserActivityPubPrivPem = "activitypub.priv_pem"
1516
// UserActivityPubPubPem is user's public key
@@ -18,4 +19,6 @@ const (
1819
SignupIP = "signup.ip"
1920
// SignupUserAgent is the user agent that the user signed up with
2021
SignupUserAgent = "signup.user_agent"
22+
23+
SettingsKeyCodeViewShowFileTree = "code_view.show_file_tree"
2124
)

modules/fileicon/material.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (m *MaterialIconProvider) loadData() {
6262
log.Debug("Loaded material icon rules and SVG images")
6363
}
6464

65-
func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name, svg string) template.HTML {
65+
func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name, svg, extraClass string) template.HTML {
6666
data := ctx.GetData()
6767
renderedSVGs, _ := data["_RenderedSVGs"].(map[string]bool)
6868
if renderedSVGs == nil {
@@ -75,7 +75,7 @@ func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name
7575
panic("Invalid SVG icon")
7676
}
7777
svgID := "svg-mfi-" + name
78-
svgCommonAttrs := `class="svg fileicon" width="16" height="16" aria-hidden="true"`
78+
svgCommonAttrs := `class="svg git-entry-icon ` + extraClass + `" width="16" height="16" aria-hidden="true"`
7979
posOuterBefore := strings.IndexByte(svg, '>')
8080
if renderedSVGs[svgID] && posOuterBefore != -1 {
8181
return template.HTML(`<svg ` + svgCommonAttrs + `><use xlink:href="#` + svgID + `"></use></svg>`)
@@ -92,18 +92,28 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr
9292

9393
if entry.IsLink() {
9494
if te, err := entry.FollowLink(); err == nil && te.IsDir() {
95-
return svg.RenderHTML("material-folder-symlink")
95+
// keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
96+
return svg.RenderHTML("material-folder-symlink", 16, "octicon-file-directory-symlink")
9697
}
9798
return svg.RenderHTML("octicon-file-symlink-file") // TODO: find some better icons for them
9899
}
99100

100101
name := m.findIconNameByGit(entry)
101102
if name == "folder" {
102103
// the material icon pack's "folder" icon doesn't look good, so use our built-in one
103-
return svg.RenderHTML("material-folder-generic")
104+
// keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
105+
return svg.RenderHTML("material-folder-generic", 16, "octicon-file-directory-fill")
104106
}
105107
if iconSVG, ok := m.svgs[name]; ok && iconSVG != "" {
106-
return m.renderFileIconSVG(ctx, name, iconSVG)
108+
// keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
109+
extraClass := "octicon-file"
110+
switch {
111+
case entry.IsDir():
112+
extraClass = "octicon-file-directory-fill"
113+
case entry.IsSubModule():
114+
extraClass = "octicon-file-submodule"
115+
}
116+
return m.renderFileIconSVG(ctx, name, iconSVG, extraClass)
107117
}
108118
return svg.RenderHTML("octicon-file")
109119
}

modules/git/parse_nogogit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func ParseTreeEntries(data []byte) ([]*TreeEntry, error) {
1919
return parseTreeEntries(data, nil)
2020
}
2121

22-
// parseTreeEntries FIXME this function's design is not right, it should make the caller read all data into memory
22+
// parseTreeEntries FIXME this function's design is not right, it should not make the caller read all data into memory
2323
func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
2424
entries := make([]*TreeEntry, 0, bytes.Count(data, []byte{'\n'})+1)
2525
for pos := 0; pos < len(data); {

modules/git/repo_tag.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package git
66

77
import (
8-
"context"
98
"fmt"
109
"io"
1110
"strings"
@@ -17,11 +16,6 @@ import (
1716
// TagPrefix tags prefix path on the repository
1817
const TagPrefix = "refs/tags/"
1918

20-
// IsTagExist returns true if given tag exists in the repository.
21-
func IsTagExist(ctx context.Context, repoPath, name string) bool {
22-
return IsReferenceExist(ctx, repoPath, TagPrefix+name)
23-
}
24-
2519
// CreateTag create one tag in the repository
2620
func (repo *Repository) CreateTag(name, revision string) error {
2721
_, _, err := NewCommand("tag").AddDashesAndList(name, revision).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})

modules/git/tree_blob_gogit.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
2121
return &TreeEntry{
2222
ID: t.ID,
2323
// Type: ObjectTree,
24+
ptree: t,
2425
gogitTreeEntry: &object.TreeEntry{
2526
Name: "",
2627
Mode: filemode.Dir,

modules/gitrepo/branch.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,21 @@ func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) {
4747
func GetWikiDefaultBranch(ctx context.Context, repo Repository) (string, error) {
4848
return git.GetDefaultBranch(ctx, wikiPath(repo))
4949
}
50+
51+
// IsReferenceExist returns true if given reference exists in the repository.
52+
func IsReferenceExist(ctx context.Context, repo Repository, name string) bool {
53+
return git.IsReferenceExist(ctx, repoPath(repo), name)
54+
}
55+
56+
func IsWikiReferenceExist(ctx context.Context, repo Repository, name string) bool {
57+
return git.IsReferenceExist(ctx, wikiPath(repo), name)
58+
}
59+
60+
// IsBranchExist returns true if given branch exists in the repository.
61+
func IsBranchExist(ctx context.Context, repo Repository, name string) bool {
62+
return IsReferenceExist(ctx, repo, git.BranchPrefix+name)
63+
}
64+
65+
func IsWikiBranchExist(ctx context.Context, repo Repository, name string) bool {
66+
return IsWikiReferenceExist(ctx, repo, git.BranchPrefix+name)
67+
}

0 commit comments

Comments
 (0)