mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-13 21:56:10 +02:00
Merge branch 'main' into sync_status_handling
This commit is contained in:
commit
f4a03de9b5
5
.github/workflows/files-changed.yml
vendored
5
.github/workflows/files-changed.yml
vendored
@ -71,15 +71,15 @@ jobs:
|
|||||||
- "assets/emoji.json"
|
- "assets/emoji.json"
|
||||||
- "package.json"
|
- "package.json"
|
||||||
- "pnpm-lock.yaml"
|
- "pnpm-lock.yaml"
|
||||||
|
- "pnpm-workspace.yaml"
|
||||||
- "Makefile"
|
- "Makefile"
|
||||||
- ".eslintrc.cjs"
|
|
||||||
- ".npmrc"
|
|
||||||
|
|
||||||
docs:
|
docs:
|
||||||
- "**/*.md"
|
- "**/*.md"
|
||||||
- ".markdownlint.yaml"
|
- ".markdownlint.yaml"
|
||||||
- "package.json"
|
- "package.json"
|
||||||
- "pnpm-lock.yaml"
|
- "pnpm-lock.yaml"
|
||||||
|
- "pnpm-workspace.yaml"
|
||||||
|
|
||||||
actions:
|
actions:
|
||||||
- ".github/workflows/*"
|
- ".github/workflows/*"
|
||||||
@ -108,6 +108,7 @@ jobs:
|
|||||||
- "Makefile"
|
- "Makefile"
|
||||||
- "package.json"
|
- "package.json"
|
||||||
- "pnpm-lock.yaml"
|
- "pnpm-lock.yaml"
|
||||||
|
- "pnpm-workspace.yaml"
|
||||||
- ".spectral.yaml"
|
- ".spectral.yaml"
|
||||||
|
|
||||||
yaml:
|
yaml:
|
||||||
|
|||||||
4
.github/workflows/pull-compliance.yml
vendored
4
.github/workflows/pull-compliance.yml
vendored
@ -44,7 +44,7 @@ jobs:
|
|||||||
go-version-file: go.mod
|
go-version-file: go.mod
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: false
|
cache: false
|
||||||
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
@ -130,7 +130,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
|
|||||||
2
.github/workflows/pull-e2e-tests.yml
vendored
2
.github/workflows/pull-e2e-tests.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
cache-name: e2e
|
cache-name: e2e
|
||||||
build-cache: "false"
|
build-cache: "false"
|
||||||
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
|
|||||||
2
.github/workflows/release-nightly.yml
vendored
2
.github/workflows/release-nightly.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version-file: go.mod
|
go-version-file: go.mod
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
|
|||||||
2
.github/workflows/release-tag-rc.yml
vendored
2
.github/workflows/release-tag-rc.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version-file: go.mod
|
go-version-file: go.mod
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
|
|||||||
2
.github/workflows/release-tag-version.yml
vendored
2
.github/workflows/release-tag-version.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version-file: go.mod
|
go-version-file: go.mod
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
|
|||||||
7
.npmrc
7
.npmrc
@ -1,7 +0,0 @@
|
|||||||
audit=false
|
|
||||||
fund=false
|
|
||||||
update-notifier=false
|
|
||||||
save-exact=true
|
|
||||||
auto-install-peers=true
|
|
||||||
dedupe-peer-dependents=false
|
|
||||||
enable-pre-post-scripts=true
|
|
||||||
@ -195,7 +195,7 @@ PR titles must follow the [Conventional Commits](https://www.conventionalcommits
|
|||||||
type(scope)!: subject
|
type(scope)!: subject
|
||||||
```
|
```
|
||||||
|
|
||||||
The allowed types are `build`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, and `test`. The generic `chore` type is intentionally not accepted; pick a more descriptive type instead.
|
The allowed types are `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, and `test`. The generic `chore` type is intentionally not accepted; pick a more descriptive type instead.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
|
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
|
||||||
RUN apk --no-cache add build-base git nodejs pnpm
|
RUN apk --no-cache add build-base git nodejs pnpm
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY package.json pnpm-lock.yaml .npmrc ./
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
|
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
|
||||||
COPY --exclude=.git/ . .
|
COPY --exclude=.git/ . .
|
||||||
RUN make frontend
|
RUN make frontend
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
|
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
|
||||||
RUN apk --no-cache add build-base git nodejs pnpm
|
RUN apk --no-cache add build-base git nodejs pnpm
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY package.json pnpm-lock.yaml .npmrc ./
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
|
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
|
||||||
COPY --exclude=.git/ . .
|
COPY --exclude=.git/ . .
|
||||||
RUN make frontend
|
RUN make frontend
|
||||||
|
|||||||
15
Makefile
15
Makefile
@ -11,15 +11,15 @@ COMMA := ,
|
|||||||
|
|
||||||
XGO_VERSION := go-1.26.x
|
XGO_VERSION := go-1.26.x
|
||||||
|
|
||||||
AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go
|
AIR_PACKAGE ?= github.com/air-verse/air@v1.65.1 # renovate: datasource=go
|
||||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3 # renovate: datasource=go
|
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.6.1 # renovate: datasource=go
|
||||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4 # renovate: datasource=go
|
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 # renovate: datasource=go
|
||||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.15 # renovate: datasource=go
|
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.15 # renovate: datasource=go
|
||||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.8.0 # renovate: datasource=go
|
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.8.0 # renovate: datasource=go
|
||||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.33.1 # renovate: datasource=go
|
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.33.2 # renovate: datasource=go
|
||||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
XGO_PACKAGE ?= src.techknowlogick.com/xgo@v1.9.0 # renovate: datasource=go
|
||||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go
|
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1.3.0 # renovate: datasource=go
|
||||||
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.7.11 # renovate: datasource=go
|
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.7.12 # renovate: datasource=go
|
||||||
|
|
||||||
HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes)
|
HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes)
|
||||||
ifeq ($(HAS_GO), yes)
|
ifeq ($(HAS_GO), yes)
|
||||||
@ -613,6 +613,7 @@ update-js: node_modules ## update js dependencies
|
|||||||
.PHONY: nolyfill
|
.PHONY: nolyfill
|
||||||
nolyfill: node_modules ## apply nolyfill overrides to package.json and relock
|
nolyfill: node_modules ## apply nolyfill overrides to package.json and relock
|
||||||
pnpm exec nolyfill install
|
pnpm exec nolyfill install
|
||||||
|
node tools/migrate-nolyfills.ts
|
||||||
pnpm install
|
pnpm install
|
||||||
@touch node_modules
|
@touch node_modules
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
|||||||
module code.gitea.io/gitea
|
module code.gitea.io/gitea
|
||||||
|
|
||||||
go 1.26.2
|
go 1.26.3
|
||||||
|
|
||||||
// rfc5280 said: "The serial number is an integer assigned by the CA to each certificate."
|
// rfc5280 said: "The serial number is an integer assigned by the CA to each certificate."
|
||||||
// But some CAs use negative serial number, just relax the check. related:
|
// But some CAs use negative serial number, just relax the check. related:
|
||||||
|
|||||||
@ -100,7 +100,7 @@ var registeredConfigs = map[Type]func() Config{}
|
|||||||
|
|
||||||
// RegisterTypeConfig register a config for a provided type
|
// RegisterTypeConfig register a config for a provided type
|
||||||
func RegisterTypeConfig(typ Type, exemplar Config) {
|
func RegisterTypeConfig(typ Type, exemplar Config) {
|
||||||
if reflect.TypeOf(exemplar).Kind() == reflect.Ptr {
|
if reflect.TypeOf(exemplar).Kind() == reflect.Pointer {
|
||||||
// Pointer:
|
// Pointer:
|
||||||
registeredConfigs[typ] = func() Config {
|
registeredConfigs[typ] = func() Config {
|
||||||
return reflect.New(reflect.ValueOf(exemplar).Elem().Type()).Interface().(Config)
|
return reflect.New(reflect.ValueOf(exemplar).Elem().Type()).Interface().(Config)
|
||||||
|
|||||||
@ -17,12 +17,15 @@ import (
|
|||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type engineContextKeyType struct{}
|
type contextKey struct{ key string }
|
||||||
|
|
||||||
var engineContextKey = engineContextKeyType{}
|
var (
|
||||||
|
contextKeyEngine = contextKey{"engine"}
|
||||||
|
ContextKeyTestFixtures = contextKey{"test-fixtures"}
|
||||||
|
)
|
||||||
|
|
||||||
func withContextEngine(ctx context.Context, e Engine) context.Context {
|
func withContextEngine(ctx context.Context, e Engine) context.Context {
|
||||||
return context.WithValue(ctx, engineContextKey, e)
|
return context.WithValue(ctx, contextKeyEngine, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -68,7 +71,7 @@ func contextSafetyCheck(e Engine) {
|
|||||||
|
|
||||||
// GetEngine gets an existing db Engine/Statement or creates a new Session
|
// GetEngine gets an existing db Engine/Statement or creates a new Session
|
||||||
func GetEngine(ctx context.Context) Engine {
|
func GetEngine(ctx context.Context) Engine {
|
||||||
if engine, ok := ctx.Value(engineContextKey).(Engine); ok {
|
if engine, ok := ctx.Value(contextKeyEngine).(Engine); ok {
|
||||||
// if reusing the existing session, need to do "contextSafetyCheck" because the Iterate creates a "autoResetStatement=false" session
|
// if reusing the existing session, need to do "contextSafetyCheck" because the Iterate creates a "autoResetStatement=false" session
|
||||||
contextSafetyCheck(engine)
|
contextSafetyCheck(engine)
|
||||||
return engine
|
return engine
|
||||||
@ -309,7 +312,7 @@ func InTransaction(ctx context.Context) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getTransactionSession(ctx context.Context) *xorm.Session {
|
func getTransactionSession(ctx context.Context) *xorm.Session {
|
||||||
e, _ := ctx.Value(engineContextKey).(Engine)
|
e, _ := ctx.Value(contextKeyEngine).(Engine)
|
||||||
if sess, ok := e.(*xorm.Session); ok && sess.IsInTx() {
|
if sess, ok := e.(*xorm.Session); ok && sess.IsInTx() {
|
||||||
return sess
|
return sess
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,11 +22,17 @@ type EngineHook struct {
|
|||||||
var _ contexts.Hook = (*EngineHook)(nil)
|
var _ contexts.Hook = (*EngineHook)(nil)
|
||||||
|
|
||||||
func (*EngineHook) BeforeProcess(c *contexts.ContextHook) (context.Context, error) {
|
func (*EngineHook) BeforeProcess(c *contexts.ContextHook) (context.Context, error) {
|
||||||
|
if c.Ctx.Value(ContextKeyTestFixtures) != nil {
|
||||||
|
return c.Ctx, nil
|
||||||
|
}
|
||||||
ctx, _ := gtprof.GetTracer().Start(c.Ctx, gtprof.TraceSpanDatabase)
|
ctx, _ := gtprof.GetTracer().Start(c.Ctx, gtprof.TraceSpanDatabase)
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *EngineHook) AfterProcess(c *contexts.ContextHook) error {
|
func (h *EngineHook) AfterProcess(c *contexts.ContextHook) error {
|
||||||
|
if c.Ctx.Value(ContextKeyTestFixtures) != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
span := gtprof.GetContextSpan(c.Ctx)
|
span := gtprof.GetContextSpan(c.Ctx)
|
||||||
if span != nil {
|
if span != nil {
|
||||||
// Do not record SQL parameters here:
|
// Do not record SQL parameters here:
|
||||||
|
|||||||
@ -72,7 +72,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu
|
|||||||
if err := unittest.InitFixtures(
|
if err := unittest.InitFixtures(
|
||||||
unittest.FixturesOptions{
|
unittest.FixturesOptions{
|
||||||
Dir: fixturesDir,
|
Dir: fixturesDir,
|
||||||
}, x); err != nil {
|
}); err != nil {
|
||||||
t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err)
|
t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err)
|
||||||
return x, deferFn
|
return x, deferFn
|
||||||
}
|
}
|
||||||
@ -110,6 +110,7 @@ func mainTest(m *testing.M) int {
|
|||||||
if err = git.InitFull(); err != nil {
|
if err = git.InitFull(); err != nil {
|
||||||
return testlogger.MainErrorf("Unable to InitFull: %v", err)
|
return testlogger.MainErrorf("Unable to InitFull: %v", err)
|
||||||
}
|
}
|
||||||
|
setting.Database.SlowQueryThreshold = 0
|
||||||
setting.LoadDBSetting()
|
setting.LoadDBSetting()
|
||||||
setting.InitLoggersForTest()
|
setting.InitLoggersForTest()
|
||||||
return m.Run()
|
return m.Run()
|
||||||
|
|||||||
@ -4,7 +4,10 @@
|
|||||||
package unittest
|
package unittest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/modules/auth/password/hash"
|
"code.gitea.io/gitea/modules/auth/password/hash"
|
||||||
@ -12,11 +15,13 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
|
"xorm.io/xorm/contexts"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FixturesLoader interface {
|
type FixturesLoader interface {
|
||||||
Load() error
|
Load() error
|
||||||
|
MarkTableChanged(tableName string)
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixturesLoader FixturesLoader
|
var fixturesLoader FixturesLoader
|
||||||
@ -57,15 +62,101 @@ func loadFixtureResetSeqPgsql(e *xorm.Engine) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fixturesHookStruct struct{}
|
||||||
|
|
||||||
|
func cutSpaceForSQL(s string) (string, string, bool) {
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
pos := strings.IndexFunc(s, unicode.IsSpace)
|
||||||
|
if pos == -1 {
|
||||||
|
return s, "", false
|
||||||
|
}
|
||||||
|
return s[:pos], strings.TrimSpace(s[pos+1:]), true
|
||||||
|
}
|
||||||
|
|
||||||
|
func trimTableNameQuotes(s string) string {
|
||||||
|
pos := strings.IndexByte(s, '.')
|
||||||
|
if pos != -1 {
|
||||||
|
s = s[pos+1:]
|
||||||
|
}
|
||||||
|
return strings.Trim(s, "\"`[]")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fixturesHookStruct) BeforeProcess(c *contexts.ContextHook) (context.Context, error) {
|
||||||
|
if c.Ctx.Value(db.ContextKeyTestFixtures) != nil {
|
||||||
|
return c.Ctx, nil
|
||||||
|
}
|
||||||
|
ctx, sql := c.Ctx, c.SQL
|
||||||
|
cmdPart, cmdRemaining, ok := cutSpaceForSQL(sql)
|
||||||
|
if !ok {
|
||||||
|
return ctx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore the SQLs which don't change data
|
||||||
|
if util.AsciiEqualFold(cmdPart, "SELECT") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "SHOW") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "PRAGMA") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "ALTER") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "CREATE") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "DROP") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "IF") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "SET") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "sp_rename") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "BEGIN") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "ROLLBACK") ||
|
||||||
|
util.AsciiEqualFold(cmdPart, "COMMIT") {
|
||||||
|
return ctx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case util.AsciiEqualFold(cmdPart, "INSERT"):
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
if util.AsciiEqualFold(cmdPart, "INTO") {
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
}
|
||||||
|
fixturesLoader.MarkTableChanged(trimTableNameQuotes(cmdPart))
|
||||||
|
case util.AsciiEqualFold(cmdPart, "MERGE"):
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
if util.AsciiEqualFold(cmdPart, "INTO") {
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
}
|
||||||
|
fixturesLoader.MarkTableChanged(trimTableNameQuotes(cmdPart))
|
||||||
|
case util.AsciiEqualFold(cmdPart, "UPDATE"):
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
fixturesLoader.MarkTableChanged(trimTableNameQuotes(cmdPart))
|
||||||
|
case util.AsciiEqualFold(cmdPart, "DELETE"):
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
if util.AsciiEqualFold(cmdPart, "FROM") {
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
}
|
||||||
|
fixturesLoader.MarkTableChanged(trimTableNameQuotes(cmdPart))
|
||||||
|
case util.AsciiEqualFold(cmdPart, "TRUNCATE"):
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
if util.AsciiEqualFold(cmdPart, "TABLE") {
|
||||||
|
cmdPart, cmdRemaining, _ = cutSpaceForSQL(cmdRemaining)
|
||||||
|
}
|
||||||
|
fixturesLoader.MarkTableChanged(trimTableNameQuotes(cmdPart))
|
||||||
|
default:
|
||||||
|
// should either parse the table name if it changes data, or ignore it
|
||||||
|
panic("unrecognized sql: " + sql)
|
||||||
|
}
|
||||||
|
_ = cmdRemaining
|
||||||
|
return ctx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fixturesHookStruct) AfterProcess(c *contexts.ContextHook) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// InitFixtures initialize test fixtures for a test database
|
// InitFixtures initialize test fixtures for a test database
|
||||||
func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
|
func InitFixtures(opts FixturesOptions) (err error) {
|
||||||
xormEngine := util.IfZero(util.OptionalArg(engine), GetXORMEngine())
|
xormEngine := GetXORMEngine()
|
||||||
fixturesLoader, err = NewFixturesLoader(xormEngine, opts)
|
fixturesLoader, err = NewFixturesLoader(xormEngine, opts)
|
||||||
// fixturesLoader = NewFixturesLoaderVendor(xormEngine, opts)
|
// fixturesLoader = NewFixturesLoaderVendor(xormEngine, opts)
|
||||||
|
|
||||||
// register the dummy hash algorithm function used in the test fixtures
|
// register the dummy hash algorithm function used in the test fixtures
|
||||||
_ = hash.Register("dummy", hash.NewDummyHasher)
|
_ = hash.Register("dummy", hash.NewDummyHasher)
|
||||||
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
||||||
|
xormEngine.AddHook(&fixturesHookStruct{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
package unittest
|
package unittest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -11,6 +12,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ type FixtureItem struct {
|
|||||||
|
|
||||||
type fixturesLoaderInternal struct {
|
type fixturesLoaderInternal struct {
|
||||||
xormEngine *xorm.Engine
|
xormEngine *xorm.Engine
|
||||||
xormTableNames map[string]bool
|
tableSyncMap sync.Map
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
dbType schemas.DBType
|
dbType schemas.DBType
|
||||||
fixtures map[string]*FixtureItem
|
fixtures map[string]*FixtureItem
|
||||||
@ -148,25 +150,36 @@ func (f *fixturesLoaderInternal) Load() error {
|
|||||||
}
|
}
|
||||||
defer func() { _ = tx.Rollback() }()
|
defer func() { _ = tx.Rollback() }()
|
||||||
|
|
||||||
|
ctx := context.WithValue(context.Background(), db.ContextKeyTestFixtures, true)
|
||||||
|
|
||||||
for _, fixture := range f.fixtures {
|
for _, fixture := range f.fixtures {
|
||||||
if !f.xormTableNames[fixture.tableName] {
|
synced, existing := f.tableSyncMap.Load(fixture.tableName)
|
||||||
|
if synced == true || !existing {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := f.loadFixtures(tx, fixture); err != nil {
|
if err := f.loadFixtures(tx, fixture); err != nil {
|
||||||
return fmt.Errorf("failed to load fixtures from %s: %w", fixture.fileFullPath, err)
|
return fmt.Errorf("failed to load fixtures from %s: %w", fixture.fileFullPath, err)
|
||||||
}
|
}
|
||||||
|
f.tableSyncMap.Store(fixture.tableName, true)
|
||||||
}
|
}
|
||||||
if err = tx.Commit(); err != nil {
|
if err = tx.Commit(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for xormTableName := range f.xormTableNames {
|
f.tableSyncMap.Range(func(k, v any) bool {
|
||||||
if f.fixtures[xormTableName] == nil {
|
tableName, synced := k.(string), v.(bool)
|
||||||
_, _ = f.xormEngine.Exec("DELETE FROM `" + xormTableName + "`")
|
if !synced && f.fixtures[tableName] == nil {
|
||||||
|
_, _ = f.xormEngine.Context(ctx).Exec("DELETE FROM `" + tableName + "`")
|
||||||
}
|
}
|
||||||
}
|
f.tableSyncMap.Store(tableName, true)
|
||||||
|
return true
|
||||||
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *fixturesLoaderInternal) MarkTableChanged(tableName string) {
|
||||||
|
f.tableSyncMap.Store(tableName, false)
|
||||||
|
}
|
||||||
|
|
||||||
func FixturesFileFullPaths(dir string, files []string) (map[string]*FixtureItem, error) {
|
func FixturesFileFullPaths(dir string, files []string) (map[string]*FixtureItem, error) {
|
||||||
if files != nil && len(files) == 0 {
|
if files != nil && len(files) == 0 {
|
||||||
return nil, nil //nolint:nilnil // load nothing
|
return nil, nil //nolint:nilnil // load nothing
|
||||||
@ -215,11 +228,12 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er
|
|||||||
f.paramPlaceholder = func(idx int) string { return "?" }
|
f.paramPlaceholder = func(idx int) string { return "?" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a model is not imported in a package (no bean is registered), the table won't exist in database.
|
||||||
|
// So only use tables of registered models (beans).
|
||||||
xormBeans, _ := db.NamesToBean()
|
xormBeans, _ := db.NamesToBean()
|
||||||
f.xormTableNames = map[string]bool{}
|
|
||||||
for _, bean := range xormBeans {
|
for _, bean := range xormBeans {
|
||||||
f.xormTableNames[x.TableName(bean)] = true
|
beanTableName := x.TableName(bean)
|
||||||
|
f.tableSyncMap.Store(trimTableNameQuotes(beanTableName), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func fieldByName(v reflect.Value, field string) reflect.Value {
|
func fieldByName(v reflect.Value, field string) reflect.Value {
|
||||||
if v.Kind() == reflect.Ptr {
|
if v.Kind() == reflect.Pointer {
|
||||||
v = v.Elem()
|
v = v.Elem()
|
||||||
}
|
}
|
||||||
f := v.FieldByName(field)
|
f := v.FieldByName(field)
|
||||||
|
|||||||
@ -91,7 +91,7 @@ func (e *MarshalEncoder) marshal(v any) error {
|
|||||||
val := reflect.ValueOf(v)
|
val := reflect.ValueOf(v)
|
||||||
typ := reflect.TypeOf(v)
|
typ := reflect.TypeOf(v)
|
||||||
|
|
||||||
if typ.Kind() == reflect.Ptr {
|
if typ.Kind() == reflect.Pointer {
|
||||||
val = val.Elem()
|
val = val.Elem()
|
||||||
typ = typ.Elem()
|
typ = typ.Elem()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,8 @@ var (
|
|||||||
AutoMigration bool
|
AutoMigration bool
|
||||||
SlowQueryThreshold time.Duration
|
SlowQueryThreshold time.Duration
|
||||||
}{
|
}{
|
||||||
IterateBufferSize: 50,
|
IterateBufferSize: 50,
|
||||||
|
SlowQueryThreshold: 5 * time.Second,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ func loadDBSetting(rootCfg ConfigProvider) {
|
|||||||
Database.DBConnectRetries = sec.Key("DB_RETRIES").MustInt(10)
|
Database.DBConnectRetries = sec.Key("DB_RETRIES").MustInt(10)
|
||||||
Database.DBConnectBackoff = sec.Key("DB_RETRY_BACKOFF").MustDuration(3 * time.Second)
|
Database.DBConnectBackoff = sec.Key("DB_RETRY_BACKOFF").MustDuration(3 * time.Second)
|
||||||
Database.AutoMigration = sec.Key("AUTO_MIGRATION").MustBool(true)
|
Database.AutoMigration = sec.Key("AUTO_MIGRATION").MustBool(true)
|
||||||
Database.SlowQueryThreshold = sec.Key("SLOW_QUERY_THRESHOLD").MustDuration(5 * time.Second)
|
Database.SlowQueryThreshold = sec.Key("SLOW_QUERY_THRESHOLD").MustDuration(Database.SlowQueryThreshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DatabaseType FIXME: it is also used directly with "schemas.DBType", so the names must be consistent
|
// DatabaseType FIXME: it is also used directly with "schemas.DBType", so the names must be consistent
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/web/routing"
|
"code.gitea.io/gitea/modules/web/routing"
|
||||||
@ -131,8 +132,8 @@ type middlewareProvider = func(next http.Handler) http.Handler
|
|||||||
|
|
||||||
func executeMiddlewaresHandler(w http.ResponseWriter, r *http.Request, middlewares []middlewareProvider, endpoint http.HandlerFunc) {
|
func executeMiddlewaresHandler(w http.ResponseWriter, r *http.Request, middlewares []middlewareProvider, endpoint http.HandlerFunc) {
|
||||||
handler := endpoint
|
handler := endpoint
|
||||||
for i := len(middlewares) - 1; i >= 0; i-- {
|
for _, middleware := range slices.Backward(middlewares) {
|
||||||
handler = middlewares[i](handler).ServeHTTP
|
handler = middleware(handler).ServeHTTP
|
||||||
}
|
}
|
||||||
handler(w, r)
|
handler(w, r)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ func AssignForm(form any, data map[string]any) {
|
|||||||
typ := reflect.TypeOf(form)
|
typ := reflect.TypeOf(form)
|
||||||
val := reflect.ValueOf(form)
|
val := reflect.ValueOf(form)
|
||||||
|
|
||||||
for typ.Kind() == reflect.Ptr {
|
for typ.Kind() == reflect.Pointer {
|
||||||
typ = typ.Elem()
|
typ = typ.Elem()
|
||||||
val = val.Elem()
|
val = val.Elem()
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ func Validate(errs binding.Errors, data map[string]any, f Form, l translation.Lo
|
|||||||
data["ErrorMsg"] = l.TrString("form.unknown_error")
|
data["ErrorMsg"] = l.TrString("form.unknown_error")
|
||||||
|
|
||||||
typ := reflect.TypeOf(f)
|
typ := reflect.TypeOf(f)
|
||||||
if typ.Kind() == reflect.Ptr {
|
if typ.Kind() == reflect.Pointer {
|
||||||
typ = typ.Elem()
|
typ = typ.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
33
package.json
33
package.json
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "pnpm@10.33.2",
|
"packageManager": "pnpm@11.0.8",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 22.18.0",
|
"node": ">= 22.18.0",
|
||||||
"pnpm": ">= 10.0.0"
|
"pnpm": ">= 11.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@citation-js/core": "0.7.21",
|
"@citation-js/core": "0.7.21",
|
||||||
@ -124,34 +124,5 @@
|
|||||||
"updates": "17.16.8",
|
"updates": "17.16.8",
|
||||||
"vitest": "4.1.5",
|
"vitest": "4.1.5",
|
||||||
"vue-tsc": "3.2.8"
|
"vue-tsc": "3.2.8"
|
||||||
},
|
|
||||||
"pnpm": {
|
|
||||||
"peerDependencyRules": {
|
|
||||||
"allowedVersions": {
|
|
||||||
"eslint-plugin-github>eslint": ">=9"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": {
|
|
||||||
"array-includes": "npm:@nolyfill/array-includes@^1",
|
|
||||||
"array.prototype.findlastindex": "npm:@nolyfill/array.prototype.findlastindex@^1",
|
|
||||||
"array.prototype.flat": "npm:@nolyfill/array.prototype.flat@^1",
|
|
||||||
"array.prototype.flatmap": "npm:@nolyfill/array.prototype.flatmap@^1",
|
|
||||||
"es-aggregate-error": "npm:@nolyfill/es-aggregate-error@^1",
|
|
||||||
"hasown": "npm:@nolyfill/hasown@^1",
|
|
||||||
"is-core-module": "npm:@nolyfill/is-core-module@^1",
|
|
||||||
"object.assign": "npm:@nolyfill/object.assign@^1",
|
|
||||||
"object.fromentries": "npm:@nolyfill/object.fromentries@^1",
|
|
||||||
"object.groupby": "npm:@nolyfill/object.groupby@^1",
|
|
||||||
"object.values": "npm:@nolyfill/object.values@^1",
|
|
||||||
"safe-buffer": "npm:@nolyfill/safe-buffer@^1",
|
|
||||||
"safe-regex-test": "npm:@nolyfill/safe-regex-test@^1",
|
|
||||||
"safer-buffer": "npm:@nolyfill/safer-buffer@^1",
|
|
||||||
"string.prototype.includes": "npm:@nolyfill/string.prototype.includes@^1",
|
|
||||||
"string.prototype.trimend": "npm:@nolyfill/string.prototype.trimend@^1",
|
|
||||||
"object-keys": "npm:@nolyfill/object-keys@^1",
|
|
||||||
"object.entries": "npm:@nolyfill/object.entries@^1",
|
|
||||||
"abab": "npm:@nolyfill/abab@^1",
|
|
||||||
"es-set-tostringtag": "npm:@nolyfill/es-set-tostringtag@^1"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
pnpm-workspace.yaml
Normal file
32
pnpm-workspace.yaml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
packages: [.] # workaround for https://github.com/SukkaW/nolyfill/issues/119
|
||||||
|
savePrefix: ''
|
||||||
|
dedupePeerDependents: false
|
||||||
|
updateNotifier: false
|
||||||
|
strictDepBuilds: false
|
||||||
|
minimumReleaseAge: 0
|
||||||
|
|
||||||
|
peerDependencyRules:
|
||||||
|
allowedVersions:
|
||||||
|
eslint-plugin-github>eslint: '>=9'
|
||||||
|
|
||||||
|
overrides:
|
||||||
|
array-includes: npm:@nolyfill/array-includes@^1
|
||||||
|
array.prototype.findlastindex: npm:@nolyfill/array.prototype.findlastindex@^1
|
||||||
|
array.prototype.flat: npm:@nolyfill/array.prototype.flat@^1
|
||||||
|
array.prototype.flatmap: npm:@nolyfill/array.prototype.flatmap@^1
|
||||||
|
es-aggregate-error: npm:@nolyfill/es-aggregate-error@^1
|
||||||
|
hasown: npm:@nolyfill/hasown@^1
|
||||||
|
is-core-module: npm:@nolyfill/is-core-module@^1
|
||||||
|
object.assign: npm:@nolyfill/object.assign@^1
|
||||||
|
object.fromentries: npm:@nolyfill/object.fromentries@^1
|
||||||
|
object.groupby: npm:@nolyfill/object.groupby@^1
|
||||||
|
object.values: npm:@nolyfill/object.values@^1
|
||||||
|
safe-buffer: npm:@nolyfill/safe-buffer@^1
|
||||||
|
safe-regex-test: npm:@nolyfill/safe-regex-test@^1
|
||||||
|
safer-buffer: npm:@nolyfill/safer-buffer@^1
|
||||||
|
string.prototype.includes: npm:@nolyfill/string.prototype.includes@^1
|
||||||
|
string.prototype.trimend: npm:@nolyfill/string.prototype.trimend@^1
|
||||||
|
object-keys: npm:@nolyfill/object-keys@^1
|
||||||
|
object.entries: npm:@nolyfill/object.entries@^1
|
||||||
|
abab: npm:@nolyfill/abab@^1
|
||||||
|
es-set-tostringtag: npm:@nolyfill/es-set-tostringtag@^1
|
||||||
@ -2,7 +2,7 @@
|
|||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
"extends": ["config:recommended", "helpers:pinGitHubActionDigests", "customManagers:githubActionsVersions"],
|
"extends": ["config:recommended", "helpers:pinGitHubActionDigests", "customManagers:githubActionsVersions"],
|
||||||
"configMigration": true,
|
"configMigration": true,
|
||||||
"enabledManagers": ["github-actions", "gomod", "npm", "pep621", "nix"],
|
"enabledManagers": ["github-actions", "gomod", "npm", "pep621", "nix", "custom.regex"],
|
||||||
"labels": ["dependencies"],
|
"labels": ["dependencies"],
|
||||||
"branchPrefix": "renovate/",
|
"branchPrefix": "renovate/",
|
||||||
"schedule": ["* * * * 1"], // dependency update PRs weekly, vulnerabilityAlerts bypasses this
|
"schedule": ["* * * * 1"], // dependency update PRs weekly, vulnerabilityAlerts bypasses this
|
||||||
@ -60,19 +60,32 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"groupName": "go dependencies",
|
"groupName": "go dependencies",
|
||||||
"matchDatasources": ["go"], // covers gomod manager + Makefile go-tool customManager
|
"matchManagers": ["gomod"],
|
||||||
"postUpgradeTasks": {
|
"postUpgradeTasks": {
|
||||||
"commands": ["make tidy"],
|
"commands": ["make tidy"],
|
||||||
"fileFilters": ["go.mod", "go.sum", "assets/go-licenses.json"],
|
"fileFilters": ["go.mod", "go.sum", "assets/go-licenses.json"],
|
||||||
"executionMode": "branch",
|
"executionMode": "branch",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"groupName": "tool dependencies",
|
||||||
|
"matchManagers": ["custom.regex"],
|
||||||
|
"matchFileNames": ["**/Makefile"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchManagers": ["gomod"],
|
||||||
|
"matchDepNames": ["go"],
|
||||||
|
"matchDepTypes": ["golang"],
|
||||||
|
"rangeStrategy": "bump",
|
||||||
|
"schedule": ["at any time"],
|
||||||
|
"minimumReleaseAge": "0",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"groupName": "npm dependencies",
|
"groupName": "npm dependencies",
|
||||||
"matchManagers": ["npm"],
|
"matchManagers": ["npm"],
|
||||||
"postUpgradeTasks": {
|
"postUpgradeTasks": {
|
||||||
"commands": ["make svg nolyfill"],
|
"commands": ["make svg nolyfill"],
|
||||||
"fileFilters": ["package.json", "pnpm-lock.yaml", "public/assets/img/svg/**"],
|
"fileFilters": ["package.json", "pnpm-lock.yaml", "pnpm-workspace.yaml", "public/assets/img/svg/**"],
|
||||||
"executionMode": "branch",
|
"executionMode": "branch",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -57,14 +57,14 @@ func RequireUnitReader(unitTypes ...unit.Type) func(ctx *Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckRepoScopedToken check whether personal access token has repo scope
|
// CheckRepoScopedToken checks whether the authenticated API token has repo scope.
|
||||||
func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_model.AccessTokenScopeLevel) {
|
func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_model.AccessTokenScopeLevel) {
|
||||||
if !ctx.IsBasicAuth || ctx.Data["IsApiToken"] != true {
|
if ctx.Data["IsApiToken"] != true {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
scope, ok := ctx.Data["ApiTokenScope"].(auth_model.AccessTokenScope)
|
scope, ok := ctx.Data["ApiTokenScope"].(auth_model.AccessTokenScope)
|
||||||
if ok { // it's a personal access token but not oauth2 token
|
if ok {
|
||||||
var scopeMatched bool
|
var scopeMatched bool
|
||||||
|
|
||||||
requiredScopes := auth_model.GetRequiredScopes(level, auth_model.AccessTokenScopeCategoryRepository)
|
requiredScopes := auth_model.GetRequiredScopes(level, auth_model.AccessTokenScopeCategoryRepository)
|
||||||
@ -76,7 +76,7 @@ func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if publicOnly && repo.IsPrivate {
|
if publicOnly && repo != nil && repo.IsPrivate {
|
||||||
ctx.HTTPError(http.StatusForbidden)
|
ctx.HTTPError(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
actions_model "code.gitea.io/gitea/models/actions"
|
actions_model "code.gitea.io/gitea/models/actions"
|
||||||
|
db "code.gitea.io/gitea/models/db"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unit"
|
"code.gitea.io/gitea/models/unit"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -124,3 +125,55 @@ func TestToActionWorkflowRun_UsesTriggerEvent(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "schedule", apiRun.Event)
|
assert.Equal(t, "schedule", apiRun.Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestToActionWorkflowJob_StepStatusIsIndependentOfJobStatus(t *testing.T) {
|
||||||
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
|
ctx := t.Context()
|
||||||
|
|
||||||
|
run := &actions_model.ActionRun{
|
||||||
|
ID: 9001,
|
||||||
|
RepoID: 2,
|
||||||
|
TriggerUserID: 1,
|
||||||
|
WorkflowID: "test.yaml",
|
||||||
|
Index: 12345,
|
||||||
|
Ref: "refs/heads/main",
|
||||||
|
Status: actions_model.StatusFailure,
|
||||||
|
}
|
||||||
|
require.NoError(t, db.Insert(ctx, run))
|
||||||
|
|
||||||
|
task := &actions_model.ActionTask{
|
||||||
|
ID: 900102,
|
||||||
|
JobID: 9001,
|
||||||
|
RepoID: 2,
|
||||||
|
Status: actions_model.StatusFailure,
|
||||||
|
}
|
||||||
|
require.NoError(t, db.Insert(ctx, task))
|
||||||
|
|
||||||
|
job := &actions_model.ActionRunJob{
|
||||||
|
ID: 90010203,
|
||||||
|
RunID: 9001,
|
||||||
|
TaskID: 900102,
|
||||||
|
RepoID: 2,
|
||||||
|
Name: "test-job-name",
|
||||||
|
Attempt: 1,
|
||||||
|
JobID: "test-job-id",
|
||||||
|
Status: actions_model.StatusFailure,
|
||||||
|
}
|
||||||
|
require.NoError(t, db.Insert(ctx, job))
|
||||||
|
|
||||||
|
require.NoError(t, db.Insert(ctx,
|
||||||
|
&actions_model.ActionTaskStep{TaskID: task.ID, RepoID: 2, Index: 0, Name: "step-success", Status: actions_model.StatusSuccess},
|
||||||
|
&actions_model.ActionTaskStep{TaskID: task.ID, RepoID: 2, Index: 1, Name: "step-failure", Status: actions_model.StatusFailure},
|
||||||
|
))
|
||||||
|
|
||||||
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||||
|
|
||||||
|
apiJob, err := ToActionWorkflowJob(ctx, repo, task, job)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, apiJob.Steps, 2)
|
||||||
|
|
||||||
|
assert.Equal(t, "completed", apiJob.Steps[0].Status, "step 0 status")
|
||||||
|
assert.Equal(t, "success", apiJob.Steps[0].Conclusion, "step 0 conclusion (succeeded before the failure)")
|
||||||
|
assert.Equal(t, "completed", apiJob.Steps[1].Status, "step 1 status")
|
||||||
|
assert.Equal(t, "failure", apiJob.Steps[1].Conclusion, "step 1 conclusion")
|
||||||
|
}
|
||||||
|
|||||||
@ -314,33 +314,31 @@ func ToActionWorkflowRun(ctx context.Context, run *actions_model.ActionRun, atte
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToWorkflowRunAction(status actions_model.Status) string {
|
func ToWorkflowRunAction(status actions_model.Status) (action string) {
|
||||||
var action string
|
|
||||||
switch status {
|
switch status {
|
||||||
case actions_model.StatusWaiting, actions_model.StatusBlocked:
|
case actions_model.StatusWaiting, actions_model.StatusBlocked:
|
||||||
action = "requested"
|
action = "requested"
|
||||||
case actions_model.StatusRunning:
|
case actions_model.StatusRunning:
|
||||||
action = "in_progress"
|
action = "in_progress"
|
||||||
}
|
default:
|
||||||
if status.IsDone() {
|
if status.IsDone() {
|
||||||
action = "completed"
|
action = "completed"
|
||||||
|
} else {
|
||||||
|
setting.PanicInDevOrTesting("unknown action status: %v", status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return action
|
return action
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToActionsStatus(status actions_model.Status) (string, string) {
|
func ToActionsStatus(status actions_model.Status) (action, conclusion string) {
|
||||||
var action string
|
|
||||||
var conclusion string
|
|
||||||
switch status {
|
switch status {
|
||||||
// This is a naming conflict of the webhook between Gitea and GitHub Actions
|
|
||||||
case actions_model.StatusWaiting:
|
case actions_model.StatusWaiting:
|
||||||
action = "queued"
|
action = "queued" // "waiting" is a naming conflict of the webhook between Gitea and GitHub Actions
|
||||||
case actions_model.StatusBlocked:
|
case actions_model.StatusBlocked:
|
||||||
action = "waiting"
|
action = "waiting" // naming conflict (as above)
|
||||||
case actions_model.StatusRunning:
|
case actions_model.StatusRunning:
|
||||||
action = "in_progress"
|
action = "in_progress"
|
||||||
}
|
default:
|
||||||
if status.IsDone() {
|
|
||||||
action = "completed"
|
action = "completed"
|
||||||
switch status {
|
switch status {
|
||||||
case actions_model.StatusSuccess:
|
case actions_model.StatusSuccess:
|
||||||
@ -351,6 +349,8 @@ func ToActionsStatus(status actions_model.Status) (string, string) {
|
|||||||
conclusion = "failure"
|
conclusion = "failure"
|
||||||
case actions_model.StatusSkipped:
|
case actions_model.StatusSkipped:
|
||||||
conclusion = "skipped"
|
conclusion = "skipped"
|
||||||
|
default:
|
||||||
|
setting.PanicInDevOrTesting("unknown action status: %v", status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return action, conclusion
|
return action, conclusion
|
||||||
@ -390,7 +390,7 @@ func ToActionWorkflowJob(ctx context.Context, repo *repo_model.Repository, task
|
|||||||
runnerName = runner.Name
|
runnerName = runner.Name
|
||||||
}
|
}
|
||||||
for i, step := range task.Steps {
|
for i, step := range task.Steps {
|
||||||
stepStatus, stepConclusion := ToActionsStatus(job.Status)
|
stepStatus, stepConclusion := ToActionsStatus(step.Status)
|
||||||
steps = append(steps, &api.ActionWorkflowStep{
|
steps = append(steps, &api.ActionWorkflowStep{
|
||||||
Name: step.Name,
|
Name: step.Name,
|
||||||
Number: int64(i),
|
Number: int64(i),
|
||||||
|
|||||||
@ -57,7 +57,7 @@ func (t *Task) IsEnabled() bool {
|
|||||||
|
|
||||||
// GetConfig will return a copy of the task's config
|
// GetConfig will return a copy of the task's config
|
||||||
func (t *Task) GetConfig() Config {
|
func (t *Task) GetConfig() Config {
|
||||||
if reflect.TypeOf(t.config).Kind() == reflect.Ptr {
|
if reflect.TypeOf(t.config).Kind() == reflect.Pointer {
|
||||||
// Pointer:
|
// Pointer:
|
||||||
return reflect.New(reflect.ValueOf(t.config).Elem().Type()).Interface().(Config)
|
return reflect.New(reflect.ValueOf(t.config).Elem().Type()).Interface().(Config)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ package gitdiff
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@ -385,8 +386,7 @@ func (hcd *highlightCodeDiff) recoverOneDiff(str string) template.HTML {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// close all opening tags
|
// close all opening tags
|
||||||
for i := len(tagStack) - 1; i >= 0; i-- {
|
for _, tagToClose := range slices.Backward(tagStack) {
|
||||||
tagToClose := tagStack[i]
|
|
||||||
// get the closing tag "</span>" from "<span class=...>" or "<span>"
|
// get the closing tag "</span>" from "<span class=...>" or "<span>"
|
||||||
pos := strings.IndexAny(tagToClose, " >")
|
pos := strings.IndexAny(tagToClose, " >")
|
||||||
// pos must be positive, because the tags were pushed by us
|
// pos must be positive, because the tags were pushed by us
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
"html"
|
"html"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -123,9 +124,7 @@ func getIssueFromRef(ctx context.Context, repo *repo_model.Repository, index int
|
|||||||
// UpdateIssuesCommit checks if issues are manipulated by commit message.
|
// UpdateIssuesCommit checks if issues are manipulated by commit message.
|
||||||
func UpdateIssuesCommit(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, commits []*repository.PushCommit, branchName string) error {
|
func UpdateIssuesCommit(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, commits []*repository.PushCommit, branchName string) error {
|
||||||
// Commits are appended in the reverse order.
|
// Commits are appended in the reverse order.
|
||||||
for i := len(commits) - 1; i >= 0; i-- {
|
for _, c := range slices.Backward(commits) {
|
||||||
c := commits[i]
|
|
||||||
|
|
||||||
type markKey struct {
|
type markKey struct {
|
||||||
ID int64
|
ID int64
|
||||||
Action references.XRefAction
|
Action references.XRefAction
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
@ -845,8 +846,7 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ
|
|||||||
// use PR's commit messages as squash commit message
|
// use PR's commit messages as squash commit message
|
||||||
// commits list is in reverse chronological order
|
// commits list is in reverse chronological order
|
||||||
maxMsgSize := setting.Repository.PullRequest.DefaultMergeMessageSize
|
maxMsgSize := setting.Repository.PullRequest.DefaultMergeMessageSize
|
||||||
for i := len(commits) - 1; i >= 0; i-- {
|
for _, commit := range slices.Backward(commits) {
|
||||||
commit := commits[i]
|
|
||||||
msg := strings.TrimSpace(commit.MessageUTF8())
|
msg := strings.TrimSpace(commit.MessageUTF8())
|
||||||
if msg == "" {
|
if msg == "" {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@ -6,6 +6,7 @@ package gitgraph
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parser represents a git graph parser. It is stateful containing the previous
|
// Parser represents a git graph parser. It is stateful containing the previous
|
||||||
@ -163,8 +164,7 @@ func (parser *Parser) ParseGlyphs(glyphs []byte) {
|
|||||||
// release unused colors
|
// release unused colors
|
||||||
parser.releaseUnusedColors()
|
parser.releaseUnusedColors()
|
||||||
|
|
||||||
for i := len(glyphs) - 1; i >= 0; i-- {
|
for i, glyph := range slices.Backward(glyphs) {
|
||||||
glyph := glyphs[i]
|
|
||||||
switch glyph {
|
switch glyph {
|
||||||
case '|':
|
case '|':
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
// @ts-check
|
|
||||||
// TODO: Move to .ts after https://github.com/stylelint/stylelint/issues/8893 is fixed
|
|
||||||
import {fileURLToPath} from 'node:url';
|
import {fileURLToPath} from 'node:url';
|
||||||
|
import type {Config} from 'stylelint';
|
||||||
|
|
||||||
const cssVarFiles = [
|
const cssVarFiles = [
|
||||||
fileURLToPath(new URL('web_src/css/base.css', import.meta.url)),
|
fileURLToPath(new URL('web_src/css/base.css', import.meta.url)),
|
||||||
@ -8,7 +7,6 @@ const cssVarFiles = [
|
|||||||
fileURLToPath(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url)),
|
fileURLToPath(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url)),
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @type {import('stylelint').Config} */
|
|
||||||
export default {
|
export default {
|
||||||
extends: 'stylelint-config-recommended',
|
extends: 'stylelint-config-recommended',
|
||||||
reportUnscopedDisables: true,
|
reportUnscopedDisables: true,
|
||||||
@ -25,18 +23,6 @@ export default {
|
|||||||
'/web_src/fomantic',
|
'/web_src/fomantic',
|
||||||
],
|
],
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
|
||||||
files: ['**/chroma/*', '**/codemirror/*', '**/console.css', 'font_i18n.css'],
|
|
||||||
rules: {
|
|
||||||
'scale-unlimited/declaration-strict-value': null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['**/chroma/*', '**/codemirror/*'],
|
|
||||||
rules: {
|
|
||||||
'block-no-empty': null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
files: ['**/*.vue'],
|
files: ['**/*.vue'],
|
||||||
customSyntax: 'postcss-html',
|
customSyntax: 'postcss-html',
|
||||||
@ -139,7 +125,7 @@ export default {
|
|||||||
'no-unknown-custom-media': null, // disabled until stylelint supports multi-file linting
|
'no-unknown-custom-media': null, // disabled until stylelint supports multi-file linting
|
||||||
'no-unknown-custom-properties': null, // disabled until stylelint supports multi-file linting
|
'no-unknown-custom-properties': null, // disabled until stylelint supports multi-file linting
|
||||||
'plugin/declaration-block-no-ignored-properties': true,
|
'plugin/declaration-block-no-ignored-properties': true,
|
||||||
'scale-unlimited/declaration-strict-value': [['/color$/', 'font-weight'], {ignoreValues: '/^(inherit|transparent|unset|initial|currentcolor|none)$/', ignoreFunctions: true, disableFix: true, expandShorthand: true}],
|
'scale-unlimited/declaration-strict-value': [['/color$/', 'fill', 'stroke', 'font-weight'], {ignoreValues: '/^(inherit|transparent|unset|initial|currentcolor|none)$/', ignoreFunctions: true, disableFix: true, expandShorthand: true}],
|
||||||
'selector-attribute-quotes': 'always',
|
'selector-attribute-quotes': 'always',
|
||||||
'selector-no-vendor-prefix': true,
|
'selector-no-vendor-prefix': true,
|
||||||
'selector-pseudo-element-colon-notation': 'double',
|
'selector-pseudo-element-colon-notation': 'double',
|
||||||
@ -148,4 +134,4 @@ export default {
|
|||||||
'shorthand-property-no-redundant-values': true,
|
'shorthand-property-no-redundant-values': true,
|
||||||
'value-no-vendor-prefix': [true, {ignoreValues: ['box', 'inline-box']}],
|
'value-no-vendor-prefix': [true, {ignoreValues: ['box', 'inline-box']}],
|
||||||
},
|
},
|
||||||
};
|
} satisfies Config;
|
||||||
@ -9,6 +9,9 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
auth_model "code.gitea.io/gitea/models/auth"
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
"code.gitea.io/gitea/models/unittest"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/test"
|
"code.gitea.io/gitea/modules/test"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
@ -20,6 +23,7 @@ import (
|
|||||||
func TestGitSmartHTTP(t *testing.T) {
|
func TestGitSmartHTTP(t *testing.T) {
|
||||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
testGitSmartHTTP(t, u)
|
testGitSmartHTTP(t, u)
|
||||||
|
testGitSmartHTTPTokenScopes(t)
|
||||||
testRenamedRepoRedirect(t)
|
testRenamedRepoRedirect(t)
|
||||||
testGitArchiveRemote(t, u)
|
testGitArchiveRemote(t, u)
|
||||||
})
|
})
|
||||||
@ -80,6 +84,42 @@ func testGitSmartHTTP(t *testing.T, u *url.URL) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testGitSmartHTTPTokenScopes(t *testing.T) {
|
||||||
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2, OwnerName: "user2", Name: "repo2"})
|
||||||
|
require.True(t, repo.IsPrivate)
|
||||||
|
|
||||||
|
session := loginUser(t, "user2")
|
||||||
|
badToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadNotification)
|
||||||
|
readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository)
|
||||||
|
writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||||
|
publicOnlyToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopePublicOnly, auth_model.AccessTokenScopeReadRepository)
|
||||||
|
|
||||||
|
t.Run("upload-pack requires read repository scope", func(t *testing.T) {
|
||||||
|
path := "/user2/repo2/info/refs?service=git-upload-pack"
|
||||||
|
|
||||||
|
MakeRequest(t, NewRequest(t, "GET", path).AddBasicAuth(badToken, "x-oauth-basic"), http.StatusForbidden)
|
||||||
|
MakeRequest(t, NewRequest(t, "GET", path).AddTokenAuth(badToken), http.StatusForbidden)
|
||||||
|
|
||||||
|
resp := MakeRequest(t, NewRequest(t, "GET", path).AddTokenAuth(readToken), http.StatusOK)
|
||||||
|
assert.Contains(t, resp.Body.String(), "refs/heads/master")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("receive-pack requires write repository scope", func(t *testing.T) {
|
||||||
|
path := "/user2/repo2/info/refs?service=git-receive-pack"
|
||||||
|
|
||||||
|
MakeRequest(t, NewRequest(t, "GET", path).AddBasicAuth(readToken, "x-oauth-basic"), http.StatusForbidden)
|
||||||
|
MakeRequest(t, NewRequest(t, "GET", path).AddTokenAuth(readToken), http.StatusForbidden)
|
||||||
|
|
||||||
|
resp := MakeRequest(t, NewRequest(t, "GET", path).AddTokenAuth(writeToken), http.StatusOK)
|
||||||
|
assert.Contains(t, resp.Body.String(), "refs/heads/master")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("public-only scope rejects private repo", func(t *testing.T) {
|
||||||
|
path := "/user2/repo2/info/refs?service=git-upload-pack"
|
||||||
|
MakeRequest(t, NewRequest(t, "GET", path).AddTokenAuth(publicOnlyToken), http.StatusForbidden)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testRenamedRepoRedirect(t *testing.T) {
|
func testRenamedRepoRedirect(t *testing.T) {
|
||||||
defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)()
|
defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)()
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,7 @@ func InitIntegrationTest() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setting.Database.SlowQueryThreshold = 0
|
||||||
setting.LoadDBSetting()
|
setting.LoadDBSetting()
|
||||||
cleanupDb, err := unittest.ResetTestDatabase()
|
cleanupDb, err := unittest.ResetTestDatabase()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import {env, exit} from 'node:process';
|
import {env, exit} from 'node:process';
|
||||||
|
|
||||||
const allowedTypes = 'build, ci, docs, feat, fix, perf, refactor, revert, style, test';
|
const allowedTypes = 'build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test';
|
||||||
const title = env.PR_TITLE;
|
const title = env.PR_TITLE;
|
||||||
|
|
||||||
if (!title) {
|
if (!title) {
|
||||||
|
|||||||
33
tools/migrate-nolyfills.ts
Normal file
33
tools/migrate-nolyfills.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// nolyfill writes overrides to package.json#pnpm.overrides which pnpm v11 ignores.
|
||||||
|
// This moves them to pnpm-workspace.yaml until SukkaW/nolyfill#119 is fixed.
|
||||||
|
import {readFileSync, writeFileSync} from 'node:fs';
|
||||||
|
import {exit} from 'node:process';
|
||||||
|
import {fileURLToPath} from 'node:url';
|
||||||
|
import {dump} from 'js-yaml';
|
||||||
|
|
||||||
|
const packagePath = fileURLToPath(new URL('../package.json', import.meta.url));
|
||||||
|
const workspacePath = fileURLToPath(new URL('../pnpm-workspace.yaml', import.meta.url));
|
||||||
|
|
||||||
|
const packageJson: {pnpm?: {overrides?: Record<string, string>}} = JSON.parse(readFileSync(packagePath, 'utf8'));
|
||||||
|
const overrides = packageJson.pnpm?.overrides;
|
||||||
|
|
||||||
|
if (!overrides || !Object.keys(overrides).length) {
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const block = dump({overrides}, {lineWidth: -1, quotingType: "'"});
|
||||||
|
const workspace = readFileSync(workspacePath, 'utf8');
|
||||||
|
const overridesRegex = /^overrides:[^\n]*(?:\n(?:[ \t][^\n]*|[ \t]*(?=\n[ \t])))*\n?/m;
|
||||||
|
|
||||||
|
if (!overridesRegex.test(workspace)) {
|
||||||
|
console.error(`No 'overrides:' block found in pnpm-workspace.yaml`);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFileSync(workspacePath, workspace.replace(overridesRegex, block));
|
||||||
|
|
||||||
|
const pnpm = packageJson.pnpm!;
|
||||||
|
delete pnpm.overrides;
|
||||||
|
if (!Object.keys(pnpm).length) delete packageJson.pnpm;
|
||||||
|
writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
||||||
@ -1,4 +1,5 @@
|
|||||||
/* Based on https://github.com/buildkite/terminal-to-html/blob/697ff23bd8dc48b9d23f11f259f5256dae2455f0/assets/terminal.css */
|
/* Based on https://github.com/buildkite/terminal-to-html/blob/697ff23bd8dc48b9d23f11f259f5256dae2455f0/assets/terminal.css */
|
||||||
|
/* stylelint-disable scale-unlimited/declaration-strict-value -- terminal ANSI palette uses literal hex values */
|
||||||
|
|
||||||
.console {
|
.console {
|
||||||
background: var(--color-console-bg);
|
background: var(--color-console-bg);
|
||||||
|
|||||||
@ -84,162 +84,82 @@
|
|||||||
fill: var(--color-secondary-dark-5);
|
fill: var(--color-secondary-dark-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-0 {
|
||||||
|
stroke: var(--color-series-16-0);
|
||||||
|
fill: var(--color-series-16-0);
|
||||||
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-1 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-1 {
|
||||||
stroke: #499a37;
|
stroke: var(--color-series-16-1);
|
||||||
fill: #499a37;
|
fill: var(--color-series-16-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-2 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-2 {
|
||||||
stroke: #ce4751;
|
stroke: var(--color-series-16-2);
|
||||||
fill: #ce4751;
|
fill: var(--color-series-16-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-3 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-3 {
|
||||||
stroke: #8f9121;
|
stroke: var(--color-series-16-3);
|
||||||
fill: #8f9121;
|
fill: var(--color-series-16-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-4 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-4 {
|
||||||
stroke: #ac32a6;
|
stroke: var(--color-series-16-4);
|
||||||
fill: #ac32a6;
|
fill: var(--color-series-16-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-5 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-5 {
|
||||||
stroke: #7445e9;
|
stroke: var(--color-series-16-5);
|
||||||
fill: #7445e9;
|
fill: var(--color-series-16-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-6 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-6 {
|
||||||
stroke: #c67d28;
|
stroke: var(--color-series-16-6);
|
||||||
fill: #c67d28;
|
fill: var(--color-series-16-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-7 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-7 {
|
||||||
stroke: #4db392;
|
stroke: var(--color-series-16-7);
|
||||||
fill: #4db392;
|
fill: var(--color-series-16-7);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-8 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-8 {
|
||||||
stroke: #aa4d30;
|
stroke: var(--color-series-16-8);
|
||||||
fill: #aa4d30;
|
fill: var(--color-series-16-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-9 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-9 {
|
||||||
stroke: #2a6f84;
|
stroke: var(--color-series-16-9);
|
||||||
fill: #2a6f84;
|
fill: var(--color-series-16-9);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-10 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-10 {
|
||||||
stroke: #c45327;
|
stroke: var(--color-series-16-10);
|
||||||
fill: #c45327;
|
fill: var(--color-series-16-10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-11 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-11 {
|
||||||
stroke: #3d965c;
|
stroke: var(--color-series-16-11);
|
||||||
fill: #3d965c;
|
fill: var(--color-series-16-11);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-12 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-12 {
|
||||||
stroke: #792a93;
|
stroke: var(--color-series-16-12);
|
||||||
fill: #792a93;
|
fill: var(--color-series-16-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-13 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-13 {
|
||||||
stroke: #439d73;
|
stroke: var(--color-series-16-13);
|
||||||
fill: #439d73;
|
fill: var(--color-series-16-13);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-14 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-14 {
|
||||||
stroke: #103aad;
|
stroke: var(--color-series-16-14);
|
||||||
fill: #103aad;
|
fill: var(--color-series-16-14);
|
||||||
}
|
}
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-15 {
|
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-15 {
|
||||||
stroke: #982e85;
|
stroke: var(--color-series-16-15);
|
||||||
fill: #982e85;
|
fill: var(--color-series-16-15);
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-0 {
|
|
||||||
stroke: #7db233;
|
|
||||||
fill: #7db233;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-1 {
|
|
||||||
stroke: #5ac144;
|
|
||||||
fill: #5ac144;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-2 {
|
|
||||||
stroke: #ed5a8b;
|
|
||||||
fill: #ed5a8b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-3 {
|
|
||||||
stroke: #ced049;
|
|
||||||
fill: #ced048;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-4 {
|
|
||||||
stroke: #db61d7;
|
|
||||||
fill: #db62d6;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-5 {
|
|
||||||
stroke: #8455f9;
|
|
||||||
fill: #8455f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-6 {
|
|
||||||
stroke: #e6a151;
|
|
||||||
fill: #e6a151;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-7 {
|
|
||||||
stroke: #44daaa;
|
|
||||||
fill: #44daaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-8 {
|
|
||||||
stroke: #dd7a5c;
|
|
||||||
fill: #dd7a5c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-9 {
|
|
||||||
stroke: #38859c;
|
|
||||||
fill: #38859c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-10 {
|
|
||||||
stroke: #d95520;
|
|
||||||
fill: #d95520;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-11 {
|
|
||||||
stroke: #42ae68;
|
|
||||||
fill: #42ae68;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-12 {
|
|
||||||
stroke: #9126b5;
|
|
||||||
fill: #9126b5;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-13 {
|
|
||||||
stroke: #4ab080;
|
|
||||||
fill: #4ab080;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-14 {
|
|
||||||
stroke: #284fb8;
|
|
||||||
fill: #284fb8;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-15 {
|
|
||||||
stroke: #971c80;
|
|
||||||
fill: #971c80;
|
|
||||||
}
|
|
||||||
|
|
||||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-0 {
|
|
||||||
stroke: #87ca28;
|
|
||||||
fill: #87ca28;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@
|
|||||||
local("SourceHanSans-Light"), local("Yu Gothic Regular"),
|
local("SourceHanSans-Light"), local("Yu Gothic Regular"),
|
||||||
local("YuGothic Regular"), local("Droid Sans Japanese"), local("Meiryo"),
|
local("YuGothic Regular"), local("Droid Sans Japanese"), local("Meiryo"),
|
||||||
local("MS PGothic");
|
local("MS PGothic");
|
||||||
font-weight: 300;
|
font-weight: 300; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@
|
|||||||
local("SourceHanSans-Regular"), local("Yu Gothic Medium"),
|
local("SourceHanSans-Regular"), local("Yu Gothic Medium"),
|
||||||
local("YuGothic Medium"), local("Droid Sans Japanese"), local("Meiryo"),
|
local("YuGothic Medium"), local("Droid Sans Japanese"), local("Meiryo"),
|
||||||
local("MS PGothic");
|
local("MS PGothic");
|
||||||
font-weight: 400;
|
font-weight: 400; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@
|
|||||||
local("SourceHanSans-Medium"), local("Yu Gothic Medium"),
|
local("SourceHanSans-Medium"), local("Yu Gothic Medium"),
|
||||||
local("YuGothic Medium"), local("Droid Sans Japanese"), local("Meiryo"),
|
local("YuGothic Medium"), local("Droid Sans Japanese"), local("Meiryo"),
|
||||||
local("MS PGothic");
|
local("MS PGothic");
|
||||||
font-weight: 500;
|
font-weight: 500; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@
|
|||||||
local("NotoSansCJKJP-Bold"), local("Source Han Sans Bold"),
|
local("NotoSansCJKJP-Bold"), local("Source Han Sans Bold"),
|
||||||
local("SourceHanSans-Bold"), local("Yu Gothic Bold"), local("YuGothic Bold"),
|
local("SourceHanSans-Bold"), local("Yu Gothic Bold"), local("YuGothic Bold"),
|
||||||
local("Droid Sans Japanese"), local("Meiryo Bold"), local("MS PGothic");
|
local("Droid Sans Japanese"), local("Meiryo Bold"), local("MS PGothic");
|
||||||
font-weight: 600;
|
font-weight: 600; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@
|
|||||||
local("NotoSansCJKSC-Light"), local("HiraginoSansGB-W3"),
|
local("NotoSansCJKSC-Light"), local("HiraginoSansGB-W3"),
|
||||||
local("Hiragino Sans GB W3"), local("Microsoft YaHei Light"),
|
local("Hiragino Sans GB W3"), local("Microsoft YaHei Light"),
|
||||||
local("Heiti SC Light"), local("SimHei");
|
local("Heiti SC Light"), local("SimHei");
|
||||||
font-weight: 300;
|
font-weight: 300; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@
|
|||||||
local("NotoSansCJKSC-Regular"), local("HiraginoSansGB-W3"),
|
local("NotoSansCJKSC-Regular"), local("HiraginoSansGB-W3"),
|
||||||
local("Hiragino Sans GB W3"), local("Microsoft YaHei"),
|
local("Hiragino Sans GB W3"), local("Microsoft YaHei"),
|
||||||
local("Heiti SC Light"), local("SimHei");
|
local("Heiti SC Light"), local("SimHei");
|
||||||
font-weight: 400;
|
font-weight: 400; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@
|
|||||||
local("NotoSansCJKSC-Medium"), local("HiraginoSansGB-W3"),
|
local("NotoSansCJKSC-Medium"), local("HiraginoSansGB-W3"),
|
||||||
local("Hiragino Sans GB W3"), local("Microsoft YaHei"),
|
local("Hiragino Sans GB W3"), local("Microsoft YaHei"),
|
||||||
local("Heiti SC Light"), local("SimHei");
|
local("Heiti SC Light"), local("SimHei");
|
||||||
font-weight: 500;
|
font-weight: 500; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -163,7 +163,7 @@
|
|||||||
local("NotoSansCJKSC-Bold"), local("HiraginoSansGB-W6"),
|
local("NotoSansCJKSC-Bold"), local("HiraginoSansGB-W6"),
|
||||||
local("Hiragino Sans GB W6"), local("Microsoft YaHei Bold"),
|
local("Hiragino Sans GB W6"), local("Microsoft YaHei Bold"),
|
||||||
local("Heiti SC Medium"), local("SimHei");
|
local("Heiti SC Medium"), local("SimHei");
|
||||||
font-weight: 600;
|
font-weight: 600; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -192,7 +192,7 @@
|
|||||||
local("NotoSansCJKTC-Light"), local("HiraginoSansTC-W3"),
|
local("NotoSansCJKTC-Light"), local("HiraginoSansTC-W3"),
|
||||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei Light"),
|
local("Hiragino Sans TC W3"), local("Microsoft JhengHei Light"),
|
||||||
local("Heiti TC Light"), local("PMingLiU");
|
local("Heiti TC Light"), local("PMingLiU");
|
||||||
font-weight: 300;
|
font-weight: 300; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -205,7 +205,7 @@
|
|||||||
local("NotoSansCJKTC-Regular"), local("HiraginoSansTC-W3"),
|
local("NotoSansCJKTC-Regular"), local("HiraginoSansTC-W3"),
|
||||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
||||||
local("Heiti TC Light"), local("PMingLiU");
|
local("Heiti TC Light"), local("PMingLiU");
|
||||||
font-weight: 400;
|
font-weight: 400; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@
|
|||||||
local("NotoSansCJKTC-Medium"), local("HiraginoSansTC-W3"),
|
local("NotoSansCJKTC-Medium"), local("HiraginoSansTC-W3"),
|
||||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
||||||
local("Heiti TC Light"), local("PMingLiU");
|
local("Heiti TC Light"), local("PMingLiU");
|
||||||
font-weight: 500;
|
font-weight: 500; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -231,7 +231,7 @@
|
|||||||
local("NotoSansCJKTC-Bold"), local("HiraginoSansTC-W6"),
|
local("NotoSansCJKTC-Bold"), local("HiraginoSansTC-W6"),
|
||||||
local("Hiragino Sans TC W6"), local("Microsoft JhengHei Bold"),
|
local("Hiragino Sans TC W6"), local("Microsoft JhengHei Bold"),
|
||||||
local("Heiti TC Medium"), local("PMingLiU");
|
local("Heiti TC Medium"), local("PMingLiU");
|
||||||
font-weight: 600;
|
font-weight: 600; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -262,7 +262,7 @@
|
|||||||
local("NotoSansCJKTC-Light"), local("HiraginoSansTC-W3"),
|
local("NotoSansCJKTC-Light"), local("HiraginoSansTC-W3"),
|
||||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei Light"),
|
local("Hiragino Sans TC W3"), local("Microsoft JhengHei Light"),
|
||||||
local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
|
local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
|
||||||
font-weight: 300;
|
font-weight: 300; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -277,7 +277,7 @@
|
|||||||
local("NotoSansCJKTC-Regular"), local("HiraginoSansTC-W3"),
|
local("NotoSansCJKTC-Regular"), local("HiraginoSansTC-W3"),
|
||||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
||||||
local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
|
local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
|
||||||
font-weight: 400;
|
font-weight: 400; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -292,7 +292,7 @@
|
|||||||
local("NotoSansCJKTC-Medium"), local("HiraginoSansTC-W3"),
|
local("NotoSansCJKTC-Medium"), local("HiraginoSansTC-W3"),
|
||||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
||||||
local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
|
local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
|
||||||
font-weight: 500;
|
font-weight: 500; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@
|
|||||||
local("NotoSansCJKTC-Bold"), local("HiraginoSansTC-W6"),
|
local("NotoSansCJKTC-Bold"), local("HiraginoSansTC-W6"),
|
||||||
local("Hiragino Sans TC W6"), local("Microsoft JhengHei Bold"),
|
local("Hiragino Sans TC W6"), local("Microsoft JhengHei Bold"),
|
||||||
local("Heiti TC Medium"), local("PMingLiU_HKSCS"), local("PMingLiU");
|
local("Heiti TC Medium"), local("PMingLiU_HKSCS"), local("PMingLiU");
|
||||||
font-weight: 600;
|
font-weight: 600; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -335,7 +335,7 @@
|
|||||||
local("SourceHanSansK-Light"), local("Noto Sans CJK KR Light"),
|
local("SourceHanSansK-Light"), local("Noto Sans CJK KR Light"),
|
||||||
local("NotoSansCJKKR-Light"), local("NanumBarunGothic Light"),
|
local("NotoSansCJKKR-Light"), local("NanumBarunGothic Light"),
|
||||||
local("Malgun Gothic Semilight"), local("Nanum Gothic"), local("Dotum");
|
local("Malgun Gothic Semilight"), local("Nanum Gothic"), local("Dotum");
|
||||||
font-weight: 300;
|
font-weight: 300; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -347,7 +347,7 @@
|
|||||||
local("SourceHanSansK-Regular"), local("Noto Sans CJK KR Regular"),
|
local("SourceHanSansK-Regular"), local("Noto Sans CJK KR Regular"),
|
||||||
local("NotoSansCJKKR-Regular"), local("NanumBarunGothic"),
|
local("NotoSansCJKKR-Regular"), local("NanumBarunGothic"),
|
||||||
local("Malgun Gothic"), local("Nanum Gothic"), local("Dotum");
|
local("Malgun Gothic"), local("Nanum Gothic"), local("Dotum");
|
||||||
font-weight: 400;
|
font-weight: 400; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -359,7 +359,7 @@
|
|||||||
local("SourceHanSansK-Medium"), local("Noto Sans CJK KR Medium"),
|
local("SourceHanSansK-Medium"), local("Noto Sans CJK KR Medium"),
|
||||||
local("NotoSansCJKKR-Medium"), local("NanumBarunGothic"),
|
local("NotoSansCJKKR-Medium"), local("NanumBarunGothic"),
|
||||||
local("Malgun Gothic"), local("Nanum Gothic"), local("Dotum");
|
local("Malgun Gothic"), local("Nanum Gothic"), local("Dotum");
|
||||||
font-weight: 500;
|
font-weight: 500; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
@ -371,7 +371,7 @@
|
|||||||
local("SourceHanSansK-Bold"), local("Noto Sans CJK KR Bold"),
|
local("SourceHanSansK-Bold"), local("Noto Sans CJK KR Bold"),
|
||||||
local("NotoSansCJKKR-Bold"), local("NanumBarunGothic Bold"),
|
local("NotoSansCJKKR-Bold"), local("NanumBarunGothic Bold"),
|
||||||
local("Malgun Gothic Bold"), local("Nanum Gothic Bold"), local("Dotum");
|
local("Malgun Gothic Bold"), local("Nanum Gothic Bold"), local("Dotum");
|
||||||
font-weight: 600;
|
font-weight: 600; /* stylelint-disable-line scale-unlimited/declaration-strict-value */
|
||||||
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
|
||||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,6 +141,23 @@ gitea-theme-meta-info {
|
|||||||
--color-ansi-bright-magenta: #d74397;
|
--color-ansi-bright-magenta: #d74397;
|
||||||
--color-ansi-bright-cyan: #00b6ad;
|
--color-ansi-bright-cyan: #00b6ad;
|
||||||
--color-ansi-bright-white: var(--color-console-fg);
|
--color-ansi-bright-white: var(--color-console-fg);
|
||||||
|
/* 16-color series */
|
||||||
|
--color-series-16-0: #7db233;
|
||||||
|
--color-series-16-1: #499a37;
|
||||||
|
--color-series-16-2: #ce4751;
|
||||||
|
--color-series-16-3: #8f9121;
|
||||||
|
--color-series-16-4: #ac32a6;
|
||||||
|
--color-series-16-5: #7445e9;
|
||||||
|
--color-series-16-6: #c67d28;
|
||||||
|
--color-series-16-7: #4db392;
|
||||||
|
--color-series-16-8: #aa4d30;
|
||||||
|
--color-series-16-9: #2a6f84;
|
||||||
|
--color-series-16-10: #c45327;
|
||||||
|
--color-series-16-11: #3d965c;
|
||||||
|
--color-series-16-12: #792a93;
|
||||||
|
--color-series-16-13: #439d73;
|
||||||
|
--color-series-16-14: #103aad;
|
||||||
|
--color-series-16-15: #982e85;
|
||||||
/* other colors */
|
/* other colors */
|
||||||
--color-grey: #3d3f44;
|
--color-grey: #3d3f44;
|
||||||
--color-grey-light: #898d96;
|
--color-grey-light: #898d96;
|
||||||
|
|||||||
@ -141,6 +141,23 @@ gitea-theme-meta-info {
|
|||||||
--color-ansi-bright-magenta: #d74397;
|
--color-ansi-bright-magenta: #d74397;
|
||||||
--color-ansi-bright-cyan: #00b6ad;
|
--color-ansi-bright-cyan: #00b6ad;
|
||||||
--color-ansi-bright-white: var(--color-console-fg);
|
--color-ansi-bright-white: var(--color-console-fg);
|
||||||
|
/* 16-color series */
|
||||||
|
--color-series-16-0: #7db233;
|
||||||
|
--color-series-16-1: #499a37;
|
||||||
|
--color-series-16-2: #ce4751;
|
||||||
|
--color-series-16-3: #8f9121;
|
||||||
|
--color-series-16-4: #ac32a6;
|
||||||
|
--color-series-16-5: #7445e9;
|
||||||
|
--color-series-16-6: #c67d28;
|
||||||
|
--color-series-16-7: #4db392;
|
||||||
|
--color-series-16-8: #aa4d30;
|
||||||
|
--color-series-16-9: #2a6f84;
|
||||||
|
--color-series-16-10: #c45327;
|
||||||
|
--color-series-16-11: #3d965c;
|
||||||
|
--color-series-16-12: #792a93;
|
||||||
|
--color-series-16-13: #439d73;
|
||||||
|
--color-series-16-14: #103aad;
|
||||||
|
--color-series-16-15: #982e85;
|
||||||
/* other colors */
|
/* other colors */
|
||||||
--color-grey: #697077;
|
--color-grey: #697077;
|
||||||
--color-grey-light: #7c838a;
|
--color-grey-light: #7c838a;
|
||||||
|
|||||||
@ -16,5 +16,3 @@ window.config = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
window.testModules = {};
|
window.testModules = {};
|
||||||
|
|
||||||
export {}; // mark as module for top-level await
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user