Merge branch 'main' into main

This commit is contained in:
Timon van der Berg 2024-08-05 14:20:45 +02:00 committed by GitHub
commit 51d8ecac7c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
57 changed files with 1550 additions and 759 deletions

View File

@ -224,7 +224,6 @@ rules:
"@typescript-eslint/await-thenable": [2] "@typescript-eslint/await-thenable": [2]
"@typescript-eslint/ban-ts-comment": [2, {'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': false, 'ts-check': false}] "@typescript-eslint/ban-ts-comment": [2, {'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': false, 'ts-check': false}]
"@typescript-eslint/ban-tslint-comment": [0] "@typescript-eslint/ban-tslint-comment": [0]
"@typescript-eslint/ban-types": [2, {extendDefaults: true, types: {Function: false}}]
"@typescript-eslint/class-literal-property-style": [0] "@typescript-eslint/class-literal-property-style": [0]
"@typescript-eslint/class-methods-use-this": [0] "@typescript-eslint/class-methods-use-this": [0]
"@typescript-eslint/consistent-generic-constructors": [0] "@typescript-eslint/consistent-generic-constructors": [0]
@ -255,6 +254,7 @@ rules:
"@typescript-eslint/no-dynamic-delete": [0] "@typescript-eslint/no-dynamic-delete": [0]
"@typescript-eslint/no-empty-function": [0] "@typescript-eslint/no-empty-function": [0]
"@typescript-eslint/no-empty-interface": [0] "@typescript-eslint/no-empty-interface": [0]
"@typescript-eslint/no-empty-object-type": [2]
"@typescript-eslint/no-explicit-any": [0] "@typescript-eslint/no-explicit-any": [0]
"@typescript-eslint/no-extra-non-null-assertion": [2] "@typescript-eslint/no-extra-non-null-assertion": [2]
"@typescript-eslint/no-extraneous-class": [0] "@typescript-eslint/no-extraneous-class": [0]
@ -266,7 +266,7 @@ rules:
"@typescript-eslint/no-invalid-this": [0] "@typescript-eslint/no-invalid-this": [0]
"@typescript-eslint/no-invalid-void-type": [0] "@typescript-eslint/no-invalid-void-type": [0]
"@typescript-eslint/no-loop-func": [0] "@typescript-eslint/no-loop-func": [0]
"@typescript-eslint/no-loss-of-precision": [2] "@typescript-eslint/no-loss-of-precision": [0]
"@typescript-eslint/no-magic-numbers": [0] "@typescript-eslint/no-magic-numbers": [0]
"@typescript-eslint/no-meaningless-void-operator": [0] "@typescript-eslint/no-meaningless-void-operator": [0]
"@typescript-eslint/no-misused-new": [2] "@typescript-eslint/no-misused-new": [2]
@ -278,8 +278,9 @@ rules:
"@typescript-eslint/no-non-null-assertion": [0] "@typescript-eslint/no-non-null-assertion": [0]
"@typescript-eslint/no-redeclare": [0] "@typescript-eslint/no-redeclare": [0]
"@typescript-eslint/no-redundant-type-constituents": [2] "@typescript-eslint/no-redundant-type-constituents": [2]
"@typescript-eslint/no-require-imports": [0] "@typescript-eslint/no-require-imports": [2]
"@typescript-eslint/no-restricted-imports": [0] "@typescript-eslint/no-restricted-imports": [0]
"@typescript-eslint/no-restricted-types": [0]
"@typescript-eslint/no-shadow": [0] "@typescript-eslint/no-shadow": [0]
"@typescript-eslint/no-this-alias": [0] # handled by unicorn/no-this-assignment "@typescript-eslint/no-this-alias": [0] # handled by unicorn/no-this-assignment
"@typescript-eslint/no-unnecessary-boolean-literal-compare": [0] "@typescript-eslint/no-unnecessary-boolean-literal-compare": [0]
@ -294,6 +295,7 @@ rules:
"@typescript-eslint/no-unsafe-call": [0] "@typescript-eslint/no-unsafe-call": [0]
"@typescript-eslint/no-unsafe-declaration-merging": [2] "@typescript-eslint/no-unsafe-declaration-merging": [2]
"@typescript-eslint/no-unsafe-enum-comparison": [2] "@typescript-eslint/no-unsafe-enum-comparison": [2]
"@typescript-eslint/no-unsafe-function-type": [2]
"@typescript-eslint/no-unsafe-member-access": [0] "@typescript-eslint/no-unsafe-member-access": [0]
"@typescript-eslint/no-unsafe-return": [0] "@typescript-eslint/no-unsafe-return": [0]
"@typescript-eslint/no-unsafe-unary-minus": [2] "@typescript-eslint/no-unsafe-unary-minus": [2]
@ -302,7 +304,7 @@ rules:
"@typescript-eslint/no-use-before-define": [0] "@typescript-eslint/no-use-before-define": [0]
"@typescript-eslint/no-useless-constructor": [0] "@typescript-eslint/no-useless-constructor": [0]
"@typescript-eslint/no-useless-empty-export": [0] "@typescript-eslint/no-useless-empty-export": [0]
"@typescript-eslint/no-var-requires": [2] "@typescript-eslint/no-wrapper-object-types": [2]
"@typescript-eslint/non-nullable-type-assertion-style": [0] "@typescript-eslint/non-nullable-type-assertion-style": [0]
"@typescript-eslint/only-throw-error": [2] "@typescript-eslint/only-throw-error": [2]
"@typescript-eslint/parameter-properties": [0] "@typescript-eslint/parameter-properties": [0]
@ -334,7 +336,7 @@ rules:
"@typescript-eslint/switch-exhaustiveness-check": [0] "@typescript-eslint/switch-exhaustiveness-check": [0]
"@typescript-eslint/triple-slash-reference": [2] "@typescript-eslint/triple-slash-reference": [2]
"@typescript-eslint/typedef": [0] "@typescript-eslint/typedef": [0]
"@typescript-eslint/unbound-method": [2] "@typescript-eslint/unbound-method": [0] # too many false-positives
"@typescript-eslint/unified-signatures": [2] "@typescript-eslint/unified-signatures": [2]
accessor-pairs: [2] accessor-pairs: [2]
array-callback-return: [2, {checkForEach: true}] array-callback-return: [2, {checkForEach: true}]
@ -599,7 +601,7 @@ rules:
no-lone-blocks: [2] no-lone-blocks: [2]
no-lonely-if: [0] no-lonely-if: [0]
no-loop-func: [0] no-loop-func: [0]
no-loss-of-precision: [0] # handled by @typescript-eslint/no-loss-of-precision no-loss-of-precision: [2]
no-magic-numbers: [0] no-magic-numbers: [0]
no-misleading-character-class: [2] no-misleading-character-class: [2]
no-multi-assign: [0] no-multi-assign: [0]
@ -843,6 +845,7 @@ rules:
unicorn/no-invalid-fetch-options: [2] unicorn/no-invalid-fetch-options: [2]
unicorn/no-invalid-remove-event-listener: [2] unicorn/no-invalid-remove-event-listener: [2]
unicorn/no-keyword-prefix: [0] unicorn/no-keyword-prefix: [0]
unicorn/no-length-as-slice-end: [2]
unicorn/no-lonely-if: [2] unicorn/no-lonely-if: [2]
unicorn/no-magic-array-flat-depth: [0] unicorn/no-magic-array-flat-depth: [0]
unicorn/no-negated-condition: [0] unicorn/no-negated-condition: [0]

View File

@ -2684,6 +2684,8 @@ LEVEL = Info
;; ;;
;; Default platform to get action plugins, `github` for `https://github.com`, `self` for the current Gitea instance. ;; Default platform to get action plugins, `github` for `https://github.com`, `self` for the current Gitea instance.
;DEFAULT_ACTIONS_URL = github ;DEFAULT_ACTIONS_URL = github
;; Logs retention time in days. Old logs will be deleted after this period.
;LOG_RETENTION_DAYS = 365
;; Default artifact retention time in days. Artifacts could have their own retention periods by setting the `retention-days` option in `actions/upload-artifact` step. ;; Default artifact retention time in days. Artifacts could have their own retention periods by setting the `retention-days` option in `actions/upload-artifact` step.
;ARTIFACT_RETENTION_DAYS = 90 ;ARTIFACT_RETENTION_DAYS = 90
;; Timeout to stop the task which have running status, but haven't been updated for a long time ;; Timeout to stop the task which have running status, but haven't been updated for a long time

10
go.mod
View File

