mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-13 19:45:47 +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"
|
||||
- "package.json"
|
||||
- "pnpm-lock.yaml"
|
||||
- "pnpm-workspace.yaml"
|
||||
- "Makefile"
|
||||
- ".eslintrc.cjs"
|
||||
- ".npmrc"
|
||||
|
||||
docs:
|
||||
- "**/*.md"
|
||||
- ".markdownlint.yaml"
|
||||
- "package.json"
|
||||
- "pnpm-lock.yaml"
|
||||
- "pnpm-workspace.yaml"
|
||||
|
||||
actions:
|
||||
- ".github/workflows/*"
|
||||
@ -108,6 +108,7 @@ jobs:
|
||||
- "Makefile"
|
||||
- "package.json"
|
||||
- "pnpm-lock.yaml"
|
||||
- "pnpm-workspace.yaml"
|
||||
- ".spectral.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
|
||||
check-latest: true
|
||||
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
|
||||
with:
|
||||
node-version: 24
|
||||
@ -130,7 +130,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- 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
|
||||
with:
|
||||
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:
|
||||
cache-name: e2e
|
||||
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
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
2
.github/workflows/release-nightly.yml
vendored
2
.github/workflows/release-nightly.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
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
|
||||
with:
|
||||
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:
|
||||
go-version-file: go.mod
|
||||
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
|
||||
with:
|
||||
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:
|
||||
go-version-file: go.mod
|
||||
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
|
||||
with:
|
||||
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
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
|
||||
RUN apk --no-cache add build-base git nodejs pnpm
|
||||
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
|
||||
COPY --exclude=.git/ . .
|
||||
RUN make frontend
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
|
||||
RUN apk --no-cache add build-base git nodejs pnpm
|
||||
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
|
||||
COPY --exclude=.git/ . .
|
||||
RUN make frontend
|
||||
|
||||
15
Makefile
15
Makefile
@ -11,15 +11,15 @@ COMMA := ,
|
||||
|
||||
XGO_VERSION := go-1.26.x
|
||||
|
||||
AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3 # renovate: datasource=go
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4 # 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.6.1 # 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
|
||||
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
|
||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go
|
||||
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.7.11 # 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@v1.9.0 # 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.12 # renovate: datasource=go
|
||||
|
||||
HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes)
|
||||
ifeq ($(HAS_GO), yes)
|
||||
@ -613,6 +613,7 @@ update-js: node_modules ## update js dependencies
|
||||
.PHONY: nolyfill
|
||||
nolyfill: node_modules ## apply nolyfill overrides to package.json and relock
|
||||
pnpm exec nolyfill install
|
||||
node tools/migrate-nolyfills.ts
|
||||
pnpm install
|
||||
@touch node_modules
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
||||
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."
|
||||
// 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
|
||||
func RegisterTypeConfig(typ Type, exemplar Config) {
|
||||
if reflect.TypeOf(exemplar).Kind() == reflect.Ptr {
|
||||
if reflect.TypeOf(exemplar).Kind() == reflect.Pointer {
|
||||
// Pointer:
|
||||
registeredConfigs[typ] = func() Config {
|
||||
return reflect.New(reflect.ValueOf(exemplar).Elem().Type()).Interface().(Config)
|
||||
|
||||
@ -17,12 +17,15 @@ import (
|
||||
"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 {
|
||||
return context.WithValue(ctx, engineContextKey, e)
|
||||
return context.WithValue(ctx, contextKeyEngine, e)
|
||||
}
|
||||
|
||||
var (
|
||||
@ -68,7 +71,7 @@ func contextSafetyCheck(e Engine) {
|
||||
|
||||
// GetEngine gets an existing db Engine/Statement or creates a new Session
|
||||
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
|
||||
contextSafetyCheck(engine)
|
||||
return engine
|
||||
@ -309,7 +312,7 @@ func InTransaction(ctx context.Context) bool {
|
||||
}
|
||||
|
||||
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() {
|
||||
return sess
|
||||
}
|
||||
|
||||
@ -22,11 +22,17 @@ type EngineHook struct {
|
||||
var _ contexts.Hook = (*EngineHook)(nil)
|
||||
|
||||
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)
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func (h *EngineHook) AfterProcess(c *contexts.ContextHook) error {
|
||||
if c.Ctx.Value(ContextKeyTestFixtures) != nil {
|
||||
return nil
|
||||
}
|
||||
span := gtprof.GetContextSpan(c.Ctx)
|
||||
if span != nil {
|
||||
// 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(
|
||||
unittest.FixturesOptions{
|
||||
Dir: fixturesDir,
|
||||
}, x); err != nil {
|
||||
}); err != nil {
|
||||
t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err)
|
||||
return x, deferFn
|
||||
}
|
||||
@ -110,6 +110,7 @@ func mainTest(m *testing.M) int {
|
||||
if err = git.InitFull(); err != nil {
|
||||
return testlogger.MainErrorf("Unable to InitFull: %v", err)
|
||||
}
|
||||
setting.Database.SlowQueryThreshold = 0
|
||||
setting.LoadDBSetting()
|
||||
setting.InitLoggersForTest()
|
||||
return m.Run()
|
||||
|
||||
@ -4,7 +4,10 @@
|
||||
package unittest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/auth/password/hash"
|
||||
@ -12,11 +15,13 @@ import (
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/contexts"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
type FixturesLoader interface {
|
||||
Load() error
|
||||
MarkTableChanged(tableName string)
|
||||
}
|
||||
|
||||
var fixturesLoader FixturesLoader
|
||||
@ -57,15 +62,101 @@ func loadFixtureResetSeqPgsql(e *xorm.Engine) error {
|
||||
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
|
||||
func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
|
||||
xormEngine := util.IfZero(util.OptionalArg(engine), GetXORMEngine())
|
||||
func InitFixtures(opts FixturesOptions) (err error) {
|
||||
xormEngine := GetXORMEngine()
|
||||
fixturesLoader, err = NewFixturesLoader(xormEngine, opts)
|
||||
// fixturesLoader = NewFixturesLoaderVendor(xormEngine, opts)
|
||||
|
||||
// register the dummy hash algorithm function used in the test fixtures
|
||||
_ = hash.Register("dummy", hash.NewDummyHasher)
|
||||
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
||||
xormEngine.AddHook(&fixturesHookStruct{})
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
package unittest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
@ -11,6 +12,7 @@ import (
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
||||
@ -32,7 +34,7 @@ type FixtureItem struct {
|
||||
|
||||
type fixturesLoaderInternal struct {
|
||||
xormEngine *xorm.Engine
|
||||
xormTableNames map[string]bool
|
||||
tableSyncMap sync.Map
|
||||
db *sql.DB
|
||||
dbType schemas.DBType
|
||||
fixtures map[string]*FixtureItem
|
||||
@ -148,25 +150,36 @@ func (f *fixturesLoaderInternal) Load() error {
|
||||
}
|
||||
defer func() { _ = tx.Rollback() }()
|
||||
|
||||
ctx := context.WithValue(context.Background(), db.ContextKeyTestFixtures, true)
|
||||
|
||||
for _, fixture := range f.fixtures {
|
||||
if !f.xormTableNames[fixture.tableName] {
|
||||
synced, existing := f.tableSyncMap.Load(fixture.tableName)
|
||||
if synced == true || !existing {
|
||||
continue
|
||||
}
|
||||
if err := f.loadFixtures(tx, fixture); err != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
for xormTableName := range f.xormTableNames {
|
||||
if f.fixtures[xormTableName] == nil {
|
||||
_, _ = f.xormEngine.Exec("DELETE FROM `" + xormTableName + "`")
|
||||
f.tableSyncMap.Range(func(k, v any) bool {
|
||||
tableName, synced := k.(string), v.(bool)
|
||||
if !synced && f.fixtures[tableName] == nil {
|
||||
_, _ = f.xormEngine.Context(ctx).Exec("DELETE FROM `" + tableName + "`")
|
||||
}
|
||||
}
|
||||
f.tableSyncMap.Store(tableName, true)
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fixturesLoaderInternal) MarkTableChanged(tableName string) {
|
||||
f.tableSyncMap.Store(tableName, false)
|
||||
}
|
||||
|
||||
func FixturesFileFullPaths(dir string, files []string) (map[string]*FixtureItem, error) {
|
||||
if files != nil && len(files) == 0 {
|
||||
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 "?" }
|
||||
}
|
||||
|
||||
// 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()
|
||||
f.xormTableNames = map[string]bool{}
|
||||
for _, bean := range xormBeans {
|
||||
f.xormTableNames[x.TableName(bean)] = true
|
||||
beanTableName := x.TableName(bean)
|
||||
f.tableSyncMap.Store(trimTableNameQuotes(beanTableName), false)
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func fieldByName(v reflect.Value, field string) reflect.Value {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if v.Kind() == reflect.Pointer {
|
||||
v = v.Elem()
|
||||
}
|
||||
f := v.FieldByName(field)
|
||||
|
||||
@ -91,7 +91,7 @@ func (e *MarshalEncoder) marshal(v any) error {
|
||||
val := reflect.ValueOf(v)
|
||||
typ := reflect.TypeOf(v)
|
||||
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
if typ.Kind() == reflect.Pointer {
|
||||
val = val.Elem()
|
||||
typ = typ.Elem()
|
||||
}
|
||||
|
||||
@ -41,7 +41,8 @@ var (
|
||||
AutoMigration bool
|
||||
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.DBConnectBackoff = sec.Key("DB_RETRY_BACKOFF").MustDuration(3 * time.Second)
|
||||
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
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"slices"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"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) {
|
||||
handler := endpoint
|
||||
for i := len(middlewares) - 1; i >= 0; i-- {
|
||||
handler = middlewares[i](handler).ServeHTTP
|
||||
for _, middleware := range slices.Backward(middlewares) {
|
||||
handler = middleware(handler).ServeHTTP
|
||||
}
|
||||
handler(w, r)
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ func AssignForm(form any, data map[string]any) {
|
||||
typ := reflect.TypeOf(form)
|
||||
val := reflect.ValueOf(form)
|
||||
|
||||
for typ.Kind() == reflect.Ptr {
|
||||
for typ.Kind() == reflect.Pointer {
|
||||
typ = typ.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")
|
||||
|
||||
typ := reflect.TypeOf(f)
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
if typ.Kind() == reflect.Pointer {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
|
||||
|
||||
33
package.json
33
package.json
@ -1,9 +1,9 @@
|
||||
{
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.33.2",
|
||||
"packageManager": "pnpm@11.0.8",
|
||||
"engines": {
|
||||
"node": ">= 22.18.0",
|
||||
"pnpm": ">= 10.0.0"
|
||||
"pnpm": ">= 11.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@citation-js/core": "0.7.21",
|
||||
@ -124,34 +124,5 @@
|
||||
"updates": "17.16.8",
|
||||
"vitest": "4.1.5",
|
||||
"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",
|
||||
"extends": ["config:recommended", "helpers:pinGitHubActionDigests", "customManagers:githubActionsVersions"],
|
||||
"configMigration": true,
|
||||
"enabledManagers": ["github-actions", "gomod", "npm", "pep621", "nix"],
|
||||
"enabledManagers": ["github-actions", "gomod", "npm", "pep621", "nix", "custom.regex"],
|
||||
"labels": ["dependencies"],
|
||||
"branchPrefix": "renovate/",
|
||||
"schedule": ["* * * * 1"], // dependency update PRs weekly, vulnerabilityAlerts bypasses this
|
||||
@ -60,19 +60,32 @@
|
||||
},
|
||||
{
|
||||
"groupName": "go dependencies",
|
||||
"matchDatasources": ["go"], // covers gomod manager + Makefile go-tool customManager
|
||||
"matchManagers": ["gomod"],
|
||||
"postUpgradeTasks": {
|
||||
"commands": ["make tidy"],
|
||||
"fileFilters": ["go.mod", "go.sum", "assets/go-licenses.json"],
|
||||
"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",
|
||||
"matchManagers": ["npm"],
|
||||
"postUpgradeTasks": {
|
||||
"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",
|
||||
},
|
||||
},
|
||||
|
||||
@ -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) {
|
||||
if !ctx.IsBasicAuth || ctx.Data["IsApiToken"] != true {
|
||||
if ctx.Data["IsApiToken"] != true {
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
requiredScopes := auth_model.GetRequiredScopes(level, auth_model.AccessTokenScopeCategoryRepository)
|
||||
@ -76,7 +76,7 @@ func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_
|
||||
return
|
||||
}
|
||||
|
||||
if publicOnly && repo.IsPrivate {
|
||||
if publicOnly && repo != nil && repo.IsPrivate {
|
||||
ctx.HTTPError(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"testing"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
db "code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
@ -124,3 +125,55 @@ func TestToActionWorkflowRun_UsesTriggerEvent(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
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
|
||||
}
|
||||
|
||||
func ToWorkflowRunAction(status actions_model.Status) string {
|
||||
var action string
|
||||
func ToWorkflowRunAction(status actions_model.Status) (action string) {
|
||||
switch status {
|
||||
case actions_model.StatusWaiting, actions_model.StatusBlocked:
|
||||
action = "requested"
|
||||
case actions_model.StatusRunning:
|
||||
action = "in_progress"
|
||||
}
|
||||
if status.IsDone() {
|
||||
action = "completed"
|
||||
default:
|
||||
if status.IsDone() {
|
||||
action = "completed"
|
||||
} else {
|
||||
setting.PanicInDevOrTesting("unknown action status: %v", status)
|
||||
}
|
||||
}
|
||||
return action
|
||||
}
|
||||
|
||||
func ToActionsStatus(status actions_model.Status) (string, string) {
|
||||
var action string
|
||||
var conclusion string
|
||||
func ToActionsStatus(status actions_model.Status) (action, conclusion string) {
|
||||
switch status {
|
||||
// This is a naming conflict of the webhook between Gitea and GitHub Actions
|
||||
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:
|
||||
action = "waiting"
|
||||
action = "waiting" // naming conflict (as above)
|
||||
case actions_model.StatusRunning:
|
||||
action = "in_progress"
|
||||
}
|
||||
if status.IsDone() {
|
||||
default:
|
||||
action = "completed"
|
||||
switch status {
|
||||
case actions_model.StatusSuccess:
|
||||
@ -351,6 +349,8 @@ func ToActionsStatus(status actions_model.Status) (string, string) {
|
||||
conclusion = "failure"
|
||||
case actions_model.StatusSkipped:
|
||||
conclusion = "skipped"
|
||||
default:
|
||||
setting.PanicInDevOrTesting("unknown action status: %v", status)
|
||||
}
|
||||
}
|
||||
return action, conclusion
|
||||
@ -390,7 +390,7 @@ func ToActionWorkflowJob(ctx context.Context, repo *repo_model.Repository, task
|
||||
runnerName = runner.Name
|
||||
}
|
||||
for i, step := range task.Steps {
|
||||
stepStatus, stepConclusion := ToActionsStatus(job.Status)
|
||||
stepStatus, stepConclusion := ToActionsStatus(step.Status)
|
||||
steps = append(steps, &api.ActionWorkflowStep{
|
||||
Name: step.Name,
|
||||
Number: int64(i),
|
||||
|
||||
@ -57,7 +57,7 @@ func (t *Task) IsEnabled() bool {
|
||||
|
||||
// GetConfig will return a copy of the task's config
|
||||
func (t *Task) GetConfig() Config {
|
||||
if reflect.TypeOf(t.config).Kind() == reflect.Ptr {
|
||||
if reflect.TypeOf(t.config).Kind() == reflect.Pointer {
|
||||
// Pointer:
|
||||
return reflect.New(reflect.ValueOf(t.config).Elem().Type()).Interface().(Config)
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ package gitdiff
|
||||
import (
|
||||
"bytes"
|
||||
"html/template"
|
||||
"slices"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
@ -385,8 +386,7 @@ func (hcd *highlightCodeDiff) recoverOneDiff(str string) template.HTML {
|
||||
}
|
||||
|
||||
// close all opening tags
|
||||
for i := len(tagStack) - 1; i >= 0; i-- {
|
||||
tagToClose := tagStack[i]
|
||||
for _, tagToClose := range slices.Backward(tagStack) {
|
||||
// get the closing tag "</span>" from "<span class=...>" or "<span>"
|
||||
pos := strings.IndexAny(tagToClose, " >")
|
||||
// pos must be positive, because the tags were pushed by us
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"html"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"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.
|
||||
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.
|
||||
for i := len(commits) - 1; i >= 0; i-- {
|
||||
c := commits[i]
|
||||
|
||||
for _, c := range slices.Backward(commits) {
|
||||
type markKey struct {
|
||||
ID int64
|
||||
Action references.XRefAction
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
@ -845,8 +846,7 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ
|
||||
// use PR's commit messages as squash commit message
|
||||
// commits list is in reverse chronological order
|
||||
maxMsgSize := setting.Repository.PullRequest.DefaultMergeMessageSize
|
||||
for i := len(commits) - 1; i >= 0; i-- {
|
||||
commit := commits[i]
|
||||
for _, commit := range slices.Backward(commits) {
|
||||
msg := strings.TrimSpace(commit.MessageUTF8())
|
||||
if msg == "" {
|
||||
continue
|
||||
|
||||
@ -6,6 +6,7 @@ package gitgraph
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// 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
|
||||
parser.releaseUnusedColors()
|
||||
|
||||
for i := len(glyphs) - 1; i >= 0; i-- {
|
||||
glyph := glyphs[i]
|
||||
for i, glyph := range slices.Backward(glyphs) {
|
||||
switch glyph {
|
||||
case '|':
|
||||
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 type {Config} from 'stylelint';
|
||||
|
||||
const cssVarFiles = [
|
||||
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)),
|
||||
];
|
||||
|
||||
/** @type {import('stylelint').Config} */
|
||||
export default {
|
||||
extends: 'stylelint-config-recommended',
|
||||
reportUnscopedDisables: true,
|
||||
@ -25,18 +23,6 @@ export default {
|
||||
'/web_src/fomantic',
|
||||
],
|
||||
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'],
|
||||
customSyntax: 'postcss-html',
|
||||
@ -139,7 +125,7 @@ export default {
|
||||
'no-unknown-custom-media': 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,
|
||||
'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-no-vendor-prefix': true,
|
||||
'selector-pseudo-element-colon-notation': 'double',
|
||||
@ -148,4 +134,4 @@ export default {
|
||||
'shorthand-property-no-redundant-values': true,
|
||||
'value-no-vendor-prefix': [true, {ignoreValues: ['box', 'inline-box']}],
|
||||
},
|
||||
};
|
||||
} satisfies Config;
|
||||
@ -9,6 +9,9 @@ import (
|
||||
"net/url"
|
||||
"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/test"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
@ -20,6 +23,7 @@ import (
|
||||
func TestGitSmartHTTP(t *testing.T) {
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
testGitSmartHTTP(t, u)
|
||||
testGitSmartHTTPTokenScopes(t)
|
||||
testRenamedRepoRedirect(t)
|
||||
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) {
|
||||
defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)()
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ func InitIntegrationTest() error {
|
||||
return err
|
||||
}
|
||||
|
||||
setting.Database.SlowQueryThreshold = 0
|
||||
setting.LoadDBSetting()
|
||||
cleanupDb, err := unittest.ResetTestDatabase()
|
||||
if err != nil {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
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;
|
||||
|
||||
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 */
|
||||
/* stylelint-disable scale-unlimited/declaration-strict-value -- terminal ANSI palette uses literal hex values */
|
||||
|
||||
.console {
|
||||
background: var(--color-console-bg);
|
||||
|
||||
@ -84,162 +84,82 @@
|
||||
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 {
|
||||
stroke: #499a37;
|
||||
fill: #499a37;
|
||||
stroke: var(--color-series-16-1);
|
||||
fill: var(--color-series-16-1);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-2 {
|
||||
stroke: #ce4751;
|
||||
fill: #ce4751;
|
||||
stroke: var(--color-series-16-2);
|
||||
fill: var(--color-series-16-2);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-3 {
|
||||
stroke: #8f9121;
|
||||
fill: #8f9121;
|
||||
stroke: var(--color-series-16-3);
|
||||
fill: var(--color-series-16-3);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-4 {
|
||||
stroke: #ac32a6;
|
||||
fill: #ac32a6;
|
||||
stroke: var(--color-series-16-4);
|
||||
fill: var(--color-series-16-4);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-5 {
|
||||
stroke: #7445e9;
|
||||
fill: #7445e9;
|
||||
stroke: var(--color-series-16-5);
|
||||
fill: var(--color-series-16-5);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-6 {
|
||||
stroke: #c67d28;
|
||||
fill: #c67d28;
|
||||
stroke: var(--color-series-16-6);
|
||||
fill: var(--color-series-16-6);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-7 {
|
||||
stroke: #4db392;
|
||||
fill: #4db392;
|
||||
stroke: var(--color-series-16-7);
|
||||
fill: var(--color-series-16-7);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-8 {
|
||||
stroke: #aa4d30;
|
||||
fill: #aa4d30;
|
||||
stroke: var(--color-series-16-8);
|
||||
fill: var(--color-series-16-8);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-9 {
|
||||
stroke: #2a6f84;
|
||||
fill: #2a6f84;
|
||||
stroke: var(--color-series-16-9);
|
||||
fill: var(--color-series-16-9);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-10 {
|
||||
stroke: #c45327;
|
||||
fill: #c45327;
|
||||
stroke: var(--color-series-16-10);
|
||||
fill: var(--color-series-16-10);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-11 {
|
||||
stroke: #3d965c;
|
||||
fill: #3d965c;
|
||||
stroke: var(--color-series-16-11);
|
||||
fill: var(--color-series-16-11);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-12 {
|
||||
stroke: #792a93;
|
||||
fill: #792a93;
|
||||
stroke: var(--color-series-16-12);
|
||||
fill: var(--color-series-16-12);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-13 {
|
||||
stroke: #439d73;
|
||||
fill: #439d73;
|
||||
stroke: var(--color-series-16-13);
|
||||
fill: var(--color-series-16-13);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-14 {
|
||||
stroke: #103aad;
|
||||
fill: #103aad;
|
||||
stroke: var(--color-series-16-14);
|
||||
fill: var(--color-series-16-14);
|
||||
}
|
||||
|
||||
#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-15 {
|
||||
stroke: #982e85;
|
||||
fill: #982e85;
|
||||
}
|
||||
|
||||
#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;
|
||||
stroke: var(--color-series-16-15);
|
||||
fill: var(--color-series-16-15);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
local("SourceHanSans-Light"), local("Yu Gothic Regular"),
|
||||
local("YuGothic Regular"), local("Droid Sans Japanese"), local("Meiryo"),
|
||||
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,
|
||||
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("YuGothic Medium"), local("Droid Sans Japanese"), local("Meiryo"),
|
||||
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,
|
||||
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("YuGothic Medium"), local("Droid Sans Japanese"), local("Meiryo"),
|
||||
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,
|
||||
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("SourceHanSans-Bold"), local("Yu Gothic Bold"), local("YuGothic Bold"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -124,7 +124,7 @@
|
||||
local("NotoSansCJKSC-Light"), local("HiraginoSansGB-W3"),
|
||||
local("Hiragino Sans GB W3"), local("Microsoft YaHei Light"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -137,7 +137,7 @@
|
||||
local("NotoSansCJKSC-Regular"), local("HiraginoSansGB-W3"),
|
||||
local("Hiragino Sans GB W3"), local("Microsoft YaHei"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -150,7 +150,7 @@
|
||||
local("NotoSansCJKSC-Medium"), local("HiraginoSansGB-W3"),
|
||||
local("Hiragino Sans GB W3"), local("Microsoft YaHei"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -163,7 +163,7 @@
|
||||
local("NotoSansCJKSC-Bold"), local("HiraginoSansGB-W6"),
|
||||
local("Hiragino Sans GB W6"), local("Microsoft YaHei Bold"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -192,7 +192,7 @@
|
||||
local("NotoSansCJKTC-Light"), local("HiraginoSansTC-W3"),
|
||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei Light"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -205,7 +205,7 @@
|
||||
local("NotoSansCJKTC-Regular"), local("HiraginoSansTC-W3"),
|
||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -218,7 +218,7 @@
|
||||
local("NotoSansCJKTC-Medium"), local("HiraginoSansTC-W3"),
|
||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -231,7 +231,7 @@
|
||||
local("NotoSansCJKTC-Bold"), local("HiraginoSansTC-W6"),
|
||||
local("Hiragino Sans TC W6"), local("Microsoft JhengHei Bold"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -262,7 +262,7 @@
|
||||
local("NotoSansCJKTC-Light"), local("HiraginoSansTC-W3"),
|
||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei Light"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -277,7 +277,7 @@
|
||||
local("NotoSansCJKTC-Regular"), local("HiraginoSansTC-W3"),
|
||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -292,7 +292,7 @@
|
||||
local("NotoSansCJKTC-Medium"), local("HiraginoSansTC-W3"),
|
||||
local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
|
||||
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,
|
||||
U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
|
||||
}
|
||||
@ -307,7 +307,7 @@
|
||||
local("NotoSansCJKTC-Bold"), local("HiraginoSansTC-W6"),
|
||||
local("Hiragino Sans TC W6"), local("Microsoft JhengHei Bold"),
|
||||
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,
|
||||
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("NotoSansCJKKR-Light"), local("NanumBarunGothic Light"),
|
||||
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,
|
||||
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("NotoSansCJKKR-Regular"), local("NanumBarunGothic"),
|
||||
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,
|
||||
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("NotoSansCJKKR-Medium"), local("NanumBarunGothic"),
|
||||
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,
|
||||
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("NotoSansCJKKR-Bold"), local("NanumBarunGothic Bold"),
|
||||
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,
|
||||
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-cyan: #00b6ad;
|
||||
--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 */
|
||||
--color-grey: #3d3f44;
|
||||
--color-grey-light: #898d96;
|
||||
|
||||
@ -141,6 +141,23 @@ gitea-theme-meta-info {
|
||||
--color-ansi-bright-magenta: #d74397;
|
||||
--color-ansi-bright-cyan: #00b6ad;
|
||||
--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 */
|
||||
--color-grey: #697077;
|
||||
--color-grey-light: #7c838a;
|
||||
|
||||
@ -16,5 +16,3 @@ window.config = {
|
||||
};
|
||||
|
||||
window.testModules = {};
|
||||
|
||||
export {}; // mark as module for top-level await
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user