diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml
index 66f48d5af8..d168c2ecc5 100644
--- a/.github/workflows/pull-db-tests.yml
+++ b/.github/workflows/pull-db-tests.yml
@@ -63,7 +63,6 @@ jobs:
RACE_ENABLED: true
TEST_TAGS: gogit
TEST_LDAP: 1
- USE_REPO_TEST_DIR: 1
test-sqlite:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
@@ -90,7 +89,6 @@ jobs:
TAGS: bindata gogit sqlite sqlite_unlock_notify
RACE_ENABLED: true
TEST_TAGS: gogit sqlite sqlite_unlock_notify
- USE_REPO_TEST_DIR: 1
test-unit:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
@@ -206,7 +204,6 @@ jobs:
env:
TAGS: bindata
RACE_ENABLED: true
- USE_REPO_TEST_DIR: 1
TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200"
test-mssql:
@@ -246,4 +243,3 @@ jobs:
timeout-minutes: 50
env:
TAGS: bindata
- USE_REPO_TEST_DIR: 1
diff --git a/Makefile b/Makefile
index 6b16780eb1..3c7582dd57 100644
--- a/Makefile
+++ b/Makefile
@@ -1,22 +1,5 @@
-ifeq ($(USE_REPO_TEST_DIR),1)
-
-# This rule replaces the whole Makefile when we're trying to use /tmp repository temporary files
-location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
-self := $(location)
-
-%:
- @tmpdir=`mktemp --tmpdir -d` ; \
- echo Using temporary directory $$tmpdir for test repositories ; \
- USE_REPO_TEST_DIR= $(MAKE) -f $(self) --no-print-directory REPO_TEST_DIR=$$tmpdir/ $@ ; \
- STATUS=$$? ; rm -r "$$tmpdir" ; exit $$STATUS
-
-else
-
-# This is the "normal" part of the Makefile
-
DIST := dist
DIST_DIRS := $(DIST)/binaries $(DIST)/release
-IMPORT := code.gitea.io/gitea
# By default use go's 1.25 experimental json v2 library when building
# TODO: remove when no longer experimental
@@ -83,7 +66,6 @@ endif
EXTRA_GOFLAGS ?=
-MAKE_VERSION := $(shell "$(MAKE)" -v | cat | head -n 1)
MAKE_EVIDENCE_DIR := .make_evidence
GOTESTFLAGS ?=
@@ -129,7 +111,7 @@ ifeq ($(VERSION),main)
VERSION := main-nightly
endif
-LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
+LDFLAGS := $(LDFLAGS) -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/riscv64
@@ -227,7 +209,7 @@ clean: ## delete backend and integration files
e2e*.test \
tests/integration/gitea-integration-* \
tests/integration/indexers-* \
- tests/mysql.ini tests/pgsql.ini tests/mssql.ini man/ \
+ tests/sqlite.ini tests/mysql.ini tests/pgsql.ini tests/mssql.ini man/ \
tests/e2e/gitea-e2e-*/ \
tests/e2e/indexers-*/ \
tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/
@@ -474,9 +456,8 @@ $(GO_LICENSE_FILE): go.mod go.sum
GO=$(GO) $(GO) run build/generate-go-licenses.go $(GO_LICENSE_FILE)
generate-ini-sqlite:
- sed -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
+ sed -e 's|{{WORK_PATH}}|$(CURDIR)/tests/$(or $(TEST_TYPE),integration)/gitea-$(or $(TEST_TYPE),integration)-sqlite|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
- -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/sqlite.ini.tmpl > tests/sqlite.ini
.PHONY: test-sqlite
@@ -495,9 +476,8 @@ generate-ini-mysql:
-e 's|{{TEST_MYSQL_DBNAME}}|${TEST_MYSQL_DBNAME}|g' \
-e 's|{{TEST_MYSQL_USERNAME}}|${TEST_MYSQL_USERNAME}|g' \
-e 's|{{TEST_MYSQL_PASSWORD}}|${TEST_MYSQL_PASSWORD}|g' \
- -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
+ -e 's|{{WORK_PATH}}|$(CURDIR)/tests/$(or $(TEST_TYPE),integration)/gitea-$(or $(TEST_TYPE),integration)-mysql|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
- -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/mysql.ini.tmpl > tests/mysql.ini
.PHONY: test-mysql
@@ -518,9 +498,8 @@ generate-ini-pgsql:
-e 's|{{TEST_PGSQL_PASSWORD}}|${TEST_PGSQL_PASSWORD}|g' \
-e 's|{{TEST_PGSQL_SCHEMA}}|${TEST_PGSQL_SCHEMA}|g' \
-e 's|{{TEST_MINIO_ENDPOINT}}|${TEST_MINIO_ENDPOINT}|g' \
- -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
+ -e 's|{{WORK_PATH}}|$(CURDIR)/tests/$(or $(TEST_TYPE),integration)/gitea-$(or $(TEST_TYPE),integration)-pgsql|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
- -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/pgsql.ini.tmpl > tests/pgsql.ini
.PHONY: test-pgsql
@@ -539,9 +518,8 @@ generate-ini-mssql:
-e 's|{{TEST_MSSQL_DBNAME}}|${TEST_MSSQL_DBNAME}|g' \
-e 's|{{TEST_MSSQL_USERNAME}}|${TEST_MSSQL_USERNAME}|g' \
-e 's|{{TEST_MSSQL_PASSWORD}}|${TEST_MSSQL_PASSWORD}|g' \
- -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
+ -e 's|{{WORK_PATH}}|$(CURDIR)/tests/$(or $(TEST_TYPE),integration)/gitea-$(or $(TEST_TYPE),integration)-mssql|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
- -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/mssql.ini.tmpl > tests/mssql.ini
.PHONY: test-mssql
@@ -662,7 +640,7 @@ migrations.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
GITEA_TEST_CONF=tests/sqlite.ini ./migrations.sqlite.test
.PHONY: migrations.individual.mysql.test
-migrations.individual.mysql.test: $(GO_SOURCES)
+migrations.individual.mysql.test: $(GO_SOURCES) generate-ini-mysql
GITEA_TEST_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
.PHONY: migrations.individual.sqlite.test\#%
@@ -670,7 +648,7 @@ migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
GITEA_TEST_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: migrations.individual.pgsql.test
-migrations.individual.pgsql.test: $(GO_SOURCES)
+migrations.individual.pgsql.test: $(GO_SOURCES) generate-ini-pgsql
GITEA_TEST_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
.PHONY: migrations.individual.pgsql.test\#%
@@ -735,7 +713,7 @@ generate-go: $(TAGS_PREREQ)
.PHONY: security-check
security-check:
- GOEXPERIMENT= go run $(GOVULNCHECK_PACKAGE) -show color ./...
+ GOEXPERIMENT= go run $(GOVULNCHECK_PACKAGE) -show color ./... || true
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
ifneq ($(and $(STATIC),$(findstring pam,$(TAGS))),)
@@ -901,9 +879,6 @@ docker:
docker build --disable-content-trust=false -t $(DOCKER_REF) .
# support also build args docker build --build-arg GITEA_VERSION=v1.2.3 --build-arg TAGS="bindata sqlite sqlite_unlock_notify" .
-# This endif closes the if at the top of the file
-endif
-
# Disable parallel execution because it would break some targets that don't
# specify exact dependencies like 'backend' which does currently not depend
# on 'frontend' to enable Node.js-less builds from source tarballs.
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index 084c66aab0..c7f8401cd9 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -2858,6 +2858,9 @@ LEVEL = Info
;ABANDONED_JOB_TIMEOUT = 24h
;; Strings committers can place inside a commit message or PR title to skip executing the corresponding actions workflow
;SKIP_WORKFLOW_STRINGS = [skip ci],[ci skip],[no ci],[skip actions],[actions skip]
+;; Comma-separated list of workflow directories, the first one to exist
+;; in a repo is used to find Actions workflow files
+;WORKFLOW_DIRS = .gitea/workflows,.github/workflows
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/flake.lock b/flake.lock
index 4cbc85b87a..a608aa3b89 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
- "lastModified": 1760038930,
- "narHash": "sha256-Oncbh0UmHjSlxO7ErQDM3KM0A5/Znfofj2BSzlHLeVw=",
+ "lastModified": 1771369470,
+ "narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "0b4defa2584313f3b781240b29d61f6f9f7e0df3",
+ "rev": "0182a361324364ae3f436a63005877674cf45efb",
"type": "github"
},
"original": {
diff --git a/go.mod b/go.mod
index f784ac2581..b7a3af6a3f 100644
--- a/go.mod
+++ b/go.mod
@@ -53,7 +53,7 @@ require (
github.com/go-co-op/gocron v1.37.0
github.com/go-enry/go-enry/v2 v2.9.4
github.com/go-git/go-billy/v5 v5.7.0
- github.com/go-git/go-git/v5 v5.16.4
+ github.com/go-git/go-git/v5 v5.16.5
github.com/go-ldap/ldap/v3 v3.4.12
github.com/go-redsync/redsync/v4 v4.15.0
github.com/go-sql-driver/mysql v1.9.3
diff --git a/go.sum b/go.sum
index b10e259c91..1a6decc18b 100644
--- a/go.sum
+++ b/go.sum
@@ -332,8 +332,8 @@ github.com/go-git/go-billy/v5 v5.7.0 h1:83lBUJhGWhYp0ngzCMSgllhUSuoHP1iEWYjsPl9n
github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
-github.com/go-git/go-git/v5 v5.16.4 h1:7ajIEZHZJULcyJebDLo99bGgS0jRrOxzZG4uCk2Yb2Y=
-github.com/go-git/go-git/v5 v5.16.4/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
+github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=
+github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
diff --git a/main.go b/main.go
index bc2121b1e7..fcfbb73371 100644
--- a/main.go
+++ b/main.go
@@ -26,9 +26,8 @@ import (
// these flags will be set by the build flags
var (
- Version = "development" // program version for this build
- Tags = "" // the Golang build tags
- MakeVersion = "" // "make" program version if built with make
+ Version = "development" // program version for this build
+ Tags = "" // the Golang build tags
)
func init() {
@@ -50,9 +49,6 @@ func main() {
func formatBuiltWith() string {
version := runtime.Version()
- if len(MakeVersion) > 0 {
- version = MakeVersion + ", " + runtime.Version()
- }
if len(Tags) == 0 {
return " built with " + version
}
diff --git a/models/actions/run.go b/models/actions/run.go
index be332d6857..99e6267071 100644
--- a/models/actions/run.go
+++ b/models/actions/run.go
@@ -168,7 +168,7 @@ func (run *ActionRun) GetPushEventPayload() (*api.PushPayload, error) {
}
func (run *ActionRun) GetPullRequestEventPayload() (*api.PullRequestPayload, error) {
- if run.Event.IsPullRequest() {
+ if run.Event.IsPullRequest() || run.Event.IsPullRequestReview() {
var payload api.PullRequestPayload
if err := json.Unmarshal([]byte(run.EventPayload), &payload); err != nil {
return nil, err
diff --git a/models/migrations/base/tests.go b/models/migrations/base/tests.go
index 36afd35dd4..17ea951b5a 100644
--- a/models/migrations/base/tests.go
+++ b/models/migrations/base/tests.go
@@ -10,7 +10,6 @@ import (
"path"
"path/filepath"
"testing"
- "time"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
@@ -27,18 +26,6 @@ import (
// FIXME: this file shouldn't be in a normal package, it should only be compiled for tests
-func removeAllWithRetry(dir string) error {
- var err error
- for range 20 {
- err = os.RemoveAll(dir)
- if err == nil {
- break
- }
- time.Sleep(100 * time.Millisecond)
- }
- return err
-}
-
func newXORMEngine(t *testing.T) (*xorm.Engine, error) {
if err := db.InitEngine(t.Context()); err != nil {
return nil, err
@@ -213,13 +200,12 @@ func LoadTableSchemasMap(t *testing.T, x *xorm.Engine) map[string]*schemas.Table
return tableMap
}
-func MainTest(m *testing.M) {
+func mainTest(m *testing.M) int {
testlogger.Init()
- setting.SetupGiteaTestEnv()
tmpDataPath, cleanup, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("data")
if err != nil {
- testlogger.Fatalf("Unable to create temporary data path %v\n", err)
+ testlogger.Panicf("Unable to create temporary data path %v\n", err)
}
defer cleanup()
@@ -227,15 +213,13 @@ func MainTest(m *testing.M) {
unittest.InitSettingsForTesting()
if err = git.InitFull(); err != nil {
- testlogger.Fatalf("Unable to InitFull: %v\n", err)
+ testlogger.Panicf("Unable to InitFull: %v\n", err)
}
setting.LoadDBSetting()
setting.InitLoggersForTest()
-
- exitStatus := m.Run()
-
- if err := removeAllWithRetry(setting.RepoRootPath); err != nil {
- _, _ = fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err)
- }
- os.Exit(exitStatus)
+ return m.Run()
+}
+
+func MainTest(m *testing.M) {
+ os.Exit(mainTest(m))
}
diff --git a/models/unittest/fixtures_test.go b/models/unittest/fixtures_test.go
index 879277c9b1..72944ec0db 100644
--- a/models/unittest/fixtures_test.go
+++ b/models/unittest/fixtures_test.go
@@ -4,6 +4,7 @@
package unittest_test
import (
+ "os"
"path/filepath"
"testing"
@@ -58,9 +59,14 @@ func NewFixturesLoaderVendorGoTestfixtures(e *xorm.Engine, opts unittest.Fixture
}
*/
+func TestMain(m *testing.M) {
+ setting.SetupGiteaTestEnv()
+ os.Exit(m.Run())
+}
+
func prepareTestFixturesLoaders(t testing.TB) unittest.FixturesOptions {
_ = user_model.User{}
- giteaRoot := setting.SetupGiteaTestEnv()
+ giteaRoot := setting.GetGiteaTestSourceRoot()
opts := unittest.FixturesOptions{Dir: filepath.Join(giteaRoot, "models", "fixtures"), Files: []string{
"user.yml",
}}
diff --git a/models/unittest/fscopy.go b/models/unittest/fscopy.go
index 98b01815bd..cddb7a3f77 100644
--- a/models/unittest/fscopy.go
+++ b/models/unittest/fscopy.go
@@ -4,10 +4,12 @@
package unittest
import (
+ "errors"
"os"
"path/filepath"
"strings"
+ "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)
@@ -39,7 +41,20 @@ func SyncFile(srcPath, destPath string) error {
// SyncDirs synchronizes files recursively from source to target directory.
// It returns error when error occurs in underlying functions.
func SyncDirs(srcPath, destPath string) error {
- err := os.MkdirAll(destPath, os.ModePerm)
+ destPath = filepath.Clean(destPath)
+ destPathAbs, err := filepath.Abs(destPath)
+ if err != nil {
+ return err
+ }
+ devDataPathAbs, err := filepath.Abs(filepath.Join(setting.GetGiteaTestSourceRoot(), "data"))
+ if err != nil {
+ return err
+ }
+ if strings.HasPrefix(destPathAbs+string(filepath.Separator), devDataPathAbs+string(filepath.Separator)) {
+ return errors.New("destination path should not be inside Gitea data directory, otherwise your data for dev mode will be removed")
+ }
+
+ err = os.MkdirAll(destPath, os.ModePerm)
if err != nil {
return err
}
diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go
index 398090760e..63c9a3a999 100644
--- a/models/unittest/testdb.go
+++ b/models/unittest/testdb.go
@@ -21,6 +21,7 @@ import (
"code.gitea.io/gitea/modules/setting/config"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/tempdir"
+ "code.gitea.io/gitea/modules/testlogger"
"code.gitea.io/gitea/modules/util"
"github.com/stretchr/testify/assert"
@@ -28,16 +29,10 @@ import (
"xorm.io/xorm/names"
)
-var giteaRoot string
-
-func fatalTestError(fmtStr string, args ...any) {
- _, _ = fmt.Fprintf(os.Stderr, fmtStr, args...)
- os.Exit(1)
-}
-
// InitSettingsForTesting initializes config provider and load common settings for tests
func InitSettingsForTesting() {
- setting.IsInTesting = true
+ setting.SetupGiteaTestEnv()
+
log.OsExiter = func(code int) {
if code != 0 {
// non-zero exit code (log.Fatal) shouldn't occur during testing, if it happens, show a full stacktrace for more details
@@ -49,8 +44,12 @@ func InitSettingsForTesting() {
setting.CustomConf = filepath.Join(setting.CustomPath, "conf/app-unittest-tmp.ini")
_ = os.Remove(setting.CustomConf)
}
- setting.InitCfgProvider(setting.CustomConf)
- setting.LoadCommonSettings()
+
+ // init paths and config system for testing
+ getTestEnv := func(key string) string {
+ return ""
+ }
+ setting.InitWorkPathAndCommonConfig(getTestEnv, setting.ArgWorkPathAndCustomConf{CustomConf: setting.CustomConf})
if err := setting.PrepareAppDataPath(); err != nil {
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
@@ -71,16 +70,18 @@ type TestOptions struct {
// MainTest a reusable TestMain(..) function for unit tests that need to use a
// test database. Creates the test database, and sets necessary settings.
func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
- testOpts := util.OptionalArg(testOptsArg, &TestOptions{})
- giteaRoot = setting.SetupGiteaTestEnv()
- InitSettingsForTesting()
+ os.Exit(mainTest(m, testOptsArg...))
+}
+func mainTest(m *testing.M, testOptsArg ...*TestOptions) int {
+ testOpts := util.OptionalArg(testOptsArg, &TestOptions{})
+ InitSettingsForTesting()
+ giteaRoot := setting.GetGiteaTestSourceRoot()
fixturesOpts := FixturesOptions{Dir: filepath.Join(giteaRoot, "models", "fixtures"), Files: testOpts.FixtureFiles}
if err := CreateTestEngine(fixturesOpts); err != nil {
- fatalTestError("Error creating test engine: %v\n", err)
+ testlogger.Panicf("Error creating test engine: %v\n", err)
}
- setting.IsInTesting = true
setting.AppURL = "https://try.gitea.io/"
setting.Domain = "try.gitea.io"
setting.RunUser = "runuser"
@@ -92,20 +93,18 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
repoRootPath, cleanup1, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("repos")
if err != nil {
- fatalTestError("TempDir: %v\n", err)
+ testlogger.Panicf("TempDir: %v\n", err)
}
defer cleanup1()
setting.RepoRootPath = repoRootPath
appDataPath, cleanup2, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("appdata")
if err != nil {
- fatalTestError("TempDir: %v\n", err)
+ testlogger.Panicf("TempDir: %v\n", err)
}
defer cleanup2()
setting.AppDataPath = appDataPath
- setting.AppWorkPath = giteaRoot
- setting.StaticRootPath = giteaRoot
setting.GravatarSource = "https://secure.gravatar.com/avatar/"
setting.Attachment.Storage.Path = filepath.Join(setting.AppDataPath, "attachments")
@@ -129,22 +128,22 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
config.SetDynGetter(system.NewDatabaseDynKeyGetter())
if err = cache.Init(); err != nil {
- fatalTestError("cache.Init: %v\n", err)
+ testlogger.Panicf("cache.Init: %v\n", err)
}
if err = storage.Init(); err != nil {
- fatalTestError("storage.Init: %v\n", err)
+ testlogger.Panicf("storage.Init: %v\n", err)
}
if err = SyncDirs(filepath.Join(giteaRoot, "tests", "gitea-repositories-meta"), setting.RepoRootPath); err != nil {
- fatalTestError("util.SyncDirs: %v\n", err)
+ testlogger.Panicf("util.SyncDirs: %v\n", err)
}
if err = git.InitFull(); err != nil {
- fatalTestError("git.Init: %v\n", err)
+ testlogger.Panicf("git.Init: %v\n", err)
}
if testOpts.SetUp != nil {
if err := testOpts.SetUp(); err != nil {
- fatalTestError("set up failed: %v\n", err)
+ testlogger.Panicf("set up failed: %v\n", err)
}
}
@@ -152,10 +151,10 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
if testOpts.TearDown != nil {
if err := testOpts.TearDown(); err != nil {
- fatalTestError("tear down failed: %v\n", err)
+ testlogger.Panicf("tear down failed: %v\n", err)
}
}
- os.Exit(exitStatus)
+ return exitStatus
}
// FixturesOptions fixtures needs to be loaded options
@@ -196,7 +195,6 @@ func PrepareTestDatabase() error {
// by tests that use the above MainTest(..) function.
func PrepareTestEnv(t testing.TB) {
assert.NoError(t, PrepareTestDatabase())
- metaPath := filepath.Join(giteaRoot, "tests", "gitea-repositories-meta")
+ metaPath := filepath.Join(setting.GetGiteaTestSourceRoot(), "tests", "gitea-repositories-meta")
assert.NoError(t, SyncDirs(metaPath, setting.RepoRootPath))
- setting.SetupGiteaTestEnv()
}
diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go
index 26a6ebc370..72892f4124 100644
--- a/modules/actions/workflows.go
+++ b/modules/actions/workflows.go
@@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -41,22 +42,30 @@ func IsWorkflow(path string) bool {
return false
}
- return strings.HasPrefix(path, ".gitea/workflows") || strings.HasPrefix(path, ".github/workflows")
+ for _, workflowDir := range setting.Actions.WorkflowDirs {
+ if strings.HasPrefix(path, workflowDir+"/") {
+ return true
+ }
+ }
+ return false
}
func ListWorkflows(commit *git.Commit) (string, git.Entries, error) {
- rpath := ".gitea/workflows"
- tree, err := commit.SubTree(rpath)
- if _, ok := err.(git.ErrNotExist); ok {
- rpath = ".github/workflows"
- tree, err = commit.SubTree(rpath)
+ var tree *git.Tree
+ var err error
+ var workflowDir string
+ for _, workflowDir = range setting.Actions.WorkflowDirs {
+ tree, err = commit.SubTree(workflowDir)
+ if err == nil {
+ break
+ }
+ if !git.IsErrNotExist(err) {
+ return "", nil, err
+ }
}
- if _, ok := err.(git.ErrNotExist); ok {
+ if tree == nil {
return "", nil, nil
}
- if err != nil {
- return "", nil, err
- }
entries, err := tree.ListEntriesRecursiveFast()
if err != nil {
@@ -69,7 +78,7 @@ func ListWorkflows(commit *git.Commit) (string, git.Entries, error) {
ret = append(ret, entry)
}
}
- return rpath, ret, nil
+ return workflowDir, ret, nil
}
func GetContentFromEntry(entry *git.TreeEntry) ([]byte, error) {
diff --git a/modules/actions/workflows_test.go b/modules/actions/workflows_test.go
index 89620fb698..77a65aae49 100644
--- a/modules/actions/workflows_test.go
+++ b/modules/actions/workflows_test.go
@@ -7,12 +7,83 @@ import (
"testing"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
)
+func TestIsWorkflow(t *testing.T) {
+ oldDirs := setting.Actions.WorkflowDirs
+ defer func() {
+ setting.Actions.WorkflowDirs = oldDirs
+ }()
+
+ tests := []struct {
+ name string
+ dirs []string
+ path string
+ expected bool
+ }{
+ {
+ name: "default with yml extension",
+ dirs: []string{".gitea/workflows", ".github/workflows"},
+ path: ".gitea/workflows/test.yml",
+ expected: true,
+ },
+ {
+ name: "default with yaml extension",
+ dirs: []string{".gitea/workflows", ".github/workflows"},
+ path: ".github/workflows/test.yaml",
+ expected: true,
+ },
+ {
+ name: "only gitea configured, github path rejected",
+ dirs: []string{".gitea/workflows"},
+ path: ".github/workflows/test.yml",
+ expected: false,
+ },
+ {
+ name: "only github configured, gitea path rejected",
+ dirs: []string{".github/workflows"},
+ path: ".gitea/workflows/test.yml",
+ expected: false,
+ },
+ {
+ name: "custom workflow dir",
+ dirs: []string{".custom/workflows"},
+ path: ".custom/workflows/deploy.yml",
+ expected: true,
+ },
+ {
+ name: "non-workflow file",
+ dirs: []string{".gitea/workflows", ".github/workflows"},
+ path: ".gitea/workflows/readme.md",
+ expected: false,
+ },
+ {
+ name: "directory boundary",
+ dirs: []string{".gitea/workflows"},
+ path: ".gitea/workflows2/test.yml",
+ expected: false,
+ },
+ {
+ name: "unrelated path",
+ dirs: []string{".gitea/workflows", ".github/workflows"},
+ path: "src/main.go",
+ expected: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ setting.Actions.WorkflowDirs = tt.dirs
+ assert.Equal(t, tt.expected, IsWorkflow(tt.path))
+ })
+ }
+}
+
func TestDetectMatched(t *testing.T) {
testCases := []struct {
desc string
diff --git a/modules/git/git.go b/modules/git/git.go
index 932da1989b..2df83f9843 100644
--- a/modules/git/git.go
+++ b/modules/git/git.go
@@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/tempdir"
+ "code.gitea.io/gitea/modules/testlogger"
"github.com/hashicorp/go-version"
)
@@ -185,21 +186,19 @@ func InitFull() (err error) {
// RunGitTests helps to init the git module and run tests.
// FIXME: GIT-PACKAGE-DEPENDENCY: the dependency is not right, setting.Git.HomePath is initialized in this package but used in gitcmd package
func RunGitTests(m interface{ Run() int }) {
- fatalf := func(exitCode int, format string, args ...any) {
- _, _ = fmt.Fprintf(os.Stderr, format, args...)
- os.Exit(exitCode)
- }
+ os.Exit(runGitTests(m))
+}
+
+func runGitTests(m interface{ Run() int }) int {
gitHomePath, cleanup, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("git-home")
if err != nil {
- fatalf(1, "unable to create temp dir: %s", err.Error())
+ testlogger.Panicf("unable to create temp dir: %s", err.Error())
}
defer cleanup()
setting.Git.HomePath = gitHomePath
if err = InitFull(); err != nil {
- fatalf(1, "failed to call Init: %s", err.Error())
- }
- if exitCode := m.Run(); exitCode != 0 {
- fatalf(exitCode, "run test failed, ExitCode=%d", exitCode)
+ testlogger.Panicf("failed to call Init: %s", err.Error())
}
+ return m.Run()
}
diff --git a/modules/git/gitcmd/command_test.go b/modules/git/gitcmd/command_test.go
index 86771f499f..662356bc3f 100644
--- a/modules/git/gitcmd/command_test.go
+++ b/modules/git/gitcmd/command_test.go
@@ -12,23 +12,27 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/tempdir"
+ "code.gitea.io/gitea/modules/testlogger"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
-func TestMain(m *testing.M) {
+func testMain(m *testing.M) int {
// FIXME: GIT-PACKAGE-DEPENDENCY: the dependency is not right.
// "setting.Git.HomePath" is initialized in "git" package but really used in "gitcmd" package
gitHomePath, cleanup, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("git-home")
if err != nil {
- _, _ = fmt.Fprintf(os.Stderr, "unable to create temp dir: %v", err)
- os.Exit(1)
+ testlogger.Panicf("failed to create temp dir: %v", err)
}
defer cleanup()
setting.Git.HomePath = gitHomePath
- os.Exit(m.Run())
+ return m.Run()
+}
+
+func TestMain(m *testing.M) {
+ os.Exit(testMain(m))
}
func TestRunWithContextStd(t *testing.T) {
diff --git a/modules/gitrepo/main_test.go b/modules/gitrepo/main_test.go
index e47eda7bc9..08afdffcc6 100644
--- a/modules/gitrepo/main_test.go
+++ b/modules/gitrepo/main_test.go
@@ -13,12 +13,13 @@ import (
func TestMain(m *testing.M) {
// resolve repository path relative to the test directory
- testRootDir := setting.SetupGiteaTestEnv()
+ setting.SetupGiteaTestEnv()
+ giteaRoot := setting.GetGiteaTestSourceRoot()
repoPath = func(repo Repository) string {
if filepath.IsAbs(repo.RelativePath()) {
return repo.RelativePath() // for testing purpose only
}
- return filepath.Join(testRootDir, "modules/git/tests/repos", repo.RelativePath())
+ return filepath.Join(giteaRoot, "modules/git/tests/repos", repo.RelativePath())
}
git.RunGitTests(m)
}
diff --git a/modules/hcaptcha/hcaptcha_test.go b/modules/hcaptcha/hcaptcha_test.go
index 5906faf17c..6b207bfb77 100644
--- a/modules/hcaptcha/hcaptcha_test.go
+++ b/modules/hcaptcha/hcaptcha_test.go
@@ -8,7 +8,6 @@ import (
"io"
"net/http"
"net/url"
- "os"
"strings"
"testing"
"time"
@@ -20,10 +19,6 @@ const (
dummyToken = "10000000-aaaa-bbbb-cccc-000000000001"
)
-func TestMain(m *testing.M) {
- os.Exit(m.Run())
-}
-
type mockTransport struct{}
func (mockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
diff --git a/modules/session/virtual.go b/modules/session/virtual.go
index 35a995d2d0..597b9e55c1 100644
--- a/modules/session/virtual.go
+++ b/modules/session/virtual.go
@@ -65,7 +65,6 @@ func (o *VirtualSessionProvider) Read(sid string) (session.RawStore, error) {
return nil, fmt.Errorf("check if '%s' exist failed: %w", sid, err)
}
kv := make(map[any]any)
- kv["_old_uid"] = "0"
return NewVirtualStore(o, sid, kv), nil
}
@@ -160,7 +159,7 @@ func (s *VirtualStore) Release() error {
// Now need to lock the provider
s.p.lock.Lock()
defer s.p.lock.Unlock()
- if oldUID, ok := s.data["_old_uid"]; (ok && (oldUID != "0" || len(s.data) > 1)) || (!ok && len(s.data) > 0) {
+ if len(s.data) > 0 {
// Now ensure that we don't exist!
realProvider := s.p.provider
diff --git a/modules/setting/actions.go b/modules/setting/actions.go
index 34346b62cf..7a91ecb593 100644
--- a/modules/setting/actions.go
+++ b/modules/setting/actions.go
@@ -4,6 +4,7 @@
package setting
import (
+ "errors"
"fmt"
"strings"
"time"
@@ -25,10 +26,12 @@ var (
EndlessTaskTimeout time.Duration `ini:"ENDLESS_TASK_TIMEOUT"`
AbandonedJobTimeout time.Duration `ini:"ABANDONED_JOB_TIMEOUT"`
SkipWorkflowStrings []string `ini:"SKIP_WORKFLOW_STRINGS"`
+ WorkflowDirs []string `ini:"WORKFLOW_DIRS"`
}{
Enabled: true,
DefaultActionsURL: defaultActionsURLGitHub,
SkipWorkflowStrings: []string{"[skip ci]", "[ci skip]", "[no ci]", "[skip actions]", "[actions skip]"},
+ WorkflowDirs: []string{".gitea/workflows", ".github/workflows"},
}
)
@@ -119,5 +122,20 @@ func loadActionsFrom(rootCfg ConfigProvider) error {
return fmt.Errorf("invalid [actions] LOG_COMPRESSION: %q", Actions.LogCompression)
}
+ workflowDirs := make([]string, 0, len(Actions.WorkflowDirs))
+ for _, dir := range Actions.WorkflowDirs {
+ dir = strings.TrimSpace(dir)
+ if dir == "" {
+ continue
+ }
+ dir = strings.ReplaceAll(dir, `\`, `/`)
+ dir = strings.TrimRight(dir, "/")
+ workflowDirs = append(workflowDirs, dir)
+ }
+ if len(workflowDirs) == 0 {
+ return errors.New("[actions] WORKFLOW_DIRS must contain at least one entry")
+ }
+ Actions.WorkflowDirs = workflowDirs
+
return nil
}
diff --git a/modules/setting/actions_test.go b/modules/setting/actions_test.go
index 353cc657fa..5c7ab268c1 100644
--- a/modules/setting/actions_test.go
+++ b/modules/setting/actions_test.go
@@ -97,6 +97,65 @@ STORAGE_TYPE = minio
assert.Equal(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path))
}
+func Test_WorkflowDirs(t *testing.T) {
+ oldActions := Actions
+ defer func() {
+ Actions = oldActions
+ }()
+
+ tests := []struct {
+ name string
+ iniStr string
+ wantDirs []string
+ wantErr bool
+ }{
+ {
+ name: "default",
+ iniStr: `[actions]`,
+ wantDirs: []string{".gitea/workflows", ".github/workflows"},
+ },
+ {
+ name: "single dir",
+ iniStr: "[actions]\nWORKFLOW_DIRS = .github/workflows",
+ wantDirs: []string{".github/workflows"},
+ },
+ {
+ name: "custom order",
+ iniStr: "[actions]\nWORKFLOW_DIRS = .github/workflows,.gitea/workflows",
+ wantDirs: []string{".github/workflows", ".gitea/workflows"},
+ },
+ {
+ name: "whitespace trimming",
+ iniStr: "[actions]\nWORKFLOW_DIRS = .gitea/workflows , .github/workflows ",
+ wantDirs: []string{".gitea/workflows", ".github/workflows"},
+ },
+ {
+ name: "trailing slash normalization",
+ iniStr: "[actions]\nWORKFLOW_DIRS = .gitea/workflows/,.github/workflows/",
+ wantDirs: []string{".gitea/workflows", ".github/workflows"},
+ },
+ {
+ name: "only commas and whitespace",
+ iniStr: "[actions]\nWORKFLOW_DIRS = , , ,",
+ wantErr: true,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ cfg, err := NewConfigProviderFromData(tt.iniStr)
+ require.NoError(t, err)
+ err = loadActionsFrom(cfg)
+ if tt.wantErr {
+ require.Error(t, err)
+ return
+ }
+ require.NoError(t, err)
+ assert.Equal(t, tt.wantDirs, Actions.WorkflowDirs)
+ })
+ }
+}
+
func Test_getDefaultActionsURLForActions(t *testing.T) {
oldActions := Actions
oldAppURL := AppURL
diff --git a/modules/setting/testenv.go b/modules/setting/testenv.go
index 52e8912af0..853521c328 100644
--- a/modules/setting/testenv.go
+++ b/modules/setting/testenv.go
@@ -13,7 +13,18 @@ import (
"code.gitea.io/gitea/modules/util"
)
-func SetupGiteaTestEnv() string {
+var giteaTestSourceRoot *string
+
+func GetGiteaTestSourceRoot() string {
+ return *giteaTestSourceRoot
+}
+
+func SetupGiteaTestEnv() {
+ if giteaTestSourceRoot != nil {
+ return // already initialized
+ }
+
+ IsInTesting = true
giteaRoot := os.Getenv("GITEA_TEST_ROOT")
if giteaRoot == "" {
_, filename, _, _ := runtime.Caller(0)
@@ -27,6 +38,7 @@ func SetupGiteaTestEnv() string {
appWorkPathBuiltin = giteaRoot
AppWorkPath = giteaRoot
AppPath = filepath.Join(giteaRoot, "gitea") + util.Iif(IsWindows, ".exe", "")
+ StaticRootPath = giteaRoot // need to load assets (options, public) from the source code directory for testing
// giteaConf (GITEA_CONF) must be relative because it is used in the git hooks as "$GITEA_ROOT/$GITEA_CONF"
giteaConf := os.Getenv("GITEA_TEST_CONF")
@@ -56,6 +68,5 @@ func SetupGiteaTestEnv() string {
// TODO: some git repo hooks (test fixtures) still use these env variables, need to be refactored in the future
_ = os.Setenv("GITEA_ROOT", giteaRoot)
_ = os.Setenv("GITEA_CONF", giteaConf) // test fixture git hooks use "$GITEA_ROOT/$GITEA_CONF" in their scripts
-
- return giteaRoot
+ giteaTestSourceRoot = &giteaRoot
}
diff --git a/modules/testlogger/testlogger.go b/modules/testlogger/testlogger.go
index bf08e1d6d5..39232a3eed 100644
--- a/modules/testlogger/testlogger.go
+++ b/modules/testlogger/testlogger.go
@@ -173,7 +173,7 @@ func Init() {
log.RegisterEventWriter("test", newTestLoggerWriter)
}
-func Fatalf(format string, args ...any) {
- Printf(format+"\n", args...)
- os.Exit(1)
+func Panicf(format string, args ...any) {
+ // don't call os.Exit, otherwise the "defer" functions won't be executed
+ panic(fmt.Sprintf(format, args...))
}
diff --git a/modules/timeutil/since_test.go b/modules/timeutil/since_test.go
index 40fefe8700..bf848bd05a 100644
--- a/modules/timeutil/since_test.go
+++ b/modules/timeutil/since_test.go
@@ -32,11 +32,7 @@ func TestMain(m *testing.M) {
// setup
translation.InitLocales(context.Background())
BaseDate = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
-
- // run the tests
- retVal := m.Run()
-
- os.Exit(retVal)
+ os.Exit(m.Run())
}
func TestTimeSincePro(t *testing.T) {
diff --git a/modules/webhook/type.go b/modules/webhook/type.go
index 89c6a4bfe5..18a4086710 100644
--- a/modules/webhook/type.go
+++ b/modules/webhook/type.go
@@ -98,6 +98,20 @@ func (h HookEventType) IsPullRequest() bool {
return h.Event() == "pull_request"
}
+// IsPullRequestReview returns true for pull request review events
+// (approved, rejected, comment). These events use the same PullRequestPayload
+// as regular pull_request events.
+func (h HookEventType) IsPullRequestReview() bool {
+ switch h {
+ case HookEventPullRequestReviewApproved,
+ HookEventPullRequestReviewRejected,
+ HookEventPullRequestReviewComment:
+ return true
+ default:
+ return false
+ }
+}
+
// HookType is the type of a webhook
type HookType = string
diff --git a/package.json b/package.json
index e8f1c55816..a7792c5fee 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,7 @@
"swagger-ui-dist": "5.31.1",
"tailwindcss": "3.4.17",
"throttle-debounce": "5.0.2",
- "tinycolor2": "1.6.0",
+ "colord": "2.9.3",
"tippy.js": "6.3.7",
"toastify-js": "1.12.0",
"tributejs": "5.1.3",
@@ -77,11 +77,11 @@
"@types/jquery": "3.5.33",
"@types/js-yaml": "4.0.9",
"@types/katex": "0.16.8",
+ "@types/node": "25.2.3",
"@types/pdfobject": "2.2.5",
"@types/sortablejs": "1.15.9",
"@types/swagger-ui-dist": "3.30.6",
"@types/throttle-debounce": "5.0.2",
- "@types/tinycolor2": "1.4.6",
"@types/toastify-js": "1.12.4",
"@typescript-eslint/parser": "8.56.0",
"@vitejs/plugin-vue": "6.0.4",
@@ -119,9 +119,6 @@
"vitest": "4.0.18",
"vue-tsc": "3.2.4"
},
- "browserslist": [
- "defaults"
- ],
"pnpm": {
"overrides": {
"array-includes": "npm:@nolyfill/array-includes@^1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f273662cad..e67da15ad3 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -89,6 +89,9 @@ importers:
clippie:
specifier: 4.1.10
version: 4.1.10
+ colord:
+ specifier: 2.9.3
+ version: 2.9.3
compare-versions:
specifier: 6.1.1
version: 6.1.1
@@ -164,9 +167,6 @@ importers:
throttle-debounce:
specifier: 5.0.2
version: 5.0.2
- tinycolor2:
- specifier: 1.6.0
- version: 1.6.0
tippy.js:
specifier: 6.3.7
version: 6.3.7
@@ -234,6 +234,9 @@ importers:
'@types/katex':
specifier: 0.16.8
version: 0.16.8
+ '@types/node':
+ specifier: 25.2.3
+ version: 25.2.3
'@types/pdfobject':
specifier: 2.2.5
version: 2.2.5
@@ -246,9 +249,6 @@ importers:
'@types/throttle-debounce':
specifier: 5.0.2
version: 5.0.2
- '@types/tinycolor2':
- specifier: 1.4.6
- version: 1.4.6
'@types/toastify-js':
specifier: 1.12.4
version: 1.12.4
@@ -1294,9 +1294,6 @@ packages:
'@types/throttle-debounce@5.0.2':
resolution: {integrity: sha512-pDzSNulqooSKvSNcksnV72nk8p7gRqN8As71Sp28nov1IgmPKWbOEIwAWvBME5pPTtaXJAvG3O4oc76HlQ4kqQ==}
- '@types/tinycolor2@1.4.6':
- resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==}
-
'@types/toastify-js@1.12.4':
resolution: {integrity: sha512-zfZHU4tKffPCnZRe7pjv/eFKzTVHozKewFCKaCjZ4gFinKgJRz/t0bkZiMCXJxPhv/ZoeDGNOeRD09R0kQZ/nw==}
@@ -4053,9 +4050,6 @@ packages:
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
- tinycolor2@1.6.0:
- resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
-
tinyexec@1.0.2:
resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
engines: {node: '>=18'}
@@ -5238,8 +5232,6 @@ snapshots:
'@types/throttle-debounce@5.0.2': {}
- '@types/tinycolor2@1.4.6': {}
-
'@types/toastify-js@1.12.4': {}
'@types/trusted-types@2.0.7':
@@ -8212,8 +8204,6 @@ snapshots:
tinybench@2.9.0: {}
- tinycolor2@1.6.0: {}
-
tinyexec@1.0.2: {}
tinyglobby@0.2.15:
diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go
index 7271f58091..884b98e966 100644
--- a/services/actions/commit_status.go
+++ b/services/actions/commit_status.go
@@ -115,6 +115,21 @@ func getCommitStatusEventNameAndCommitID(run *actions_model.ActionRun) (event, c
return "", "", errors.New("head of pull request is missing in event payload")
}
commitID = payload.PullRequest.Head.Sha
+ case // pull_request_review events share the same PullRequestPayload as pull_request
+ webhook_module.HookEventPullRequestReviewApproved,
+ webhook_module.HookEventPullRequestReviewRejected,
+ webhook_module.HookEventPullRequestReviewComment:
+ event = run.TriggerEvent
+ payload, err := run.GetPullRequestEventPayload()
+ if err != nil {
+ return "", "", fmt.Errorf("GetPullRequestEventPayload: %w", err)
+ }
+ if payload.PullRequest == nil {
+ return "", "", errors.New("pull request is missing in event payload")
+ } else if payload.PullRequest.Head == nil {
+ return "", "", errors.New("head of pull request is missing in event payload")
+ }
+ commitID = payload.PullRequest.Head.Sha
case webhook_module.HookEventRelease:
event = string(run.Event)
commitID = run.CommitSHA
diff --git a/services/actions/init_test.go b/services/actions/init_test.go
index 2d33a4e5cc..e61b3759e1 100644
--- a/services/actions/init_test.go
+++ b/services/actions/init_test.go
@@ -18,7 +18,6 @@ import (
func TestMain(m *testing.M) {
unittest.MainTest(m)
- os.Exit(m.Run())
}
func TestInitToken(t *testing.T) {
diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go
index 95093ffd29..6e7890105c 100644
--- a/tests/e2e/e2e_test.go
+++ b/tests/e2e/e2e_test.go
@@ -37,7 +37,7 @@ func TestMain(m *testing.M) {
graceful.InitManager(managerCtx)
defer cancel()
- tests.InitTest(false)
+ tests.InitTest()
testE2eWebRoutes = routers.NormalRoutes()
err := unittest.InitFixtures(
diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go
index b0eabdd432..7fff796af6 100644
--- a/tests/integration/actions_trigger_test.go
+++ b/tests/integration/actions_trigger_test.go
@@ -691,6 +691,144 @@ func insertFakeStatus(t *testing.T, repo *repo_model.Repository, sha, targetURL,
assert.NoError(t, err)
}
+func TestPullRequestReviewCommitStatusEvent(t *testing.T) {
+ onGiteaRun(t, func(t *testing.T, u *url.URL) {
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // reviewer
+
+ // create a repo
+ repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
+ Name: "repo-pull-request-review",
+ Description: "test pull-request-review commit status",
+ AutoInit: true,
+ Gitignores: "Go",
+ License: "MIT",
+ Readme: "Default",
+ DefaultBranch: "main",
+ IsPrivate: false,
+ })
+ assert.NoError(t, err)
+ assert.NotEmpty(t, repo)
+
+ // add user4 as collaborator so they can review
+ ctx := NewAPITestContext(t, repo.OwnerName, repo.Name, auth_model.AccessTokenScopeWriteRepository)
+ t.Run("AddUser4AsCollaboratorWithWriteAccess", doAPIAddCollaborator(ctx, "user4", perm.AccessModeWrite))
+
+ // add workflow file that triggers on pull_request_review
+ addWorkflow, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
+ Files: []*files_service.ChangeRepoFile{
+ {
+ Operation: "create",
+ TreePath: ".gitea/workflows/pr-review.yml",
+ ContentReader: strings.NewReader(`name: test
+on:
+ pull_request_review:
+ types: [submitted]
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo helloworld
+`),
+ },
+ },
+ Message: "add workflow",
+ OldBranch: "main",
+ NewBranch: "main",
+ Author: &files_service.IdentityOptions{
+ GitUserName: user2.Name,
+ GitUserEmail: user2.Email,
+ },
+ Committer: &files_service.IdentityOptions{
+ GitUserName: user2.Name,
+ GitUserEmail: user2.Email,
+ },
+ Dates: &files_service.CommitDateOptions{
+ Author: time.Now(),
+ Committer: time.Now(),
+ },
+ })
+ assert.NoError(t, err)
+ assert.NotEmpty(t, addWorkflow)
+
+ // create a branch and a PR
+ testBranch := "test-review-branch"
+ err = repo_service.CreateNewBranch(t.Context(), user2, repo, "main", testBranch)
+ assert.NoError(t, err)
+
+ // add a file on the test branch so the PR has changes
+ addFileResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
+ Files: []*files_service.ChangeRepoFile{
+ {
+ Operation: "create",
+ TreePath: "test.txt",
+ ContentReader: strings.NewReader("test content"),
+ },
+ },
+ Message: "add test file",
+ OldBranch: testBranch,
+ NewBranch: testBranch,
+ Author: &files_service.IdentityOptions{
+ GitUserName: user2.Name,
+ GitUserEmail: user2.Email,
+ },
+ Committer: &files_service.IdentityOptions{
+ GitUserName: user2.Name,
+ GitUserEmail: user2.Email,
+ },
+ Dates: &files_service.CommitDateOptions{
+ Author: time.Now(),
+ Committer: time.Now(),
+ },
+ })
+ assert.NoError(t, err)
+ assert.NotEmpty(t, addFileResp)
+ sha := addFileResp.Commit.SHA
+
+ pullIssue := &issues_model.Issue{
+ RepoID: repo.ID,
+ Title: "A test PR for review",
+ PosterID: user2.ID,
+ Poster: user2,
+ IsPull: true,
+ }
+ pullRequest := &issues_model.PullRequest{
+ HeadRepoID: repo.ID,
+ BaseRepoID: repo.ID,
+ HeadBranch: testBranch,
+ BaseBranch: "main",
+ HeadRepo: repo,
+ BaseRepo: repo,
+ Type: issues_model.PullRequestGitea,
+ }
+ prOpts := &pull_service.NewPullRequestOptions{Repo: repo, Issue: pullIssue, PullRequest: pullRequest}
+ err = pull_service.NewPullRequest(t.Context(), prOpts)
+ assert.NoError(t, err)
+
+ // submit an approval review as user4
+ gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
+ assert.NoError(t, err)
+ defer gitRepo.Close()
+
+ _, _, err = pull_service.SubmitReview(t.Context(), user4, gitRepo, pullIssue, issues_model.ReviewTypeApprove, "lgtm", sha, nil)
+ assert.NoError(t, err)
+
+ // verify that a commit status was created for the review event
+ assert.Eventually(t, func() bool {
+ latestCommitStatuses, err := git_model.GetLatestCommitStatus(t.Context(), repo.ID, sha, db.ListOptionsAll)
+ assert.NoError(t, err)
+ if len(latestCommitStatuses) == 0 {
+ return false
+ }
+ if latestCommitStatuses[0].State == commitstatus.CommitStatusPending {
+ insertFakeStatus(t, repo, sha, latestCommitStatuses[0].TargetURL, latestCommitStatuses[0].Context)
+ return true
+ }
+ return false
+ }, 1*time.Second, 100*time.Millisecond)
+ })
+}
+
func TestWorkflowDispatchPublicApi(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go
index 3803f331c4..ca1e094ac2 100644
--- a/tests/integration/integration_test.go
+++ b/tests/integration/integration_test.go
@@ -1,7 +1,6 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//nolint:forbidigo // use of print functions is allowed in tests
package integration
import (
@@ -27,6 +26,7 @@ import (
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/testlogger"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/modules/web/middleware"
@@ -79,14 +79,14 @@ func NewNilResponseHashSumRecorder() *NilResponseHashSumRecorder {
}
}
-func TestMain(m *testing.M) {
+func testMain(m *testing.M) int {
defer log.GetManager().Close()
managerCtx, cancel := context.WithCancel(context.Background())
graceful.InitManager(managerCtx)
defer cancel()
- tests.InitTest(true)
+ tests.InitTest()
testWebRoutes = routers.NormalRoutes()
err := unittest.InitFixtures(
@@ -95,8 +95,7 @@ func TestMain(m *testing.M) {
},
)
if err != nil {
- fmt.Printf("Error initializing test database: %v\n", err)
- os.Exit(1)
+ testlogger.Panicf("InitFixtures: %v", err)
}
// FIXME: the console logger is deleted by mistake, so if there is any `log.Fatal`, developers won't see any error message.
@@ -104,15 +103,16 @@ func TestMain(m *testing.M) {
exitCode := m.Run()
if err = util.RemoveAll(setting.Indexer.IssuePath); err != nil {
- fmt.Printf("util.RemoveAll: %v\n", err)
- os.Exit(1)
+ log.Error("Failed to remove indexer path: %v", err)
}
if err = util.RemoveAll(setting.Indexer.RepoPath); err != nil {
- fmt.Printf("Unable to remove repo indexer: %v\n", err)
- os.Exit(1)
+ log.Error("Failed to remove indexer path: %v", err)
}
+ return exitCode
+}
- os.Exit(exitCode)
+func TestMain(m *testing.M) {
+ os.Exit(testMain(m))
}
type TestSession struct {
diff --git a/tests/integration/migration-test/migration_test.go b/tests/integration/migration-test/migration_test.go
index ee49829127..2e25afb43c 100644
--- a/tests/integration/migration-test/migration_test.go
+++ b/tests/integration/migration-test/migration_test.go
@@ -36,8 +36,6 @@ var currentEngine *xorm.Engine
func initMigrationTest(t *testing.T) func() {
testlogger.Init()
- setting.SetupGiteaTestEnv()
-
unittest.InitSettingsForTesting()
assert.NotEmpty(t, setting.RepoRootPath)
diff --git a/tests/integration/pull_create_test.go b/tests/integration/pull_create_test.go
index 3db335fc3f..2c17557eb0 100644
--- a/tests/integration/pull_create_test.go
+++ b/tests/integration/pull_create_test.go
@@ -176,41 +176,6 @@ func TestPullCreate(t *testing.T) {
})
}
-func TestPullCreate_TitleEscape(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, u *url.URL) {
- session := loginUser(t, "user1")
- testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
- testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
- resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "XSS PR")
-
- // check the redirected URL
- url := test.RedirectURL(resp)
- assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
-
- // Edit title
- req := NewRequest(t, "GET", url)
- resp = session.MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
- editTestTitleURL, exists := htmlDoc.doc.Find(".issue-title-buttons button[data-update-url]").First().Attr("data-update-url")
- assert.True(t, exists, "The template has changed")
-
- req = NewRequestWithValues(t, "POST", editTestTitleURL, map[string]string{
- "title": "XSS PR",
- })
- session.MakeRequest(t, req, http.StatusOK)
-
- req = NewRequest(t, "GET", url)
- resp = session.MakeRequest(t, req, http.StatusOK)
- htmlDoc = NewHTMLParser(t, resp.Body)
- titleHTML, err := htmlDoc.doc.Find(".comment-list .timeline-item.event .comment-text-line b").First().Html()
- assert.NoError(t, err)
- assert.Equal(t, "<i>XSS PR</i>", titleHTML)
- titleHTML, err = htmlDoc.doc.Find(".comment-list .timeline-item.event .comment-text-line b").Next().Html()
- assert.NoError(t, err)
- assert.Equal(t, "<u>XSS PR</u>", titleHTML)
- })
-}
-
func testUIDeleteBranch(t *testing.T, session *TestSession, ownerName, repoName, branchName string) {
relURL := "/" + path.Join(ownerName, repoName, "branches")
req := NewRequestWithValues(t, "POST", relURL+"/delete", map[string]string{
diff --git a/tests/integration/xss_test.go b/tests/integration/xss_test.go
deleted file mode 100644
index 62d2e27bcd..0000000000
--- a/tests/integration/xss_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package integration
-
-import (
- "net/http"
- "testing"
-
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/tests"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestXSSUserFullName(t *testing.T) {
- defer tests.PrepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- const fullName = `name & `
-
- session := loginUser(t, user.Name)
- req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
- "name": user.Name,
- "full_name": fullName,
- "email": user.Email,
- "language": "en-US",
- })
- session.MakeRequest(t, req, http.StatusSeeOther)
-
- req = NewRequestf(t, "GET", "/%s", user.Name)
- resp := session.MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
- assert.Equal(t, 0, htmlDoc.doc.Find("script.evil").Length())
- assert.Equal(t, fullName,
- htmlDoc.doc.Find("div.content").Find(".header.text.center").Text(),
- )
-}
diff --git a/tests/mssql.ini.tmpl b/tests/mssql.ini.tmpl
index 42bf683a07..0d16905033 100644
--- a/tests/mssql.ini.tmpl
+++ b/tests/mssql.ini.tmpl
@@ -1,3 +1,4 @@
+WORK_PATH = {{WORK_PATH}}
APP_NAME = Gitea: Git with a cup of tea
RUN_MODE = prod
@@ -11,11 +12,9 @@ SSL_MODE = disable
[indexer]
REPO_INDEXER_ENABLED = true
-REPO_INDEXER_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/indexers/repos.bleve
[queue.issue_indexer]
TYPE = level
-DATADIR = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/indexers/issues.queue
[queue]
TYPE = immediate
@@ -29,15 +28,6 @@ TYPE = immediate
[queue.webhook_sender]
TYPE = immediate
-[repository]
-ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/gitea-repositories
-
-[repository.local]
-LOCAL_COPY_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/tmp/local-repo
-
-[repository.upload]
-TEMP_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/tmp/uploads
-
[repository.signing]
SIGNING_KEY = none
@@ -53,14 +43,13 @@ START_SSH_SERVER = true
LFS_START_SERVER = true
OFFLINE_MODE = false
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
-APP_DATA_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/data
BUILTIN_SSH_SERVER_USER = git
SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE=
[mailer]
ENABLED = true
PROTOCOL = dummy
-FROM = mssql-{{TEST_TYPE}}-test@gitea.io
+FROM = mssql-integration-test@gitea.io
[service]
REGISTER_EMAIL_CONFIRM = false
@@ -76,16 +65,12 @@ ENABLE_NOTIFY_MAIL = true
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
-AVATAR_UPLOAD_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/data/avatars
-REPOSITORY_AVATAR_UPLOAD_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/data/repo-avatars
[session]
PROVIDER = file
-PROVIDER_CONFIG = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/data/sessions
[log]
MODE = {{TEST_LOGGER}}
-ROOT_PATH = {{REPO_TEST_DIR}}mssql-log
ENABLE_SSH_LOG = true
logger.xorm.MODE = file
diff --git a/tests/mysql.ini.tmpl b/tests/mysql.ini.tmpl
index 7cef540d1d..bf59efde4c 100644
--- a/tests/mysql.ini.tmpl
+++ b/tests/mysql.ini.tmpl
@@ -1,3 +1,4 @@
+WORK_PATH = {{WORK_PATH}}
APP_NAME = Gitea: Git with a cup of tea
RUN_MODE = prod
@@ -11,13 +12,11 @@ SSL_MODE = disable
[indexer]
REPO_INDEXER_ENABLED = true
-REPO_INDEXER_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/indexers/repos.bleve
ISSUE_INDEXER_TYPE = elasticsearch
ISSUE_INDEXER_CONN_STR = http://elastic:changeme@elasticsearch:9200
[queue.issue_indexer]
TYPE = level
-DATADIR = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/indexers/issues.queue
[queue]
TYPE = immediate
@@ -31,15 +30,6 @@ TYPE = immediate
[queue.webhook_sender]
TYPE = immediate
-[repository]
-ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/gitea-repositories
-
-[repository.local]
-LOCAL_COPY_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/tmp/local-repo
-
-[repository.upload]
-TEMP_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/tmp/uploads
-
[repository.signing]
SIGNING_KEY = none
@@ -51,7 +41,6 @@ LOCAL_ROOT_URL = http://127.0.0.1:3001/
DISABLE_SSH = false
SSH_LISTEN_HOST = localhost
SSH_PORT = 2201
-APP_DATA_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/data
BUILTIN_SSH_SERVER_USER = git
START_SSH_SERVER = true
OFFLINE_MODE = false
@@ -63,7 +52,7 @@ SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXW
[mailer]
ENABLED = true
PROTOCOL = dummy
-FROM = mysql-{{TEST_TYPE}}-test@gitea.io
+FROM = mysql-integration-test@gitea.io
[service]
REGISTER_EMAIL_CONFIRM = false
@@ -82,11 +71,9 @@ ENABLE_FEDERATED_AVATAR = false
[session]
PROVIDER = file
-PROVIDER_CONFIG = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/data/sessions
[log]
MODE = {{TEST_LOGGER}}
-ROOT_PATH = {{REPO_TEST_DIR}}mysql-log
ENABLE_SSH_LOG = true
logger.xorm.MODE = file
@@ -103,9 +90,6 @@ SECRET_KEY = 9pCviYTWSb
INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTU1NTE2MTh9.hhSVGOANkaKk3vfCd2jDOIww4pUk0xtg9JRde5UogyQ
DISABLE_QUERY_AUTH_TOKEN = true
-[lfs]
-PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/data/lfs
-
[packages]
ENABLED = true
diff --git a/tests/pgsql.ini.tmpl b/tests/pgsql.ini.tmpl
index 13a5932608..b6fcd33f70 100644
--- a/tests/pgsql.ini.tmpl
+++ b/tests/pgsql.ini.tmpl
@@ -1,3 +1,4 @@
+WORK_PATH = {{WORK_PATH}}
APP_NAME = Gitea: Git with a cup of tea
RUN_MODE = prod
@@ -12,11 +13,9 @@ SSL_MODE = disable
[indexer]
REPO_INDEXER_ENABLED = true
-REPO_INDEXER_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/indexers/repos.bleve
[queue.issue_indexer]
TYPE = level
-DATADIR = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/indexers/issues.queue
[queue]
TYPE = immediate
@@ -30,15 +29,6 @@ TYPE = immediate
[queue.webhook_sender]
TYPE = immediate
-[repository]
-ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/gitea-repositories
-
-[repository.local]
-LOCAL_COPY_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/tmp/local-repo
-
-[repository.upload]
-TEMP_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/tmp/uploads
-
[repository.signing]
SIGNING_KEY = none
@@ -54,14 +44,13 @@ START_SSH_SERVER = true
LFS_START_SERVER = true
OFFLINE_MODE = false
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
-APP_DATA_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/data
BUILTIN_SSH_SERVER_USER = git
SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE=
[mailer]
ENABLED = true
PROTOCOL = dummy
-FROM = pgsql-{{TEST_TYPE}}-test@gitea.io
+FROM = pgsql-integration-test@gitea.io
[service]
REGISTER_EMAIL_CONFIRM = false
@@ -77,16 +66,12 @@ ENABLE_NOTIFY_MAIL = true
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
-AVATAR_UPLOAD_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/data/avatars
-REPOSITORY_AVATAR_UPLOAD_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/data/repo-avatars
[session]
PROVIDER = file
-PROVIDER_CONFIG = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/data/sessions
[log]
MODE = {{TEST_LOGGER}}
-ROOT_PATH = {{REPO_TEST_DIR}}pgsql-log
ENABLE_SSH_LOG = true
logger.xorm.MODE = file
diff --git a/tests/sqlite.ini.tmpl b/tests/sqlite.ini.tmpl
index 61f7e2a46d..243bea86f1 100644
--- a/tests/sqlite.ini.tmpl
+++ b/tests/sqlite.ini.tmpl
@@ -1,17 +1,16 @@
+WORK_PATH = {{WORK_PATH}}
APP_NAME = Gitea: Git with a cup of tea
RUN_MODE = prod
[database]
DB_TYPE = sqlite3
-PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/gitea.db
+PATH = gitea.db
[indexer]
REPO_INDEXER_ENABLED = true
-REPO_INDEXER_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/indexers/repos.bleve
[queue.issue_indexer]
TYPE = level
-DATADIR = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/indexers/issues.queue
[queue]
TYPE = immediate
@@ -25,15 +24,6 @@ TYPE = immediate
[queue.webhook_sender]
TYPE = immediate
-[repository]
-ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/gitea-repositories
-
-[repository.local]
-LOCAL_COPY_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/tmp/local-repo
-
-[repository.upload]
-TEMP_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/tmp/uploads
-
[repository.signing]
SIGNING_KEY = none
@@ -49,18 +39,14 @@ START_SSH_SERVER = true
LFS_START_SERVER = true
OFFLINE_MODE = false
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
-APP_DATA_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/data
ENABLE_GZIP = true
BUILTIN_SSH_SERVER_USER = git
SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE=
-[attachment]
-PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/data/attachments
-
[mailer]
ENABLED = true
PROTOCOL = dummy
-FROM = sqlite-{{TEST_TYPE}}-test@gitea.io
+FROM = sqlite-integration-test@gitea.io
[service]
REGISTER_EMAIL_CONFIRM = false
@@ -76,16 +62,12 @@ NO_REPLY_ADDRESS = noreply.example.org
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
-AVATAR_UPLOAD_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/data/avatars
-REPOSITORY_AVATAR_UPLOAD_PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/data/repo-avatars
[session]
PROVIDER = file
-PROVIDER_CONFIG = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/data/sessions
[log]
MODE = {{TEST_LOGGER}}
-ROOT_PATH = {{REPO_TEST_DIR}}sqlite-log
ENABLE_SSH_LOG = true
logger.xorm.MODE = file
@@ -105,9 +87,6 @@ DISABLE_QUERY_AUTH_TOKEN = true
[oauth2]
JWT_SECRET = KZb_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko
-[lfs]
-PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/data/lfs
-
[packages]
ENABLED = true
diff --git a/tests/test_utils.go b/tests/test_utils.go
index 0cb99a1f2c..34645e5370 100644
--- a/tests/test_utils.go
+++ b/tests/test_utils.go
@@ -24,11 +24,8 @@ import (
"github.com/stretchr/testify/assert"
)
-func InitTest(requireGitea bool) {
+func InitTest() {
testlogger.Init()
-
- setting.SetupGiteaTestEnv()
-
unittest.InitSettingsForTesting()
setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
@@ -38,7 +35,7 @@ func InitTest(requireGitea bool) {
setting.LoadDBSetting()
if err := storage.Init(); err != nil {
- testlogger.Fatalf("Init storage failed: %v\n", err)
+ testlogger.Panicf("Init storage failed: %v\n", err)
}
switch {
diff --git a/tsconfig.json b/tsconfig.json
index 7b16df0196..9b978cf54e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -44,6 +44,7 @@
"stripInternal": true,
"verbatimModuleSyntax": true,
"types": [
+ "node",
"webpack/module",
"vitest/globals",
"./web_src/js/globals.d.ts",
diff --git a/web_src/js/features/codeeditor.ts b/web_src/js/features/codeeditor.ts
index 47f378c47a..b2aa9ea1c5 100644
--- a/web_src/js/features/codeeditor.ts
+++ b/web_src/js/features/codeeditor.ts
@@ -1,4 +1,4 @@
-import tinycolor from 'tinycolor2';
+import {colord} from 'colord';
import {basename, extname, isObject, isDarkTheme} from '../utils.ts';
import {onInputDebounce} from '../utils/dom.ts';
import type MonacoNamespace from 'monaco-editor';
@@ -94,7 +94,7 @@ function updateTheme(monaco: Monaco): void {
// https://github.com/microsoft/monaco-editor/issues/2427
// also, monaco can only parse 6-digit hex colors, so we convert the colors to that format
const styles = window.getComputedStyle(document.documentElement);
- const getColor = (name: string) => tinycolor(styles.getPropertyValue(name).trim()).toString('hex6');
+ const getColor = (name: string) => colord(styles.getPropertyValue(name).trim()).alpha(1).toHex();
monaco.editor.defineTheme('gitea', {
base: isDarkTheme() ? 'vs-dark' : 'vs',
diff --git a/web_src/js/utils/color.ts b/web_src/js/utils/color.ts
index 57c909b8a0..096356983a 100644
--- a/web_src/js/utils/color.ts
+++ b/web_src/js/utils/color.ts
@@ -1,22 +1,21 @@
-import tinycolor from 'tinycolor2';
-import type {ColorInput} from 'tinycolor2';
+import {colord} from 'colord';
+import type {AnyColor} from 'colord';
/** Returns relative luminance for a SRGB color - https://en.wikipedia.org/wiki/Relative_luminance */
// Keep this in sync with modules/util/color.go
-function getRelativeLuminance(color: ColorInput): number {
- const {r, g, b} = tinycolor(color).toRgb();
+function getRelativeLuminance(color: AnyColor): number {
+ const {r, g, b} = colord(color).toRgb();
return (0.2126729 * r + 0.7151522 * g + 0.072175 * b) / 255;
}
-function useLightText(backgroundColor: ColorInput): boolean {
+function useLightText(backgroundColor: AnyColor): boolean {
return getRelativeLuminance(backgroundColor) < 0.453;
}
-/** Given a background color, returns a black or white foreground color that the highest
- * contrast ratio. */
+/** Given a background color, returns a black or white foreground color with the highest contrast ratio. */
// In the future, the APCA contrast function, or CSS `contrast-color` will be better.
// https://github.com/color-js/color.js/blob/eb7b53f7a13bb716ec8b28c7a56f052cd599acd9/src/contrast/APCA.js#L42
-export function contrastColor(backgroundColor: ColorInput): string {
+export function contrastColor(backgroundColor: AnyColor): string {
return useLightText(backgroundColor) ? '#fff' : '#000';
}