@ -22,7 +22,7 @@ require (
github.com/PuerkitoBio/goquery v1.9.2 github.com/PuerkitoBio/goquery v1.9.2
github.com/alecthomas/chroma/v2 v2.14.0 github.com/alecthomas/chroma/v2 v2.14.0
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
github.com/blevesearch/bleve/v2 v2.4.0 github.com/blevesearch/bleve/v2 v2.4.2
github.com/buildkite/terminal-to-html/v3 v3.12.1 github.com/buildkite/terminal-to-html/v3 v3.12.1
github.com/caddyserver/certmagic v0.21.3 github.com/caddyserver/certmagic v0.21.3
github.com/chi-middleware/proxy v1.1.1 github.com/chi-middleware/proxy v1.1.1
@ -147,13 +147,13 @@ require (
github.com/aymerick/douceur v0.2.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect
github.com/blevesearch/bleve_index_api v1.1.9 // indirect github.com/blevesearch/bleve_index_api v1.1.10 // indirect
github.com/blevesearch/geo v0.1.20 // indirect github.com/blevesearch/geo v0.1.20 // indirect
github.com/blevesearch/go-faiss v1.0.19 // indirect github.com/blevesearch/go-faiss v1.0.20 // indirect
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
github.com/blevesearch/gtreap v0.1.1 // indirect github.com/blevesearch/gtreap v0.1.1 // indirect
github.com/blevesearch/mmap-go v1.0.4 // indirect github.com/blevesearch/mmap-go v1.0.4 // indirect
github.com/blevesearch/scorch_segment_api/v2 v2.2.14 // indirect github.com/blevesearch/scorch_segment_api/v2 v2.2.15 // indirect
github.com/blevesearch/segment v0.9.1 // indirect github.com/blevesearch/segment v0.9.1 // indirect
github.com/blevesearch/snowballstem v0.9.0 // indirect github.com/blevesearch/snowballstem v0.9.0 // indirect
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
@ -163,7 +163,7 @@ require (
github.com/blevesearch/zapx/v13 v13.3.10 // indirect github.com/blevesearch/zapx/v13 v13.3.10 // indirect
github.com/blevesearch/zapx/v14 v14.3.10 // indirect github.com/blevesearch/zapx/v14 v14.3.10 // indirect
github.com/blevesearch/zapx/v15 v15.3.13 // indirect github.com/blevesearch/zapx/v15 v15.3.13 // indirect
github.com/blevesearch/zapx/v16 v16.1.4 // indirect github.com/blevesearch/zapx/v16 v16.1.5 // indirect
github.com/boombuler/barcode v1.0.1 // indirect github.com/boombuler/barcode v1.0.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
github.com/caddyserver/zerossl v0.1.3 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect

20
go.sum
View File

@ -117,15 +117,15 @@ github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM= github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
github.com/blevesearch/bleve/v2 v2.4.0 h1:2xyg+Wv60CFHYccXc+moGxbL+8QKT/dZK09AewHgKsg= github.com/blevesearch/bleve/v2 v2.4.2 h1:NooYP1mb3c0StkiY9/xviiq2LGSaE8BQBCc/pirMx0U=
github.com/blevesearch/bleve/v2 v2.4.0/go.mod h1:IhQHoFAbHgWKYavb9rQgQEJJVMuY99cKdQ0wPpst2aY= github.com/blevesearch/bleve/v2 v2.4.2/go.mod h1:ATNKj7Yl2oJv/lGuF4kx39bST2dveX6w0th2FFYLkc8=
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
github.com/blevesearch/bleve_index_api v1.1.9 h1:Cpq0Lp3As0Gfk3+PmcoNDRKeI50C5yuFNpj0YlN/bOE= github.com/blevesearch/bleve_index_api v1.1.10 h1:PDLFhVjrjQWr6jCuU7TwlmByQVCSEURADHdCqVS9+g0=
github.com/blevesearch/bleve_index_api v1.1.9/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8= github.com/blevesearch/bleve_index_api v1.1.10/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8=
github.com/blevesearch/geo v0.1.20 h1:paaSpu2Ewh/tn5DKn/FB5SzvH0EWupxHEIwbCk/QPqM= github.com/blevesearch/geo v0.1.20 h1:paaSpu2Ewh/tn5DKn/FB5SzvH0EWupxHEIwbCk/QPqM=
github.com/blevesearch/geo v0.1.20/go.mod h1:DVG2QjwHNMFmjo+ZgzrIq2sfCh6rIHzy9d9d0B59I6w= github.com/blevesearch/geo v0.1.20/go.mod h1:DVG2QjwHNMFmjo+ZgzrIq2sfCh6rIHzy9d9d0B59I6w=
github.com/blevesearch/go-faiss v1.0.19 h1:UKoP8hS7DVsVSRRloNJb4qPfe2UQ99pP4D3oXd23g2A= github.com/blevesearch/go-faiss v1.0.20 h1:AIkdTQFWuZ5LQmKQSebgMR4RynGNw8ZseJXaan5kvtI=
github.com/blevesearch/go-faiss v1.0.19/go.mod h1:jrxHrbl42X/RnDPI+wBoZU8joxxuRwedrxqswQ3xfU8= github.com/blevesearch/go-faiss v1.0.20/go.mod h1:jrxHrbl42X/RnDPI+wBoZU8joxxuRwedrxqswQ3xfU8=
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y= github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
@ -134,8 +134,8 @@ github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc= github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs= github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU= github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
github.com/blevesearch/scorch_segment_api/v2 v2.2.14 h1:fgMLMpGWR7u2TdRm7XSZVWhPvMAcdYHh25Lq1fQ6Fjo= github.com/blevesearch/scorch_segment_api/v2 v2.2.15 h1:prV17iU/o+A8FiZi9MXmqbagd8I0bCqM7OKUYPbnb5Y=
github.com/blevesearch/scorch_segment_api/v2 v2.2.14/go.mod h1:B7+a7vfpY4NsjuTkpv/eY7RZ91Xr90VaJzT2t7upZN8= github.com/blevesearch/scorch_segment_api/v2 v2.2.15/go.mod h1:db0cmP03bPNadXrCDuVkKLV6ywFSiRgPFT1YVrestBc=
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ= github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU= github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw= github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
@ -163,8 +163,8 @@ github.com/blevesearch/zapx/v14 v14.3.10/go.mod h1:qqyuR0u230jN1yMmE4FIAuCxmahRQ
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A= github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
github.com/blevesearch/zapx/v15 v15.3.13 h1:6EkfaZiPlAxqXz0neniq35my6S48QI94W/wyhnpDHHQ= github.com/blevesearch/zapx/v15 v15.3.13 h1:6EkfaZiPlAxqXz0neniq35my6S48QI94W/wyhnpDHHQ=
github.com/blevesearch/zapx/v15 v15.3.13/go.mod h1:Turk/TNRKj9es7ZpKK95PS7f6D44Y7fAFy8F4LXQtGg= github.com/blevesearch/zapx/v15 v15.3.13/go.mod h1:Turk/TNRKj9es7ZpKK95PS7f6D44Y7fAFy8F4LXQtGg=
github.com/blevesearch/zapx/v16 v16.1.4 h1:TBQfG77g2UUXwfjOVcEtB9pXkg6JBmGXkeZKI67+TiA= github.com/blevesearch/zapx/v16 v16.1.5 h1:b0sMcarqNFxuXvjoXsF8WtwVahnxyhEvBSRJi/AUHjU=
github.com/blevesearch/zapx/v16 v16.1.4/go.mod h1:+Q+Z89Iv7ewhdX2jyE6Qs/RUnN4tZuokaQ0xvTaFmx8= github.com/blevesearch/zapx/v16 v16.1.5/go.mod h1:J4mSF39w1QELc11EWRSBFkPeZuO7r/NPKkHzDCoiaI8=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=

View File

@ -23,14 +23,25 @@ import (
) )
// ActionRunner represents runner machines // ActionRunner represents runner machines
//
// It can be:
// 1. global runner, OwnerID is 0 and RepoID is 0
// 2. org/user level runner, OwnerID is org/user ID and RepoID is 0
// 3. repo level runner, OwnerID is 0 and RepoID is repo ID
//
// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero,
// or it will be complicated to find runners belonging to a specific owner.
// For example, conditions like `OwnerID = 1` will also return runner {OwnerID: 1, RepoID: 1},
// but it's a repo level runner, not an org/user level runner.
// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level runners.
type ActionRunner struct { type ActionRunner struct {
ID int64 ID int64
UUID string `xorm:"CHAR(36) UNIQUE"` UUID string `xorm:"CHAR(36) UNIQUE"`
Name string `xorm:"VARCHAR(255)"` Name string `xorm:"VARCHAR(255)"`
Version string `xorm:"VARCHAR(64)"` Version string `xorm:"VARCHAR(64)"`
OwnerID int64 `xorm:"index"` // org level runner, 0 means system OwnerID int64 `xorm:"index"`
Owner *user_model.User `xorm:"-"` Owner *user_model.User `xorm:"-"`
RepoID int64 `xorm:"index"` // repo level runner, if OwnerID also is zero, then it's a global RepoID int64 `xorm:"index"`
Repo *repo_model.Repository `xorm:"-"` Repo *repo_model.Repository `xorm:"-"`
Description string `xorm:"TEXT"` Description string `xorm:"TEXT"`
Base int // 0 native 1 docker 2 virtual machine Base int // 0 native 1 docker 2 virtual machine
@ -157,7 +168,7 @@ func init() {
type FindRunnerOptions struct { type FindRunnerOptions struct {
db.ListOptions db.ListOptions
RepoID int64 RepoID int64
OwnerID int64 OwnerID int64 // it will be ignored if RepoID is set
Sort string Sort string
Filter string Filter string
IsOnline optional.Option[bool] IsOnline optional.Option[bool]
@ -174,8 +185,7 @@ func (opts FindRunnerOptions) ToConds() builder.Cond {
c = c.Or(builder.Eq{"repo_id": 0, "owner_id": 0}) c = c.Or(builder.Eq{"repo_id": 0, "owner_id": 0})
} }
cond = cond.And(c) cond = cond.And(c)
} } else if opts.OwnerID > 0 { // OwnerID is ignored if RepoID is set
if opts.OwnerID > 0 {
c := builder.NewCond().And(builder.Eq{"owner_id": opts.OwnerID}) c := builder.NewCond().And(builder.Eq{"owner_id": opts.OwnerID})
if opts.WithAvailable { if opts.WithAvailable {
c = c.Or(builder.Eq{"repo_id": 0, "owner_id": 0}) c = c.Or(builder.Eq{"repo_id": 0, "owner_id": 0})
@ -263,6 +273,11 @@ func DeleteRunner(ctx context.Context, id int64) error {
// CreateRunner creates new runner. // CreateRunner creates new runner.
func CreateRunner(ctx context.Context, t *ActionRunner) error { func CreateRunner(ctx context.Context, t *ActionRunner) error {
if t.OwnerID != 0 && t.RepoID != 0 {
// It's trying to create a runner that belongs to a repository, but OwnerID has been set accidentally.
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
t.OwnerID = 0
}
return db.Insert(ctx, t) return db.Insert(ctx, t)
} }

View File

@ -15,12 +15,23 @@ import (
) )
// ActionRunnerToken represents runner tokens // ActionRunnerToken represents runner tokens
//
// It can be:
// 1. global token, OwnerID is 0 and RepoID is 0
// 2. org/user level token, OwnerID is org/user ID and RepoID is 0
// 3. repo level token, OwnerID is 0 and RepoID is repo ID
//
// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero,
// or it will be complicated to find tokens belonging to a specific owner.
// For example, conditions like `OwnerID = 1` will also return token {OwnerID: 1, RepoID: 1},
// but it's a repo level token, not an org/user level token.
// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level tokens.
type ActionRunnerToken struct { type ActionRunnerToken struct {
ID int64 ID int64
Token string `xorm:"UNIQUE"` Token string `xorm:"UNIQUE"`
OwnerID int64 `xorm:"index"` // org level runner, 0 means system OwnerID int64 `xorm:"index"`
Owner *user_model.User `xorm:"-"` Owner *user_model.User `xorm:"-"`
RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global RepoID int64 `xorm:"index"`
Repo *repo_model.Repository `xorm:"-"` Repo *repo_model.Repository `xorm:"-"`
IsActive bool // true means it can be used IsActive bool // true means it can be used
@ -58,7 +69,14 @@ func UpdateRunnerToken(ctx context.Context, r *ActionRunnerToken, cols ...string
} }
// NewRunnerToken creates a new active runner token and invalidate all old tokens // NewRunnerToken creates a new active runner token and invalidate all old tokens
// ownerID will be ignored and treated as 0 if repoID is non-zero.
func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) { func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
if ownerID != 0 && repoID != 0 {
// It's trying to create a runner token that belongs to a repository, but OwnerID has been set accidentally.
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
ownerID = 0
}
token, err := util.CryptoRandomString(40) token, err := util.CryptoRandomString(40)
if err != nil { if err != nil {
return nil, err return nil, err
@ -84,6 +102,12 @@ func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerTo
// GetLatestRunnerToken returns the latest runner token // GetLatestRunnerToken returns the latest runner token
func GetLatestRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) { func GetLatestRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
if ownerID != 0 && repoID != 0 {
// It's trying to get a runner token that belongs to a repository, but OwnerID has been set accidentally.
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
ownerID = 0
}
var runnerToken ActionRunnerToken var runnerToken ActionRunnerToken
has, err := db.GetEngine(ctx).Where("owner_id=? AND repo_id=?", ownerID, repoID). has, err := db.GetEngine(ctx).Where("owner_id=? AND repo_id=?", ownerID, repoID).
OrderBy("id DESC").Get(&runnerToken) OrderBy("id DESC").Get(&runnerToken)

View File

@ -13,8 +13,6 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
webhook_module "code.gitea.io/gitea/modules/webhook" webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/robfig/cron/v3"
) )
// ActionSchedule represents a schedule of a workflow file // ActionSchedule represents a schedule of a workflow file
@ -53,8 +51,6 @@ func GetReposMapByIDs(ctx context.Context, ids []int64) (map[int64]*repo_model.R
return repos, db.GetEngine(ctx).In("id", ids).Find(&repos) return repos, db.GetEngine(ctx).In("id", ids).Find(&repos)
} }
var cronParser = cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
// CreateScheduleTask creates new schedule task. // CreateScheduleTask creates new schedule task.
func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error { func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
// Return early if there are no rows to insert // Return early if there are no rows to insert
@ -80,19 +76,21 @@ func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
now := time.Now() now := time.Now()
for _, spec := range row.Specs { for _, spec := range row.Specs {
specRow := &ActionScheduleSpec{
RepoID: row.RepoID,
ScheduleID: row.ID,
Spec: spec,
}
// Parse the spec and check for errors // Parse the spec and check for errors
schedule, err := cronParser.Parse(spec) schedule, err := specRow.Parse()
if err != nil { if err != nil {
continue // skip to the next spec if there's an error continue // skip to the next spec if there's an error
} }
specRow.Next = timeutil.TimeStamp(schedule.Next(now).Unix())
// Insert the new schedule spec row // Insert the new schedule spec row
if err = db.Insert(ctx, &ActionScheduleSpec{ if err = db.Insert(ctx, specRow); err != nil {
RepoID: row.RepoID,
ScheduleID: row.ID,
Spec: spec,
Next: timeutil.TimeStamp(schedule.Next(now).Unix()),
}); err != nil {
return err return err
} }
} }

View File

@ -5,6 +5,8 @@ package actions
import ( import (
"context" "context"
"strings"
"time"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
@ -32,8 +34,29 @@ type ActionScheduleSpec struct {
Updated timeutil.TimeStamp `xorm:"updated"` Updated timeutil.TimeStamp `xorm:"updated"`
} }
// Parse parses the spec and returns a cron.Schedule
// Unlike the default cron parser, Parse uses UTC timezone as the default if none is specified.
func (s *ActionScheduleSpec) Parse() (cron.Schedule, error) { func (s *ActionScheduleSpec) Parse() (cron.Schedule, error) {
return cronParser.Parse(s.Spec) parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
schedule, err := parser.Parse(s.Spec)
if err != nil {
return nil, err
}
// If the spec has specified a timezone, use it
if strings.HasPrefix(s.Spec, "TZ=") || strings.HasPrefix(s.Spec, "CRON_TZ=") {
return schedule, nil
}
specSchedule, ok := schedule.(*cron.SpecSchedule)
// If it's not a spec schedule, like "@every 5m", timezone is not relevant
if !ok {
return schedule, nil
}
// Set the timezone to UTC
specSchedule.Location = time.UTC
return specSchedule, nil
} }
func init() { func init() {

View File

@ -0,0 +1,71 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestActionScheduleSpec_Parse(t *testing.T) {
// Mock the local timezone is not UTC
local := time.Local
tz, err := time.LoadLocation("Asia/Shanghai")
require.NoError(t, err)
defer func() {
time.Local = local
}()
time.Local = tz
now, err := time.Parse(time.RFC3339, "2024-07-31T15:47:55+08:00")
require.NoError(t, err)
tests := []struct {
name string
spec string
want string
wantErr assert.ErrorAssertionFunc
}{
{
name: "regular",
spec: "0 10 * * *",
want: "2024-07-31T10:00:00Z",
wantErr: assert.NoError,
},
{
name: "invalid",
spec: "0 10 * *",
want: "",
wantErr: assert.Error,
},
{
name: "with timezone",
spec: "TZ=America/New_York 0 10 * * *",
want: "2024-07-31T14:00:00Z",
wantErr: assert.NoError,
},
{
name: "timezone irrelevant",
spec: "@every 5m",
want: "2024-07-31T07:52:55Z",
wantErr: assert.NoError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &ActionScheduleSpec{
Spec: tt.spec,
}
got, err := s.Parse()
tt.wantErr(t, err)
if err == nil {
assert.Equal(t, tt.want, got.Next(now).UTC().Format(time.RFC3339))
}
})
}
}

View File

@ -35,7 +35,7 @@ type ActionTask struct {
RunnerID int64 `xorm:"index"` RunnerID int64 `xorm:"index"`
Status Status `xorm:"index"` Status Status `xorm:"index"`
Started timeutil.TimeStamp `xorm:"index"` Started timeutil.TimeStamp `xorm:"index"`
Stopped timeutil.TimeStamp Stopped timeutil.TimeStamp `xorm:"index(stopped_log_expired)"`
RepoID int64 `xorm:"index"` RepoID int64 `xorm:"index"`
OwnerID int64 `xorm:"index"` OwnerID int64 `xorm:"index"`
@ -51,8 +51,8 @@ type ActionTask struct {
LogInStorage bool // read log from database or from storage LogInStorage bool // read log from database or from storage
LogLength int64 // lines count LogLength int64 // lines count
LogSize int64 // blob size LogSize int64 // blob size
LogIndexes LogIndexes `xorm:"LONGBLOB"` // line number to offset LogIndexes LogIndexes `xorm:"LONGBLOB"` // line number to offset
LogExpired bool // files that are too old will be deleted LogExpired bool `xorm:"index(stopped_log_expired)"` // files that are too old will be deleted
Created timeutil.TimeStamp `xorm:"created"` Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated index"` Updated timeutil.TimeStamp `xorm:"updated index"`
@ -470,6 +470,16 @@ func StopTask(ctx context.Context, taskID int64, status Status) error {
return nil return nil
} }
func FindOldTasksToExpire(ctx context.Context, olderThan timeutil.TimeStamp, limit int) ([]*ActionTask, error) {
e := db.GetEngine(ctx)
tasks := make([]*ActionTask, 0, limit)
// Check "stopped > 0" to avoid deleting tasks that are still running
return tasks, e.Where("stopped > 0 AND stopped < ? AND log_expired = ?", olderThan, false).
Limit(limit).
Find(&tasks)
}
func isSubset(set, subset []string) bool { func isSubset(set, subset []string) bool {
m := make(container.Set[string], len(set)) m := make(container.Set[string], len(set))
for _, v := range set { for _, v := range set {

View File

@ -5,7 +5,6 @@ package actions
import ( import (
"context" "context"
"errors"
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -15,6 +14,18 @@ import (
"xorm.io/builder" "xorm.io/builder"
) )
// ActionVariable represents a variable that can be used in actions
//
// It can be:
// 1. global variable, OwnerID is 0 and RepoID is 0
// 2. org/user level variable, OwnerID is org/user ID and RepoID is 0
// 3. repo level variable, OwnerID is 0 and RepoID is repo ID
//
// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero,
// or it will be complicated to find variables belonging to a specific owner.
// For example, conditions like `OwnerID = 1` will also return variable {OwnerID: 1, RepoID: 1},
// but it's a repo level variable, not an org/user level variable.
// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level variables.
type ActionVariable struct { type ActionVariable struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(owner_repo_name)"` OwnerID int64 `xorm:"UNIQUE(owner_repo_name)"`
@ -29,30 +40,26 @@ func init() {
db.RegisterModel(new(ActionVariable)) db.RegisterModel(new(ActionVariable))
} }
func (v *ActionVariable) Validate() error {
if v.OwnerID != 0 && v.RepoID != 0 {
return errors.New("a variable should not be bound to an owner and a repository at the same time")
}
return nil
}
func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*ActionVariable, error) { func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*ActionVariable, error) {
if ownerID != 0 && repoID != 0 {
// It's trying to create a variable that belongs to a repository, but OwnerID has been set accidentally.
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
ownerID = 0
}
variable := &ActionVariable{ variable := &ActionVariable{
OwnerID: ownerID, OwnerID: ownerID,
RepoID: repoID, RepoID: repoID,
Name: strings.ToUpper(name), Name: strings.ToUpper(name),
Data: data, Data: data,
} }
if err := variable.Validate(); err != nil {
return variable, err
}
return variable, db.Insert(ctx, variable) return variable, db.Insert(ctx, variable)
} }
type FindVariablesOpts struct { type FindVariablesOpts struct {
db.ListOptions db.ListOptions
OwnerID int64
RepoID int64 RepoID int64
OwnerID int64 // it will be ignored if RepoID is set
Name string Name string
} }
@ -60,8 +67,13 @@ func (opts FindVariablesOpts) ToConds() builder.Cond {
cond := builder.NewCond() cond := builder.NewCond()
// Since we now support instance-level variables, // Since we now support instance-level variables,
// there is no need to check for null values for `owner_id` and `repo_id` // there is no need to check for null values for `owner_id` and `repo_id`
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
if opts.RepoID != 0 { // if RepoID is set
// ignore OwnerID and treat it as 0
cond = cond.And(builder.Eq{"owner_id": 0})
} else {
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
}
if opts.Name != "" { if opts.Name != "" {
cond = cond.And(builder.Eq{"name": strings.ToUpper(opts.Name)}) cond = cond.And(builder.Eq{"name": strings.ToUpper(opts.Name)})

View File

@ -392,6 +392,13 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to str
return err return err
} }
// 4.1 Update all not merged pull request head branch name
if _, err = sess.Table("pull_request").Where("head_repo_id=? AND head_branch=? AND has_merged=?",
repo.ID, from, false).
Update(map[string]any{"head_branch": to}); err != nil {
return err
}
// 5. insert renamed branch record // 5. insert renamed branch record
renamedBranch := &RenamedBranch{ renamedBranch := &RenamedBranch{
RepoID: repo.ID, RepoID: repo.ID,
@ -427,7 +434,8 @@ type RecentlyPushedNewBranch struct {
// FindRecentlyPushedNewBranches return at most 2 new branches pushed by the user in 2 hours which has no opened PRs created // FindRecentlyPushedNewBranches return at most 2 new branches pushed by the user in 2 hours which has no opened PRs created
// if opts.CommitAfterUnix is 0, we will find the branches that were committed to in the last 2 hours // if opts.CommitAfterUnix is 0, we will find the branches that were committed to in the last 2 hours
// if opts.ListOptions is not set, we will only display top 2 latest branch // if opts.ListOptions is not set, we will only display top 2 latest branches.
// Protected branches will be skipped since they are unlikely to be used to create new PRs.
func FindRecentlyPushedNewBranches(ctx context.Context, doer *user_model.User, opts *FindRecentlyPushedNewBranchesOptions) ([]*RecentlyPushedNewBranch, error) { func FindRecentlyPushedNewBranches(ctx context.Context, doer *user_model.User, opts *FindRecentlyPushedNewBranchesOptions) ([]*RecentlyPushedNewBranch, error) {
if doer == nil { if doer == nil {
return []*RecentlyPushedNewBranch{}, nil return []*RecentlyPushedNewBranch{}, nil
@ -486,6 +494,18 @@ func FindRecentlyPushedNewBranches(ctx context.Context, doer *user_model.User, o
opts.MaxCount = 2 opts.MaxCount = 2
} }
for _, branch := range branches { for _, branch := range branches {
// whether the branch is protected
protected, err := IsBranchProtected(ctx, branch.RepoID, branch.Name)
if err != nil {
return nil, fmt.Errorf("IsBranchProtected: %v", err)
}
if protected {
// Skip protected branches,
// since updates to protected branches often come from PR merges,
// and they are unlikely to be used to create new PRs.
continue
}
// whether branch have already created PR // whether branch have already created PR
count, err := db.GetEngine(ctx).Table("pull_request"). count, err := db.GetEngine(ctx).Table("pull_request").
// we should not only use branch name here, because if there are branches with same name in other repos, // we should not only use branch name here, because if there are branches with same name in other repos,

View File

@ -165,6 +165,7 @@ type PullRequest struct {
Issue *Issue `xorm:"-"` Issue *Issue `xorm:"-"`
Index int64 Index int64
RequestedReviewers []*user_model.User `xorm:"-"` RequestedReviewers []*user_model.User `xorm:"-"`
RequestedReviewersTeams []*org_model.Team `xorm:"-"`
isRequestedReviewersLoaded bool `xorm:"-"` isRequestedReviewersLoaded bool `xorm:"-"`
HeadRepoID int64 `xorm:"INDEX"` HeadRepoID int64 `xorm:"INDEX"`
@ -305,7 +306,28 @@ func (pr *PullRequest) LoadRequestedReviewers(ctx context.Context) error {
} }
pr.isRequestedReviewersLoaded = true pr.isRequestedReviewersLoaded = true
for _, review := range reviews { for _, review := range reviews {
pr.RequestedReviewers = append(pr.RequestedReviewers, review.Reviewer) if review.ReviewerID != 0 {
pr.RequestedReviewers = append(pr.RequestedReviewers, review.Reviewer)
}
}
return nil
}
// LoadRequestedReviewersTeams loads the requested reviewers teams.
func (pr *PullRequest) LoadRequestedReviewersTeams(ctx context.Context) error {
reviews, err := GetReviewsByIssueID(ctx, pr.Issue.ID)
if err != nil {
return err
}
if err = reviews.LoadReviewersTeams(ctx); err != nil {
return err
}
for _, review := range reviews {
if review.ReviewerTeamID != 0 {
pr.RequestedReviewersTeams = append(pr.RequestedReviewersTeams, review.ReviewerTeam)
}
} }
return nil return nil

View File

@ -7,6 +7,7 @@ import (
"context" "context"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
organization_model "code.gitea.io/gitea/models/organization"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/optional"
@ -37,6 +38,34 @@ func (reviews ReviewList) LoadReviewers(ctx context.Context) error {
return nil return nil
} }
// LoadReviewersTeams loads reviewers teams
func (reviews ReviewList) LoadReviewersTeams(ctx context.Context) error {
reviewersTeamsIDs := make([]int64, 0)
for _, review := range reviews {
if review.ReviewerTeamID != 0 {
reviewersTeamsIDs = append(reviewersTeamsIDs, review.ReviewerTeamID)
}
}
teamsMap := make(map[int64]*organization_model.Team, 0)
for _, teamID := range reviewersTeamsIDs {
team, err := organization_model.GetTeamByID(ctx, teamID)
if err != nil {
return err
}
teamsMap[teamID] = team
}
for _, review := range reviews {
if review.ReviewerTeamID != 0 {
review.ReviewerTeam = teamsMap[review.ReviewerTeamID]
}
}
return nil
}
func (reviews ReviewList) LoadIssues(ctx context.Context) error { func (reviews ReviewList) LoadIssues(ctx context.Context) error {
issueIDs := container.FilterSlice(reviews, func(review *Review) (int64, bool) { issueIDs := container.FilterSlice(reviews, func(review *Review) (int64, bool) {
return review.IssueID, true return review.IssueID, true

View File

@ -595,6 +595,8 @@ var migrations = []Migration{
NewMigration("Add force-push branch protection support", v1_23.AddForcePushBranchProtection), NewMigration("Add force-push branch protection support", v1_23.AddForcePushBranchProtection),
// v301 -> v302 // v301 -> v302
NewMigration("Add skip_secondary_authorization option to oauth2 application table", v1_23.AddSkipSecondaryAuthColumnToOAuth2ApplicationTable), NewMigration("Add skip_secondary_authorization option to oauth2 application table", v1_23.AddSkipSecondaryAuthColumnToOAuth2ApplicationTable),
// v302 -> v303
NewMigration("Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired),
} }
// GetCurrentDBVersion returns the current db version // GetCurrentDBVersion returns the current db version

View File

@ -0,0 +1,18 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_23 //nolint
import (
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/xorm"
)
func AddIndexToActionTaskStoppedLogExpired(x *xorm.Engine) error {
type ActionTask struct {
Stopped timeutil.TimeStamp `xorm:"index(stopped_log_expired)"`
LogExpired bool `xorm:"index(stopped_log_expired)"`
}
return x.Sync(new(ActionTask))
}

View File

@ -398,32 +398,6 @@ func GetReleaseAttachments(ctx context.Context, rels ...*Release) (err error) {
return err return err
} }
type releaseSorter struct {
rels []*Release
}
func (rs *releaseSorter) Len() int {
return len(rs.rels)
}
func (rs *releaseSorter) Less(i, j int) bool {
diffNum := rs.rels[i].NumCommits - rs.rels[j].NumCommits
if diffNum != 0 {
return diffNum > 0
}
return rs.rels[i].CreatedUnix > rs.rels[j].CreatedUnix
}
func (rs *releaseSorter) Swap(i, j int) {
rs.rels[i], rs.rels[j] = rs.rels[j], rs.rels[i]
}
// SortReleases sorts releases by number of commits and created time.
func SortReleases(rels []*Release) {
sorter := &releaseSorter{rels: rels}
sort.Sort(sorter)
}
// UpdateReleasesMigrationsByType updates all migrated repositories' releases from gitServiceType to replace originalAuthorID to posterID // UpdateReleasesMigrationsByType updates all migrated repositories' releases from gitServiceType to replace originalAuthorID to posterID
func UpdateReleasesMigrationsByType(ctx context.Context, gitServiceType structs.GitServiceType, originalAuthorID string, posterID int64) error { func UpdateReleasesMigrationsByType(ctx context.Context, gitServiceType structs.GitServiceType, originalAuthorID string, posterID int64) error {
_, err := db.GetEngine(ctx).Table("release"). _, err := db.GetEngine(ctx).Table("release").

View File

@ -5,7 +5,6 @@ package secret
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"strings" "strings"
@ -22,6 +21,19 @@ import (
) )
// Secret represents a secret // Secret represents a secret
//
// It can be:
// 1. org/user level secret, OwnerID is org/user ID and RepoID is 0
// 2. repo level secret, OwnerID is 0 and RepoID is repo ID
//
// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero,
// or it will be complicated to find secrets belonging to a specific owner.
// For example, conditions like `OwnerID = 1` will also return secret {OwnerID: 1, RepoID: 1},
// but it's a repo level secret, not an org/user level secret.
// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level secrets.
//
// Please note that it's not acceptable to have both OwnerID and RepoID to zero, global secrets are not supported.
// It's for security reasons, admin may be not aware of that the secrets could be stolen by any user when setting them as global.
type Secret struct { type Secret struct {
ID int64 ID int64
OwnerID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL"` OwnerID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL"`
@ -46,6 +58,15 @@ func (err ErrSecretNotFound) Unwrap() error {
// InsertEncryptedSecret Creates, encrypts, and validates a new secret with yet unencrypted data and insert into database // InsertEncryptedSecret Creates, encrypts, and validates a new secret with yet unencrypted data and insert into database
func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*Secret, error) { func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*Secret, error) {
if ownerID != 0 && repoID != 0 {
// It's trying to create a secret that belongs to a repository, but OwnerID has been set accidentally.
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
ownerID = 0
}
if ownerID == 0 && repoID == 0 {
return nil, fmt.Errorf("%w: ownerID and repoID cannot be both zero, global secrets are not supported", util.ErrInvalidArgument)
}
encrypted, err := secret_module.EncryptSecret(setting.SecretKey, data) encrypted, err := secret_module.EncryptSecret(setting.SecretKey, data)
if err != nil { if err != nil {
return nil, err return nil, err
@ -56,9 +77,6 @@ func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, dat
Name: strings.ToUpper(name), Name: strings.ToUpper(name),
Data: encrypted, Data: encrypted,
} }
if err := secret.Validate(); err != nil {
return secret, err
}
return secret, db.Insert(ctx, secret) return secret, db.Insert(ctx, secret)
} }
@ -66,29 +84,25 @@ func init() {
db.RegisterModel(new(Secret)) db.RegisterModel(new(Secret))
} }
func (s *Secret) Validate() error {
if s.OwnerID == 0 && s.RepoID == 0 {
return errors.New("the secret is not bound to any scope")
}
return nil
}
type FindSecretsOptions struct { type FindSecretsOptions struct {
db.ListOptions db.ListOptions
OwnerID int64
RepoID int64 RepoID int64
OwnerID int64 // it will be ignored if RepoID is set
SecretID int64 SecretID int64
Name string Name string
} }
func (opts FindSecretsOptions) ToConds() builder.Cond { func (opts FindSecretsOptions) ToConds() builder.Cond {
cond := builder.NewCond() cond := builder.NewCond()
if opts.OwnerID > 0 {
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
if opts.RepoID != 0 { // if RepoID is set
// ignore OwnerID and treat it as 0
cond = cond.And(builder.Eq{"owner_id": 0})
} else {
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID}) cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
} }
if opts.RepoID > 0 {
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
}
if opts.SecretID != 0 { if opts.SecretID != 0 {
cond = cond.And(builder.Eq{"id": opts.SecretID}) cond = cond.And(builder.Eq{"id": opts.SecretID})
} }

View File

@ -136,14 +136,13 @@ func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc
for _, object := range result.Objects { for _, object := range result.Objects {
if object.Error != nil { if object.Error != nil {
objectError := errors.New(object.Error.Message) log.Trace("Error on object %v: %v", object.Pointer, object.Error)
log.Trace("Error on object %v: %v", object.Pointer, objectError)
if uc != nil { if uc != nil {
if _, err := uc(object.Pointer, objectError); err != nil { if _, err := uc(object.Pointer, object.Error); err != nil {
return err return err
} }
} else { } else {
if err := dc(object.Pointer, nil, objectError); err != nil { if err := dc(object.Pointer, nil, object.Error); err != nil {
return err return err
} }
} }

View File

@ -4,7 +4,11 @@
package lfs package lfs
import ( import (
"errors"
"fmt"
"time" "time"
"code.gitea.io/gitea/modules/util"
) )
const ( const (
@ -64,6 +68,39 @@ type ObjectError struct {
Message string `json:"message"` Message string `json:"message"`
} }
var (
// See https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md#successful-responses
// LFS object error codes should match HTTP status codes where possible:
// 404 - The object does not exist on the server.
// 409 - The specified hash algorithm disagrees with the server's acceptable options.
// 410 - The object was removed by the owner.
// 422 - Validation error.
ErrObjectNotExist = util.ErrNotExist // the object does not exist on the server
ErrObjectHashMismatch = errors.New("the specified hash algorithm disagrees with the server's acceptable options")
ErrObjectRemoved = errors.New("the object was removed by the owner")
ErrObjectValidation = errors.New("validation error")
)
func (e *ObjectError) Error() string {
return fmt.Sprintf("[%d] %s", e.Code, e.Message)
}
func (e *ObjectError) Unwrap() error {
switch e.Code {
case 404:
return ErrObjectNotExist
case 409:
return ErrObjectHashMismatch
case 410:
return ErrObjectRemoved
case 422:
return ErrObjectValidation
default:
return errors.New(e.Message)
}
}
// PointerBlob associates a Git blob with a Pointer. // PointerBlob associates a Git blob with a Pointer.
type PointerBlob struct { type PointerBlob struct {
Hash string Hash string

View File

@ -5,6 +5,7 @@ package repository
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"strings" "strings"
@ -181,6 +182,10 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re
downloadObjects := func(pointers []lfs.Pointer) error { downloadObjects := func(pointers []lfs.Pointer) error {
err := lfsClient.Download(ctx, pointers, func(p lfs.Pointer, content io.ReadCloser, objectError error) error { err := lfsClient.Download(ctx, pointers, func(p lfs.Pointer, content io.ReadCloser, objectError error) error {
if objectError != nil { if objectError != nil {
if errors.Is(objectError, lfs.ErrObjectNotExist) {
log.Warn("Repo[%-v]: Ignore missing LFS object %-v: %v", repo, p, objectError)
return nil
}
return objectError return objectError
} }

View File

@ -14,10 +14,11 @@ import (
// Actions settings // Actions settings
var ( var (
Actions = struct { Actions = struct {
LogStorage *Storage // how the created logs should be stored
ArtifactStorage *Storage // how the created artifacts should be stored
ArtifactRetentionDays int64 `ini:"ARTIFACT_RETENTION_DAYS"`
Enabled bool Enabled bool
LogStorage *Storage // how the created logs should be stored
LogRetentionDays int64 `ini:"LOG_RETENTION_DAYS"`
ArtifactStorage *Storage // how the created artifacts should be stored
ArtifactRetentionDays int64 `ini:"ARTIFACT_RETENTION_DAYS"`
DefaultActionsURL defaultActionsURL `ini:"DEFAULT_ACTIONS_URL"` DefaultActionsURL defaultActionsURL `ini:"DEFAULT_ACTIONS_URL"`
ZombieTaskTimeout time.Duration `ini:"ZOMBIE_TASK_TIMEOUT"` ZombieTaskTimeout time.Duration `ini:"ZOMBIE_TASK_TIMEOUT"`
EndlessTaskTimeout time.Duration `ini:"ENDLESS_TASK_TIMEOUT"` EndlessTaskTimeout time.Duration `ini:"ENDLESS_TASK_TIMEOUT"`
@ -78,10 +79,17 @@ func loadActionsFrom(rootCfg ConfigProvider) error {
if err != nil { if err != nil {
return err return err
} }
// default to 1 year
if Actions.LogRetentionDays <= 0 {
Actions.LogRetentionDays = 365
}
actionsSec, _ := rootCfg.GetSection("actions.artifacts") actionsSec, _ := rootCfg.GetSection("actions.artifacts")
Actions.ArtifactStorage, err = getStorage(rootCfg, "actions_artifacts", "", actionsSec) Actions.ArtifactStorage, err = getStorage(rootCfg, "actions_artifacts", "", actionsSec)
if err != nil {
return err
}
// default to 90 days in Github Actions // default to 90 days in Github Actions
if Actions.ArtifactRetentionDays <= 0 { if Actions.ArtifactRetentionDays <= 0 {
@ -92,5 +100,5 @@ func loadActionsFrom(rootCfg ConfigProvider) error {
Actions.EndlessTaskTimeout = sec.Key("ENDLESS_TASK_TIMEOUT").MustDuration(3 * time.Hour) Actions.EndlessTaskTimeout = sec.Key("ENDLESS_TASK_TIMEOUT").MustDuration(3 * time.Hour)
Actions.AbandonedJobTimeout = sec.Key("ABANDONED_JOB_TIMEOUT").MustDuration(24 * time.Hour) Actions.AbandonedJobTimeout = sec.Key("ABANDONED_JOB_TIMEOUT").MustDuration(24 * time.Hour)
return err return nil
} }

View File

@ -9,21 +9,22 @@ import (
// PullRequest represents a pull request // PullRequest represents a pull request
type PullRequest struct { type PullRequest struct {
ID int64 `json:"id"` ID int64 `json:"id"`
URL string `json:"url"` URL string `json:"url"`
Index int64 `json:"number"` Index int64 `json:"number"`
Poster *User `json:"user"` Poster *User `json:"user"`
Title string `json:"title"` Title string `json:"title"`
Body string `json:"body"` Body string `json:"body"`
Labels []*Label `json:"labels"` Labels []*Label `json:"labels"`
Milestone *Milestone `json:"milestone"` Milestone *Milestone `json:"milestone"`
Assignee *User `json:"assignee"` Assignee *User `json:"assignee"`
Assignees []*User `json:"assignees"` Assignees []*User `json:"assignees"`
RequestedReviewers []*User `json:"requested_reviewers"` RequestedReviewers []*User `json:"requested_reviewers"`
State StateType `json:"state"` RequestedReviewersTeams []*Team `json:"requested_reviewers_teams"`
Draft bool `json:"draft"` State StateType `json:"state"`
IsLocked bool `json:"is_locked"` Draft bool `json:"draft"`
Comments int `json:"comments"` IsLocked bool `json:"is_locked"`
Comments int `json:"comments"`
// number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR) // number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR)
ReviewComments int `json:"review_comments"` ReviewComments int `json:"review_comments"`
Additions int `json:"additions"` Additions int `json:"additions"`

View File

@ -5,6 +5,7 @@ package structs
// AddCollaboratorOption options when adding a user as a collaborator of a repository // AddCollaboratorOption options when adding a user as a collaborator of a repository
type AddCollaboratorOption struct { type AddCollaboratorOption struct {
// enum: read,write,admin
Permission *string `json:"permission"` Permission *string `json:"permission"`
} }

View File

@ -0,0 +1,10 @@
Copyright (C) 1995 S. M. Patel (smpatel@wam.umd.edu)
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation. No representations are made about the
suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.

View File

@ -2836,7 +2836,6 @@ dashboard.reinit_missing_repos=Znovu inicializovat všechny chybějící repozit
dashboard.sync_external_users=Synchronizovat externí uživatelská data dashboard.sync_external_users=Synchronizovat externí uživatelská data
dashboard.cleanup_hook_task_table=Vyčistit tabulku hook_task dashboard.cleanup_hook_task_table=Vyčistit tabulku hook_task
dashboard.cleanup_packages=Vyčistit prošlé balíčky dashboard.cleanup_packages=Vyčistit prošlé balíčky
dashboard.cleanup_actions=Vyčištění prošlých záznamů a artefaktů z akcí
dashboard.server_uptime=Doba provozu serveru dashboard.server_uptime=Doba provozu serveru
dashboard.current_goroutine=Aktuální Goroutines dashboard.current_goroutine=Aktuální Goroutines
dashboard.current_memory_usage=Aktuální využití paměti dashboard.current_memory_usage=Aktuální využití paměti
@ -2866,15 +2865,9 @@ dashboard.total_gc_time=Celková pauza GC
dashboard.total_gc_pause=Celková pauza GC dashboard.total_gc_pause=Celková pauza GC
dashboard.last_gc_pause=Poslední pauza GC dashboard.last_gc_pause=Poslední pauza GC
dashboard.gc_times=Časy GC dashboard.gc_times=Časy GC
dashboard.delete_old_actions=Odstranit všechny staré akce z databáze
dashboard.delete_old_actions.started=Začalo odstraňování všech starých akcí z databáze.
dashboard.update_checker=Kontrola aktualizací dashboard.update_checker=Kontrola aktualizací
dashboard.delete_old_system_notices=Odstranit všechna stará systémová upozornění z databáze dashboard.delete_old_system_notices=Odstranit všechna stará systémová upozornění z databáze
dashboard.gc_lfs=Úklid LFS meta objektů dashboard.gc_lfs=Úklid LFS meta objektů
dashboard.stop_zombie_tasks=Zastavit zombie úlohy
dashboard.stop_endless_tasks=Zastavit nekonečné úlohy
dashboard.cancel_abandoned_jobs=Zrušit opuštěné úlohy
dashboard.start_schedule_tasks=Spustit naplánované úlohy
dashboard.sync_branch.started=Synchronizace větví byla spuštěna dashboard.sync_branch.started=Synchronizace větví byla spuštěna
dashboard.sync_tag.started=Synchronizace značek spuštěna dashboard.sync_tag.started=Synchronizace značek spuštěna
dashboard.rebuild_issue_indexer=Znovu sestavit index úkolů dashboard.rebuild_issue_indexer=Znovu sestavit index úkolů

View File

@ -2814,7 +2814,6 @@ dashboard.reinit_missing_repos=Alle Git-Repositories neu einlesen, für die Eint
dashboard.sync_external_users=Externe Benutzerdaten synchronisieren dashboard.sync_external_users=Externe Benutzerdaten synchronisieren
dashboard.cleanup_hook_task_table=Hook-Task-Tabelle bereinigen dashboard.cleanup_hook_task_table=Hook-Task-Tabelle bereinigen
dashboard.cleanup_packages=Veraltete Pakete löschen dashboard.cleanup_packages=Veraltete Pakete löschen
dashboard.cleanup_actions=Abgelaufene Logs und Artefakte von Actions bereinigen
dashboard.server_uptime=Server-Uptime dashboard.server_uptime=Server-Uptime
dashboard.current_goroutine=Aktuelle Goroutinen dashboard.current_goroutine=Aktuelle Goroutinen
dashboard.current_memory_usage=Aktuelle Speichernutzung dashboard.current_memory_usage=Aktuelle Speichernutzung
@ -2844,15 +2843,9 @@ dashboard.total_gc_time=Gesamte GC-Pause
dashboard.total_gc_pause=Gesamte GC-Pause dashboard.total_gc_pause=Gesamte GC-Pause
dashboard.last_gc_pause=Letzte GC-Pause dashboard.last_gc_pause=Letzte GC-Pause
dashboard.gc_times=Anzahl GC dashboard.gc_times=Anzahl GC
dashboard.delete_old_actions=Alle alten Aktionen aus der Datenbank löschen
dashboard.delete_old_actions.started=Löschen aller alten Aktionen in der Datenbank gestartet.
dashboard.update_checker=Update-Checker dashboard.update_checker=Update-Checker
dashboard.delete_old_system_notices=Alle alten Systemmeldungen aus der Datenbank löschen dashboard.delete_old_system_notices=Alle alten Systemmeldungen aus der Datenbank löschen
dashboard.gc_lfs=Garbage-Collection für LFS Meta-Objekte ausführen dashboard.gc_lfs=Garbage-Collection für LFS Meta-Objekte ausführen
dashboard.stop_zombie_tasks=Zombie-Aufgaben stoppen
dashboard.stop_endless_tasks=Endlose Aufgaben stoppen
dashboard.cancel_abandoned_jobs=Aufgegebene Jobs abbrechen
dashboard.start_schedule_tasks=Terminierte Aufgaben starten
dashboard.sync_branch.started=Synchronisierung der Branches gestartet dashboard.sync_branch.started=Synchronisierung der Branches gestartet
dashboard.sync_tag.started=Tag-Synchronisierung gestartet dashboard.sync_tag.started=Tag-Synchronisierung gestartet
dashboard.rebuild_issue_indexer=Issue-Indexer neu bauen dashboard.rebuild_issue_indexer=Issue-Indexer neu bauen

View File

@ -2704,7 +2704,6 @@ dashboard.reinit_missing_repos=Επανεκκινήστε όλα τα αποθε
dashboard.sync_external_users=Συγχρονισμός δεδομένων εξωτερικών χρηστών dashboard.sync_external_users=Συγχρονισμός δεδομένων εξωτερικών χρηστών
dashboard.cleanup_hook_task_table=Εκκαθάριση πίνακα hook_task dashboard.cleanup_hook_task_table=Εκκαθάριση πίνακα hook_task
dashboard.cleanup_packages=Εκκαθάριση ληγμένων πακέτων dashboard.cleanup_packages=Εκκαθάριση ληγμένων πακέτων
dashboard.cleanup_actions=Οι ενέργειες καθαρισμού καταγραφές και αντικείμενα
dashboard.server_uptime=Διάρκεια Διακομιστή dashboard.server_uptime=Διάρκεια Διακομιστή
dashboard.current_goroutine=Τρέχουσες Goroutines dashboard.current_goroutine=Τρέχουσες Goroutines
dashboard.current_memory_usage=Τρέχουσα Χρήση Μνήμης dashboard.current_memory_usage=Τρέχουσα Χρήση Μνήμης
@ -2734,15 +2733,9 @@ dashboard.total_gc_time=Σύνολο Παύσης GC
dashboard.total_gc_pause=Σύνολο Παύσης GC dashboard.total_gc_pause=Σύνολο Παύσης GC
dashboard.last_gc_pause=Τελευταία Παύση GC dashboard.last_gc_pause=Τελευταία Παύση GC
dashboard.gc_times=Πλήθος GC dashboard.gc_times=Πλήθος GC
dashboard.delete_old_actions=Διαγραφή όλων των παλαιών ενεργειών από τη βάση δεδομένων
dashboard.delete_old_actions.started=Η διαγραφή όλων των παλιών ενεργειών από τη βάση δεδομένων ξεκίνησε.
dashboard.update_checker=Ελεγκτής ενημερώσεων dashboard.update_checker=Ελεγκτής ενημερώσεων
dashboard.delete_old_system_notices=Διαγραφή όλων των παλιών ειδοποιήσεων συστήματος από τη βάση δεδομένων dashboard.delete_old_system_notices=Διαγραφή όλων των παλιών ειδοποιήσεων συστήματος από τη βάση δεδομένων
dashboard.gc_lfs=Συλλογή απορριμάτων στα μετα-αντικείμενα LFS dashboard.gc_lfs=Συλλογή απορριμάτων στα μετα-αντικείμενα LFS
dashboard.stop_zombie_tasks=Διακοπή εργασιών ζόμπι
dashboard.stop_endless_tasks=Διακοπή ατελείωτων εργασιών
dashboard.cancel_abandoned_jobs=Ακύρωση εγκαταλελειμμένων εργασιών
dashboard.start_schedule_tasks=Έναρξη προγραμματισμένων εργασιών
dashboard.sync_branch.started=Ο Συγχρονισμός των Κλάδων ξεκίνησε dashboard.sync_branch.started=Ο Συγχρονισμός των Κλάδων ξεκίνησε
dashboard.rebuild_issue_indexer=Αναδόμηση ευρετηρίου ζητημάτων dashboard.rebuild_issue_indexer=Αναδόμηση ευρετηρίου ζητημάτων

View File

@ -2870,7 +2870,7 @@ dashboard.reinit_missing_repos = Reinitialize all missing Git repositories for w
dashboard.sync_external_users = Synchronize external user data dashboard.sync_external_users = Synchronize external user data
dashboard.cleanup_hook_task_table = Cleanup hook_task table dashboard.cleanup_hook_task_table = Cleanup hook_task table
dashboard.cleanup_packages = Cleanup expired packages dashboard.cleanup_packages = Cleanup expired packages
dashboard.cleanup_actions = Cleanup actions expired logs and artifacts dashboard.cleanup_actions = Cleanup expired actions resources
dashboard.server_uptime = Server Uptime dashboard.server_uptime = Server Uptime
dashboard.current_goroutine = Current Goroutines dashboard.current_goroutine = Current Goroutines
dashboard.current_memory_usage = Current Memory Usage dashboard.current_memory_usage = Current Memory Usage
@ -2900,15 +2900,15 @@ dashboard.total_gc_time = Total GC Pause
dashboard.total_gc_pause = Total GC Pause dashboard.total_gc_pause = Total GC Pause
dashboard.last_gc_pause = Last GC Pause dashboard.last_gc_pause = Last GC Pause
dashboard.gc_times = GC Times dashboard.gc_times = GC Times
dashboard.delete_old_actions = Delete all old actions from database dashboard.delete_old_actions = Delete all old activities from database
dashboard.delete_old_actions.started = Delete all old actions from database started. dashboard.delete_old_actions.started = Delete all old activities from database started.
dashboard.update_checker = Update checker dashboard.update_checker = Update checker
dashboard.delete_old_system_notices = Delete all old system notices from database dashboard.delete_old_system_notices = Delete all old system notices from database
dashboard.gc_lfs = Garbage collect LFS meta objects dashboard.gc_lfs = Garbage collect LFS meta objects
dashboard.stop_zombie_tasks = Stop zombie tasks dashboard.stop_zombie_tasks = Stop actions zombie tasks
dashboard.stop_endless_tasks = Stop endless tasks dashboard.stop_endless_tasks = Stop actions endless tasks
dashboard.cancel_abandoned_jobs = Cancel abandoned jobs dashboard.cancel_abandoned_jobs = Cancel actions abandoned jobs
dashboard.start_schedule_tasks = Start schedule tasks dashboard.start_schedule_tasks = Start actions schedule tasks
dashboard.sync_branch.started = Branches Sync started dashboard.sync_branch.started = Branches Sync started
dashboard.sync_tag.started = Tags Sync started dashboard.sync_tag.started = Tags Sync started
dashboard.rebuild_issue_indexer = Rebuild issue indexer dashboard.rebuild_issue_indexer = Rebuild issue indexer
@ -3679,6 +3679,7 @@ runs.no_workflows.quick_start = Don't know how to start with Gitea Actions? See
runs.no_workflows.documentation = For more information on Gitea Actions, see <a target="_blank" rel="noopener noreferrer" href="%s">the documentation</a>. runs.no_workflows.documentation = For more information on Gitea Actions, see <a target="_blank" rel="noopener noreferrer" href="%s">the documentation</a>.
runs.no_runs = The workflow has no runs yet. runs.no_runs = The workflow has no runs yet.
runs.empty_commit_message = (empty commit message) runs.empty_commit_message = (empty commit message)
runs.expire_log_message = Logs have been purged because they were too old.
workflow.disable = Disable Workflow workflow.disable = Disable Workflow
workflow.disable_success = Workflow '%s' disabled successfully. workflow.disable_success = Workflow '%s' disabled successfully.

View File

@ -2689,7 +2689,6 @@ dashboard.reinit_missing_repos=Reiniciar todos los repositorios Git faltantes de
dashboard.sync_external_users=Sincronizar datos de usuario externo dashboard.sync_external_users=Sincronizar datos de usuario externo
dashboard.cleanup_hook_task_table=Limpiar tabla hook_task dashboard.cleanup_hook_task_table=Limpiar tabla hook_task
dashboard.cleanup_packages=Limpieza de paquetes caducados dashboard.cleanup_packages=Limpieza de paquetes caducados
dashboard.cleanup_actions=Acciones de limpieza expiradas de registros y artefactos
dashboard.server_uptime=Tiempo de actividad del servidor dashboard.server_uptime=Tiempo de actividad del servidor
dashboard.current_goroutine=Gorutinas actuales dashboard.current_goroutine=Gorutinas actuales
dashboard.current_memory_usage=Uso de memoria actual dashboard.current_memory_usage=Uso de memoria actual
@ -2719,15 +2718,9 @@ dashboard.total_gc_time=Pausa Total por GC
dashboard.total_gc_pause=Pausa Total por GC dashboard.total_gc_pause=Pausa Total por GC
dashboard.last_gc_pause=Última Pausa por GC dashboard.last_gc_pause=Última Pausa por GC
dashboard.gc_times=Ejecuciones GC dashboard.gc_times=Ejecuciones GC
dashboard.delete_old_actions=Eliminar todas las acciones antiguas de la base de datos
dashboard.delete_old_actions.started=Eliminar todas las acciones antiguas de la base de datos inicializada.
dashboard.update_checker=Buscador de actualizaciones dashboard.update_checker=Buscador de actualizaciones
dashboard.delete_old_system_notices=Borrar todos los avisos antiguos del sistema de la base de datos dashboard.delete_old_system_notices=Borrar todos los avisos antiguos del sistema de la base de datos
dashboard.gc_lfs=Recoger basura meta-objetos LFS dashboard.gc_lfs=Recoger basura meta-objetos LFS
dashboard.stop_zombie_tasks=Detener tareas zombie
dashboard.stop_endless_tasks=Detener tareas interminables
dashboard.cancel_abandoned_jobs=Cancelar trabajos abandonados
dashboard.start_schedule_tasks=Iniciar tareas programadas
dashboard.sync_branch.started=Sincronización de ramas iniciada dashboard.sync_branch.started=Sincronización de ramas iniciada
dashboard.rebuild_issue_indexer=Reconstruir indexador de incidencias dashboard.rebuild_issue_indexer=Reconstruir indexador de incidencias

View File

@ -2107,8 +2107,6 @@ dashboard.total_gc_time=کل زمان مکث GC
dashboard.total_gc_pause=کل زمان مکث GC dashboard.total_gc_pause=کل زمان مکث GC
dashboard.last_gc_pause=واپسین مکث در GC dashboard.last_gc_pause=واپسین مکث در GC
dashboard.gc_times=زمان های GC dashboard.gc_times=زمان های GC
dashboard.delete_old_actions=تمام اقدامات قدیمی را از پایگاه داده حذف کنید
dashboard.delete_old_actions.started=حذف تمام اقدامات قدیمی از پایگاه داده شروع شده است.
users.user_manage_panel=مدیریت حساب کاربری users.user_manage_panel=مدیریت حساب کاربری
users.new_account=ایجاد حساب کاربری users.new_account=ایجاد حساب کاربری

View File

@ -1764,6 +1764,7 @@ compare.compare_head=comparer
pulls.desc=Active les demandes dajouts et lévaluation du code. pulls.desc=Active les demandes dajouts et lévaluation du code.
pulls.new=Nouvelle demande d'ajout pulls.new=Nouvelle demande d'ajout
pulls.new.blocked_user=Impossible de créer une demande dajout car vous êtes bloqué par le propriétaire du dépôt. pulls.new.blocked_user=Impossible de créer une demande dajout car vous êtes bloqué par le propriétaire du dépôt.
pulls.new.must_collaborator=Vous devez être un collaborateur pour créer une demande dajout.
pulls.edit.already_changed=Impossible denregistrer la demande dajout. Il semble que le contenu ait été modifié par un autre utilisateur. Veuillez rafraîchir la page et réessayer afin déviter décraser leurs modifications. pulls.edit.already_changed=Impossible denregistrer la demande dajout. Il semble que le contenu ait été modifié par un autre utilisateur. Veuillez rafraîchir la page et réessayer afin déviter décraser leurs modifications.
pulls.view=Voir la demande d'ajout pulls.view=Voir la demande d'ajout
pulls.compare_changes=Nouvelle demande dajout pulls.compare_changes=Nouvelle demande dajout
@ -2868,7 +2869,6 @@ dashboard.reinit_missing_repos=Réinitialiser tous les dépôts Git manquants po
dashboard.sync_external_users=Synchroniser les données de lutilisateur externe dashboard.sync_external_users=Synchroniser les données de lutilisateur externe
dashboard.cleanup_hook_task_table=Nettoyer la table hook_task dashboard.cleanup_hook_task_table=Nettoyer la table hook_task
dashboard.cleanup_packages=Nettoyer des paquets expirés dashboard.cleanup_packages=Nettoyer des paquets expirés
dashboard.cleanup_actions=Nettoyer les journaux et les artefacts des actions obsolètes
dashboard.server_uptime=Uptime du serveur dashboard.server_uptime=Uptime du serveur
dashboard.current_goroutine=Goroutines actuelles dashboard.current_goroutine=Goroutines actuelles
dashboard.current_memory_usage=Utilisation Mémoire actuelle dashboard.current_memory_usage=Utilisation Mémoire actuelle
@ -2898,15 +2898,9 @@ dashboard.total_gc_time=Pause GC
dashboard.total_gc_pause=Pause GC dashboard.total_gc_pause=Pause GC
dashboard.last_gc_pause=Dernière Pause GC dashboard.last_gc_pause=Dernière Pause GC
dashboard.gc_times=Nombres de GC dashboard.gc_times=Nombres de GC
dashboard.delete_old_actions=Supprimer toutes les anciennes actions de la base de données
dashboard.delete_old_actions.started=Suppression de toutes les anciennes actions de la base de données démarrée.
dashboard.update_checker=Vérificateur de mise à jour dashboard.update_checker=Vérificateur de mise à jour
dashboard.delete_old_system_notices=Supprimer toutes les anciennes observations de la base de données dashboard.delete_old_system_notices=Supprimer toutes les anciennes observations de la base de données
dashboard.gc_lfs=Épousseter les métaobjets LFS dashboard.gc_lfs=Épousseter les métaobjets LFS
dashboard.stop_zombie_tasks=Arrêter les tâches zombies
dashboard.stop_endless_tasks=Arrêter les tâches sans fin
dashboard.cancel_abandoned_jobs=Annuler les jobs abandonnés
dashboard.start_schedule_tasks=Démarrer les tâches planifiées
dashboard.sync_branch.started=Début de la synchronisation des branches dashboard.sync_branch.started=Début de la synchronisation des branches
dashboard.sync_tag.started=Synchronisation des étiquettes dashboard.sync_tag.started=Synchronisation des étiquettes
dashboard.rebuild_issue_indexer=Reconstruire lindexeur des tickets dashboard.rebuild_issue_indexer=Reconstruire lindexeur des tickets
@ -2981,6 +2975,10 @@ emails.not_updated=Impossible de mettre à jour ladresse courriel demandée :
emails.duplicate_active=Cette adresse courriel est déjà active pour un autre utilisateur. emails.duplicate_active=Cette adresse courriel est déjà active pour un autre utilisateur.
emails.change_email_header=Mettre à jour les propriétés du courriel emails.change_email_header=Mettre à jour les propriétés du courriel
emails.change_email_text=Êtes-vous sûr de vouloir mettre à jour cette adresse courriel ? emails.change_email_text=Êtes-vous sûr de vouloir mettre à jour cette adresse courriel ?
emails.delete=Supprimer le-mail
emails.delete_desc=Êtes-vous sûr de vouloir supprimer cette adresse e-mail ?
emails.deletion_success=Ladresse e-mail a été supprimée.
emails.delete_primary_email_error=Vous ne pouvez pas supprimer le-mail principal.
orgs.org_manage_panel=Gestion des organisations orgs.org_manage_panel=Gestion des organisations
orgs.name=Nom orgs.name=Nom

View File

@ -2277,8 +2277,6 @@ dashboard.total_gc_time=Pausa Totale della GC
dashboard.total_gc_pause=Pausa Totale della GC dashboard.total_gc_pause=Pausa Totale della GC
dashboard.last_gc_pause=Ultima pausa della GC dashboard.last_gc_pause=Ultima pausa della GC
dashboard.gc_times=Esecuzioni GC dashboard.gc_times=Esecuzioni GC
dashboard.delete_old_actions=Elimina tutte le vecchie azioni dal database
dashboard.delete_old_actions.started=Elimina tutte le vecchie azioni dal database iniziate.
dashboard.update_checker=Controllore dell'aggiornamento dashboard.update_checker=Controllore dell'aggiornamento
dashboard.delete_old_system_notices=Elimina tutte le vecchie notifiche di sistema dal database dashboard.delete_old_system_notices=Elimina tutte le vecchie notifiche di sistema dal database

View File

@ -2868,7 +2868,6 @@ dashboard.reinit_missing_repos=レコードが存在するが見当たらない
dashboard.sync_external_users=外部ユーザーデータの同期 dashboard.sync_external_users=外部ユーザーデータの同期
dashboard.cleanup_hook_task_table=hook_taskテーブルのクリーンアップ dashboard.cleanup_hook_task_table=hook_taskテーブルのクリーンアップ
dashboard.cleanup_packages=期限切れパッケージのクリーンアップ dashboard.cleanup_packages=期限切れパッケージのクリーンアップ
dashboard.cleanup_actions=Actionsの期限切れのログとアーティファクトのクリーンアップ
dashboard.server_uptime=サーバーの稼働時間 dashboard.server_uptime=サーバーの稼働時間
dashboard.current_goroutine=現在のGoroutine数 dashboard.current_goroutine=現在のGoroutine数
dashboard.current_memory_usage=現在のメモリ使用量 dashboard.current_memory_usage=現在のメモリ使用量
@ -2898,15 +2897,9 @@ dashboard.total_gc_time=GC停止時間の合計
dashboard.total_gc_pause=GC停止時間の合計 dashboard.total_gc_pause=GC停止時間の合計
dashboard.last_gc_pause=前回のGC停止時間 dashboard.last_gc_pause=前回のGC停止時間
dashboard.gc_times=GC実行回数 dashboard.gc_times=GC実行回数
dashboard.delete_old_actions=データベースから古い操作履歴をすべて削除
dashboard.delete_old_actions.started=データベースからの古い操作履歴の削除を開始しました。
dashboard.update_checker=更新チェック dashboard.update_checker=更新チェック
dashboard.delete_old_system_notices=データベースから古いシステム通知をすべて削除 dashboard.delete_old_system_notices=データベースから古いシステム通知をすべて削除
dashboard.gc_lfs=LFSメタオブジェクトのガベージコレクション dashboard.gc_lfs=LFSメタオブジェクトのガベージコレクション
dashboard.stop_zombie_tasks=ゾンビタスクを停止
dashboard.stop_endless_tasks=終わらないタスクを停止
dashboard.cancel_abandoned_jobs=放置されたままのジョブをキャンセル
dashboard.start_schedule_tasks=スケジュールタスクを開始
dashboard.sync_branch.started=ブランチの同期を開始しました dashboard.sync_branch.started=ブランチの同期を開始しました
dashboard.sync_tag.started=タグの同期を開始しました dashboard.sync_tag.started=タグの同期を開始しました
dashboard.rebuild_issue_indexer=イシューインデクサーの再構築 dashboard.rebuild_issue_indexer=イシューインデクサーの再構築

View File

@ -2711,7 +2711,6 @@ dashboard.reinit_missing_repos=Atkārtoti inicializēt visus pazaudētos Git rep
dashboard.sync_external_users=Sinhronizēt ārējo lietotāju datus dashboard.sync_external_users=Sinhronizēt ārējo lietotāju datus
dashboard.cleanup_hook_task_table=Iztīrīt tīmekļa āķu vēsturi dashboard.cleanup_hook_task_table=Iztīrīt tīmekļa āķu vēsturi
dashboard.cleanup_packages=Notīrīt novecojušās pakotnes dashboard.cleanup_packages=Notīrīt novecojušās pakotnes
dashboard.cleanup_actions=Notīrīt darbību izbeigušos žurnālus un artefaktus
dashboard.server_uptime=Servera darbības laiks dashboard.server_uptime=Servera darbības laiks
dashboard.current_goroutine=Izmantotās Gorutīnas dashboard.current_goroutine=Izmantotās Gorutīnas
dashboard.current_memory_usage=Pašreiz izmantotā atmiņa dashboard.current_memory_usage=Pašreiz izmantotā atmiņa
@ -2741,15 +2740,9 @@ dashboard.total_gc_time=Kopējais GC izpildes laiks
dashboard.total_gc_pause=Kopējais GC izpildes laiks dashboard.total_gc_pause=Kopējais GC izpildes laiks
dashboard.last_gc_pause=Pedējās GC izpildes laiks dashboard.last_gc_pause=Pedējās GC izpildes laiks
dashboard.gc_times=GC reizes dashboard.gc_times=GC reizes
dashboard.delete_old_actions=Dzēst visas darbības no datu bāzes
dashboard.delete_old_actions.started=Uzsākta visu novecojušo darbību dzēšana no datu bāzes.
dashboard.update_checker=Atjauninājumu pārbaudītājs dashboard.update_checker=Atjauninājumu pārbaudītājs
dashboard.delete_old_system_notices=Dzēst vecos sistēmas paziņojumus no datubāzes dashboard.delete_old_system_notices=Dzēst vecos sistēmas paziņojumus no datubāzes
dashboard.gc_lfs=Veikt atkritumu uzkopšanas darbus LFS meta objektiem dashboard.gc_lfs=Veikt atkritumu uzkopšanas darbus LFS meta objektiem
dashboard.stop_zombie_tasks=Apturēt zombija uzdevumus
dashboard.stop_endless_tasks=Apturēt nepārtrauktus uzdevumus
dashboard.cancel_abandoned_jobs=Atcelt pamestus darbus
dashboard.start_schedule_tasks=Sākt plānotos uzdevumus
dashboard.sync_branch.started=Sākta atzaru sinhronizācija dashboard.sync_branch.started=Sākta atzaru sinhronizācija
dashboard.rebuild_issue_indexer=Pārbūvēt problēmu indeksu dashboard.rebuild_issue_indexer=Pārbūvēt problēmu indeksu

View File

@ -2053,8 +2053,6 @@ dashboard.total_gc_time=Sumaryczny czas wstrzymania przez GC
dashboard.total_gc_pause=Sumaryczny czas wstrzymania przez GC dashboard.total_gc_pause=Sumaryczny czas wstrzymania przez GC
dashboard.last_gc_pause=Ostatnie wstrzymanie przez GC dashboard.last_gc_pause=Ostatnie wstrzymanie przez GC
dashboard.gc_times=Ilość wywołań GC dashboard.gc_times=Ilość wywołań GC
dashboard.delete_old_actions=Usuń wszystkie stare akcje z bazy danych
dashboard.delete_old_actions.started=Usuwanie wszystkich starych akcji z bazy danych rozpoczęte.
users.user_manage_panel=Zarządzanie kontami użytkowników users.user_manage_panel=Zarządzanie kontami użytkowników
users.new_account=Nowy użytkownik users.new_account=Nowy użytkownik

View File

@ -2691,14 +2691,9 @@ dashboard.total_gc_time=Pausa total do GC
dashboard.total_gc_pause=Pausa total do GC dashboard.total_gc_pause=Pausa total do GC
dashboard.last_gc_pause=Última pausa do GC dashboard.last_gc_pause=Última pausa do GC
dashboard.gc_times=Nº de execuções do GC dashboard.gc_times=Nº de execuções do GC
dashboard.delete_old_actions=Excluir todas as ações antigas do banco de dados
dashboard.delete_old_actions.started=A exclusão de todas as ações antigas do banco de dados foi iniciada.
dashboard.update_checker=Verificador de atualização dashboard.update_checker=Verificador de atualização
dashboard.delete_old_system_notices=Excluir todos os avisos de sistema antigos do banco de dados dashboard.delete_old_system_notices=Excluir todos os avisos de sistema antigos do banco de dados
dashboard.gc_lfs=Coletar lixos dos meta-objetos LFS dashboard.gc_lfs=Coletar lixos dos meta-objetos LFS
dashboard.stop_zombie_tasks=Parar tarefas zumbi
dashboard.stop_endless_tasks=Parar tarefas infinitas
dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados
users.user_manage_panel=Gerenciamento de conta de usuário users.user_manage_panel=Gerenciamento de conta de usuário
users.new_account=Criar conta de usuário users.new_account=Criar conta de usuário

View File

@ -1764,6 +1764,7 @@ compare.compare_head=comparar
pulls.desc=Habilitar pedidos de integração e revisão de código. pulls.desc=Habilitar pedidos de integração e revisão de código.
pulls.new=Novo pedido de integração pulls.new=Novo pedido de integração
pulls.new.blocked_user=Não pode criar o pedido de integração porque foi bloqueado/a pelo/a proprietário/a do repositório. pulls.new.blocked_user=Não pode criar o pedido de integração porque foi bloqueado/a pelo/a proprietário/a do repositório.
pulls.new.must_collaborator=Tem de ser um/a colaborador/a para criar um pedido de integração.
pulls.edit.already_changed=Não foi possível guardar as modificações do pedido de integração. O conteúdo parece ter sido modificado por outro utilizador, entretanto. Refresque a página e tente editar de novo para evitar sobrepor as modificações dele. pulls.edit.already_changed=Não foi possível guardar as modificações do pedido de integração. O conteúdo parece ter sido modificado por outro utilizador, entretanto. Refresque a página e tente editar de novo para evitar sobrepor as modificações dele.
pulls.view=Ver pedido de integração pulls.view=Ver pedido de integração
pulls.compare_changes=Novo pedido de integração pulls.compare_changes=Novo pedido de integração
@ -2868,7 +2869,7 @@ dashboard.reinit_missing_repos=Reinicializar todos os repositórios Git em falta
dashboard.sync_external_users=Sincronizar dados externos do utilizador dashboard.sync_external_users=Sincronizar dados externos do utilizador
dashboard.cleanup_hook_task_table=Limpar tabela hook_task dashboard.cleanup_hook_task_table=Limpar tabela hook_task
dashboard.cleanup_packages=Limpar pacotes expirados dashboard.cleanup_packages=Limpar pacotes expirados
dashboard.cleanup_actions=Limpar registos e artefactos expirados das operações dashboard.cleanup_actions=Limpar recursos das operações expirados
dashboard.server_uptime=Tempo em funcionamento contínuo do servidor dashboard.server_uptime=Tempo em funcionamento contínuo do servidor
dashboard.current_goroutine=Goroutines em execução dashboard.current_goroutine=Goroutines em execução
dashboard.current_memory_usage=Utilização de memória corrente dashboard.current_memory_usage=Utilização de memória corrente
@ -2898,15 +2899,15 @@ dashboard.total_gc_time=Pausa total da recolha de lixo
dashboard.total_gc_pause=Pausa total da recolha de lixo dashboard.total_gc_pause=Pausa total da recolha de lixo
dashboard.last_gc_pause=Última pausa da recolha de lixo dashboard.last_gc_pause=Última pausa da recolha de lixo
dashboard.gc_times=N.º de recolhas de lixo dashboard.gc_times=N.º de recolhas de lixo
dashboard.delete_old_actions=Eliminar todas as operações antigas da base de dados dashboard.delete_old_actions=Eliminar todo o trabalho antigo da base de dados
dashboard.delete_old_actions.started=Foi iniciado o processo de eliminação de todas as operações antigas da base de dados. dashboard.delete_old_actions.started=Foi iniciado o processo de eliminação de todo o trabalho antigo da base de dados.
dashboard.update_checker=Verificador de novas versões dashboard.update_checker=Verificador de novas versões
dashboard.delete_old_system_notices=Eliminar todas as notificações do sistema antigas da base de dados dashboard.delete_old_system_notices=Eliminar todas as notificações do sistema antigas da base de dados
dashboard.gc_lfs=Recolher lixo dos meta-elementos LFS dashboard.gc_lfs=Recolher lixo dos meta-elementos LFS
dashboard.stop_zombie_tasks=Parar tarefas zombies dashboard.stop_zombie_tasks=Parar tarefas zombie das operações
dashboard.stop_endless_tasks=Parar tarefas intermináveis dashboard.stop_endless_tasks=Parar tarefas intermináveis das operações
dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados das operações
dashboard.start_schedule_tasks=Iniciar tarefas de agendamento dashboard.start_schedule_tasks=Iniciar tarefas de agendamento das operações
dashboard.sync_branch.started=Sincronização de ramos iniciada dashboard.sync_branch.started=Sincronização de ramos iniciada
dashboard.sync_tag.started=Sincronização de etiquetas iniciada dashboard.sync_tag.started=Sincronização de etiquetas iniciada
dashboard.rebuild_issue_indexer=Reconstruir indexador de questões dashboard.rebuild_issue_indexer=Reconstruir indexador de questões
@ -3677,6 +3678,7 @@ runs.no_workflows.quick_start=Não sabe como começar com o Gitea Actions? Veja
runs.no_workflows.documentation=Para mais informação sobre o Gitea Actions veja <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>. runs.no_workflows.documentation=Para mais informação sobre o Gitea Actions veja <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
runs.no_runs=A sequência de trabalho ainda não foi executada. runs.no_runs=A sequência de trabalho ainda não foi executada.
runs.empty_commit_message=(mensagem de cometimento vazia) runs.empty_commit_message=(mensagem de cometimento vazia)
runs.expire_log_message=Os registros foram removidos porque eram muito antigos.
workflow.disable=Desabilitar sequência de trabalho workflow.disable=Desabilitar sequência de trabalho
workflow.disable_success=A sequência de trabalho '%s' foi desabilitada com sucesso. workflow.disable_success=A sequência de trabalho '%s' foi desabilitada com sucesso.
@ -3703,6 +3705,7 @@ variables.update.failed=Falha ao editar a variável.
variables.update.success=A variável foi editada. variables.update.success=A variável foi editada.
[projects] [projects]
deleted.display_name=Planeamento eliminado
type-1.display_name=Planeamento individual type-1.display_name=Planeamento individual
type-2.display_name=Planeamento do repositório type-2.display_name=Planeamento do repositório
type-3.display_name=Planeamento da organização type-3.display_name=Planeamento da organização

View File

@ -2679,15 +2679,9 @@ dashboard.total_gc_time=Итоговая задержка GC
dashboard.total_gc_pause=Итоговая задержка GC dashboard.total_gc_pause=Итоговая задержка GC
dashboard.last_gc_pause=Последняя пауза сборщика мусора dashboard.last_gc_pause=Последняя пауза сборщика мусора
dashboard.gc_times=Количество сборок мусора dashboard.gc_times=Количество сборок мусора
dashboard.delete_old_actions=Удалите все старые действия из базы данных
dashboard.delete_old_actions.started=Удалите все старые действия из запущенной базы данных.
dashboard.update_checker=Проверка обновлений dashboard.update_checker=Проверка обновлений
dashboard.delete_old_system_notices=Удалить все старые системные уведомления из базы данных dashboard.delete_old_system_notices=Удалить все старые системные уведомления из базы данных
dashboard.gc_lfs=Выполнить сборку мусора метаобъектов LFS dashboard.gc_lfs=Выполнить сборку мусора метаобъектов LFS
dashboard.stop_zombie_tasks=Остановить задания-зомби
dashboard.stop_endless_tasks=Остановить бесконечные задания
dashboard.cancel_abandoned_jobs=Отменить брошенные задания
dashboard.start_schedule_tasks=Запустить запланированные задания
users.user_manage_panel=Панель управления пользователями users.user_manage_panel=Панель управления пользователями
users.new_account=Создать новый аккаунт users.new_account=Создать новый аккаунт

View File

@ -2067,8 +2067,6 @@ dashboard.total_gc_time=මුළු GC විරාමය
dashboard.total_gc_pause=මුළු GC විරාමය dashboard.total_gc_pause=මුළු GC විරාමය
dashboard.last_gc_pause=අවසන් GC විරාමය dashboard.last_gc_pause=අවසන් GC විරාමය
dashboard.gc_times=GC ටයිම්ස් dashboard.gc_times=GC ටයිම්ස්
dashboard.delete_old_actions=සියලු පැරණි ක්රියා දත්ත සමුදායෙන් මකන්න
dashboard.delete_old_actions.started=දත්ත සමුදාය ආරම්භ සිට සියලු පැරණි ක්රියා මකන්න.
users.user_manage_panel=පරිශීලක ගිණුම් කළමනාකරණය users.user_manage_panel=පරිශීලක ගිණුම් කළමනාකරණය
users.new_account=පරිශීලක ගිණුමක් සාදන්න users.new_account=පරිශීලක ගිණුමක් සාදන්න

View File

@ -93,6 +93,7 @@ remove_all=Tümünü Kaldır
remove_label_str=`"%s" öğesini kaldır` remove_label_str=`"%s" öğesini kaldır`
edit=Düzenle edit=Düzenle
view=Görüntüle view=Görüntüle
test=Sınama
enabled=Aktifleştirilmiş enabled=Aktifleştirilmiş
disabled=Devre Dışı disabled=Devre Dışı
@ -386,6 +387,8 @@ relevant_repositories=Sadece ilişkili depolar gösteriliyor, <a href="%s">süz
[auth] [auth]
create_new_account=Hesap Oluştur create_new_account=Hesap Oluştur
already_have_account=Zaten bir hesabınız var mı?
sign_in_now=Şimdi oturum açın!
disable_register_prompt=Kayıt işlemi devre dışıdır. Lütfen site yöneticinizle iletişim kurun. disable_register_prompt=Kayıt işlemi devre dışıdır. Lütfen site yöneticinizle iletişim kurun.
disable_register_mail=Kayıt için e-posta doğrulama devre dışıdır. disable_register_mail=Kayıt için e-posta doğrulama devre dışıdır.
manual_activation_only=Etkinleştirmeyi tamamlamak için site yöneticinizle bağlantıya geçin. manual_activation_only=Etkinleştirmeyi tamamlamak için site yöneticinizle bağlantıya geçin.
@ -393,6 +396,8 @@ remember_me=Bu Aygıtı hatırla
remember_me.compromised=Oturum açma tokeni artık geçerli değil, bu ele geçirilmiş bir hesaba işaret ediyor olabilir. Lütfen hesabınızda olağandışı faaliyet olup olmadığını denetleyin. remember_me.compromised=Oturum açma tokeni artık geçerli değil, bu ele geçirilmiş bir hesaba işaret ediyor olabilir. Lütfen hesabınızda olağandışı faaliyet olup olmadığını denetleyin.
forgot_password_title=Şifremi unuttum forgot_password_title=Şifremi unuttum
forgot_password=Şifrenizi mi unuttunuz? forgot_password=Şifrenizi mi unuttunuz?
need_account=Bir hesaba mı ihtiyacın var?
sign_up_now=Hemen kaydolun.
sign_up_successful=Hesap başarılı bir şekilde oluşturuldu. Hoşgeldiniz! sign_up_successful=Hesap başarılı bir şekilde oluşturuldu. Hoşgeldiniz!
confirmation_mail_sent_prompt_ex=Yeni bir doğrulama e-postası <b>%s</b> adresine gönderildi. Lütfen kayıt sürecini tamamlamak için %s içinde gelen kutunuzu denetleyin. Eğer kayıt e-posta adresiniz hatalı ise, tekrar oturum açıp değiştirebilirsiniz. confirmation_mail_sent_prompt_ex=Yeni bir doğrulama e-postası <b>%s</b> adresine gönderildi. Lütfen kayıt sürecini tamamlamak için %s içinde gelen kutunuzu denetleyin. Eğer kayıt e-posta adresiniz hatalı ise, tekrar oturum açıp değiştirebilirsiniz.
must_change_password=Parolanızı güncelleyin must_change_password=Parolanızı güncelleyin
@ -433,6 +438,7 @@ oauth_signin_submit=Hesabı Bağla
oauth.signin.error=Yetkilendirme isteğini işlerken bir hata oluştu. Eğer hata devam ederse lütfen site yöneticisiyle bağlantıya geçin. oauth.signin.error=Yetkilendirme isteğini işlerken bir hata oluştu. Eğer hata devam ederse lütfen site yöneticisiyle bağlantıya geçin.
oauth.signin.error.access_denied=Yetkilendirme isteği reddedildi. oauth.signin.error.access_denied=Yetkilendirme isteği reddedildi.
oauth.signin.error.temporarily_unavailable=Yetkilendirme sunucusu geçici olarak erişilemez olduğu için yetkilendirme başarısız oldu. Lütfen daha sonra tekrar deneyin. oauth.signin.error.temporarily_unavailable=Yetkilendirme sunucusu geçici olarak erişilemez olduğu için yetkilendirme başarısız oldu. Lütfen daha sonra tekrar deneyin.
oauth_callback_unable_auto_reg=Otomatik kayıt etkin ancak OAuth2 Sağlayıcı %[1] eksik sahalar döndürdü: %[2]s, otomatik olarak hesap oluşturulamıyor, lütfen bir hesap oluşturun veya bağlantı verin, veya site yöneticisiyle iletişim kurun.
openid_connect_submit=Bağlan openid_connect_submit=Bağlan
openid_connect_title=Mevcut olan bir hesaba bağlan openid_connect_title=Mevcut olan bir hesaba bağlan
openid_connect_desc=Seçilen OpenID URI'si bilinmiyor. Burada yeni bir hesapla ilişkilendir. openid_connect_desc=Seçilen OpenID URI'si bilinmiyor. Burada yeni bir hesapla ilişkilendir.
@ -453,6 +459,8 @@ sspi_auth_failed=SSPI kimlik doğrulaması başarısız oldu
password_pwned=Seçtiğiniz parola, daha önce herkese açık veri ihlallerinde açığa çıkan bir <a target="_blank" rel="noopener noreferrer" href="https://haveibeenpwned.com/Passwords">çalınan parola listesindedir</a>. Lütfen farklı bir parola ile tekrar deneyin ve başka yerlerde de bu parolayı değiştirmeyi düşünün. password_pwned=Seçtiğiniz parola, daha önce herkese açık veri ihlallerinde açığa çıkan bir <a target="_blank" rel="noopener noreferrer" href="https://haveibeenpwned.com/Passwords">çalınan parola listesindedir</a>. Lütfen farklı bir parola ile tekrar deneyin ve başka yerlerde de bu parolayı değiştirmeyi düşünün.
password_pwned_err=HaveIBeenPwned'e yapılan istek tamamlanamadı password_pwned_err=HaveIBeenPwned'e yapılan istek tamamlanamadı
last_admin=Son yöneticiyi silemezsiniz. En azından bir yönetici olmalıdır. last_admin=Son yöneticiyi silemezsiniz. En azından bir yönetici olmalıdır.
signin_passkey=Bir parola anahtarı ile oturum aç
back_to_sign_in=Oturum Açmaya geri dön
[mail] [mail]
view_it_on=%s üzerinde görüntüle view_it_on=%s üzerinde görüntüle
@ -469,6 +477,7 @@ activate_email=E-posta adresinizi doğrulayın
activate_email.title=%s, lütfen e-posta adresinizi doğrulayın activate_email.title=%s, lütfen e-posta adresinizi doğrulayın
activate_email.text=E posta adresinizi doğrulamak için lütfen <b>%s</b> içinde linke tıklayın: activate_email.text=E posta adresinizi doğrulamak için lütfen <b>%s</b> içinde linke tıklayın:
register_notify=%s'ya Hoş Geldiniz
register_notify.title=%[1]s, %[2]s e hoşgeldiniz register_notify.title=%[1]s, %[2]s e hoşgeldiniz
register_notify.text_1=bu %s için kayıt onay e postanızdır! register_notify.text_1=bu %s için kayıt onay e postanızdır!
register_notify.text_2=Artık %s kullanıcı adı ile oturum açabilirsiniz. register_notify.text_2=Artık %s kullanıcı adı ile oturum açabilirsiniz.
@ -760,6 +769,7 @@ manage_openid=OpenID Adreslerini Yönet
email_desc=Ana e-posta adresiniz bildirimler, parola kurtarma ve gizlenmemişse eğer web tabanlı Git işlemleri için kullanılacaktır. email_desc=Ana e-posta adresiniz bildirimler, parola kurtarma ve gizlenmemişse eğer web tabanlı Git işlemleri için kullanılacaktır.
theme_desc=Bu, sitedeki varsayılan temanız olacak. theme_desc=Bu, sitedeki varsayılan temanız olacak.
theme_colorblindness_help=Renk Körlüğü için Tema Desteği theme_colorblindness_help=Renk Körlüğü için Tema Desteği
theme_colorblindness_prompt=Gitea temel renk körlüğü desteği olan, yalnızca az sayıda rengin tanımlı olduğu, sadece birkaç temaya sahip. Çalışmalar sürüyor. Tema CSS dosyalarında daha çok renk tanımlanmasıyla daha fazla iyileştirme yapılabilir.
primary=Birincil primary=Birincil
activated=Aktifleştirildi activated=Aktifleştirildi
requires_activation=Etkinleştirme gerekiyor requires_activation=Etkinleştirme gerekiyor
@ -904,6 +914,7 @@ create_oauth2_application_success=Yeni bir OAuth2 uygulamasını başarıyla olu
update_oauth2_application_success=OAuth2 uygulamasını başarıyla güncellediniz. update_oauth2_application_success=OAuth2 uygulamasını başarıyla güncellediniz.
oauth2_application_name=Uygulama Adı oauth2_application_name=Uygulama Adı
oauth2_confidential_client=Güvenli İstemci. Web uygulamaları gibi sırları güvende tutan uygulamalar için bunu seçin. Masaüstü ve mobil uygulamaları da içeren doğal uygulamalar için seçmeyin. oauth2_confidential_client=Güvenli İstemci. Web uygulamaları gibi sırları güvende tutan uygulamalar için bunu seçin. Masaüstü ve mobil uygulamaları da içeren doğal uygulamalar için seçmeyin.
oauth2_skip_secondary_authorization=Herkese açık istemcilerin yetkilendirilmesini bir kere erişim izni verdikten sonra atla. <strong>Bu bir güvenlik riski oluşturabilir.</strong>
oauth2_redirect_uris=Yönlendirme URI'leri. Lütfen her bir URI'yi yeni bir satıra yazın. oauth2_redirect_uris=Yönlendirme URI'leri. Lütfen her bir URI'yi yeni bir satıra yazın.
save_application=Kaydet save_application=Kaydet
oauth2_client_id=İstemci Kimliği oauth2_client_id=İstemci Kimliği
@ -1232,6 +1243,7 @@ file_view_rendered=Oluşturulanları Görüntüle
file_view_raw=Ham Görünüm file_view_raw=Ham Görünüm
file_permalink=Kalıcı Bağlantı file_permalink=Kalıcı Bağlantı
file_too_large=Bu dosya görüntülemek için çok büyük. file_too_large=Bu dosya görüntülemek için çok büyük.
file_is_empty=Dosya boş.
code_preview_line_from_to=%[3]s içinde %[1]d ve %[2]d arasındaki satırlar code_preview_line_from_to=%[3]s içinde %[1]d ve %[2]d arasındaki satırlar
code_preview_line_in=%[2]s içinde %[1]d satırı code_preview_line_in=%[2]s içinde %[1]d satırı
invisible_runes_header=`Bu dosya görünmez Evrensel Kodlu karakter içeriyor` invisible_runes_header=`Bu dosya görünmez Evrensel Kodlu karakter içeriyor`
@ -1372,6 +1384,7 @@ commitstatus.success=Başarılı
ext_issues=Harici Konulara Erişim ext_issues=Harici Konulara Erişim
ext_issues.desc=Dışsal konu takip sistemine bağla. ext_issues.desc=Dışsal konu takip sistemine bağla.
projects.desc=Proje panolarındaki konuları ve değişiklikleri yönetin.
projects.description=ıklama (isteğe bağlı) projects.description=ıklama (isteğe bağlı)
projects.description_placeholder=ıklama projects.description_placeholder=ıklama
projects.create=Proje Oluştur projects.create=Proje Oluştur
@ -1433,7 +1446,7 @@ issues.new.closed_milestone=Kapanmış Kilometre Taşları
issues.new.assignees=Atananlar issues.new.assignees=Atananlar
issues.new.clear_assignees=Atamaları Temizle issues.new.clear_assignees=Atamaları Temizle
issues.new.no_assignees=Atanan Kişi Yok issues.new.no_assignees=Atanan Kişi Yok
issues.new.no_reviewers=Değerlendirici yok issues.new.no_reviewers=Gözden geçiren yok
issues.new.blocked_user=Konu oluşturulamıyor, depo sahibi tarafından engellenmişsiniz. issues.new.blocked_user=Konu oluşturulamıyor, depo sahibi tarafından engellenmişsiniz.
issues.edit.already_changed=Konuya yapılan değişiklikler kaydedilemiyor. İçerik başka kullanıcı tarafından değiştirilmiş gözüküyor. Diğerlerinin değişikliklerinin üzerine yazmamak için lütfen sayfayı yenileyin ve tekrar düzenlemeye çalışın issues.edit.already_changed=Konuya yapılan değişiklikler kaydedilemiyor. İçerik başka kullanıcı tarafından değiştirilmiş gözüküyor. Diğerlerinin değişikliklerinin üzerine yazmamak için lütfen sayfayı yenileyin ve tekrar düzenlemeye çalışın
issues.edit.blocked_user=İçerik düzenlenemiyor, gönderen veya depo sahibi tarafından engellenmişsiniz. issues.edit.blocked_user=İçerik düzenlenemiyor, gönderen veya depo sahibi tarafından engellenmişsiniz.
@ -1547,7 +1560,9 @@ issues.no_content=Herhangi bir açıklama sağlanmadı.
issues.close=Konuyu Kapat issues.close=Konuyu Kapat
issues.comment_pull_merged_at=%[1]s işlemesi, %[2]s dalına birleştirildi %[3]s issues.comment_pull_merged_at=%[1]s işlemesi, %[2]s dalına birleştirildi %[3]s
issues.comment_manually_pull_merged_at=%[1]s işlemesi, %[2]s dalına elle birleştirildi %[3]s issues.comment_manually_pull_merged_at=%[1]s işlemesi, %[2]s dalına elle birleştirildi %[3]s
issues.close_comment_issue=Yorum Yap ve Kapat
issues.reopen_issue=Yeniden aç issues.reopen_issue=Yeniden aç
issues.reopen_comment_issue=Yorum Yap ve Yeniden Aç
issues.create_comment=Yorum yap issues.create_comment=Yorum yap
issues.comment.blocked_user=Yorum oluşturulamıyor veya düzenlenemiyor, gönderen veya depo sahibi tarafından engellenmişsiniz. issues.comment.blocked_user=Yorum oluşturulamıyor veya düzenlenemiyor, gönderen veya depo sahibi tarafından engellenmişsiniz.
issues.closed_at=`<a id="%[1]s" href="#%[1]s">%[2]s</a> konusunu kapattı` issues.closed_at=`<a id="%[1]s" href="#%[1]s">%[2]s</a> konusunu kapattı`
@ -1749,6 +1764,7 @@ compare.compare_head=karşılaştır
pulls.desc=Değişiklik isteklerini ve kod incelemelerini etkinleştir. pulls.desc=Değişiklik isteklerini ve kod incelemelerini etkinleştir.
pulls.new=Yeni Değişiklik İsteği pulls.new=Yeni Değişiklik İsteği
pulls.new.blocked_user=Değişiklik isteği oluşturulamıyor, depo sahibi tarafından engellenmişsiniz. pulls.new.blocked_user=Değişiklik isteği oluşturulamıyor, depo sahibi tarafından engellenmişsiniz.
pulls.new.must_collaborator=Değişiklik isteği oluşturmak için bir katkıcı olmalısınız.
pulls.edit.already_changed=Değişiklik isteğine yapılan değişiklikler kaydedilemiyor. İçerik başka kullanıcı tarafından değiştirilmiş gözüküyor. Diğerlerinin değişikliklerinin üzerine yazmamak için lütfen sayfayı yenileyin ve tekrar düzenlemeye çalışın pulls.edit.already_changed=Değişiklik isteğine yapılan değişiklikler kaydedilemiyor. İçerik başka kullanıcı tarafından değiştirilmiş gözüküyor. Diğerlerinin değişikliklerinin üzerine yazmamak için lütfen sayfayı yenileyin ve tekrar düzenlemeye çalışın
pulls.view=Değişiklik İsteği Görüntüle pulls.view=Değişiklik İsteği Görüntüle
pulls.compare_changes=Yeni Değişiklik İsteği pulls.compare_changes=Yeni Değişiklik İsteği
@ -1806,7 +1822,7 @@ pulls.required_status_check_failed=Bazı gerekli denetimler başarılı olmadı.
pulls.required_status_check_missing=Gerekli bazı kontroller eksik. pulls.required_status_check_missing=Gerekli bazı kontroller eksik.
pulls.required_status_check_administrator=Yönetici olarak, bu değişiklik isteğini yine de birleştirebilirsiniz. pulls.required_status_check_administrator=Yönetici olarak, bu değişiklik isteğini yine de birleştirebilirsiniz.
pulls.blocked_by_approvals=Bu değişiklik isteğinin henüz yeterli onayı yok. %d onay var, %d onay gerekiyor. pulls.blocked_by_approvals=Bu değişiklik isteğinin henüz yeterli onayı yok. %d onay var, %d onay gerekiyor.
pulls.blocked_by_rejection=Bu değişiklik isteğinde resmi bir inceleyici tarafından istenen değişiklikler var. pulls.blocked_by_rejection=Bu değişiklik isteğinde resmi bir gözden geçiren tarafından istenen değişiklikler var.
pulls.blocked_by_official_review_requests=Bu değişiklik isteğinde resmi inceleme istekleri var. pulls.blocked_by_official_review_requests=Bu değişiklik isteğinde resmi inceleme istekleri var.
pulls.blocked_by_outdated_branch=Bu değişiklik isteği eskidiği için engellendi. pulls.blocked_by_outdated_branch=Bu değişiklik isteği eskidiği için engellendi.
pulls.blocked_by_changed_protected_files_1=Bu değişiklik isteği, korumalı bir dosyayı değiştirdiği için engellendi: pulls.blocked_by_changed_protected_files_1=Bu değişiklik isteği, korumalı bir dosyayı değiştirdiği için engellendi:
@ -1920,7 +1936,7 @@ milestones.edit_success=`"%s" dönüm noktası güncellendi.`
milestones.deletion=Kilometre Taşını Sil milestones.deletion=Kilometre Taşını Sil
milestones.deletion_desc=Bir kilometre taşını silmek, onu ilgili tüm sorunlardan kaldırır. Devam edilsin mi? milestones.deletion_desc=Bir kilometre taşını silmek, onu ilgili tüm sorunlardan kaldırır. Devam edilsin mi?
milestones.deletion_success=Kilometre taşı silindi. milestones.deletion_success=Kilometre taşı silindi.
milestones.filter_sort.name=İsim milestones.filter_sort.name=Ad
milestones.filter_sort.earliest_due_data=En erken bitiş tarihi milestones.filter_sort.earliest_due_data=En erken bitiş tarihi
milestones.filter_sort.latest_due_date=En uzak bitiş tarihi milestones.filter_sort.latest_due_date=En uzak bitiş tarihi
milestones.filter_sort.least_complete=En az tamamlama milestones.filter_sort.least_complete=En az tamamlama
@ -2266,6 +2282,7 @@ settings.event_wiki_desc=Viki sayfası oluşturuldu, adı değiştirildi, düzen
settings.event_release=Sürüm settings.event_release=Sürüm
settings.event_release_desc=Sürüm yayınlandığında, güncellendiğinde veya silindiğinde. settings.event_release_desc=Sürüm yayınlandığında, güncellendiğinde veya silindiğinde.
settings.event_push=Çek settings.event_push=Çek
settings.event_force_push=Zorla İtme
settings.event_push_desc=Depo ittirildiğinde. settings.event_push_desc=Depo ittirildiğinde.
settings.event_repository=Depo settings.event_repository=Depo
settings.event_repository_desc=Depo oluşturuldu veya silindi. settings.event_repository_desc=Depo oluşturuldu veya silindi.
@ -2359,10 +2376,28 @@ settings.protect_this_branch=Dal Korumayı Etkinleştir
settings.protect_this_branch_desc=Silmeyi önler ve dala Git gönderimini ve birleştirmesini kısıtlar. settings.protect_this_branch_desc=Silmeyi önler ve dala Git gönderimini ve birleştirmesini kısıtlar.
settings.protect_disable_push=İtmeyi Devre Dışı Bırak settings.protect_disable_push=İtmeyi Devre Dışı Bırak
settings.protect_disable_push_desc=Bu dala itme yapılmasına izin verilmeyecek. settings.protect_disable_push_desc=Bu dala itme yapılmasına izin verilmeyecek.
settings.protect_disable_force_push=Zorla İtmeyi Devre Dışı Bırak
settings.protect_disable_force_push_desc=Bu dala zorla itme yapılmasına izin verilmeyecek.
settings.protect_enable_push=İtmeyi Etkinleştir settings.protect_enable_push=İtmeyi Etkinleştir
settings.protect_enable_push_desc=Yazma erişimi olan herkesin bu dala itmesine izin verilir (ancak zorla itmeyin). settings.protect_enable_push_desc=Yazma erişimi olan herkesin bu dala itmesine izin verilir (ancak zorla itmeyin).
settings.protect_enable_force_push_all=Zorla İtmeyi Etkinleştir
settings.protect_enable_force_push_all_desc=İtme erişimi olan herhangi bir kimse, bu dala zorla itme yapabilecektir.
settings.protect_enable_force_push_allowlist=Kısıtlanmış Zorla İtme İzin Listesi
settings.protect_enable_force_push_allowlist_desc=Sadece beyaz listedeki itme erişimi olan kişi veya takımlar, bu dala zorla itme yapabilecektir.
settings.protect_enable_merge=Birleştirmeyi Etkinleştir settings.protect_enable_merge=Birleştirmeyi Etkinleştir
settings.protect_enable_merge_desc=Yazma erişimi olan herhangi bir kimse, değişiklik isteklerini bu dala birleştirebilecektir. settings.protect_enable_merge_desc=Yazma erişimi olan herhangi bir kimse, değişiklik isteklerini bu dala birleştirebilecektir.
settings.protect_whitelist_committers=Beyaz Liste Kısıtlı Gönderme
settings.protect_whitelist_committers_desc=Sadece izin listesine alınmış kullanıcıların veya takımların bu dala göndermesine izin verilir (ancak zorla itme yok).
settings.protect_whitelist_deploy_keys=İzin listesi göndermek için yazma erişimi olan anahtarları dağıtır.
settings.protect_whitelist_users=İtme için izin listesindeki kullanıcılar:
settings.protect_whitelist_teams=İtme için izin listesindeki takımlar:
settings.protect_force_push_allowlist_users=Zorla itme izin listesine eklenmiş kullanıcılar:
settings.protect_force_push_allowlist_teams=Zorla itme izin listesine eklenmiş ekipler:
settings.protect_force_push_allowlist_deploy_keys=Zorla itme için itme izni olan dağıtım anahtarları izin listesi.
settings.protect_merge_whitelist_committers=Birleştirme İzin Listesini Etkinleştir
settings.protect_merge_whitelist_committers_desc=Yalnızca izin listesindeki kullanıcıların veya takımların bu daldaki değişiklik isteklerini birleştirmesine izin verin.
settings.protect_merge_whitelist_users=Birleştirme için izin listesindeki kullanıcılar:
settings.protect_merge_whitelist_teams=Birleştirme için izin listesindeki takımlar:
settings.protect_check_status_contexts=Durum Denetimini Etkinleştir settings.protect_check_status_contexts=Durum Denetimini Etkinleştir
settings.protect_status_check_patterns=Durum denetleme desenleri: settings.protect_status_check_patterns=Durum denetleme desenleri:
settings.protect_status_check_patterns_desc=Bu kurala uyan dala diğer dallar birleştirilmeden önce başarılı olması gereken durum denetlemelerini belirten desenleri girin. Her bir satır bir desen tanımlıyor. Desenler boş olamaz. settings.protect_status_check_patterns_desc=Bu kurala uyan dala diğer dallar birleştirilmeden önce başarılı olması gereken durum denetlemelerini belirten desenleri girin. Her bir satır bir desen tanımlıyor. Desenler boş olamaz.
@ -2373,6 +2408,10 @@ settings.protect_invalid_status_check_pattern=Hatalı durum denetleme deseni: "%
settings.protect_no_valid_status_check_patterns=Geçerli durum denetleme deseni yok. settings.protect_no_valid_status_check_patterns=Geçerli durum denetleme deseni yok.
settings.protect_required_approvals=Gerekli onaylar: settings.protect_required_approvals=Gerekli onaylar:
settings.protect_required_approvals_desc=Değişiklik isteğini yalnızca yeterince olumlu yorumla birleştirmeye izin ver. settings.protect_required_approvals_desc=Değişiklik isteğini yalnızca yeterince olumlu yorumla birleştirmeye izin ver.
settings.protect_approvals_whitelist_enabled=Onayları izin listesine giren kullanıcılar veya takımlar için kısıtla
settings.protect_approvals_whitelist_enabled_desc=Yalnızca izin listesindeki kullanıcıların veya takımların gözden geçirmeleri gerekli onaylar için dikkate alınır. Onaylı izin listesi olmadan, yazma erişimi olan herkesin gözden geçirmeleri gerekli onaylar için dikkate alınır.
settings.protect_approvals_whitelist_users=İzin listesindeki gözden geçirenler:
settings.protect_approvals_whitelist_teams=Gözden geçirme için izin listesindeki takımlar:
settings.dismiss_stale_approvals=Eski onayları reddet settings.dismiss_stale_approvals=Eski onayları reddet
settings.dismiss_stale_approvals_desc=Değişiklik isteğinin içeriğini değiştiren yeni işlemeler dala itildiğinde, eski onaylar reddedilir. settings.dismiss_stale_approvals_desc=Değişiklik isteğinin içeriğini değiştiren yeni işlemeler dala itildiğinde, eski onaylar reddedilir.
settings.ignore_stale_approvals=Eskimiş onayları yoksay settings.ignore_stale_approvals=Eskimiş onayları yoksay
@ -2394,7 +2433,7 @@ settings.remove_protected_branch_failed=Dal koruma kuralı "%s" kaldırılamadı
settings.protected_branch_deletion=Dal Korumasını Devre Dışı Bırak settings.protected_branch_deletion=Dal Korumasını Devre Dışı Bırak
settings.protected_branch_deletion_desc=Dal korumasını devre dışı bırakmak, kullanıcıların dalı itmek için yazma izni olmasını sağlar. Devam edilsin mi? settings.protected_branch_deletion_desc=Dal korumasını devre dışı bırakmak, kullanıcıların dalı itmek için yazma izni olmasını sağlar. Devam edilsin mi?
settings.block_rejected_reviews=Reddedilen incelemelerde birleştirmeyi engelle settings.block_rejected_reviews=Reddedilen incelemelerde birleştirmeyi engelle
settings.block_rejected_reviews_desc=Yeterli onay olsa bile resmi inceleyiciler tarafından değişiklik istendiğinde birleşme mümkün olmayacaktır. settings.block_rejected_reviews_desc=Yeterli onay olsa bile resmi gözden geçirenler tarafından değişiklik istendiğinde birleşme mümkün olmayacaktır.
settings.block_on_official_review_requests=Resmi inceleme isteklerinde birleştirmeyi engelle settings.block_on_official_review_requests=Resmi inceleme isteklerinde birleştirmeyi engelle
settings.block_on_official_review_requests_desc=Yeterli onay olsa bile, resmi inceleme istekleri olduğunda birleştirme mümkün olmayacaktır. settings.block_on_official_review_requests_desc=Yeterli onay olsa bile, resmi inceleme istekleri olduğunda birleştirme mümkün olmayacaktır.
settings.block_outdated_branch=Değişiklik isteği güncel değilse birleştirmeyi engelle settings.block_outdated_branch=Değişiklik isteği güncel değilse birleştirmeyi engelle
@ -2860,15 +2899,15 @@ dashboard.total_gc_time=Toplam GC Durması
dashboard.total_gc_pause=Toplam GC Durması dashboard.total_gc_pause=Toplam GC Durması
dashboard.last_gc_pause=Son GC Durması dashboard.last_gc_pause=Son GC Durması
dashboard.gc_times=GC Zamanları dashboard.gc_times=GC Zamanları
dashboard.delete_old_actions=Veritabanından tüm eski eylemleri sil dashboard.delete_old_actions=Veritabanından tüm eski faaliyetleri sil
dashboard.delete_old_actions.started=Veritabanından başlatılan tüm eski eylemleri silin. dashboard.delete_old_actions.started=Veritabanından başlatılan tüm eski faaliyetleri silin.
dashboard.update_checker=Denetleyiciyi güncelle dashboard.update_checker=Denetleyiciyi güncelle
dashboard.delete_old_system_notices=Veritabanından tüm eski sistem bildirimlerini sil dashboard.delete_old_system_notices=Veritabanından tüm eski sistem bildirimlerini sil
dashboard.gc_lfs=LFS üst nesnelerin atıklarını temizle dashboard.gc_lfs=LFS üst nesnelerin atıklarını temizle
dashboard.stop_zombie_tasks=Zombi görevleri durdur dashboard.stop_zombie_tasks=Zombi görevlerin durdurma eylemleri
dashboard.stop_endless_tasks=Daimi görevleri durdur dashboard.stop_endless_tasks=Daimi görevlerin durdurma eylemleri
dashboard.cancel_abandoned_jobs=Terkedilmiş görevleri iptal et dashboard.cancel_abandoned_jobs=Terkedilmiş görevlerin iptal eylemleri
dashboard.start_schedule_tasks=Zamanlanmış görevleri başlat dashboard.start_schedule_tasks=Zamanlanmış görevlerin başlatma eylemleri
dashboard.sync_branch.started=Dal Eşzamanlaması başladı dashboard.sync_branch.started=Dal Eşzamanlaması başladı
dashboard.sync_tag.started=Etiket eşitlemesi başladı dashboard.sync_tag.started=Etiket eşitlemesi başladı
dashboard.rebuild_issue_indexer=Konu indeksini yeniden oluştur dashboard.rebuild_issue_indexer=Konu indeksini yeniden oluştur
@ -2943,6 +2982,10 @@ emails.not_updated=İstenen e-posta adresi güncellenemedi: %v
emails.duplicate_active=Bu e-posta adresi farklı bir kullanıcı için zaten aktif. emails.duplicate_active=Bu e-posta adresi farklı bir kullanıcı için zaten aktif.
emails.change_email_header=E-posta Özelliklerini Güncelle emails.change_email_header=E-posta Özelliklerini Güncelle
emails.change_email_text=Bu e-posta adresini güncellemek istediğinizden emin misiniz? emails.change_email_text=Bu e-posta adresini güncellemek istediğinizden emin misiniz?
emails.delete=E-postayı Sil
emails.delete_desc=Bu e-posta adresini silmek istediğinizden emin misiniz?
emails.deletion_success=E-posta adresi silindi.
emails.delete_primary_email_error=Ana e-posta adresini silemezsiniz.
orgs.org_manage_panel=Organizasyon Yönetimi orgs.org_manage_panel=Organizasyon Yönetimi
orgs.name=İsim orgs.name=İsim
@ -3202,6 +3245,10 @@ config.cache_adapter=Önbellek Uyarlayıcısı
config.cache_interval=Önbellek Aralığı config.cache_interval=Önbellek Aralığı
config.cache_conn=Önbellek Bağlantısı config.cache_conn=Önbellek Bağlantısı
config.cache_item_ttl=TTL Önbellek Öğesi config.cache_item_ttl=TTL Önbellek Öğesi
config.cache_test=Önbelleği Sına
config.cache_test_failed=Önbelleğin incelenmesi başarısız oldu: %v.
config.cache_test_slow=Önbellek sınaması başarılı, ancak yanıt yavaş: %s.
config.cache_test_succeeded=Önbellek sınaması başarılı, %s sürede bir yanıt alındı.
config.session_config=Oturum Yapılandırması config.session_config=Oturum Yapılandırması
config.session_provider=Oturum Sağlayıcı config.session_provider=Oturum Sağlayıcı
@ -3302,6 +3349,7 @@ self_check.database_collation_case_insensitive=Veritabanı %s harmanlamasını k
self_check.database_inconsistent_collation_columns=Veritabanı %s harmanlamasını kullanıyor, ancak bu sütunlar uyumsuz harmanlamalar kullanıyor. Bu beklenmedik sorunlar oluşturabilir. self_check.database_inconsistent_collation_columns=Veritabanı %s harmanlamasını kullanıyor, ancak bu sütunlar uyumsuz harmanlamalar kullanıyor. Bu beklenmedik sorunlar oluşturabilir.
self_check.database_fix_mysql=MySQL/MariaDB kullanıcıları "gitea doctor convert" komutunu harmanlama sorunlarını çözmek için kullanabilir veya "ALTER ... COLLATE ..." SQL'lerini şahsen çalıştırarak sorunu çözebilirler. self_check.database_fix_mysql=MySQL/MariaDB kullanıcıları "gitea doctor convert" komutunu harmanlama sorunlarını çözmek için kullanabilir veya "ALTER ... COLLATE ..." SQL'lerini şahsen çalıştırarak sorunu çözebilirler.
self_check.database_fix_mssql=MSSQL kullanıcıları sorunu şu an sadece "ALTER ... COLLATE ..." SQL'lerini şahsen çalıştırarak çözebilirler. self_check.database_fix_mssql=MSSQL kullanıcıları sorunu şu an sadece "ALTER ... COLLATE ..." SQL'lerini şahsen çalıştırarak çözebilirler.
self_check.location_origin_mismatch=Mevcut URL (%[1]s) Gitea tarafından görülen URL (%[2]s) ile eşleşmiyor. Eğer bir vekil sunucu kullanıyorsanız, lütfen "Host" ve "X-Forwarded-Proto" başlıklarının doğru ayarlandığından emin olunuz.
[action] [action]
create_repo=depo <a href="%s">%s</a> oluşturuldu create_repo=depo <a href="%s">%s</a> oluşturuldu
@ -3329,6 +3377,7 @@ mirror_sync_create=<a href="%[2]s">%[3]s</a> yeni referansını, <a href="%[1]s"
mirror_sync_delete=<a href="%[1]s">%[3]s</a> adresindeki <code>%[2]s</code> referansını eşitledi ve sildi mirror_sync_delete=<a href="%[1]s">%[3]s</a> adresindeki <code>%[2]s</code> referansını eşitledi ve sildi
approve_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> değişiklik isteğini onayladı` approve_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> değişiklik isteğini onayladı`
reject_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> için değişiklikler önerdi` reject_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> için değişiklikler önerdi`
publish_release=`<a href="%[1]s">%[3]s</a> deposu için <a href="%[2]s"> "%[4]s" </a> sürümü yayınlandı`
review_dismissed=`<a href="%[1]s">%[3]s#%[2]s</a> için <b>%[4]s</b> yorumunu reddetti` review_dismissed=`<a href="%[1]s">%[3]s#%[2]s</a> için <b>%[4]s</b> yorumunu reddetti`
review_dismissed_reason=Sebep: review_dismissed_reason=Sebep:
create_branch=<a href="%[1]s">%[4]s</a> deposunda <a href="%[2]s">%[3]s</a> dalını oluşturdu create_branch=<a href="%[1]s">%[4]s</a> deposunda <a href="%[2]s">%[3]s</a> dalını oluşturdu
@ -3395,6 +3444,7 @@ error.unit_not_allowed=Bu depo bölümüne erişme izniniz yok.
title=Paketler title=Paketler
desc=Depo paketlerini yönet. desc=Depo paketlerini yönet.
empty=Henüz hiçbir paket yok. empty=Henüz hiçbir paket yok.
no_metadata=Üstveri yok.
empty.documentation=Paket kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/usage/packages/overview/">belgeye</a> bakabilirsiniz. empty.documentation=Paket kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/usage/packages/overview/">belgeye</a> bakabilirsiniz.
empty.repo=Bir paket yüklediniz ama burada gösterilmiyor mu? <a href="%[1]s">Paket ayarları</a>na gidin ve bu depoya bağlantı verin. empty.repo=Bir paket yüklediniz ama burada gösterilmiyor mu? <a href="%[1]s">Paket ayarları</a>na gidin ve bu depoya bağlantı verin.
registry.documentation=%s kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="%s">belgeye</a> bakabilirsiniz. registry.documentation=%s kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="%s">belgeye</a> bakabilirsiniz.
@ -3476,6 +3526,7 @@ npm.install=Paketi npm ile kurmak için, şu komutu çalıştırın:
npm.install2=veya paketi package.json dosyasına ekleyin: npm.install2=veya paketi package.json dosyasına ekleyin:
npm.dependencies=Bağımlılıklar npm.dependencies=Bağımlılıklar
npm.dependencies.development=Geliştirme Bağımlılıkları npm.dependencies.development=Geliştirme Bağımlılıkları
npm.dependencies.bundle=Paketlenmiş Bağımlılıklar
npm.dependencies.peer=Eş Bağımlılıkları npm.dependencies.peer=Eş Bağımlılıkları
npm.dependencies.optional=İsteğe Bağlı Bağımlılıklar npm.dependencies.optional=İsteğe Bağlı Bağımlılıklar
npm.details.tag=Etiket npm.details.tag=Etiket
@ -3616,6 +3667,7 @@ runs.pushed_by=iten
runs.invalid_workflow_helper=İş akışı yapılandırma dosyası geçersiz. Lütfen yapılandırma dosyanızı denetleyin: %s runs.invalid_workflow_helper=İş akışı yapılandırma dosyası geçersiz. Lütfen yapılandırma dosyanızı denetleyin: %s
runs.no_matching_online_runner_helper=Şu etiket ile eşleşen çevrimiçi çalıştırıcı bulunamadı: %s runs.no_matching_online_runner_helper=Şu etiket ile eşleşen çevrimiçi çalıştırıcı bulunamadı: %s
runs.no_job_without_needs=İş akışı en azından bağımlılığı olmayan bir görev içermelidir. runs.no_job_without_needs=İş akışı en azından bağımlılığı olmayan bir görev içermelidir.
runs.no_job=İş akışı en azından bir görev içermelidir
runs.actor=Aktör runs.actor=Aktör
runs.status=Durum runs.status=Durum
runs.actors_no_select=Tüm aktörler runs.actors_no_select=Tüm aktörler
@ -3626,6 +3678,7 @@ runs.no_workflows.quick_start=Gitea İşlemlerini nasıl başlatacağınızı bi
runs.no_workflows.documentation=Gitea İşlemleri hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="%s">belgelere</a> bakabilirsiniz. runs.no_workflows.documentation=Gitea İşlemleri hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="%s">belgelere</a> bakabilirsiniz.
runs.no_runs=İş akışı henüz hiç çalıştırılmadı. runs.no_runs=İş akışı henüz hiç çalıştırılmadı.
runs.empty_commit_message=(boş işleme iletisi) runs.empty_commit_message=(boş işleme iletisi)
runs.expire_log_message=Günlükler, çok eski oldukları için temizlendiler.
workflow.disable=İş Akışını Devre Dışı Bırak workflow.disable=İş Akışını Devre Dışı Bırak
workflow.disable_success='%s' iş akışı başarıyla devre dışı bırakıldı. workflow.disable_success='%s' iş akışı başarıyla devre dışı bırakıldı.
@ -3652,6 +3705,7 @@ variables.update.failed=Değişken düzenlenemedi.
variables.update.success=Değişken düzenlendi. variables.update.success=Değişken düzenlendi.
[projects] [projects]
deleted.display_name=Silinmiş Proje
type-1.display_name=Kişisel Proje type-1.display_name=Kişisel Proje
type-2.display_name=Depo Projesi type-2.display_name=Depo Projesi
type-3.display_name=Organizasyon Projesi type-3.display_name=Organizasyon Projesi

View File

@ -2117,8 +2117,6 @@ dashboard.total_gc_time=Загальна пауза збирача сміття
dashboard.total_gc_pause=Загальна пауза збирача сміття (GC) dashboard.total_gc_pause=Загальна пауза збирача сміття (GC)
dashboard.last_gc_pause=Остання пауза збирача сміття (GC) dashboard.last_gc_pause=Остання пауза збирача сміття (GC)
dashboard.gc_times=Кількість запусків збирача сміття (GC) dashboard.gc_times=Кількість запусків збирача сміття (GC)
dashboard.delete_old_actions=Видалити всі старі дії з бази даних
dashboard.delete_old_actions.started=Видалення всіх старі дії з бази даних розпочато.
users.user_manage_panel=Керування обліковими записами користувачів users.user_manage_panel=Керування обліковими записами користувачів
users.new_account=Створити обліковий запис users.new_account=Створити обліковий запис

View File

@ -2833,7 +2833,6 @@ dashboard.reinit_missing_repos=重新初始化所有丢失的 Git 仓库存在
dashboard.sync_external_users=同步外部用户数据 dashboard.sync_external_users=同步外部用户数据
dashboard.cleanup_hook_task_table=清理 hook_task 表 dashboard.cleanup_hook_task_table=清理 hook_task 表
dashboard.cleanup_packages=清理过期的软件包 dashboard.cleanup_packages=清理过期的软件包
dashboard.cleanup_actions=清理过期的Actions日志和制品
dashboard.server_uptime=服务运行时间 dashboard.server_uptime=服务运行时间
dashboard.current_goroutine=当前 Goroutines 数量 dashboard.current_goroutine=当前 Goroutines 数量
dashboard.current_memory_usage=当前内存使用量 dashboard.current_memory_usage=当前内存使用量
@ -2863,15 +2862,9 @@ dashboard.total_gc_time=GC 暂停时间总量
dashboard.total_gc_pause=GC 暂停时间总量 dashboard.total_gc_pause=GC 暂停时间总量
dashboard.last_gc_pause=上次 GC 暂停时间 dashboard.last_gc_pause=上次 GC 暂停时间
dashboard.gc_times=GC 执行次数 dashboard.gc_times=GC 执行次数
dashboard.delete_old_actions=从数据库中删除所有旧操作记录
dashboard.delete_old_actions.started=已开始从数据库中删除所有旧操作记录。
dashboard.update_checker=更新检查器 dashboard.update_checker=更新检查器
dashboard.delete_old_system_notices=从数据库中删除所有旧系统通知 dashboard.delete_old_system_notices=从数据库中删除所有旧系统通知
dashboard.gc_lfs=垃圾回收 LFS 元数据 dashboard.gc_lfs=垃圾回收 LFS 元数据
dashboard.stop_zombie_tasks=停止僵尸任务
dashboard.stop_endless_tasks=停止永不停止的任务
dashboard.cancel_abandoned_jobs=取消丢弃的任务
dashboard.start_schedule_tasks=开始调度任务
dashboard.sync_branch.started=分支同步已开始 dashboard.sync_branch.started=分支同步已开始
dashboard.sync_tag.started=标签同步已开始 dashboard.sync_tag.started=标签同步已开始
dashboard.rebuild_issue_indexer=重建工单索引 dashboard.rebuild_issue_indexer=重建工单索引

View File

@ -2483,14 +2483,9 @@ dashboard.total_gc_time=總 GC 暫停時間
dashboard.total_gc_pause=總 GC 暫停時間 dashboard.total_gc_pause=總 GC 暫停時間
dashboard.last_gc_pause=上次 GC 暫停時間 dashboard.last_gc_pause=上次 GC 暫停時間
dashboard.gc_times=GC 執行次數 dashboard.gc_times=GC 執行次數
dashboard.delete_old_actions=從資料庫刪除所有舊行為
dashboard.delete_old_actions.started=從資料庫刪除所有舊行為的任務已啟動。
dashboard.update_checker=更新檢查器 dashboard.update_checker=更新檢查器
dashboard.delete_old_system_notices=從資料庫刪除所有舊系統提示 dashboard.delete_old_system_notices=從資料庫刪除所有舊系統提示
dashboard.gc_lfs=對 LFS meta objects 進行垃圾回收 dashboard.gc_lfs=對 LFS meta objects 進行垃圾回收
dashboard.stop_zombie_tasks=停止殭屍任務
dashboard.stop_endless_tasks=停止永不停止的任務
dashboard.cancel_abandoned_jobs=取消已放棄的工作
users.user_manage_panel=使用者帳戶管理 users.user_manage_panel=使用者帳戶管理
users.new_account=建立使用者帳戶 users.new_account=建立使用者帳戶

1401
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,10 +22,10 @@
"chartjs-plugin-zoom": "2.0.1", "chartjs-plugin-zoom": "2.0.1",
"clippie": "4.1.3", "clippie": "4.1.3",
"css-loader": "7.1.2", "css-loader": "7.1.2",
"dayjs": "1.11.11", "dayjs": "1.11.12",
"dropzone": "6.0.0-beta.2", "dropzone": "6.0.0-beta.2",
"easymde": "2.18.0", "easymde": "2.18.0",
"esbuild-loader": "4.2.0", "esbuild-loader": "4.2.2",
"escape-goat": "4.0.0", "escape-goat": "4.0.0",
"fast-glob": "3.3.2", "fast-glob": "3.3.2",
"htmx.org": "2.0.0", "htmx.org": "2.0.0",
@ -39,35 +39,35 @@
"monaco-editor": "0.50.0", "monaco-editor": "0.50.0",
"monaco-editor-webpack-plugin": "7.1.0", "monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.0", "pdfobject": "2.3.0",
"postcss": "8.4.39", "postcss": "8.4.40",
"postcss-loader": "8.1.1", "postcss-loader": "8.1.1",
"postcss-nesting": "12.1.5", "postcss-nesting": "12.1.5",
"sortablejs": "1.15.2", "sortablejs": "1.15.2",
"swagger-ui-dist": "5.17.14", "swagger-ui-dist": "5.17.14",
"tailwindcss": "3.4.4", "tailwindcss": "3.4.7",
"temporal-polyfill": "0.2.5", "temporal-polyfill": "0.2.5",
"throttle-debounce": "5.0.2", "throttle-debounce": "5.0.2",
"tinycolor2": "1.6.0", "tinycolor2": "1.6.0",
"tippy.js": "6.3.7", "tippy.js": "6.3.7",
"toastify-js": "1.12.0", "toastify-js": "1.12.0",
"tributejs": "5.1.3", "tributejs": "5.1.3",
"typescript": "5.5.3", "typescript": "5.5.4",
"uint8-to-base64": "0.2.0", "uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2", "vanilla-colorful": "0.7.2",
"vue": "3.4.31", "vue": "3.4.35",
"vue-bar-graph": "2.0.0", "vue-bar-graph": "2.1.0",
"vue-chartjs": "5.3.1", "vue-chartjs": "5.3.1",
"vue-loader": "17.4.2", "vue-loader": "17.4.2",
"webpack": "5.92.1", "webpack": "5.93.0",
"webpack-cli": "5.1.4", "webpack-cli": "5.1.4",
"wrap-ansi": "9.0.0" "wrap-ansi": "9.0.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "4.3.0", "@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
"@playwright/test": "1.45.1", "@playwright/test": "1.45.3",
"@stoplight/spectral-cli": "6.11.1", "@stoplight/spectral-cli": "6.11.1",
"@stylistic/eslint-plugin-js": "2.3.0", "@stylistic/eslint-plugin-js": "2.6.1",
"@stylistic/stylelint-plugin": "2.1.2", "@stylistic/stylelint-plugin": "3.0.0",
"@types/dropzone": "5.7.8", "@types/dropzone": "5.7.8",
"@types/jquery": "3.5.30", "@types/jquery": "3.5.30",
"@types/katex": "0.16.7", "@types/katex": "0.16.7",
@ -78,9 +78,9 @@
"@types/throttle-debounce": "5.0.2", "@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6", "@types/tinycolor2": "1.4.6",
"@types/toastify-js": "1.12.3", "@types/toastify-js": "1.12.3",
"@typescript-eslint/eslint-plugin": "7.16.0", "@typescript-eslint/eslint-plugin": "8.0.0",
"@typescript-eslint/parser": "7.16.0", "@typescript-eslint/parser": "8.0.0",
"@vitejs/plugin-vue": "5.0.5", "@vitejs/plugin-vue": "5.1.2",
"eslint": "8.57.0", "eslint": "8.57.0",
"eslint-import-resolver-typescript": "3.6.1", "eslint-import-resolver-typescript": "3.6.1",
"eslint-plugin-array-func": "4.0.0", "eslint-plugin-array-func": "4.0.0",
@ -91,8 +91,8 @@
"eslint-plugin-no-use-extend-native": "0.5.0", "eslint-plugin-no-use-extend-native": "0.5.0",
"eslint-plugin-playwright": "1.6.2", "eslint-plugin-playwright": "1.6.2",
"eslint-plugin-regexp": "2.6.0", "eslint-plugin-regexp": "2.6.0",
"eslint-plugin-sonarjs": "1.0.3", "eslint-plugin-sonarjs": "1.0.4",
"eslint-plugin-unicorn": "54.0.0", "eslint-plugin-unicorn": "55.0.0",
"eslint-plugin-vitest": "0.4.1", "eslint-plugin-vitest": "0.4.1",
"eslint-plugin-vitest-globals": "1.5.0", "eslint-plugin-vitest-globals": "1.5.0",
"eslint-plugin-vue": "9.27.0", "eslint-plugin-vue": "9.27.0",
@ -102,14 +102,14 @@
"markdownlint-cli": "0.41.0", "markdownlint-cli": "0.41.0",
"nolyfill": "1.0.39", "nolyfill": "1.0.39",
"postcss-html": "1.7.0", "postcss-html": "1.7.0",
"stylelint": "16.6.1", "stylelint": "16.8.1",
"stylelint-declaration-block-no-ignored-properties": "2.8.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0",
"stylelint-declaration-strict-value": "1.10.4", "stylelint-declaration-strict-value": "1.10.6",
"stylelint-value-no-unknown-custom-properties": "6.0.1", "stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.3.2", "svgo": "3.3.2",
"updates": "16.2.1", "updates": "16.3.7",
"vite-string-plugin": "1.3.4", "vite-string-plugin": "1.3.4",
"vitest": "2.0.2" "vitest": "2.0.5"
}, },
"browserslist": [ "browserslist": [
"defaults" "defaults"

View File

@ -222,6 +222,27 @@ func ViewPost(ctx *context_module.Context) {
step := steps[cursor.Step] step := steps[cursor.Step]
// if task log is expired, return a consistent log line
if task.LogExpired {
if cursor.Cursor == 0 {
resp.Logs.StepsLog = append(resp.Logs.StepsLog, &ViewStepLog{
Step: cursor.Step,
Cursor: 1,
Lines: []*ViewStepLogLine{
{
Index: 1,
Message: ctx.Locale.TrString("actions.runs.expire_log_message"),
// Timestamp doesn't mean anything when the log is expired.
// Set it to the task's updated time since it's probably the time when the log has expired.
Timestamp: float64(task.Updated.AsTime().UnixNano()) / float64(time.Second),
},
},
Started: int64(step.Started),
})
}
continue
}
logLines := make([]*ViewStepLogLine, 0) // marshal to '[]' instead fo 'null' in json logLines := make([]*ViewStepLogLine, 0) // marshal to '[]' instead fo 'null' in json
index := step.LogIndex + cursor.Cursor index := step.LogIndex + cursor.Cursor

View File

@ -410,6 +410,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5) pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx) pager.SetDefaultParams(ctx)
pager.AddParamString("action", "_revision")
ctx.Data["Page"] = pager ctx.Data["Page"] = pager
return wikiRepo, entry return wikiRepo, entry

View File

@ -5,18 +5,30 @@ package actions
import ( import (
"context" "context"
"fmt"
"time"
"code.gitea.io/gitea/models/actions" actions_model "code.gitea.io/gitea/models/actions"
actions_module "code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/timeutil"
) )
// Cleanup removes expired actions logs, data and artifacts // Cleanup removes expired actions logs, data and artifacts
func Cleanup(taskCtx context.Context) error { func Cleanup(ctx context.Context) error {
// TODO: clean up expired actions logs
// clean up expired artifacts // clean up expired artifacts
return CleanupArtifacts(taskCtx) if err := CleanupArtifacts(ctx); err != nil {
return fmt.Errorf("cleanup artifacts: %w", err)
}
// clean up old logs
if err := CleanupLogs(ctx); err != nil {
return fmt.Errorf("cleanup logs: %w", err)
}
return nil
} }
// CleanupArtifacts removes expired add need-deleted artifacts and set records expired status // CleanupArtifacts removes expired add need-deleted artifacts and set records expired status
@ -28,13 +40,13 @@ func CleanupArtifacts(taskCtx context.Context) error {
} }
func cleanExpiredArtifacts(taskCtx context.Context) error { func cleanExpiredArtifacts(taskCtx context.Context) error {
artifacts, err := actions.ListNeedExpiredArtifacts(taskCtx) artifacts, err := actions_model.ListNeedExpiredArtifacts(taskCtx)
if err != nil { if err != nil {
return err return err
} }
log.Info("Found %d expired artifacts", len(artifacts)) log.Info("Found %d expired artifacts", len(artifacts))
for _, artifact := range artifacts { for _, artifact := range artifacts {
if err := actions.SetArtifactExpired(taskCtx, artifact.ID); err != nil { if err := actions_model.SetArtifactExpired(taskCtx, artifact.ID); err != nil {
log.Error("Cannot set artifact %d expired: %v", artifact.ID, err) log.Error("Cannot set artifact %d expired: %v", artifact.ID, err)
continue continue
} }
@ -52,13 +64,13 @@ const deleteArtifactBatchSize = 100
func cleanNeedDeleteArtifacts(taskCtx context.Context) error { func cleanNeedDeleteArtifacts(taskCtx context.Context) error {
for { for {
artifacts, err := actions.ListPendingDeleteArtifacts(taskCtx, deleteArtifactBatchSize) artifacts, err := actions_model.ListPendingDeleteArtifacts(taskCtx, deleteArtifactBatchSize)
if err != nil { if err != nil {
return err return err
} }
log.Info("Found %d artifacts pending deletion", len(artifacts)) log.Info("Found %d artifacts pending deletion", len(artifacts))
for _, artifact := range artifacts { for _, artifact := range artifacts {
if err := actions.SetArtifactDeleted(taskCtx, artifact.ID); err != nil { if err := actions_model.SetArtifactDeleted(taskCtx, artifact.ID); err != nil {
log.Error("Cannot set artifact %d deleted: %v", artifact.ID, err) log.Error("Cannot set artifact %d deleted: %v", artifact.ID, err)
continue continue
} }
@ -75,3 +87,40 @@ func cleanNeedDeleteArtifacts(taskCtx context.Context) error {
} }
return nil return nil
} }
const deleteLogBatchSize = 100
// CleanupLogs removes logs which are older than the configured retention time
func CleanupLogs(ctx context.Context) error {
olderThan := timeutil.TimeStampNow().AddDuration(-time.Duration(setting.Actions.LogRetentionDays) * 24 * time.Hour)
count := 0
for {
tasks, err := actions_model.FindOldTasksToExpire(ctx, olderThan, deleteLogBatchSize)
if err != nil {
return fmt.Errorf("find old tasks: %w", err)
}
for _, task := range tasks {
if err := actions_module.RemoveLogs(ctx, task.LogInStorage, task.LogFilename); err != nil {
log.Error("Failed to remove log %s (in storage %v) of task %v: %v", task.LogFilename, task.LogInStorage, task.ID, err)
// do not return error here, continue to next task
continue
}
task.LogIndexes = nil // clear log indexes since it's a heavy field
task.LogExpired = true
if err := actions_model.UpdateTask(ctx, task, "log_indexes", "log_expired"); err != nil {
log.Error("Failed to update task %v: %v", task.ID, err)
// do not return error here, continue to next task
continue
}
count++
log.Trace("Removed log %s of task %v", task.LogFilename, task.ID)
}
if len(tasks) < deleteLogBatchSize {
break
}
}
log.Info("Removed %d logs", count)
return nil
}

View File

@ -106,10 +106,25 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
log.Error("LoadRequestedReviewers[%d]: %v", pr.ID, err) log.Error("LoadRequestedReviewers[%d]: %v", pr.ID, err)
return nil return nil
} }
if err = pr.LoadRequestedReviewersTeams(ctx); err != nil {
log.Error("LoadRequestedReviewersTeams[%d]: %v", pr.ID, err)
return nil
}
for _, reviewer := range pr.RequestedReviewers { for _, reviewer := range pr.RequestedReviewers {
apiPullRequest.RequestedReviewers = append(apiPullRequest.RequestedReviewers, ToUser(ctx, reviewer, nil)) apiPullRequest.RequestedReviewers = append(apiPullRequest.RequestedReviewers, ToUser(ctx, reviewer, nil))
} }
for _, reviewerTeam := range pr.RequestedReviewersTeams {
convertedTeam, err := ToTeam(ctx, reviewerTeam, true)
if err != nil {
log.Error("LoadRequestedReviewersTeams[%d]: %v", pr.ID, err)
return nil
}
apiPullRequest.RequestedReviewersTeams = append(apiPullRequest.RequestedReviewersTeams, convertedTeam)
}
if pr.Issue.ClosedUnix != 0 { if pr.Issue.ClosedUnix != 0 {
apiPullRequest.Closed = pr.Issue.ClosedUnix.AsTimePtr() apiPullRequest.Closed = pr.Issue.ClosedUnix.AsTimePtr()
} }

View File

@ -68,7 +68,7 @@ func registerScheduleTasks() {
func registerActionsCleanup() { func registerActionsCleanup() {
RegisterTaskFatal("cleanup_actions", &BaseConfig{ RegisterTaskFatal("cleanup_actions", &BaseConfig{
Enabled: true, Enabled: true,
RunAtStart: true, RunAtStart: false,
Schedule: "@midnight", Schedule: "@midnight",
}, func(ctx context.Context, _ *user_model.User, _ Config) error { }, func(ctx context.Context, _ *user_model.User, _ Config) error {
return actions_service.Cleanup(ctx) return actions_service.Cleanup(ctx)

View File

@ -169,6 +169,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
lfsClient := lfs.NewClient(endpoint, httpTransport) lfsClient := lfs.NewClient(endpoint, httpTransport)
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil { if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil {
log.Error("Failed to store missing LFS objects for repository: %v", err) log.Error("Failed to store missing LFS objects for repository: %v", err)
return repo, fmt.Errorf("StoreMissingLfsObjectsInRepository: %w", err)
} }
} }
} }

View File

@ -18484,6 +18484,11 @@
"properties": { "properties": {
"permission": { "permission": {
"type": "string", "type": "string",
"enum": [
"read",
"write",
"admin"
],
"x-go-name": "Permission" "x-go-name": "Permission"
} }
}, },
@ -23512,6 +23517,13 @@
}, },
"x-go-name": "RequestedReviewers" "x-go-name": "RequestedReviewers"
}, },
"requested_reviewers_teams": {
"type": "array",
"items": {
"$ref": "#/definitions/Team"
},
"x-go-name": "RequestedReviewersTeams"
},
"review_comments": { "review_comments": {
"description": "number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR)", "description": "number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR)",
"type": "integer", "type": "integer",

View File

@ -19,7 +19,7 @@ func TestAPIUserVariables(t *testing.T) {
session := loginUser(t, "user1") session := loginUser(t, "user1")
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)
t.Run("CreateRepoVariable", func(t *testing.T) { t.Run("CreateUserVariable", func(t *testing.T) {
cases := []struct { cases := []struct {
Name string Name string
ExpectedStatus int ExpectedStatus int
@ -70,7 +70,7 @@ func TestAPIUserVariables(t *testing.T) {
} }
}) })
t.Run("UpdateRepoVariable", func(t *testing.T) { t.Run("UpdateUserVariable", func(t *testing.T) {
variableName := "test_update_var" variableName := "test_update_var"
url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName) url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName)
req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import VueBarGraph from 'vue-bar-graph'; import {VueBarGraph} from 'vue-bar-graph';
import {createApp} from 'vue'; import {createApp} from 'vue';
const sfc = { const sfc = {

View File

@ -10,7 +10,9 @@ test('createElementFromAttrs', () => {
class: 'cls-1 cls-2', class: 'cls-1 cls-2',
'data-foo': 'the-data', 'data-foo': 'the-data',
disabled: true, disabled: true,
checked: false,
required: null, required: null,
tabindex: 0,
}); });
expect(el.outerHTML).toEqual('<button id="the-id" class="cls-1 cls-2" data-foo="the-data" disabled=""></button>'); expect(el.outerHTML).toEqual('<button id="the-id" class="cls-1 cls-2" data-foo="the-data" disabled="" tabindex="0"></button>');
}); });

View File

@ -297,7 +297,7 @@ export function createElementFromAttrs(tagName, attrs) {
const el = document.createElement(tagName); const el = document.createElement(tagName);
for (const [key, value] of Object.entries(attrs)) { for (const [key, value] of Object.entries(attrs)) {
if (value === undefined || value === null) continue; if (value === undefined || value === null) continue;
if (value === true) { if (typeof value === 'boolean') {
el.toggleAttribute(key, value); el.toggleAttribute(key, value);
} else { } else {
el.setAttribute(key, String(value)); el.setAttribute(key, String(value));