mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-21 09:06:46 +09:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
726d6a5077 | ||
|
|
b33cae7a3a | ||
|
|
854fcb1434 | ||
|
|
4730ed18f1 | ||
|
|
937996c74c | ||
|
|
3f253b3f5a | ||
|
|
f5a98b0f5b | ||
|
|
1a97a84023 | ||
|
|
420d015b76 | ||
|
|
22911a1ece | ||
|
|
4b763d8d37 | ||
|
|
1254fc668a | ||
|
|
09824025f7 | ||
|
|
bd1a915bdb | ||
|
|
cab7044772 | ||
|
|
68c9f1abd8 | ||
|
|
301de3ab6b | ||
|
|
8f8bd3c0cb | ||
|
|
23a6fa9421 | ||
|
|
b7c2f48ebf | ||
|
|
70e31b4aa0 | ||
|
|
d73846f0b4 | ||
|
|
527bbf67e8 | ||
|
|
5feb31f219 | ||
|
|
31efbafbe3 | ||
|
|
28af02eea0 | ||
|
|
c698a6fc5d | ||
|
|
e5a51eca45 | ||
|
|
8536dc4b73 | ||
|
|
0a0f46f299 | ||
|
|
1543ac9c8d | ||
|
|
c3c0710412 | ||
|
|
fa33919e24 | ||
|
|
b1162495af | ||
|
|
41655ee878 | ||
|
|
0d9b44c0e3 | ||
|
|
e87f36e885 | ||
|
|
b301cb17a3 | ||
|
|
e259daeff8 | ||
|
|
edb618c136 | ||
|
|
43cf04c031 | ||
|
|
e9991b1f06 | ||
|
|
975785dd42 | ||
|
|
e269e8901f | ||
|
|
87c31c2ffe | ||
|
|
54c674c936 | ||
|
|
2ba58fab22 | ||
|
|
cd7bd8568c | ||
|
|
cf80f829b4 | ||
|
|
ed25e094ab | ||
|
|
10df304b2f | ||
|
|
ecae62837c | ||
|
|
e8e871b44e | ||
|
|
6be6c19daf | ||
|
|
61f91bdc7e | ||
|
|
8ab50be000 | ||
|
|
dfab6e2d1c | ||
|
|
2f7bbdf8c9 | ||
|
|
af4767df5c | ||
|
|
233a399706 | ||
|
|
dcf1717793 | ||
|
|
b1e68f39e7 | ||
|
|
ee3d9330a8 | ||
|
|
d1d15306d1 | ||
|
|
e3b1ebbbfe | ||
|
|
17ae7e335e | ||
|
|
1edb57eda9 | ||
|
|
a2a9b0f977 | ||
|
|
ff96f804b6 | ||
|
|
a926994bfe | ||
|
|
83903535e3 | ||
|
|
8142408d3a | ||
|
|
a4158d1904 | ||
|
|
781019216c | ||
|
|
1322cd7a58 | ||
|
|
464bbd747e | ||
|
|
574182e1eb | ||
|
|
ef8209a953 | ||
|
|
9309098eab | ||
|
|
790a79b04c | ||
|
|
f8a40dafb9 | ||
|
|
9843a0b741 | ||
|
|
085a4debd5 | ||
|
|
4c1e24864f | ||
|
|
5d5f907e7f | ||
|
|
39178b5756 | ||
|
|
3d8412dd51 | ||
|
|
ff7057a46d | ||
|
|
bb8ef28913 | ||
|
|
13918ad344 | ||
|
|
7528ce60e7 | ||
|
|
6c6a7e7d97 | ||
|
|
111c509287 | ||
|
|
9d7ef0ad63 | ||
|
|
9aae54c81f | ||
|
|
1bc4ffc337 | ||
|
|
27879bc45e | ||
|
|
a3694b6989 | ||
|
|
28625fba5b | ||
|
|
7c3196ceac | ||
|
|
80c1264f4b | ||
|
|
f0340c28f1 | ||
|
|
5beb29ad35 | ||
|
|
27e307142b | ||
|
|
e02e752f68 | ||
|
|
5ddf67a9c2 | ||
|
|
4d3e2b23b8 | ||
|
|
ddf61373f6 | ||
|
|
b4ed3f07e4 | ||
|
|
ced94f2e0d | ||
|
|
aff432b197 | ||
|
|
0ac3be1482 | ||
|
|
75eaf99076 | ||
|
|
e67d60d336 |
No files matched your search
+97
-32
@@ -43,7 +43,7 @@ steps:
|
||||
depends_on: [deps-frontend]
|
||||
|
||||
- name: lint-backend
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
pull: always
|
||||
commands:
|
||||
- make lint-backend
|
||||
@@ -57,7 +57,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: lint-backend-windows
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
commands:
|
||||
- make golangci-lint-windows vet
|
||||
environment:
|
||||
@@ -72,7 +72,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: lint-backend-gogit
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
commands:
|
||||
- make lint-backend
|
||||
environment:
|
||||
@@ -264,13 +264,13 @@ steps:
|
||||
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
|
||||
|
||||
- name: prepare-test-env
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
pull: always
|
||||
commands:
|
||||
- ./build/test-env-prepare.sh
|
||||
|
||||
- name: build
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- ./build/test-env-check.sh
|
||||
@@ -285,7 +285,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: unit-test
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- make unit-test-coverage test-check
|
||||
@@ -301,7 +301,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: unit-test-gogit
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- make unit-test-coverage test-check
|
||||
@@ -317,7 +317,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: test-mysql
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- make test-mysql-migration integration-test-coverage
|
||||
@@ -334,7 +334,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: test-mysql8
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- timeout -s ABRT 50m make test-mysql8-migration test-mysql8
|
||||
@@ -350,7 +350,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: test-mssql
|
||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- make test-mssql-migration test-mssql
|
||||
@@ -454,13 +454,13 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: prepare-test-env
|
||||
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-arm64 # https://gitea.com/gitea/test-env
|
||||
pull: always
|
||||
commands:
|
||||
- ./build/test-env-prepare.sh
|
||||
|
||||
- name: build
|
||||
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-arm64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- ./build/test-env-check.sh
|
||||
@@ -475,7 +475,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: test-sqlite
|
||||
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-arm64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- timeout -s ABRT 50m make test-sqlite-migration test-sqlite
|
||||
@@ -491,7 +491,7 @@ steps:
|
||||
path: /go
|
||||
|
||||
- name: test-pgsql
|
||||
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env
|
||||
image: gitea/test_env:linux-1.19-arm64 # https://gitea.com/gitea/test-env
|
||||
user: gitea
|
||||
commands:
|
||||
- timeout -s ABRT 50m make test-pgsql-migration test-pgsql
|
||||
@@ -1016,7 +1016,7 @@ steps:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: true
|
||||
@@ -1028,13 +1028,17 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: true
|
||||
@@ -1046,6 +1050,10 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
@@ -1080,7 +1088,7 @@ steps:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
tags: ${DRONE_TAG##v}-linux-amd64
|
||||
@@ -1091,13 +1099,17 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
tags: ${DRONE_TAG##v}-linux-amd64-rootless
|
||||
@@ -1108,6 +1120,10 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
@@ -1142,7 +1158,7 @@ steps:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
@@ -1154,13 +1170,17 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
@@ -1172,6 +1192,10 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
@@ -1205,7 +1229,7 @@ steps:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
@@ -1217,13 +1241,17 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
@@ -1235,6 +1263,10 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
@@ -1243,7 +1275,7 @@ steps:
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-linux-arm64-dry-run
|
||||
name: docker-linux-amd64-dry-run
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
@@ -1261,7 +1293,7 @@ trigger:
|
||||
|
||||
steps:
|
||||
- name: dryrun
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
dry_run: true
|
||||
@@ -1272,6 +1304,7 @@ steps:
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
@@ -1308,7 +1341,7 @@ steps:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: true
|
||||
@@ -1320,13 +1353,17 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: true
|
||||
@@ -1338,6 +1375,10 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
@@ -1372,7 +1413,7 @@ steps:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
tags: ${DRONE_TAG##v}-linux-arm64
|
||||
@@ -1383,13 +1424,17 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
tags: ${DRONE_TAG##v}-linux-arm64-rootless
|
||||
@@ -1400,6 +1445,10 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
@@ -1434,7 +1483,7 @@ steps:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
@@ -1446,13 +1495,17 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
@@ -1464,6 +1517,10 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
@@ -1497,7 +1554,7 @@ steps:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
@@ -1509,13 +1566,17 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
@@ -1527,6 +1588,10 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
|
||||
+6
-2
@@ -1,12 +1,16 @@
|
||||
plugins:
|
||||
- stylelint-declaration-strict-value
|
||||
|
||||
ignoreFiles:
|
||||
- "**/*.go"
|
||||
|
||||
overrides:
|
||||
- files: ["**/*.less"]
|
||||
customSyntax: postcss-less
|
||||
- files: ["**/chroma/*", "**/codemirror/*", "**/standalone/*", "**/console/*"]
|
||||
rules:
|
||||
scale-unlimited/declaration-strict-value: null
|
||||
- files: ["**/chroma/*", "**/codemirror/*"]
|
||||
rules:
|
||||
block-no-empty: null
|
||||
|
||||
rules:
|
||||
alpha-value-notation: null
|
||||
|
||||
+350
@@ -4,6 +4,356 @@ This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.19.0](https://github.com/go-gitea/gitea/releases/tag/1.19.0) - 2023-03-19
|
||||
|
||||
* BREAKING
|
||||
* Add loading yaml label template files (#22976) (#23232)
|
||||
* Make issue and code search support camel case for Bleve (#22829)
|
||||
* Repositories: by default disable all units except code and pulls on forks (#22541)
|
||||
* Support template for merge message description (#22248)
|
||||
* Remove ONLY_SHOW_RELEVANT_REPOS setting (#21962)
|
||||
* Implement actions (#21937)
|
||||
* Remove deprecated DSA host key from Docker Container (#21522)
|
||||
* Improve valid user name check (#20136)
|
||||
* SECURITY
|
||||
* Return 404 instead of 403 if user can not access the repo (#23155) (#23158)
|
||||
* Support scoped access tokens (#20908)
|
||||
* FEATURES
|
||||
* Add support for commit cross references (#22645)
|
||||
* Scoped labels (#22585)
|
||||
* Add Chef package registry (#22554)
|
||||
* Support asciicast files as new markup (#22448)
|
||||
* cgo cross-compile for freebsd (#22397)
|
||||
* Add cron method to gc LFS MetaObjects (#22385)
|
||||
* Add new captcha: cloudflare turnstile (#22369)
|
||||
* Enable `@<user>`- completion popup on the release description textarea (#22359)
|
||||
* make /{username}.png redirect to user/org avatar (#22356)
|
||||
* Add Conda package registry (#22262)
|
||||
* Support org/user level projects (#22235)
|
||||
* Add Mermaid copy button (#22225)
|
||||
* Add user secrets (#22191)
|
||||
* Secrets storage with SecretKey encrypted (#22142)
|
||||
* Preview images for Issue cards in Project Board view (#22112)
|
||||
* Add support for incoming emails (#22056)
|
||||
* Add Cargo package registry (#21888)
|
||||
* Add option to prohibit fork if user reached maximum limit of repositories (#21848)
|
||||
* Add attention blocks within quote blocks for `Note` and `Warning` (#21711)
|
||||
* Add Feed for Releases and Tags (#21696)
|
||||
* Add package registry cleanup rules (#21658)
|
||||
* Add "Copy" button to file view of raw text (#21629)
|
||||
* Allow disable sitemap (#21617)
|
||||
* Add package registry quota limits (#21584)
|
||||
* Map OIDC groups to Orgs/Teams (#21441)
|
||||
* Keep languages defined in .gitattributes (#21403)
|
||||
* Add Webhook authorization header (#20926)
|
||||
* Supports wildcard protected branch (#20825)
|
||||
* Copy citation file content, in APA and BibTex format, on repo home page (#19999)
|
||||
* API
|
||||
* Match api migration behavior to web behavior (#23552) (#23573)
|
||||
* Purge API comment (#23451) (#23452)
|
||||
* User creation API: allow custom "created" timestamps (#22549)
|
||||
* Add `updated_at` field to PullReview API object (#21812)
|
||||
* Add API management for issue/pull and comment attachments (#21783)
|
||||
* Add API endpoint to get latest release (#21267)
|
||||
* Support system hook API (#14537)
|
||||
* ENHANCEMENTS
|
||||
* Add `.patch` to `attachment.ALLOWED_TYPES` (#23580) (#23582)
|
||||
* Fix sticky header in diff view (#23554) (#23568)
|
||||
* Refactor merge/update git command calls (#23366) (#23544)
|
||||
* Fix review comment context menu clipped bug (#23523) (#23543)
|
||||
* Imrove scroll behavior to hash issuecomment(scroll position, auto expand if file is folded, and on refreshing) (#23513) (#23540)
|
||||
* Increase horizontal page padding (#23507) (#23537)
|
||||
* Use octicon-verified for gpg signatures (#23529) (#23536)
|
||||
* Make time tooltips interactive (#23526) (#23527)
|
||||
* Replace Less with CSS (#23508)
|
||||
* Fix 'View File' button in code search (#23478) (#23483)
|
||||
* Convert GitHub event on actions and fix some pull_request events. (#23037) (#23471)
|
||||
* Support reflogs (#22451) (#23438)
|
||||
* Fix actions frontend bugs (pagination, long name alignment) and small simplify (#23370) (#23436)
|
||||
* Scoped label display and documentation tweaks (#23430) (#23433)
|
||||
* Add missing tabs to org projects page (#22705) (#23412)
|
||||
* Fix and move "Use this template" button (#23398) (#23408)
|
||||
* Handle OpenID discovery URL errors a little nicer when creating/editing sources (#23397) (#23403)
|
||||
* Rename `canWriteUnit` to `canWriteProjects` (#23386) (#23399)
|
||||
* Refactor and tidy-up the merge/update branch code (#22568) (#23365)
|
||||
* Refactor `setting.Database.UseXXX` to methods (#23354) (#23356)
|
||||
* Fix incorrect project links and use symlink icon for org-wide projects (#23325) (#23336)
|
||||
* Fix PR view misalignment caused by long name file (#23321) (#23335)
|
||||
* Scoped labels: don't require holding alt key to remove (#23303) (#23331)
|
||||
* Add context when rendering labels or emojis (#23281) (#23319)
|
||||
* Change interactiveBorder to fix popup preview (#23169) (#23314)
|
||||
* Scoped labels: set aria-disabled on muted Exclusive option for a11y (#23306) (#23311)
|
||||
* update to mermaid v10 (#23178) (#23299)
|
||||
* Fix code wrap for unbroken lines (#23268) (#23293)
|
||||
* Use async await to fix empty quote reply at first time (#23168) (#23256)
|
||||
* Fix switched citation format (#23250) (#23253)
|
||||
* Allow `<video>` in MarkDown (#22892) (#23236)
|
||||
* Order pull request conflict checking by recently updated, for each push (#23220) (#23225)
|
||||
* Fix Fomantic UI's `touchstart` fastclick, always use `click` for click events (#23065) (#23195)
|
||||
* Add word-break to sidebar-item-link (#23146) (#23180)
|
||||
* Add InsecureSkipVerify to Minio Client for Storage (#23166) (#23177)
|
||||
* Fix height for sticky head on large screen on PR page (#23111) (#23123)
|
||||
* Change style to improve whitespaces trimming inside inline markdown code (#23093) (#23120)
|
||||
* Avoid warning for system setting when start up (#23054) (#23116)
|
||||
* Add accessibility to the menu on the navbar (#23059) (#23095)
|
||||
* Improve accessibility for issue comments (#22612) (#23083)
|
||||
* Remove delete button for review comment (#23036)
|
||||
* Remove dashes between organization member avatars on hover (#23034)
|
||||
* Use `gt-relative` class instead of the ambiguous `gt-pr` class (#23008)
|
||||
* handle deprecated settings (#22992)
|
||||
* Add scopes to API to create token and display them (#22989)
|
||||
* Improve PR Review Box UI (#22986)
|
||||
* Improve issues.LoadProject (#22982)
|
||||
* Add all units to the units permission list in org team members sidebar (#22971)
|
||||
* Rename `GetUnits` to `LoadUnits` (#22970)
|
||||
* Rename `repo.GetOwner` to `repo.LoadOwner` (#22967)
|
||||
* Rename "People" to "Members" in organization page and use a better icon (#22960)
|
||||
* Fix avatar misalignment (#22955)
|
||||
* Sort issues and pulls by recently updated in user and organization home (#22925)
|
||||
* Add `title` to PR file tree items (#22918)
|
||||
* First step to refactor the `.hide` to `.gt-hidden` (#22916)
|
||||
* Add tooltip to issue reference (#22913)
|
||||
* Always show the `command line instructions` button even if there are conflicts (#22909)
|
||||
* Fix dark-colored description text in arc-green theme (#22908)
|
||||
* Remove Fomantic-UI's `.hidden` CSS class for menu elements (#22895)
|
||||
* Move helpers to be prefixed with `gt-` (#22879)
|
||||
* Move `IsReadmeFile*` from `modules/markup/` to `modules/util` (#22877)
|
||||
* Highlight focused diff file (#22870)
|
||||
* Add some headings to repo views (#22869)
|
||||
* Fix milestone title font problem (#22863)
|
||||
* Pull Requests: setting to allow edits by maintainers by default, tweak UI (#22862)
|
||||
* Introduce customized HTML elements, fix incorrect AppUrl usages in templates (#22861)
|
||||
* Add `/$count` endpoints for NuGet v2 (#22855)
|
||||
* Remove Fomantic-UI's `.hidden` CSS class for checkbox elements (#22851)
|
||||
* Fix notification and stopwatch empty states (#22845)
|
||||
* Always go full width in PR view (#22844)
|
||||
* Improve AppUrl/ROOT_URL checking (#22836)
|
||||
* Fix style of actions rerun button (#22835)
|
||||
* Fix more HTMLURL in templates (#22831)
|
||||
* Fix inconsistent Filter Project name in issue list (#22827)
|
||||
* include build info in Prometheus metrics (#22819)
|
||||
* Make clone URL use current page's host (#22808)
|
||||
* Refactor legacy strange git operations (#22756)
|
||||
* Improve error report when user passes a private key (#22726)
|
||||
* set user dashboard org visibility to basic (#22706)
|
||||
* Fix diff UI for unexpandable items (#22700)
|
||||
* Remove 'primary' class from tab counter labels (#22687)
|
||||
* Add more events details supports for actions (#22680)
|
||||
* Refactor git command package to improve security and maintainability (#22678)
|
||||
* Use relative url in actions view (#22675)
|
||||
* set user visibility class to basic (#22674)
|
||||
* Add repository setting to enable/disable releases unit (#22671)
|
||||
* Remove label color from global issue filters (#22660)
|
||||
* Fix poor alignment of organization description on organization home page (#22656)
|
||||
* Small refactor for loading PRs (#22652)
|
||||
* Allow setting access token scope by CLI (#22648)
|
||||
* Improve accessibility of navigation bar and footer (#22635)
|
||||
* Fixes accessibility behavior of Watching, Staring and Fork buttons (#22634)
|
||||
* Fixes accessibility of empty repository commit status (#22632)
|
||||
* Pull request yaml template support for including commit body in a field (#22629)
|
||||
* Show migration validation error (#22619)
|
||||
* set org visibility class to basic in header (#22605)
|
||||
* Fix cache-control header clearing comment text when editing issue (#22604)
|
||||
* Add ARIA support for Fomantic UI checkboxes (#22599)
|
||||
* Add templates to customize text when creating and migrating repositories (#22597)
|
||||
* Allow setting `redirect_to` cookie on OAuth login (#22594)
|
||||
* Improve checkbox accessibility a bit by adding the title attribute (#22593)
|
||||
* Allow issue templates to not render title (#22589)
|
||||
* Webhooks: for issue close/reopen action, add commit ID that caused it (#22583)
|
||||
* Fix missing title and filter in issue sidebar project menu (#22557)
|
||||
* Issues: support setting issue template field values with query (#22545)
|
||||
* Issues: add Project filter to issues list and search (#22544)
|
||||
* Pull Requests: add color to approved/reject icon in pull requests list (#22543)
|
||||
* Mute all links in issue timeline (#22533)
|
||||
* Dropzone: Add "Copy link" button for new uploads (#22517)
|
||||
* Support importing comment types (#22510)
|
||||
* Load asciicast css async (#22502)
|
||||
* Move delete user to service (#22478)
|
||||
* Change use of Walk to WalkDir to improve disk performance (#22462)
|
||||
* Add reply hint to mail text (#22459)
|
||||
* fix wrong theme class when logged out if default theme is changed (#22408)
|
||||
* Refactor the setting to make unit test easier (#22405)
|
||||
* Improve utils of slices (#22379)
|
||||
* Use context parameter in models/git (#22367)
|
||||
* Always reuse transaction (#22362)
|
||||
* Fix unstable emoji sort (#22346)
|
||||
* Add context cache as a request level cache (#22294)
|
||||
* Reminder for no more logs to console (#22282)
|
||||
* Support estimated count with multiple schemas (#22276)
|
||||
* Move `convert` package to services (#22264)
|
||||
* Use dynamic package type list (#22263)
|
||||
* Hide file borders on sticky diff box (#22217)
|
||||
* Improve notification and stopwatch styles (#22169)
|
||||
* Fixed Project view .board-column height for tall screens. (#22108)
|
||||
* Use multi reader instead to concat strings (#22099)
|
||||
* Use git command instead of exec.Cmd in blame (#22098)
|
||||
* Fix autofilled text visibility in dark mode (#22088)
|
||||
* Rename almost all Ctx functions (#22071)
|
||||
* Rename actions to operations on UI (#22067)
|
||||
* refactor bind functions based on generics (#22055)
|
||||
* Support disabling database auto migration (#22053)
|
||||
* remove duplicated read file code (#22042)
|
||||
* Use link in UI which returned a relative url but not html_url which contains an absolute url (#21986)
|
||||
* Skip initing disabled storages (#21985)
|
||||
* Add doctor command for full GC of LFS (#21978)
|
||||
* Util type to parse ref name (#21969)
|
||||
* Replace fmt.Sprintf with hex.EncodeToString (#21960)
|
||||
* Use random bytes to generate access token (#21959)
|
||||
* Add index for access_token (#21908)
|
||||
* Move all remaining colors into CSS variables (#21903)
|
||||
* Webhook list enhancements (#21893)
|
||||
* Embed Matrix icon as SVG (#21890)
|
||||
* Remove useless "Cancel" buttons (#21872)
|
||||
* fix(web): keep the pages of the navigation in the center (#21867)
|
||||
* fix(web): reduce page jitter on browsers that support overlay scrollbar (#21850)
|
||||
* Improvements for Content Copy (#21842)
|
||||
* Tweak katex options (#21828)
|
||||
* Show syntax lexer name in file view/blame (#21814)
|
||||
* Remove `href="javascript:;"` in "save topics (Done)" button (#21813)
|
||||
* Render number of commits in repo page in a user friendly way (#21786)
|
||||
* Adjust clone timeout error to suggest increasing timeout (#21769)
|
||||
* Update message of reach_limit_of_creation (#21757)
|
||||
* Allow detect whether it's in a database transaction for a context.Context (#21756)
|
||||
* Add configuration for CORS allowed headers (#21747)
|
||||
* Move svg html render to modules/svg (#21716)
|
||||
* Release and Tag List tweaks (#21712)
|
||||
* Remove template previewer (#21701)
|
||||
* Clean up formatting on install page (#21668)
|
||||
* Configure update checker on installation page (#21655)
|
||||
* Merge db.Iterate and IterateObjects (#21641)
|
||||
* Add option to enable CAPTCHA validation for login (#21638)
|
||||
* Allow disable RSS/Atom feed (#21622)
|
||||
* Use CSS color-scheme instead of invert (#21616)
|
||||
* Localize time units on activity heatmap (#21570)
|
||||
* Fix UI column width, button overflow Fomantic's grid (#21559)
|
||||
* feat: notify doers of a merge when automerging (#21553)
|
||||
* Split migrations folder (#21549)
|
||||
* feat: add button to quickly clear merge message (#21548)
|
||||
* Add `context.Context` to more methods (#21546)
|
||||
* Add index for hook_task table (#21545)
|
||||
* Allow disable code tab (#20805)
|
||||
* BUGFIXES
|
||||
* Fix template error when reference Project (#23584)
|
||||
* Fix dropdown icon misalignment when using fomantic icon (#23558) (#23577)
|
||||
* Fix diff detail buttons wrapping, use tippy for review box (#23271) (#23546)
|
||||
* Handle missing `README` in create repos API (#23387) (#23510)
|
||||
* Disable sending email after push a commit to a closed PR (#23462) (#23492)
|
||||
* Fix aria.js bugs: incorrect role element problem, mobile focus problem, tippy problem (#23450) (#23486)
|
||||
* Fix due date being wrong on issue list (#23475) (#23477)
|
||||
* Remove wrongly added column on migration test fixtures (#23456) (#23470)
|
||||
* Make branches list page operations remember current page (#23420) (#23460)
|
||||
* Fix missing commit status in PR which from forked repo (#23351) (#23453)
|
||||
* Show edit/close/delete button on organization wide repositories (#23388) (#23429)
|
||||
* Preserve file size when creating attachments (#23406) (#23426)
|
||||
* Fix broken Chroma CSS styles (#23174) (#23402)
|
||||
* Fix incorrect NotFound conditions in org/projects.go (#23384) (#23395)
|
||||
* Set `X-Gitea-Debug` header once (#23361) (#23381)
|
||||
* Pass context to avatar for projects view (#23359) (#23378)
|
||||
* Fix panic when getting notes by ref (#23372) (#23377)
|
||||
* Do not recognize text files as audio (#23355) (#23368)
|
||||
* Fix adding of empty class name (#23352) (#23360)
|
||||
* Fix various ImageDiff/SVG bugs (#23312) (#23358)
|
||||
* Fix incorrect display for comment context menu (#23343) (#23344)
|
||||
* Remove unnecessary space on link (#23334) (#23340)
|
||||
* Fix incorrect redirect link of delete org project (#23327) (#23339)
|
||||
* Fix cannot reopen after pushing commits to a closed PR (#23189) (#23324)
|
||||
* Fix broken code editor diff preview (#23307) (#23320)
|
||||
* Support sanitising the URL by removing extra slashes in the URL (#21333) (#23300)
|
||||
* Avoid panic caused by broken payload when creating commit status (#23216) (#23294)
|
||||
* Fill head commit to in payload when notifying push commits for mirroring (#23215) (#23292)
|
||||
* Fix various bugs for "install" page (#23194) (#23286)
|
||||
* Fix GetFilesChangedBetween if the file name may be escaped (#23272) (#23279)
|
||||
* Revert relative links to absolute links in mail templates (#23267) (#23269)
|
||||
* Fix commit retrieval by tag (#21804) (#23266)
|
||||
* Use correct README link to render the README (#23152) (#23264)
|
||||
* Close the temp file when dumping database to make the temp file can be deleted on Windows (#23249) (#23251)
|
||||
* Use the correct selector to hide the checkmark of selected labels on clear (#23224) (#23228)
|
||||
* Fix incorrect checkbox behaviors in the dashboard repolist's filter (#23147) (#23205)
|
||||
* Properly flush unique queues on startup (#23154) (#23201)
|
||||
* Pass `--global` when calling `git config --get`, for consistency with `git config --set` (#23157) (#23199)
|
||||
* Make `gitea serv` respect git binary home (#23138) (#23197)
|
||||
* Change button text for commenting and closing an issue at the same time (#23135) (#23182)
|
||||
* Fix DBConsistency checks on MSSQL (#23132) (#23134)
|
||||
* Show empty repos in Admin Repository Management page (#23114) (#23130)
|
||||
* Redirect to the commit page after applying patch (#23056) (#23127)
|
||||
* Fix nil context in RenderMarkdownToHtml (#23092) (#23108)
|
||||
* Make issue meta dropdown support Enter, confirm before reloading (#23014) (#23102)
|
||||
* Fix SyncOnCommit always return false in API of push_mirrors (#23088) (#23100)
|
||||
* Fix commit name in Apply Patch page (#23086) (#23099)
|
||||
* Fix some more hidden problems (#23074) (#23075)
|
||||
* Bump golang.org/x/net from 0.4.0 to 0.7.0 (#22980)
|
||||
* Get rules by id when editing branch protection rule (#22932)
|
||||
* Fix panic when call api (/repos/{owner}/{repo}/pulls/{index}/files) (#22921)
|
||||
* Increase Content field size of gpg_import_key to MEDIUMTEXT (#22897)
|
||||
* Fix hidden commit status on multiple checks (#22889)
|
||||
* Fix update by rebase being wrongly disabled by protected base branch (#22825)
|
||||
* Make issue title edit buttons focusable and fix incorrect ajax requests (#22807)
|
||||
* Fix rerun button of Actions (#22798)
|
||||
* remove update language in ProfilePost (#22748)
|
||||
* Do not overwrite empty DefaultBranch (#22708)
|
||||
* Fix ref to trigger Actions (#22679)
|
||||
* Fix time to NotifyPullRequestSynchronized (#22650)
|
||||
* Show all projects, not just repo projects and open/closed projects (#22640)
|
||||
* Project links should use parent link methods (#22587)
|
||||
* Fix group filter for ldap source sync (#22506)
|
||||
* Check quota limits for container uploads (#22450)
|
||||
* Fix halfCommitter and WithTx (#22366)
|
||||
* Attempt to fix TestExportUserGPGKeys (#22159)
|
||||
* Fix heatmap first color being unused (#22157)
|
||||
* Fix scroll over mermaid frame (#21925)
|
||||
* Move migration test fixtures to the correct directories (#21901)
|
||||
* fix(web): add `alt` for logo in home page (#21887)
|
||||
* Fix webhook attachment text is not set in review comment (#21763)
|
||||
* Alter package_version.metadata_json to LONGTEXT (#21667)
|
||||
* Ensure that Webhook tasks are not double delivered (#21558)
|
||||
* TESTING
|
||||
* Make CI use a dummy password hasher for all tests (#22983)
|
||||
* Disable test for incoming email (#22686)
|
||||
* Move fuzz tests into tests/fuzz (#22376)
|
||||
* Test views of LFS files (#22196)
|
||||
* Specify ID in `TestAPITeam` (#22192)
|
||||
* verify nodeinfo response by schema (#22137)
|
||||
* Skip GitHub migration tests if the API token is undefined (#21824)
|
||||
* Add a simple test for external renderer (#20033)
|
||||
* TRANSLATION
|
||||
* Use "Title Case" for text "Reference in new issue" (#22936)
|
||||
* BUILD
|
||||
* Wrap unless-check in docker manifests (#23079) (#23081)
|
||||
* Adjust manifest to prevent tagging latest on rcs (#22811)
|
||||
* update to build with go1.20 (#22732)
|
||||
* Add Bash and Zsh completion scripts (#22646)
|
||||
* Add Contributed backport command (#22643)
|
||||
* Remove deprecated packages & staticcheck fixes (#22012)
|
||||
* Update to Alpine 3.17 (#21904)
|
||||
* Fix webpack license warning (#21815)
|
||||
* DOCS
|
||||
* Update documentation for the new YAML label file format (#23020) (#23341)
|
||||
* Update hacking-on-gitea-zh_cn documentation (#23315) (#23323)
|
||||
* Add basic documentation for labels, including scoped labels (#23304) (#23309)
|
||||
* Re-add accidentally removed `hacking-on-gitea.zh-cn.md` (#23297) (#23305)
|
||||
* Fix secrets overview page missing from docs sidebar (#23143) (#23145)
|
||||
* Add some guidelines for refactoring (#22880)
|
||||
* Explain that the no-access team unit does not affect public repositories (#22661)
|
||||
* Fix incorrect Redis URL snippets in the example app.ini (#22573)
|
||||
* docs: add swagger.json file location to FAQ (#22489)
|
||||
* Update index.de-de.md (#22363)
|
||||
* Update Gmail mailer configuration (#22291)
|
||||
* Add missed reverse proxy authentication documentation (#22250)
|
||||
* Add plural definitions for German translations (#21802)
|
||||
* Attempt clarify AppWorkPath etc. (#21656)
|
||||
* Add some documentation to packages (#21648)
|
||||
* MISC
|
||||
* Use `<nav>` instead of `<div>` in the global navbar (#23125) (#23533)
|
||||
* Do not create commit graph for temporary repos (#23219) (#23229)
|
||||
* Update button is shown when a Pull Request is marked WIP - Issue #21740 (#22683)
|
||||
* Add main landmark to templates and adjust titles (#22670)
|
||||
* Fix error on account activation with wrong passwd (#22609)
|
||||
* Update JS dependencies (#22538)
|
||||
* Display unreferenced packages total size in package admin panel (#22498)
|
||||
* Mobile fix for Project view: Add delay to Sortable.js on mobile, to ensure scrolling is possible. (#22152)
|
||||
* Update chroma to v2.4.0 (#22000)
|
||||
* Hide collapse icon in diff with no lines (#21094)
|
||||
|
||||
## [1.18.5](https://github.com/go-gitea/gitea/releases/tag/v1.18.5) - 2023-02-21
|
||||
|
||||
* ENHANCEMENTS
|
||||
|
||||
@@ -105,7 +105,7 @@ GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/m
|
||||
|
||||
FOMANTIC_WORK_DIR := web_src/fomantic
|
||||
|
||||
WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f)
|
||||
WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
|
||||
WEBPACK_CONFIGS := webpack.config.js
|
||||
WEBPACK_DEST := public/js/index.js public/css/index.css
|
||||
WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/img/webpack public/serviceworker.js
|
||||
@@ -131,7 +131,7 @@ TEST_TAGS ?= sqlite sqlite_unlock_notify
|
||||
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR)
|
||||
|
||||
GO_DIRS := cmd tests models modules routers build services tools
|
||||
WEB_DIRS := web_src/js web_src/less
|
||||
WEB_DIRS := web_src/js web_src/css
|
||||
|
||||
GO_SOURCES := $(wildcard *.go)
|
||||
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go)
|
||||
@@ -341,7 +341,7 @@ lint: lint-frontend lint-backend
|
||||
.PHONY: lint-frontend
|
||||
lint-frontend: node_modules
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e
|
||||
npx stylelint --color --max-warnings=0 web_src/less
|
||||
npx stylelint --color --max-warnings=0 web_src/css
|
||||
npx spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||
npx markdownlint docs *.md
|
||||
|
||||
@@ -859,6 +859,8 @@ fomantic:
|
||||
cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config
|
||||
cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/
|
||||
cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build
|
||||
# fomantic uses "touchstart" as click event for some browsers, it's not ideal, so we force fomantic to always use "click" as click event
|
||||
$(SED_INPLACE) -e 's/clickEvent[ \t]*=/clickEvent = "click", unstableClickEvent =/g' $(FOMANTIC_WORK_DIR)/build/semantic.js
|
||||
$(SED_INPLACE) -e 's/\r//g' $(FOMANTIC_WORK_DIR)/build/semantic.css $(FOMANTIC_WORK_DIR)/build/semantic.js
|
||||
rm -f $(FOMANTIC_WORK_DIR)/build/*.min.*
|
||||
|
||||
|
||||
Generated
-5
@@ -414,11 +414,6 @@
|
||||
"path": "github.com/go-git/go-git/v5/LICENSE",
|
||||
"licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under thiLine truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/go-ini/ini",
|
||||
"path": "github.com/go-ini/ini/LICENSE",
|
||||
"licenseText": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that YLine truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/go-ldap/ldap/v3",
|
||||
"path": "github.com/go-ldap/ldap/v3/LICENSE",
|
||||
|
||||
+10
-1
@@ -7,6 +7,7 @@ package cmd
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
@@ -469,11 +470,19 @@ func runAddOauth(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
config := parseOAuth2Config(c)
|
||||
if config.Provider == "openidConnect" {
|
||||
discoveryURL, err := url.Parse(config.OpenIDConnectAutoDiscoveryURL)
|
||||
if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") {
|
||||
return fmt.Errorf("invalid Auto Discovery URL: %s (this must be a valid URL starting with http:// or https://)", config.OpenIDConnectAutoDiscoveryURL)
|
||||
}
|
||||
}
|
||||
|
||||
return auth_model.CreateSource(&auth_model.Source{
|
||||
Type: auth_model.OAuth2,
|
||||
Name: c.String("name"),
|
||||
IsActive: true,
|
||||
Cfg: parseOAuth2Config(c),
|
||||
Cfg: config,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ func runConvert(ctx *cli.Context) error {
|
||||
log.Info("Log path: %s", setting.Log.RootPath)
|
||||
log.Info("Configuration file: %s", setting.CustomConf)
|
||||
|
||||
if !setting.Database.UseMySQL {
|
||||
if !setting.Database.Type.IsMySQL() {
|
||||
fmt.Println("This command can only be used with a MySQL database")
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-1
@@ -272,13 +272,14 @@ func runDump(ctx *cli.Context) error {
|
||||
fatal("Failed to create tmp file: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = dbDump.Close()
|
||||
if err := util.Remove(dbDump.Name()); err != nil {
|
||||
log.Warn("Unable to remove temporary file: %s: Error: %v", dbDump.Name(), err)
|
||||
}
|
||||
}()
|
||||
|
||||
targetDBType := ctx.String("database")
|
||||
if len(targetDBType) > 0 && targetDBType != setting.Database.Type {
|
||||
if len(targetDBType) > 0 && targetDBType != setting.Database.Type.String() {
|
||||
log.Info("Dumping database %s => %s...", setting.Database.Type, targetDBType)
|
||||
} else {
|
||||
log.Info("Dumping database...")
|
||||
|
||||
+15
-10
@@ -11,6 +11,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -290,17 +291,21 @@ func runServ(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Special handle for Windows.
|
||||
if setting.IsWindows {
|
||||
verb = strings.Replace(verb, "-", " ", 1)
|
||||
}
|
||||
|
||||
var gitcmd *exec.Cmd
|
||||
verbs := strings.Split(verb, " ")
|
||||
if len(verbs) == 2 {
|
||||
gitcmd = exec.CommandContext(ctx, verbs[0], verbs[1], repoPath)
|
||||
} else {
|
||||
gitcmd = exec.CommandContext(ctx, verb, repoPath)
|
||||
gitBinPath := filepath.Dir(git.GitExecutable) // e.g. /usr/bin
|
||||
gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack
|
||||
if _, err := os.Stat(gitBinVerb); err != nil {
|
||||
// if the command "git-upload-pack" doesn't exist, try to split "git-upload-pack" to use the sub-command with git
|
||||
// ps: Windows only has "git.exe" in the bin path, so Windows always uses this way
|
||||
verbFields := strings.SplitN(verb, "-", 2)
|
||||
if len(verbFields) == 2 {
|
||||
// use git binary with the sub-command part: "C:\...\bin\git.exe", "upload-pack", ...
|
||||
gitcmd = exec.CommandContext(ctx, git.GitExecutable, verbFields[1], repoPath)
|
||||
}
|
||||
}
|
||||
if gitcmd == nil {
|
||||
// by default, use the verb (it has been checked above by allowedCommands)
|
||||
gitcmd = exec.CommandContext(ctx, gitBinVerb, repoPath)
|
||||
}
|
||||
|
||||
process.SetSysProcAttribute(gitcmd)
|
||||
|
||||
@@ -1832,7 +1832,7 @@ ROUTER = console
|
||||
;ENABLED = true
|
||||
;;
|
||||
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
;ALLOWED_TYPES = .csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip
|
||||
;ALLOWED_TYPES = .csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip
|
||||
;;
|
||||
;; Max size of each file. Defaults to 4MB
|
||||
;MAX_SIZE = 4
|
||||
@@ -1871,6 +1871,9 @@ ROUTER = console
|
||||
;;
|
||||
;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||
;MINIO_USE_SSL = false
|
||||
;;
|
||||
;; Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
;MINIO_INSECURE_SKIP_VERIFY = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -2253,6 +2256,17 @@ ROUTER = console
|
||||
;PULL = 300
|
||||
;GC = 60
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Git Reflog timeout in days
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[git.reflog]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;ENABLED = true
|
||||
;EXPIRATION = 90
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[mirror]
|
||||
@@ -2552,6 +2566,9 @@ ROUTER = console
|
||||
;;
|
||||
;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||
;MINIO_USE_SSL = false
|
||||
;;
|
||||
;; Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
;MINIO_INSECURE_SKIP_VERIFY = false
|
||||
|
||||
;[proxy]
|
||||
;; Enable the proxy, all requests to external via HTTP will be affected
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-rootless
|
||||
{{#if build.tags}}
|
||||
{{#unless contains "-rc" build.tag}}
|
||||
{{#unless (contains "-rc" build.tag)}}
|
||||
tags:
|
||||
{{#each build.tags}}
|
||||
- {{this}}-rootless
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}
|
||||
{{#if build.tags}}
|
||||
{{#unless contains "-rc" build.tag }}
|
||||
{{#unless (contains "-rc" build.tag)}}
|
||||
tags:
|
||||
{{#each build.tags}}
|
||||
- {{this}}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
THEME := themes/gitea
|
||||
PUBLIC := public
|
||||
ARCHIVE := https://dl.gitea.io/theme/master.tar.gz
|
||||
ARCHIVE := https://dl.gitea.com/theme/main.tar.gz
|
||||
|
||||
HUGO_PACKAGE := github.com/gohugoio/hugo@v0.82.0
|
||||
|
||||
|
||||
@@ -841,7 +841,7 @@ Default templates for project boards:
|
||||
## Issue and pull request attachments (`attachment`)
|
||||
|
||||
- `ENABLED`: **true**: Whether issue and pull request attachments are enabled.
|
||||
- `ALLOWED_TYPES`: **.csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
- `ALLOWED_TYPES`: **.csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
- `MAX_SIZE`: **4**: Maximum size (MB).
|
||||
- `MAX_FILES`: **5**: Maximum number of attachments that can be uploaded at once.
|
||||
- `STORAGE_TYPE`: **local**: Storage type for attachments, `local` for local disk or `minio` for s3 compatible object storage service, default is `local` or other name defined with `[storage.xxx]`
|
||||
@@ -854,6 +854,7 @@ Default templates for project boards:
|
||||
- `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when STORAGE_TYPE is `minio`
|
||||
- `MINIO_BASE_PATH`: **attachments/**: Minio base path on the bucket only available when STORAGE_TYPE is `minio`
|
||||
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||
- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
|
||||
## Log (`log`)
|
||||
|
||||
@@ -1086,6 +1087,11 @@ Default templates for project boards:
|
||||
- `DISABLE_CORE_PROTECT_NTFS`: **false** Set to true to forcibly set `core.protectNTFS` to false.
|
||||
- `DISABLE_PARTIAL_CLONE`: **false** Disable the usage of using partial clones for git.
|
||||
|
||||
## Git - Reflog settings (`git.reflog`)
|
||||
|
||||
- `ENABLED`: **true** Set to true to enable Git to write changes to reflogs in each repo.
|
||||
- `EXPIRATION`: **90** Reflog entry lifetime, in days. Entries are removed opportunistically by Git.
|
||||
|
||||
## Git - Timeout settings (`git.timeout`)
|
||||
|
||||
- `DEFAULT`: **360**: Git operations default timeout seconds.
|
||||
@@ -1268,6 +1274,7 @@ is `data/lfs` and the default of `MINIO_BASE_PATH` is `lfs/`.
|
||||
- `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_BASE_PATH`: **lfs/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
|
||||
## Storage (`storage`)
|
||||
|
||||
@@ -1280,6 +1287,7 @@ Default storage configuration for attachments, lfs, avatars and etc.
|
||||
- `MINIO_BUCKET`: **gitea**: Minio bucket to store the data only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
|
||||
And you can also define a customize storage like below:
|
||||
|
||||
@@ -1298,6 +1306,8 @@ MINIO_BUCKET = gitea
|
||||
MINIO_LOCATION = us-east-1
|
||||
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||
MINIO_USE_SSL = false
|
||||
; Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
MINIO_INSECURE_SKIP_VERIFY = false
|
||||
```
|
||||
|
||||
And used by `[attachment]`, `[lfs]` and etc. as `STORAGE_TYPE`.
|
||||
@@ -1318,6 +1328,7 @@ is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`.
|
||||
- `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_BASE_PATH`: **repo-archive/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
|
||||
## Proxy (`proxy`)
|
||||
|
||||
|
||||
@@ -431,6 +431,8 @@ MINIO_BUCKET = gitea
|
||||
MINIO_LOCATION = us-east-1
|
||||
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||
MINIO_USE_SSL = false
|
||||
; Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
MINIO_INSECURE_SKIP_VERIFY = false
|
||||
```
|
||||
|
||||
然后你在 `[attachment]`, `[lfs]` 等中可以把这个名字用作 `STORAGE_TYPE` 的值。
|
||||
|
||||
@@ -282,9 +282,22 @@ To add custom .gitignore, add a file with existing [.gitignore rules](https://gi
|
||||
|
||||
### Labels
|
||||
|
||||
To add a custom label set, add a file that follows the [label format](https://github.com/go-gitea/gitea/blob/main/options/label/Default) to `$GITEA_CUSTOM/options/label`
|
||||
Starting with Gitea 1.19, you can add a file that follows the [YAML label format](https://github.com/go-gitea/gitea/blob/main/options/label/Advanced.yaml) to `$GITEA_CUSTOM/options/label`:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- name: "foo/bar" # name of the label that will appear in the dropdown
|
||||
exclusive: true # whether to use the exclusive namespace for scoped labels. scoped delimiter is /
|
||||
color: aabbcc # hex colour coding
|
||||
description: Some label # long description of label intent
|
||||
```
|
||||
|
||||
The [legacy file format](https://github.com/go-gitea/gitea/blob/main/options/label/Default) can still be used following the format below, however we strongly recommend using the newer YAML format instead.
|
||||
|
||||
`#hex-color label name ; label description`
|
||||
|
||||
For more information, see the [labels documentation]({{< relref "doc/usage/labels.en-us.md" >}}).
|
||||
|
||||
### Licenses
|
||||
|
||||
To add a custom license, add a file with the license text to `$GITEA_CUSTOM/options/license`
|
||||
@@ -341,7 +354,7 @@ To make a custom theme available to all users:
|
||||
|
||||
Community themes are listed in [gitea/awesome-gitea#themes](https://gitea.com/gitea/awesome-gitea#themes).
|
||||
|
||||
The `arc-green` theme source can be found [here](https://github.com/go-gitea/gitea/blob/main/web_src/less/themes/theme-arc-green.less).
|
||||
The `arc-green` theme source can be found [here](https://github.com/go-gitea/gitea/blob/main/web_src/css/themes/theme-arc-green.css).
|
||||
|
||||
If your custom theme is considered a dark theme, set the global css variable `--is-dark-theme` to `true`.
|
||||
This allows Gitea to adjust the Monaco code editor's theme accordingly.
|
||||
|
||||
@@ -21,13 +21,13 @@ menu:
|
||||
|
||||
## Background
|
||||
|
||||
Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue3](https://vuejs.org/) for its frontend.
|
||||
Gitea uses [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue3](https://vuejs.org/) for its frontend.
|
||||
|
||||
The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template).
|
||||
|
||||
The source files can be found in the following directories:
|
||||
|
||||
* **Less styles:** `web_src/less/`
|
||||
* **CSS styles:** `web_src/css/`
|
||||
* **JavaScript files:** `web_src/js/`
|
||||
* **Vue components:** `web_src/js/components/`
|
||||
* **Go HTML templates:** `templates/`
|
||||
|
||||
@@ -6,11 +6,11 @@ weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "developers"
|
||||
name: "Guidelines for Refactoring"
|
||||
weight: 20
|
||||
identifier: "guidelines-refactoring"
|
||||
sidebar:
|
||||
parent: "developers"
|
||||
name: "Guidelines for Refactoring"
|
||||
weight: 20
|
||||
identifier: "guidelines-refactoring"
|
||||
---
|
||||
|
||||
# Guidelines for Refactoring
|
||||
|
||||
@@ -0,0 +1,349 @@
|
||||
---
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "玩转 Gitea"
|
||||
slug: "hacking-on-gitea"
|
||||
weight: 10
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "developers"
|
||||
name: "玩转 Gitea"
|
||||
weight: 10
|
||||
identifier: "hacking-on-gitea"
|
||||
---
|
||||
|
||||
# Hacking on Gitea
|
||||
|
||||
**目录**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## 快速入门
|
||||
|
||||
要获得快速工作的开发环境,您可以使用 Gitpod。
|
||||
|
||||
[](https://gitpod.io/#https://github.com/go-gitea/gitea)
|
||||
|
||||
## 安装 Golang
|
||||
|
||||
您需要 [安装 go]( https://golang.org/doc/install ) 并设置您的 go 环境。
|
||||
|
||||
接下来,[使用 npm 安装 Node.js](https://nodejs.org/en/download/) ,这是构建
|
||||
JavaScript 和 CSS 文件的必要工具。最低支持的 Node.js 版本是 {{< min-node-version >}}
|
||||
并且推荐使用最新的 LTS 版本。
|
||||
|
||||
**注意** :当执行需要外部工具的 make 任务时,比如
|
||||
`make watch-backend`,Gitea 会自动下载并构建这些必要的组件。为了能够使用这些,你必须
|
||||
将 `"$GOPATH"/bin` 目录加入到可执行路径上。如果你不把go bin目录添加到可执行路径你必须手动
|
||||
指定可执行程序路径。
|
||||
|
||||
**注意2** :Go版本 {{< min-go-version >}} 或更高版本是必须的。Gitea 使用 `gofmt` 来
|
||||
格式化源代码。然而,`gofmt` 的结果可能因 `go` 的版本而有差异。因此推荐安装我们持续集成使用
|
||||
的 Go版本。截至上次更新,Go 版本应该是 {{< go-version >}}。
|
||||
|
||||
## 安装 Make
|
||||
|
||||
Gitea 大量使用 `Make` 来自动化任务和改进开发。本指南涵盖了如何安装 Make。
|
||||
|
||||
### 在 Linux 上
|
||||
|
||||
使用包管理器安装。
|
||||
|
||||
在 Ubuntu/Debian 上:
|
||||
|
||||
```bash
|
||||
sudo apt-get install make
|
||||
```
|
||||
|
||||
在 Fedora/RHEL/CentOS 上:
|
||||
|
||||
```bash
|
||||
sudo yum install make
|
||||
```
|
||||
|
||||
### 在 Windows 上
|
||||
|
||||
Make 的这三个发行版都可以在 Windows 上运行:
|
||||
|
||||
- [单个二进制构建]( http://www.equation.com/servlet/equation.cmd?fa=make )。复制到某处并添加到 `PATH`。
|
||||
- [32 位版本](http://www.equation.com/ftpdir/make/32/make.exe)
|
||||
- [64 位版本](http://www.equation.com/ftpdir/make/64/make.exe)
|
||||
- [MinGW-w64](https://www.mingw-w64.org) / [MSYS2](https://www.msys2.org/)。
|
||||
- MSYS2 是一个工具和库的集合,为您提供一个易于使用的环境来构建、安装和运行本机 Windows 软件,它包括 MinGW-w64。
|
||||
- 在 MingGW-w64 中,二进制文件称为 `mingw32-make.exe` 而不是 `make.exe`。将 `bin` 文件夹添加到 `PATH`。
|
||||
- 在 MSYS2 中,您可以直接使用 `make`。请参阅 [MSYS2 移植](https://www.msys2.org/wiki/Porting/)。
|
||||
- 要使用 CGO_ENABLED(例如:SQLite3)编译 Gitea,您可能需要使用 [tdm-gcc](https://jmeubank.github.io/tdm-gcc/) 而不是 MSYS2 gcc,因为 MSYS2 gcc 标头缺少一些 Windows -只有 CRT 函数像 _beginthread 一样。
|
||||
- [Chocolatey包管理器]( https://chocolatey.org/packages/make )。运行`choco install make`
|
||||
|
||||
**注意** :如果您尝试在 Windows 命令提示符下使用 make 进行构建,您可能会遇到问题。建议使用上述提示(Git bash 或 MinGW),但是如果您只有命令提示符(或可能是 PowerShell),则可以使用 [set](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/set_1) 命令,例如 `set TAGS=bindata`。
|
||||
|
||||
## 下载并克隆 Gitea 源代码
|
||||
|
||||
获取源代码的推荐方法是使用 `git clone`。
|
||||
|
||||
```bash
|
||||
git clone https://github.com/go-gitea/gitea
|
||||
```
|
||||
|
||||
(自从go modules出现后,不再需要构建 go 项目从 `$GOPATH` 中获取,因此不再推荐使用 `go get` 方法。)
|
||||
|
||||
## 派生 Gitea
|
||||
|
||||
如上所述下载主要的 Gitea 源代码。然后,派生 [Gitea 仓库](https://github.com/go-gitea/gitea),
|
||||
并为您的本地仓库切换 git 远程源,或添加另一个远程源:
|
||||
|
||||
```bash
|
||||
# 将原来的 Gitea origin 重命名为 upstream
|
||||
git remote rename origin upstream
|
||||
git remote add origin "git@github.com:$GITHUB_USERNAME/gitea.git"
|
||||
git fetch --all --prune
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```bash
|
||||
# 为我们的 fork 添加新的远程
|
||||
git remote add "$FORK_NAME" "git@github.com:$GITHUB_USERNAME/gitea.git"
|
||||
git fetch --all --prune
|
||||
```
|
||||
|
||||
为了能够创建合并请求,应将分叉存储库添加为 Gitea 本地仓库的远程,否则无法推送更改。
|
||||
|
||||
## 构建 Gitea(基本)
|
||||
|
||||
看看我们的
|
||||
<a href='{{ < relref "doc/installation/from-source.en-us.md" > }}'>说明</a>
|
||||
关于如何 <a href='{{ < relref "doc/installation/from-source.en-us.md" > }}'>从源代码构建</a> 。
|
||||
|
||||
从源代码构建的最简单推荐方法是:
|
||||
|
||||
```bash
|
||||
TAGS="bindata sqlite sqlite_unlock_notify" make build
|
||||
```
|
||||
|
||||
`build` 目标将同时执行 `frontend` 和 `backend` 子目标。如果存在 `bindata` 标签,资源文件将被编译成二进制文件。建议在进行前端开发时省略 `bindata` 标签,以便实时反映更改。
|
||||
|
||||
有关所有可用的 `make` 目标,请参阅 `make help`。另请参阅 [`.drone.yml`](https://github.com/go-gitea/gitea/blob/main/.drone.yml) 以了解我们的持续集成是如何工作的。
|
||||
|
||||
## 持续构建
|
||||
|
||||
要在源文件更改时运行并持续构建:
|
||||
|
||||
```bash
|
||||
# 对于前端和后端
|
||||
make watch
|
||||
|
||||
# 或者:只看前端文件(html/js/css)
|
||||
make watch-frontend
|
||||
|
||||
# 或者:只看后端文件 (go)
|
||||
make watch-backend
|
||||
```
|
||||
|
||||
在 macOS 上,监视所有后端源文件可能会达到默认的打开文件限制,这可以通过当前 shell 的 `ulimit -n 12288` 或所有未来 shell 的 shell 启动文件来增加。
|
||||
|
||||
### 格式化、代码分析和拼写检查
|
||||
|
||||
我们的持续集成将拒绝未通过代码检查(包括格式检查、代码分析和拼写检查)的 PR。
|
||||
|
||||
你应该格式化你的代码:
|
||||
|
||||
```bash
|
||||
make fmt
|
||||
```
|
||||
|
||||
并检查源代码:
|
||||
|
||||
```bash
|
||||
# lint 前端和后端代码
|
||||
make lint
|
||||
# 仅 lint 后端代码
|
||||
make lint-backend
|
||||
```
|
||||
|
||||
**注意** :`gofmt` 的结果取决于 `go` 的版本。您应该运行与持续集成相同的 go 版本。
|
||||
|
||||
### 处理 JS 和 CSS
|
||||
|
||||
前端开发应遵循 [Guidelines for Frontend Development]({{ < 相关参考 "doc/developers/guidelines-frontend.en-us.md" > }})
|
||||
|
||||
要使用前端资源构建,请使用上面提到的“watch-frontend”目标或只构建一次:
|
||||
|
||||
```bash
|
||||
make build && ./gitea
|
||||
```
|
||||
|
||||
在提交之前,确保 linters 通过:
|
||||
|
||||
```bash
|
||||
make lint-frontend
|
||||
```
|
||||
|
||||
### 配置本地 ElasticSearch 实例
|
||||
|
||||
使用 docker 启动本地 ElasticSearch 实例:
|
||||
|
||||
```sh
|
||||
mkdir -p $(pwd) /data/elasticsearch
|
||||
sudo chown -R 1000:1000 $(pwd) /data/elasticsearch
|
||||
docker run --rm --memory= "4g" -p 127.0.0.1:9200:9200 -p 127.0.0.1:9300:9300 -e "discovery.type=single-node" -v "$(pwd)/data /elasticsearch:/usr/share/elasticsearch/data" docker.elastic.co/elasticsearch/elasticsearch:7.16.3
|
||||
```
|
||||
|
||||
配置`app.ini`:
|
||||
|
||||
```ini
|
||||
[indexer]
|
||||
ISSUE_INDEXER_TYPE = elasticsearch
|
||||
ISSUE_INDEXER_CONN_STR = http://elastic:changeme@localhost:9200
|
||||
REPO_INDEXER_ENABLED = true
|
||||
REPO_INDEXER_TYPE = elasticsearch
|
||||
REPO_INDEXER_CONN_STR = http://elastic:changeme@localhost:9200
|
||||
```
|
||||
|
||||
### 构建和添加 SVGs
|
||||
|
||||
SVG 图标是使用 `make svg` 目标构建的,该目标将 `build/generate-svg.js` 中定义的图标源编译到输出目录 `public/img/svg` 中。可以在 `web_src/svg` 目录中添加自定义图标。
|
||||
|
||||
### 构建 Logo
|
||||
|
||||
Gitea Logo的 PNG 和 SVG 版本是使用 `TAGS="gitea" make generate-images` 目标从单个 SVG 源文件 assets/logo.svg 构建的。要运行它,Node.js 和 npm 必须可用。
|
||||
|
||||
通过更新 `assets/logo.svg` 并运行 `make generate-images`,同样的过程也可用于从 SVG 源文件生成自定义 Logo PNG。忽略 gitea 编译选项将仅更新用户指定的 LOGO 文件。
|
||||
|
||||
### 更新 API
|
||||
|
||||
创建新的 API 路由或修改现有的 API 路由时,您**必须**
|
||||
更新和/或创建 [Swagger](https://swagger.io/docs/specification/2-0/what-is-swagger/)
|
||||
这些使用 [go-swagger](https://goswagger.io/) 评论的文档。
|
||||
[规范]( https://goswagger.io/use/spec.html#annotation-syntax )中描述了这些注释的结构。
|
||||
如果您想了解更多有关 Swagger 结构的信息,可以查看
|
||||
[Swagger 2.0 文档](https://swagger.io/docs/specification/2-0/basic-structure/)
|
||||
或与添加新 API 端点的先前 PR 进行比较,例如 [PR #5483](https://github.com/go-gitea/gitea/pull/5843/files#diff-2e0a7b644cf31e1c8ef7d76b444fe3aaR20)
|
||||
|
||||
您应该注意不要破坏下游用户依赖的 API。在稳定的 API 上,一般来说添加是可以接受的,但删除
|
||||
或对 API 进行根本性更改将会被拒绝。
|
||||
|
||||
创建或更改 API 端点后,请用以下命令重新生成 Swagger 文档:
|
||||
|
||||
```bash
|
||||
make generate-swagger
|
||||
```
|
||||
|
||||
您应该验证生成的 Swagger 文件并使用以下命令对其进行拼写检查:
|
||||
|
||||
```bash
|
||||
make swagger-validate misspell-check
|
||||
```
|
||||
|
||||
您应该提交更改后的 swagger JSON 文件。持续集成服务器将使用以下方法检查是否已完成:
|
||||
|
||||
```bash
|
||||
make swagger-check
|
||||
```
|
||||
|
||||
**注意** :请注意,您应该使用 Swagger 2.0 文档,而不是 OpenAPI 3 文档。
|
||||
|
||||
### 创建新的配置选项
|
||||
|
||||
创建新的配置选项时,将它们添加到 `modules/setting` 的对应文件。您应该将信息添加到 `custom/conf/app.ini`
|
||||
并到 <a href = '{{ < relref "doc/advanced/config-cheat-sheet.en-us.md" > }}'>配置备忘单</a>
|
||||
在 `docs/content/doc/advanced/config-cheat-sheet.en-us.md` 中找到
|
||||
|
||||
### 更改Logo
|
||||
|
||||
更改 Gitea Logo SVG 时,您将需要运行并提交结果的:
|
||||
|
||||
```bash
|
||||
make generate-images
|
||||
```
|
||||
|
||||
这将创建必要的 Gitea 图标和其他图标。
|
||||
|
||||
### 数据库迁移
|
||||
|
||||
如果您对数据库中的任何数据库持久结构进行重大更改
|
||||
`models/` 目录,您将需要进行新的迁移。可以找到这些
|
||||
在 `models/migrations/` 中。您可以确保您的迁移适用于主要
|
||||
数据库类型使用:
|
||||
|
||||
```bash
|
||||
make test-sqlite-migration # 将 SQLite 切换为适当的数据库
|
||||
```
|
||||
|
||||
## 测试
|
||||
|
||||
Gitea 运行两种类型的测试:单元测试和集成测试。
|
||||
|
||||
### 单元测试
|
||||
|
||||
`go test` 系统中的`*_test.go` 涵盖了单元测试。
|
||||
您可以设置环境变量 `GITEA_UNIT_TESTS_LOG_SQL=1` 以在详细模式下运行测试时显示所有 SQL 语句(即设置`GOTESTFLAGS=-v` 时)。
|
||||
|
||||
```bash
|
||||
TAGS="bindata sqlite sqlite_unlock_notify" make test # Runs the unit tests
|
||||
```
|
||||
|
||||
### 集成测试
|
||||
|
||||
单元测试不会也不能完全单独测试 Gitea。因此,我们编写了集成测试;但是,这些依赖于数据库。
|
||||
|
||||
```bash
|
||||
TAGS="bindata sqlite sqlite_unlock_notify" make build test-sqlite
|
||||
```
|
||||
|
||||
将在 SQLite 环境中运行集成测试。集成测试需要安装 `git lfs`。其他数据库测试可用,但
|
||||
可能需要适应当地环境。
|
||||
|
||||
看看 [`tests/integration/README.md`](https://github.com/go-gitea/gitea/blob/main/tests/integration/README.md) 有关更多信息以及如何运行单个测试。
|
||||
|
||||
### 测试 PR
|
||||
|
||||
我们的持续集成将测试代码是否通过了单元测试,并且所有支持的数据库都将在 Docker 环境中通过集成测试。
|
||||
还将测试从几个最新版本的 Gitea 迁移。
|
||||
|
||||
请在PR中附带提交适当的单元测试和集成测试。
|
||||
|
||||
## 网站文档
|
||||
|
||||
该网站的文档位于 `docs/` 中。如果你改变了文档内容,你可以使用以下测试方法进行持续集成:
|
||||
|
||||
```bash
|
||||
# 来自 Gitea 中的 docs 目录
|
||||
make trans-copy clean build
|
||||
```
|
||||
|
||||
运行此任务依赖于 [Hugo](https://gohugo.io/)。请注意:这可能会生成一些未跟踪的 Git 对象,
|
||||
需要被清理干净。
|
||||
|
||||
## Visual Studio Code
|
||||
|
||||
`contrib/ide/vscode` 中为 Visual Studio Code 提供了 `launch.json` 和 `tasks.json`。查看
|
||||
[`contrib/ide/README.md`](https://github.com/go-gitea/gitea/blob/main/contrib/ide/README.md) 了解更多信息。
|
||||
|
||||
## Goland
|
||||
|
||||
单击 `/main.go` 中函数 `func main()` 上的 `Run Application` 箭头
|
||||
可以快速启动一个可调试的 Gitea 实例。
|
||||
|
||||
`Run/Debug Configuration` 中的 `Output Directory` 必须设置为
|
||||
gitea 项目目录(包含 `main.go` 和 `go.mod`),
|
||||
否则,启动实例的工作目录是 GoLand 的临时目录
|
||||
并防止 Gitea 在开发环境中加载动态资源(例如:模板)。
|
||||
|
||||
要在 GoLand 中使用 SQLite 运行单元测试,请设置 `-tags sqlite,sqlite_unlock_notify`
|
||||
在 `运行/调试配置` 的 `Go 工具参数` 中。
|
||||
|
||||
## 提交 PR
|
||||
|
||||
对更改感到满意后,将它们推送并打开拉取请求。它建议您允许 Gitea Managers 和 Owners 修改您的 PR
|
||||
分支,因为我们需要在合并之前将其更新为 main 和/或可能是能够直接帮助解决问题。
|
||||
|
||||
任何 PR 都需要 Gitea 维护者的两次批准,并且需要通过持续集成。看看我们的
|
||||
[CONTRIBUTING.md](https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md)
|
||||
文档。
|
||||
|
||||
如果您需要更多帮助,请访问 [Discord](https://discord.gg/gitea) #Develop 频道
|
||||
并在那里聊天。
|
||||
|
||||
现在,您已准备好 Hacking Gitea。
|
||||
@@ -9,7 +9,7 @@ menu:
|
||||
parent: "packages"
|
||||
name: "Overview"
|
||||
weight: 1
|
||||
identifier: "overview"
|
||||
identifier: "packages-overview"
|
||||
---
|
||||
|
||||
# Package Registry
|
||||
|
||||
@@ -9,7 +9,7 @@ menu:
|
||||
parent: "secrets"
|
||||
name: "Overview"
|
||||
weight: 1
|
||||
identifier: "overview"
|
||||
identifier: "secrets-overview"
|
||||
---
|
||||
|
||||
# Secrets
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
date: "2023-03-04T19:00:00+00:00"
|
||||
title: "Usage: Labels"
|
||||
slug: "labels"
|
||||
weight: 13
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "usage"
|
||||
name: "Labels"
|
||||
weight: 13
|
||||
identifier: "labels"
|
||||
---
|
||||
|
||||
# Labels
|
||||
|
||||
You can use labels to classify issues and pull requests and to improve your overview over them.
|
||||
|
||||
## Creating Labels
|
||||
|
||||
For repositories, labels can be created by going to `Issues` and clicking on `Labels`.
|
||||
|
||||
For organizations, you can define organization-wide labels that are shared with all organization repositories, including both already-existing repositories as well as newly created ones. Organization-wide labels can be created in the organization `Settings`.
|
||||
|
||||
Labels have a mandatory name, a mandatory color, an optional description, and must either be exclusive or not (see `Scoped Labels` below).
|
||||
|
||||
When you create a repository, you can ensure certain labels exist by using the `Issue Labels` option. This option lists a number of available label sets that are [configured globally on your instance](../customizing-gitea/#labels). Its contained labels will all be created as well while creating the repository.
|
||||
|
||||
## Scoped Labels
|
||||
|
||||
Scoped labels are used to ensure at most a single label with the same scope is assigned to an issue or pull request. For example, if labels `kind/bug` and `kind/enhancement` have the Exclusive option set, an issue can only be classified as a bug or an enhancement.
|
||||
|
||||
A scoped label must contain `/` in its name (not at either end of the name). The scope of a label is determined based on the **last** `/`, so for example the scope of label `scope/subscope/item` is `scope/subscope`.
|
||||
|
||||
## Filtering by Label
|
||||
|
||||
Issue and pull request lists can be filtered by label. Selecting multiple labels shows issues and pull requests that have all selected labels assigned.
|
||||
|
||||
By holding alt to click the label, issues and pull requests with the chosen label are excluded from the list.
|
||||
@@ -41,7 +41,7 @@ require (
|
||||
github.com/go-chi/cors v1.2.1
|
||||
github.com/go-enry/go-enry/v2 v2.8.3
|
||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
|
||||
github.com/go-git/go-billy/v5 v5.4.0
|
||||
github.com/go-git/go-billy/v5 v5.4.1
|
||||
github.com/go-git/go-git/v5 v5.5.2
|
||||
github.com/go-ldap/ldap/v3 v3.4.4
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
@@ -77,7 +77,7 @@ require (
|
||||
github.com/microcosm-cc/bluemonday v1.0.21
|
||||
github.com/minio/minio-go/v7 v7.0.46
|
||||
github.com/msteinert/pam v1.1.0
|
||||
github.com/nektos/act v0.0.0
|
||||
github.com/nektos/act v0.2.43
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/niklasfasching/go-org v1.6.5
|
||||
github.com/oliamb/cutter v0.2.2
|
||||
@@ -105,7 +105,7 @@ require (
|
||||
golang.org/x/crypto v0.4.0
|
||||
golang.org/x/net v0.7.0
|
||||
golang.org/x/oauth2 v0.3.0
|
||||
golang.org/x/sys v0.5.0
|
||||
golang.org/x/sys v0.6.0
|
||||
golang.org/x/text v0.7.0
|
||||
golang.org/x/tools v0.1.12
|
||||
google.golang.org/grpc v1.47.0
|
||||
@@ -172,7 +172,6 @@ require (
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-enry/go-oniguruma v1.2.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-openapi/analysis v0.21.4 // indirect
|
||||
github.com/go-openapi/errors v0.20.3 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
@@ -239,7 +238,7 @@ require (
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/rhysd/actionlint v1.6.22 // indirect
|
||||
github.com/rhysd/actionlint v1.6.23 // indirect
|
||||
github.com/rivo/uniseg v0.4.3 // indirect
|
||||
github.com/robfig/cron v1.2.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
@@ -271,7 +270,7 @@ require (
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
|
||||
@@ -286,7 +285,7 @@ replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142
|
||||
|
||||
replace github.com/blevesearch/zapx/v15 v15.3.6 => github.com/zeripath/zapx/v15 v15.3.6-alignment-fix
|
||||
|
||||
replace github.com/nektos/act => gitea.com/gitea/act v0.234.2-0.20230131074955-e46ede1b1744
|
||||
replace github.com/nektos/act => gitea.com/gitea/act v0.243.1
|
||||
|
||||
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsi
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
|
||||
gitea.com/gitea/act v0.234.2-0.20230131074955-e46ede1b1744 h1:cqzKmGlX0wynSXO04NILpL25eBGwogDrKpkkbwmIpj4=
|
||||
gitea.com/gitea/act v0.234.2-0.20230131074955-e46ede1b1744/go.mod h1:2C/WbTalu1VPNgbVaZJaZDzlOtAKqkXJhdOClxkMy14=
|
||||
gitea.com/gitea/act v0.243.1 h1:zIVlhGOLE4SHFPW++u3+5Y/jX5mub3QIhB13oNf6rtA=
|
||||
gitea.com/gitea/act v0.243.1/go.mod h1:iLHCXqOPUElA2nSyHo4wtxSmvdkym3WU7CkP3AxF39Q=
|
||||
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681 h1:MMSPgnVULVwV9kEBgvyEUhC9v/uviZ55hPJEMjpbNR4=
|
||||
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc=
|
||||
gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0=
|
||||
@@ -402,8 +402,9 @@ github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e/go.mod h1:RCMrTZv
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.4.0 h1:Vaw7LaSTRJOUric7pe4vnzBSgyuf2KrLsu2Y4ZpQBDE=
|
||||
github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
|
||||
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
|
||||
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
|
||||
github.com/go-git/go-git/v5 v5.5.2 h1:v8lgZa5k9ylUw+OR/roJHTxR4QItsNFI5nKtAXFuynw=
|
||||
@@ -411,8 +412,6 @@ github.com/go-git/go-git/v5 v5.5.2/go.mod h1:BE5hUJ5yaV2YMxhmaP4l6RBQ08kMxKSPD4B
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
@@ -791,7 +790,7 @@ github.com/jhillyerd/enmime v0.10.1 h1:3VP8gFhK7R948YJBrna5bOgnTXEuPAoICo79kKkBK
|
||||
github.com/jhillyerd/enmime v0.10.1/go.mod h1:Qpe8EEemJMFAF8+NZoWdpXvK2Yb9dRF0k/z6mkcDHsA=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
@@ -1099,8 +1098,8 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rhysd/actionlint v1.6.22 h1:cAEf2PGNwJXhdcTVF2xS/0ORqWS+ueUHwjQYsqFsGSk=
|
||||
github.com/rhysd/actionlint v1.6.22/go.mod h1:gIKOdxtV40mBOcD0ZR8EBa8NqjEXToAZioroS3oedMg=
|
||||
github.com/rhysd/actionlint v1.6.23 h1:041VOXgZddfvSJa9Il+WT3Iwuo/j0Nmu4bhpAScrds4=
|
||||
github.com/rhysd/actionlint v1.6.23/go.mod h1:o5qc1K3I9taGMBhL7mVkpRd64hx3YqI+3t8ewGfYXfE=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
|
||||
@@ -1501,8 +1500,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc=
|
||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1610,14 +1609,14 @@ golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
@@ -126,6 +126,17 @@ func (run *ActionRun) GetPushEventPayload() (*api.PushPayload, error) {
|
||||
return nil, fmt.Errorf("event %s is not a push event", run.Event)
|
||||
}
|
||||
|
||||
func (run *ActionRun) GetPullRequestEventPayload() (*api.PullRequestPayload, error) {
|
||||
if run.Event == webhook_module.HookEventPullRequest {
|
||||
var payload api.PullRequestPayload
|
||||
if err := json.Unmarshal([]byte(run.EventPayload), &payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &payload, nil
|
||||
}
|
||||
return nil, fmt.Errorf("event %s is not a pull request event", run.Event)
|
||||
}
|
||||
|
||||
func updateRepoRunsNumbers(ctx context.Context, repo *repo_model.Repository) error {
|
||||
_, err := db.GetEngine(ctx).ID(repo.ID).
|
||||
SetExpr("num_action_runs",
|
||||
@@ -194,6 +205,7 @@ func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWork
|
||||
if len(needs) > 0 {
|
||||
status = StatusBlocked
|
||||
}
|
||||
job.Name, _ = util.SplitStringAtByteN(job.Name, 255)
|
||||
runJobs = append(runJobs, &ActionRunJob{
|
||||
RunID: run.ID,
|
||||
RepoID: run.RepoID,
|
||||
|
||||
@@ -298,8 +298,9 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
|
||||
if len(workflowJob.Steps) > 0 {
|
||||
steps := make([]*ActionTaskStep, len(workflowJob.Steps))
|
||||
for i, v := range workflowJob.Steps {
|
||||
name, _ := util.SplitStringAtByteN(v.String(), 255)
|
||||
steps[i] = &ActionTaskStep{
|
||||
Name: v.String(),
|
||||
Name: name,
|
||||
TaskID: task.ID,
|
||||
Index: int64(i),
|
||||
RepoID: task.RepoID,
|
||||
|
||||
@@ -99,7 +99,7 @@ func (a *Action) TableIndices() []*schemas.Index {
|
||||
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")
|
||||
|
||||
indices := []*schemas.Index{actUserIndex, repoIndex}
|
||||
if setting.Database.UsePostgreSQL {
|
||||
if setting.Database.Type.IsPostgreSQL() {
|
||||
cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
|
||||
cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
|
||||
indices = append(indices, cudIndex)
|
||||
@@ -640,7 +640,7 @@ func DeleteIssueActions(ctx context.Context, repoID, issueID int64) error {
|
||||
|
||||
// CountActionCreatedUnixString count actions where created_unix is an empty string
|
||||
func CountActionCreatedUnixString(ctx context.Context) (int64, error) {
|
||||
if setting.Database.UseSQLite3 {
|
||||
if setting.Database.Type.IsSQLite3() {
|
||||
return db.GetEngine(ctx).Where(`created_unix = ""`).Count(new(Action))
|
||||
}
|
||||
return 0, nil
|
||||
@@ -648,7 +648,7 @@ func CountActionCreatedUnixString(ctx context.Context) (int64, error) {
|
||||
|
||||
// FixActionCreatedUnixString set created_unix to zero if it is an empty string
|
||||
func FixActionCreatedUnixString(ctx context.Context) (int64, error) {
|
||||
if setting.Database.UseSQLite3 {
|
||||
if setting.Database.Type.IsSQLite3() {
|
||||
res, err := db.GetEngine(ctx).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
||||
@@ -234,7 +234,7 @@ func TestGetFeedsCorrupted(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConsistencyUpdateAction(t *testing.T) {
|
||||
if !setting.Database.UseSQLite3 {
|
||||
if !setting.Database.Type.IsSQLite3() {
|
||||
t.Skip("Test is only for SQLite database.")
|
||||
}
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
@@ -39,9 +39,9 @@ func getUserHeatmapData(user *user_model.User, team *organization.Team, doer *us
|
||||
groupBy := "created_unix / 900 * 900"
|
||||
groupByName := "timestamp" // We need this extra case because mssql doesn't allow grouping by alias
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
groupBy = "created_unix DIV 900 * 900"
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
groupByName = groupBy
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ func generateEmailAvatarLink(ctx context.Context, email string, size int, final
|
||||
return DefaultAvatarLink()
|
||||
}
|
||||
|
||||
enableFederatedAvatar := system_model.GetSettingBool(ctx, system_model.KeyPictureEnableFederatedAvatar)
|
||||
enableFederatedAvatar := system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureEnableFederatedAvatar)
|
||||
|
||||
var err error
|
||||
if enableFederatedAvatar && system_model.LibravatarService != nil {
|
||||
@@ -174,7 +174,7 @@ func generateEmailAvatarLink(ctx context.Context, email string, size int, final
|
||||
return urlStr
|
||||
}
|
||||
|
||||
disableGravatar := system_model.GetSettingBool(ctx, system_model.KeyPictureDisableGravatar)
|
||||
disableGravatar := system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar)
|
||||
if !disableGravatar {
|
||||
// copy GravatarSourceURL, because we will modify its Path.
|
||||
avatarURLCopy := *system_model.GravatarSourceURL
|
||||
|
||||
@@ -28,7 +28,7 @@ func enableGravatar(t *testing.T) {
|
||||
err := system_model.SetSettingNoVersion(db.DefaultContext, system_model.KeyPictureDisableGravatar, "false")
|
||||
assert.NoError(t, err)
|
||||
setting.GravatarSource = gravatarSource
|
||||
err = system_model.Init()
|
||||
err = system_model.Init(db.DefaultContext)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import (
|
||||
// BuildCaseInsensitiveLike returns a condition to check if the given value is like the given key case-insensitively.
|
||||
// Handles especially SQLite correctly as UPPER there only transforms ASCII letters.
|
||||
func BuildCaseInsensitiveLike(key, value string) builder.Cond {
|
||||
if setting.Database.UseSQLite3 {
|
||||
if setting.Database.Type.IsSQLite3() {
|
||||
return builder.Like{"UPPER(" + key + ")", util.ToUpperASCII(value)}
|
||||
}
|
||||
return builder.Like{"UPPER(" + key + ")", strings.ToUpper(value)}
|
||||
|
||||
+2
-2
@@ -100,12 +100,12 @@ func newXORMEngine() (*xorm.Engine, error) {
|
||||
|
||||
var engine *xorm.Engine
|
||||
|
||||
if setting.Database.UsePostgreSQL && len(setting.Database.Schema) > 0 {
|
||||
if setting.Database.Type.IsPostgreSQL() && len(setting.Database.Schema) > 0 {
|
||||
// OK whilst we sort out our schema issues - create a schema aware postgres
|
||||
registerPostgresSchemaDriver()
|
||||
engine, err = xorm.NewEngine("postgresschema", connStr)
|
||||
} else {
|
||||
engine, err = xorm.NewEngine(setting.Database.Type, connStr)
|
||||
engine, err = xorm.NewEngine(setting.Database.Type.String(), connStr)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ func postgresGetNextResourceIndex(ctx context.Context, tableName string, groupID
|
||||
|
||||
// GetNextResourceIndex generates a resource index, it must run in the same transaction where the resource is created
|
||||
func GetNextResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
|
||||
if setting.Database.UsePostgreSQL {
|
||||
if setting.Database.Type.IsPostgreSQL() {
|
||||
return postgresGetNextResourceIndex(ctx, tableName, groupID)
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ func Find[T any](ctx context.Context, opts FindOptions, objects *[]T) error {
|
||||
if !opts.IsListAll() {
|
||||
sess.Limit(opts.GetSkipTake())
|
||||
}
|
||||
return sess.Find(&objects)
|
||||
return sess.Find(objects)
|
||||
}
|
||||
|
||||
// Count represents a common count function which accept an options interface
|
||||
@@ -148,5 +148,5 @@ func FindAndCount[T any](ctx context.Context, opts FindOptions, objects *[]T) (i
|
||||
if !opts.IsListAll() {
|
||||
sess.Limit(opts.GetSkipTake())
|
||||
}
|
||||
return sess.FindAndCount(&objects)
|
||||
return sess.FindAndCount(objects)
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package db_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
type mockListOptions struct {
|
||||
db.ListOptions
|
||||
}
|
||||
|
||||
func (opts *mockListOptions) IsListAll() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (opts *mockListOptions) ToConds() builder.Cond {
|
||||
return builder.NewCond()
|
||||
}
|
||||
|
||||
func TestFind(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
xe := unittest.GetXORMEngine()
|
||||
assert.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
|
||||
|
||||
opts := mockListOptions{}
|
||||
var repoUnits []repo_model.RepoUnit
|
||||
err := db.Find(db.DefaultContext, &opts, &repoUnits)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 83, len(repoUnits))
|
||||
|
||||
cnt, err := db.Count(db.DefaultContext, &opts, new(repo_model.RepoUnit))
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 83, cnt)
|
||||
|
||||
repoUnits = make([]repo_model.RepoUnit, 0, 10)
|
||||
newCnt, err := db.FindAndCount(db.DefaultContext, &opts, &repoUnits)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, cnt, newCnt)
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
// CountBadSequences looks for broken sequences from recreate-table mistakes
|
||||
func CountBadSequences(_ context.Context) (int64, error) {
|
||||
if !setting.Database.UsePostgreSQL {
|
||||
if !setting.Database.Type.IsPostgreSQL() {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ func CountBadSequences(_ context.Context) (int64, error) {
|
||||
|
||||
// FixBadSequences fixes for broken sequences from recreate-table mistakes
|
||||
func FixBadSequences(_ context.Context) error {
|
||||
if !setting.Database.UsePostgreSQL {
|
||||
if !setting.Database.Type.IsPostgreSQL() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
fork_id: 0
|
||||
is_template: false
|
||||
template_id: 0
|
||||
size: 6708
|
||||
size: 7028
|
||||
is_fsck_enabled: true
|
||||
close_issues_via_commit_in_any_branch: false
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ func postgresGetCommitStatusIndex(ctx context.Context, repoID int64, sha string)
|
||||
|
||||
// GetNextCommitStatusIndex retried 3 times to generate a resource index
|
||||
func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (int64, error) {
|
||||
if setting.Database.UsePostgreSQL {
|
||||
if setting.Database.Type.IsPostgreSQL() {
|
||||
return postgresGetCommitStatusIndex(ctx, repoID, sha)
|
||||
}
|
||||
|
||||
|
||||
+56
-67
@@ -7,12 +7,12 @@ package issues
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/label"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
@@ -78,9 +78,6 @@ func (err ErrLabelNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// LabelColorPattern is a regexp witch can validate LabelColor
|
||||
var LabelColorPattern = regexp.MustCompile("^#?(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})$")
|
||||
|
||||
// Label represents a label of repository for issues.
|
||||
type Label struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
@@ -109,12 +106,12 @@ func init() {
|
||||
}
|
||||
|
||||
// CalOpenIssues sets the number of open issues of a label based on the already stored number of closed issues.
|
||||
func (label *Label) CalOpenIssues() {
|
||||
label.NumOpenIssues = label.NumIssues - label.NumClosedIssues
|
||||
func (l *Label) CalOpenIssues() {
|
||||
l.NumOpenIssues = l.NumIssues - l.NumClosedIssues
|
||||
}
|
||||
|
||||
// CalOpenOrgIssues calculates the open issues of a label for a specific repo
|
||||
func (label *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) {
|
||||
func (l *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) {
|
||||
counts, _ := CountIssuesByRepo(ctx, &IssuesOptions{
|
||||
RepoID: repoID,
|
||||
LabelIDs: []int64{labelID},
|
||||
@@ -122,22 +119,22 @@ func (label *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64)
|
||||
})
|
||||
|
||||
for _, count := range counts {
|
||||
label.NumOpenRepoIssues += count
|
||||
l.NumOpenRepoIssues += count
|
||||
}
|
||||
}
|
||||
|
||||
// LoadSelectedLabelsAfterClick calculates the set of selected labels when a label is clicked
|
||||
func (label *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64, currentSelectedExclusiveScopes []string) {
|
||||
func (l *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64, currentSelectedExclusiveScopes []string) {
|
||||
var labelQuerySlice []string
|
||||
labelSelected := false
|
||||
labelID := strconv.FormatInt(label.ID, 10)
|
||||
labelScope := label.ExclusiveScope()
|
||||
labelID := strconv.FormatInt(l.ID, 10)
|
||||
labelScope := l.ExclusiveScope()
|
||||
for i, s := range currentSelectedLabels {
|
||||
if s == label.ID {
|
||||
if s == l.ID {
|
||||
labelSelected = true
|
||||
} else if -s == label.ID {
|
||||
} else if -s == l.ID {
|
||||
labelSelected = true
|
||||
label.IsExcluded = true
|
||||
l.IsExcluded = true
|
||||
} else if s != 0 {
|
||||
// Exclude other labels in the same scope from selection
|
||||
if s < 0 || labelScope == "" || labelScope != currentSelectedExclusiveScopes[i] {
|
||||
@@ -148,23 +145,23 @@ func (label *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64,
|
||||
if !labelSelected {
|
||||
labelQuerySlice = append(labelQuerySlice, labelID)
|
||||
}
|
||||
label.IsSelected = labelSelected
|
||||
label.QueryString = strings.Join(labelQuerySlice, ",")
|
||||
l.IsSelected = labelSelected
|
||||
l.QueryString = strings.Join(labelQuerySlice, ",")
|
||||
}
|
||||
|
||||
// BelongsToOrg returns true if label is an organization label
|
||||
func (label *Label) BelongsToOrg() bool {
|
||||
return label.OrgID > 0
|
||||
func (l *Label) BelongsToOrg() bool {
|
||||
return l.OrgID > 0
|
||||
}
|
||||
|
||||
// BelongsToRepo returns true if label is a repository label
|
||||
func (label *Label) BelongsToRepo() bool {
|
||||
return label.RepoID > 0
|
||||
func (l *Label) BelongsToRepo() bool {
|
||||
return l.RepoID > 0
|
||||
}
|
||||
|
||||
// Get color as RGB values in 0..255 range
|
||||
func (label *Label) ColorRGB() (float64, float64, float64, error) {
|
||||
color, err := strconv.ParseUint(label.Color[1:], 16, 64)
|
||||
func (l *Label) ColorRGB() (float64, float64, float64, error) {
|
||||
color, err := strconv.ParseUint(l.Color[1:], 16, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
@@ -176,9 +173,9 @@ func (label *Label) ColorRGB() (float64, float64, float64, error) {
|
||||
}
|
||||
|
||||
// Determine if label text should be light or dark to be readable on background color
|
||||
func (label *Label) UseLightTextColor() bool {
|
||||
if strings.HasPrefix(label.Color, "#") {
|
||||
if r, g, b, err := label.ColorRGB(); err == nil {
|
||||
func (l *Label) UseLightTextColor() bool {
|
||||
if strings.HasPrefix(l.Color, "#") {
|
||||
if r, g, b, err := l.ColorRGB(); err == nil {
|
||||
// Perceived brightness from: https://www.w3.org/TR/AERT/#color-contrast
|
||||
// In the future WCAG 3 APCA may be a better solution
|
||||
brightness := (0.299*r + 0.587*g + 0.114*b) / 255
|
||||
@@ -190,40 +187,26 @@ func (label *Label) UseLightTextColor() bool {
|
||||
}
|
||||
|
||||
// Return scope substring of label name, or empty string if none exists
|
||||
func (label *Label) ExclusiveScope() string {
|
||||
if !label.Exclusive {
|
||||
func (l *Label) ExclusiveScope() string {
|
||||
if !l.Exclusive {
|
||||
return ""
|
||||
}
|
||||
lastIndex := strings.LastIndex(label.Name, "/")
|
||||
if lastIndex == -1 || lastIndex == 0 || lastIndex == len(label.Name)-1 {
|
||||
lastIndex := strings.LastIndex(l.Name, "/")
|
||||
if lastIndex == -1 || lastIndex == 0 || lastIndex == len(l.Name)-1 {
|
||||
return ""
|
||||
}
|
||||
return label.Name[:lastIndex]
|
||||
return l.Name[:lastIndex]
|
||||
}
|
||||
|
||||
// NewLabel creates a new label
|
||||
func NewLabel(ctx context.Context, label *Label) error {
|
||||
if !LabelColorPattern.MatchString(label.Color) {
|
||||
return fmt.Errorf("bad color code: %s", label.Color)
|
||||
func NewLabel(ctx context.Context, l *Label) error {
|
||||
color, err := label.NormalizeColor(l.Color)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.Color = color
|
||||
|
||||
// normalize case
|
||||
label.Color = strings.ToLower(label.Color)
|
||||
|
||||
// add leading hash
|
||||
if label.Color[0] != '#' {
|
||||
label.Color = "#" + label.Color
|
||||
}
|
||||
|
||||
// convert 3-character shorthand into 6-character version
|
||||
if len(label.Color) == 4 {
|
||||
r := label.Color[1]
|
||||
g := label.Color[2]
|
||||
b := label.Color[3]
|
||||
label.Color = fmt.Sprintf("#%c%c%c%c%c%c", r, r, g, g, b, b)
|
||||
}
|
||||
|
||||
return db.Insert(ctx, label)
|
||||
return db.Insert(ctx, l)
|
||||
}
|
||||
|
||||
// NewLabels creates new labels
|
||||
@@ -234,11 +217,14 @@ func NewLabels(labels ...*Label) error {
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
for _, label := range labels {
|
||||
if !LabelColorPattern.MatchString(label.Color) {
|
||||
return fmt.Errorf("bad color code: %s", label.Color)
|
||||
for _, l := range labels {
|
||||
color, err := label.NormalizeColor(l.Color)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.Insert(ctx, label); err != nil {
|
||||
l.Color = color
|
||||
|
||||
if err := db.Insert(ctx, l); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -247,15 +233,18 @@ func NewLabels(labels ...*Label) error {
|
||||
|
||||
// UpdateLabel updates label information.
|
||||
func UpdateLabel(l *Label) error {
|
||||
if !LabelColorPattern.MatchString(l.Color) {
|
||||
return fmt.Errorf("bad color code: %s", l.Color)
|
||||
color, err := label.NormalizeColor(l.Color)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.Color = color
|
||||
|
||||
return updateLabelCols(db.DefaultContext, l, "name", "description", "color", "exclusive")
|
||||
}
|
||||
|
||||
// DeleteLabel delete a label
|
||||
func DeleteLabel(id, labelID int64) error {
|
||||
label, err := GetLabelByID(db.DefaultContext, labelID)
|
||||
l, err := GetLabelByID(db.DefaultContext, labelID)
|
||||
if err != nil {
|
||||
if IsErrLabelNotExist(err) {
|
||||
return nil
|
||||
@@ -271,10 +260,10 @@ func DeleteLabel(id, labelID int64) error {
|
||||
|
||||
sess := db.GetEngine(ctx)
|
||||
|
||||
if label.BelongsToOrg() && label.OrgID != id {
|
||||
if l.BelongsToOrg() && l.OrgID != id {
|
||||
return nil
|
||||
}
|
||||
if label.BelongsToRepo() && label.RepoID != id {
|
||||
if l.BelongsToRepo() && l.RepoID != id {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -682,14 +671,14 @@ func newIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer *us
|
||||
if err = issue.LoadRepo(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, label := range labels {
|
||||
for _, l := range labels {
|
||||
// Don't add already present labels and invalid labels
|
||||
if HasIssueLabel(ctx, issue.ID, label.ID) ||
|
||||
(label.RepoID != issue.RepoID && label.OrgID != issue.Repo.OwnerID) {
|
||||
if HasIssueLabel(ctx, issue.ID, l.ID) ||
|
||||
(l.RepoID != issue.RepoID && l.OrgID != issue.Repo.OwnerID) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err = newIssueLabel(ctx, issue, label, doer); err != nil {
|
||||
if err = newIssueLabel(ctx, issue, l, doer); err != nil {
|
||||
return fmt.Errorf("newIssueLabel: %w", err)
|
||||
}
|
||||
}
|
||||
@@ -778,7 +767,7 @@ func CountOrphanedLabels(ctx context.Context) (int64, error) {
|
||||
norepo, err := db.GetEngine(ctx).Table("label").
|
||||
Where(builder.And(
|
||||
builder.Gt{"repo_id": 0},
|
||||
builder.NotIn("repo_id", builder.Select("id").From("repository")),
|
||||
builder.NotIn("repo_id", builder.Select("id").From("`repository`")),
|
||||
)).
|
||||
Count()
|
||||
if err != nil {
|
||||
@@ -788,7 +777,7 @@ func CountOrphanedLabels(ctx context.Context) (int64, error) {
|
||||
noorg, err := db.GetEngine(ctx).Table("label").
|
||||
Where(builder.And(
|
||||
builder.Gt{"org_id": 0},
|
||||
builder.NotIn("org_id", builder.Select("id").From("user")),
|
||||
builder.NotIn("org_id", builder.Select("id").From("`user`")),
|
||||
)).
|
||||
Count()
|
||||
if err != nil {
|
||||
@@ -809,7 +798,7 @@ func DeleteOrphanedLabels(ctx context.Context) error {
|
||||
if _, err := db.GetEngine(ctx).
|
||||
Where(builder.And(
|
||||
builder.Gt{"repo_id": 0},
|
||||
builder.NotIn("repo_id", builder.Select("id").From("repository")),
|
||||
builder.NotIn("repo_id", builder.Select("id").From("`repository`")),
|
||||
)).
|
||||
Delete(Label{}); err != nil {
|
||||
return err
|
||||
@@ -819,7 +808,7 @@ func DeleteOrphanedLabels(ctx context.Context) error {
|
||||
if _, err := db.GetEngine(ctx).
|
||||
Where(builder.And(
|
||||
builder.Gt{"org_id": 0},
|
||||
builder.NotIn("org_id", builder.Select("id").From("user")),
|
||||
builder.NotIn("org_id", builder.Select("id").From("`user`")),
|
||||
)).
|
||||
Delete(Label{}); err != nil {
|
||||
return err
|
||||
|
||||
@@ -15,8 +15,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TODO TestGetLabelTemplateFile
|
||||
|
||||
func TestLabel_CalOpenIssues(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
|
||||
|
||||
@@ -52,13 +52,16 @@ func listPullRequestStatement(baseRepoID int64, opts *PullRequestsOptions) (*xor
|
||||
|
||||
// GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged
|
||||
// by given head information (repo and branch).
|
||||
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) {
|
||||
// arg `includeClosed` controls whether the SQL returns closed PRs
|
||||
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string, includeClosed bool) ([]*PullRequest, error) {
|
||||
prs := make([]*PullRequest, 0, 2)
|
||||
return prs, db.GetEngine(db.DefaultContext).
|
||||
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ? AND flow = ?",
|
||||
repoID, branch, false, false, PullRequestFlowGithub).
|
||||
sess := db.GetEngine(db.DefaultContext).
|
||||
Join("INNER", "issue", "issue.id = pull_request.issue_id").
|
||||
Find(&prs)
|
||||
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND flow = ?", repoID, branch, false, PullRequestFlowGithub)
|
||||
if !includeClosed {
|
||||
sess.Where("issue.is_closed = ?", false)
|
||||
}
|
||||
return prs, sess.Find(&prs)
|
||||
}
|
||||
|
||||
// CanMaintainerWriteToBranch check whether user is a maintainer and could write to the branch
|
||||
@@ -71,7 +74,7 @@ func CanMaintainerWriteToBranch(p access_model.Permission, branch string, user *
|
||||
return false
|
||||
}
|
||||
|
||||
prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch)
|
||||
prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch, false)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -111,6 +114,7 @@ func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequ
|
||||
return prs, db.GetEngine(db.DefaultContext).
|
||||
Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
|
||||
repoID, branch, false, false).
|
||||
OrderBy("issue.updated_unix DESC").
|
||||
Join("INNER", "issue", "issue.id=pull_request.issue_id").
|
||||
Find(&prs)
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
|
||||
func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(1, "branch2")
|
||||
prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(1, "branch2", false)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, prs, 1)
|
||||
for _, pr := range prs {
|
||||
|
||||
@@ -89,7 +89,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
||||
hasID = hasID || (column.IsPrimaryKey && column.IsAutoIncrement)
|
||||
}
|
||||
|
||||
if hasID && setting.Database.UseMSSQL {
|
||||
if hasID && setting.Database.Type.IsMSSQL() {
|
||||
if _, err := sess.Exec(fmt.Sprintf("SET IDENTITY_INSERT `%s` ON", tempTableName)); err != nil {
|
||||
log.Error("Unable to set identity insert for table %s. Error: %v", tempTableName, err)
|
||||
return err
|
||||
@@ -143,7 +143,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if hasID && setting.Database.UseMSSQL {
|
||||
if hasID && setting.Database.Type.IsMSSQL() {
|
||||
if _, err := sess.Exec(fmt.Sprintf("SET IDENTITY_INSERT `%s` OFF", tempTableName)); err != nil {
|
||||
log.Error("Unable to switch off identity insert for table %s. Error: %v", tempTableName, err)
|
||||
return err
|
||||
@@ -151,7 +151,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
||||
}
|
||||
|
||||
switch {
|
||||
case setting.Database.UseSQLite3:
|
||||
case setting.Database.Type.IsSQLite3():
|
||||
// SQLite will drop all the constraints on the old table
|
||||
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
||||
log.Error("Unable to drop old table %s. Error: %v", tableName, err)
|
||||
@@ -178,7 +178,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
// MySQL will drop all the constraints on the old table
|
||||
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
||||
log.Error("Unable to drop old table %s. Error: %v", tableName, err)
|
||||
@@ -205,7 +205,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
||||
log.Error("Unable to recreate uniques on table %s. Error: %v", tableName, err)
|
||||
return err
|
||||
}
|
||||
case setting.Database.UsePostgreSQL:
|
||||
case setting.Database.Type.IsPostgreSQL():
|
||||
var originalSequences []string
|
||||
type sequenceData struct {
|
||||
LastValue int `xorm:"'last_value'"`
|
||||
@@ -296,7 +296,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
||||
|
||||
}
|
||||
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
// MSSQL will drop all the constraints on the old table
|
||||
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
||||
log.Error("Unable to drop old table %s. Error: %v", tableName, err)
|
||||
@@ -323,7 +323,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
||||
// TODO: This will not work if there are foreign keys
|
||||
|
||||
switch {
|
||||
case setting.Database.UseSQLite3:
|
||||
case setting.Database.Type.IsSQLite3():
|
||||
// First drop the indexes on the columns
|
||||
res, errIndex := sess.Query(fmt.Sprintf("PRAGMA index_list(`%s`)", tableName))
|
||||
if errIndex != nil {
|
||||
@@ -405,7 +405,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
||||
return err
|
||||
}
|
||||
|
||||
case setting.Database.UsePostgreSQL:
|
||||
case setting.Database.Type.IsPostgreSQL():
|
||||
cols := ""
|
||||
for _, col := range columnNames {
|
||||
if cols != "" {
|
||||
@@ -416,7 +416,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
|
||||
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
|
||||
}
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
// Drop indexes on columns first
|
||||
sql := fmt.Sprintf("SHOW INDEX FROM %s WHERE column_name IN ('%s')", tableName, strings.Join(columnNames, "','"))
|
||||
res, err := sess.Query(sql)
|
||||
@@ -444,7 +444,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
|
||||
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
|
||||
}
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
cols := ""
|
||||
for _, col := range columnNames {
|
||||
if cols != "" {
|
||||
@@ -543,13 +543,13 @@ func newXORMEngine() (*xorm.Engine, error) {
|
||||
|
||||
func deleteDB() error {
|
||||
switch {
|
||||
case setting.Database.UseSQLite3:
|
||||
case setting.Database.Type.IsSQLite3():
|
||||
if err := util.Remove(setting.Database.Path); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.MkdirAll(path.Dir(setting.Database.Path), os.ModePerm)
|
||||
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/",
|
||||
setting.Database.User, setting.Database.Passwd, setting.Database.Host))
|
||||
if err != nil {
|
||||
@@ -565,7 +565,7 @@ func deleteDB() error {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case setting.Database.UsePostgreSQL:
|
||||
case setting.Database.Type.IsPostgreSQL():
|
||||
db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/?sslmode=%s",
|
||||
setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.SSLMode))
|
||||
if err != nil {
|
||||
@@ -612,7 +612,7 @@ func deleteDB() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
host, port := setting.ParseMSSQLHostPort(setting.Database.Host)
|
||||
db, err := sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;",
|
||||
host, port, "master", setting.Database.User, setting.Database.Passwd))
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
org_id: 0
|
||||
name: label1
|
||||
color: '#abcdef'
|
||||
exclusive: false
|
||||
num_issues: 2
|
||||
num_closed_issues: 0
|
||||
|
||||
@@ -14,7 +13,6 @@
|
||||
org_id: 0
|
||||
name: label2
|
||||
color: '#000000'
|
||||
exclusive: false
|
||||
num_issues: 1
|
||||
num_closed_issues: 1
|
||||
-
|
||||
@@ -23,7 +21,6 @@
|
||||
org_id: 3
|
||||
name: orglabel3
|
||||
color: '#abcdef'
|
||||
exclusive: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
|
||||
@@ -33,7 +30,6 @@
|
||||
org_id: 3
|
||||
name: orglabel4
|
||||
color: '#000000'
|
||||
exclusive: false
|
||||
num_issues: 1
|
||||
num_closed_issues: 0
|
||||
|
||||
@@ -43,6 +39,5 @@
|
||||
org_id: 0
|
||||
name: pull-test-label
|
||||
color: '#000000'
|
||||
exclusive: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
@@ -13,9 +13,9 @@ func PrependRefsHeadsToIssueRefs(x *xorm.Engine) error {
|
||||
var query string
|
||||
|
||||
switch {
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
query = "UPDATE `issue` SET `ref` = 'refs/heads/' + `ref` WHERE `ref` IS NOT NULL AND `ref` <> '' AND `ref` NOT LIKE 'refs/%'"
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
query = "UPDATE `issue` SET `ref` = CONCAT('refs/heads/', `ref`) WHERE `ref` IS NOT NULL AND `ref` <> '' AND `ref` NOT LIKE 'refs/%';"
|
||||
default:
|
||||
query = "UPDATE `issue` SET `ref` = 'refs/heads/' || `ref` WHERE `ref` IS NOT NULL AND `ref` <> '' AND `ref` NOT LIKE 'refs/%'"
|
||||
|
||||
@@ -41,7 +41,7 @@ func FixLanguageStatsToSaveSize(x *xorm.Engine) error {
|
||||
|
||||
// Delete language stat statuses
|
||||
truncExpr := "TRUNCATE TABLE"
|
||||
if setting.Database.UseSQLite3 {
|
||||
if setting.Database.Type.IsSQLite3() {
|
||||
truncExpr = "DELETE FROM"
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ func IncreaseLanguageField(x *xorm.Engine) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseSQLite3 {
|
||||
if setting.Database.Type.IsSQLite3() {
|
||||
// SQLite maps VARCHAR to TEXT without size so we're done
|
||||
return nil
|
||||
}
|
||||
@@ -41,11 +41,11 @@ func IncreaseLanguageField(x *xorm.Engine) error {
|
||||
}
|
||||
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat MODIFY COLUMN language %s", sqlType)); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
// Yet again MSSQL just has to be awkward.
|
||||
// Here we have to drop the constraints first and then rebuild them
|
||||
constraints := make([]string, 0)
|
||||
@@ -71,7 +71,7 @@ func IncreaseLanguageField(x *xorm.Engine) error {
|
||||
if err := sess.CreateUniques(new(LanguageStat)); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UsePostgreSQL:
|
||||
case setting.Database.Type.IsPostgreSQL():
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat ALTER COLUMN language TYPE %s", sqlType)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@ import (
|
||||
|
||||
func SetDefaultPasswordToArgon2(x *xorm.Engine) error {
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
_, err := x.Exec("ALTER TABLE `user` ALTER passwd_hash_algo SET DEFAULT 'argon2';")
|
||||
return err
|
||||
case setting.Database.UsePostgreSQL:
|
||||
case setting.Database.Type.IsPostgreSQL():
|
||||
_, err := x.Exec("ALTER TABLE `user` ALTER COLUMN passwd_hash_algo SET DEFAULT 'argon2';")
|
||||
return err
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
// need to find the constraint and drop it, then recreate it.
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
@@ -53,7 +53,7 @@ func SetDefaultPasswordToArgon2(x *xorm.Engine) error {
|
||||
}
|
||||
return sess.Commit()
|
||||
|
||||
case setting.Database.UseSQLite3:
|
||||
case setting.Database.Type.IsSQLite3():
|
||||
// drop through
|
||||
default:
|
||||
log.Fatal("Unrecognized DB")
|
||||
|
||||
@@ -62,7 +62,7 @@ func UpdateCodeCommentReplies(x *xorm.Engine) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseMSSQL {
|
||||
if setting.Database.Type.IsMSSQL() {
|
||||
if _, err := sess.Exec(sqlSelect + " INTO #temp_comments" + sqlTail); err != nil {
|
||||
log.Error("unable to create temporary table")
|
||||
return err
|
||||
@@ -72,13 +72,13 @@ func UpdateCodeCommentReplies(x *xorm.Engine) error {
|
||||
comments := make([]*Comment, 0, batchSize)
|
||||
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + ", " + strconv.Itoa(start)
|
||||
case setting.Database.UsePostgreSQL:
|
||||
case setting.Database.Type.IsPostgreSQL():
|
||||
fallthrough
|
||||
case setting.Database.UseSQLite3:
|
||||
case setting.Database.Type.IsSQLite3():
|
||||
sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + " OFFSET " + strconv.Itoa(start)
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
sqlCmd = "SELECT TOP " + strconv.Itoa(batchSize) + " * FROM #temp_comments WHERE " +
|
||||
"(id NOT IN ( SELECT TOP " + strconv.Itoa(start) + " id FROM #temp_comments ORDER BY id )) ORDER BY id"
|
||||
default:
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func FixPostgresIDSequences(x *xorm.Engine) error {
|
||||
if !setting.Database.UsePostgreSQL {
|
||||
if !setting.Database.Type.IsPostgreSQL() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -54,11 +54,11 @@ func RenameTaskErrorsToMessage(x *xorm.Engine) error {
|
||||
}
|
||||
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
if _, err := sess.Exec("sp_rename 'task.errors', 'message', 'COLUMN'"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func AlterIssueAndCommentTextFieldsToLongText(x *xorm.Engine) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseMySQL {
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
if _, err := sess.Exec("ALTER TABLE `issue` CHANGE `content` `content` LONGTEXT"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func AlterHookTaskTextFieldsToLongText(x *xorm.Engine) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseMySQL {
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
if _, err := sess.Exec("ALTER TABLE `hook_task` CHANGE `payload_content` `payload_content` LONGTEXT, CHANGE `request_content` `request_content` LONGTEXT, change `response_content` `response_content` LONGTEXT"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func (*improveActionTableIndicesAction) TableIndices() []*schemas.Index {
|
||||
actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType)
|
||||
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")
|
||||
indices := []*schemas.Index{actUserIndex, repoIndex}
|
||||
if setting.Database.UsePostgreSQL {
|
||||
if setting.Database.Type.IsPostgreSQL() {
|
||||
cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
|
||||
cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
|
||||
indices = append(indices, cudIndex)
|
||||
|
||||
@@ -65,11 +65,11 @@ func RenameCredentialIDBytes(x *xorm.Engine) error {
|
||||
}
|
||||
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
case setting.Database.Type.IsMySQL():
|
||||
if _, err := sess.Exec("ALTER TABLE `webauthn_credential` CHANGE credential_id_bytes credential_id VARBINARY(1024)"); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UseMSSQL:
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
if _, err := sess.Exec("sp_rename 'webauthn_credential.credential_id_bytes', 'credential_id', 'COLUMN'"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func AlterPublicGPGKeyContentFieldsToMediumText(x *xorm.Engine) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseMySQL {
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
if _, err := sess.Exec("ALTER TABLE `gpg_key` CHANGE `content` `content` MEDIUMTEXT"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func AlterPackageVersionMetadataToLongText(x *xorm.Engine) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseMySQL {
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
if _, err := sess.Exec("ALTER TABLE `package_version` MODIFY COLUMN `metadata_json` LONGTEXT"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ func AlterPublicGPGKeyImportContentFieldToMediumText(x *xorm.Engine) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseMySQL {
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
if _, err := sess.Exec("ALTER TABLE `gpg_key_import` CHANGE `content` `content` MEDIUMTEXT"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -239,6 +239,32 @@ func (org *Organization) CustomAvatarRelativePath() string {
|
||||
return org.Avatar
|
||||
}
|
||||
|
||||
// UnitPermission returns unit permission
|
||||
func (org *Organization) UnitPermission(ctx context.Context, doer *user_model.User, unitType unit.Type) perm.AccessMode {
|
||||
if doer != nil {
|
||||
teams, err := GetUserOrgTeams(ctx, org.ID, doer.ID)
|
||||
if err != nil {
|
||||
log.Error("GetUserOrgTeams: %v", err)
|
||||
return perm.AccessModeNone
|
||||
}
|
||||
|
||||
if err := teams.LoadUnits(ctx); err != nil {
|
||||
log.Error("LoadUnits: %v", err)
|
||||
return perm.AccessModeNone
|
||||
}
|
||||
|
||||
if len(teams) > 0 {
|
||||
return teams.UnitMaxAccess(unitType)
|
||||
}
|
||||
}
|
||||
|
||||
if org.Visibility.IsPublic() {
|
||||
return perm.AccessModeRead
|
||||
}
|
||||
|
||||
return perm.AccessModeNone
|
||||
}
|
||||
|
||||
// CreateOrganization creates record of a new organization.
|
||||
func CreateOrganization(org *Organization, owner *user_model.User) (err error) {
|
||||
if !owner.CanCreateOrganization() {
|
||||
|
||||
@@ -416,7 +416,7 @@ func DeleteProjectByID(ctx context.Context, id int64) error {
|
||||
|
||||
func DeleteProjectByRepoID(ctx context.Context, repoID int64) error {
|
||||
switch {
|
||||
case setting.Database.UseSQLite3:
|
||||
case setting.Database.Type.IsSQLite3():
|
||||
if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_issue WHERE project_issue.id IN (SELECT project_issue.id FROM project_issue INNER JOIN project WHERE project.id = project_issue.project_id AND project.repo_id = ?)", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -426,7 +426,7 @@ func DeleteProjectByRepoID(ctx context.Context, repoID int64) error {
|
||||
if _, err := db.GetEngine(ctx).Table("project").Where("repo_id = ? ", repoID).Delete(&Project{}); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UsePostgreSQL:
|
||||
case setting.Database.Type.IsPostgreSQL():
|
||||
if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_issue USING project WHERE project.id = project_issue.project_id AND project.repo_id = ? ", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+2
-2
@@ -39,9 +39,9 @@ import (
|
||||
var ItemsPerPage = 40
|
||||
|
||||
// Init initialize model
|
||||
func Init() error {
|
||||
func Init(ctx context.Context) error {
|
||||
unit.LoadUnitConfig()
|
||||
return system_model.Init()
|
||||
return system_model.Init(ctx)
|
||||
}
|
||||
|
||||
// DeleteRepository deletes a repository for a user or organization.
|
||||
|
||||
@@ -498,7 +498,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
|
||||
subQueryCond := builder.NewCond()
|
||||
|
||||
// Topic checking. Topics are present.
|
||||
if setting.Database.UsePostgreSQL { // postgres stores the topics as json and not as text
|
||||
if setting.Database.Type.IsPostgreSQL() { // postgres stores the topics as json and not as text
|
||||
subQueryCond = subQueryCond.Or(builder.And(builder.NotNull{"topics"}, builder.Neq{"(topics)::text": "[]"}))
|
||||
} else {
|
||||
subQueryCond = subQueryCond.Or(builder.And(builder.Neq{"topics": "null"}, builder.Neq{"topics": "[]"}))
|
||||
|
||||
+29
-20
@@ -79,8 +79,8 @@ func IsErrDataExpired(err error) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetSettingNoCache returns specific setting without using the cache
|
||||
func GetSettingNoCache(ctx context.Context, key string) (*Setting, error) {
|
||||
// GetSetting returns specific setting without using the cache
|
||||
func GetSetting(ctx context.Context, key string) (*Setting, error) {
|
||||
v, err := GetSettings(ctx, []string{key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -93,11 +93,11 @@ func GetSettingNoCache(ctx context.Context, key string) (*Setting, error) {
|
||||
|
||||
const contextCacheKey = "system_setting"
|
||||
|
||||
// GetSetting returns the setting value via the key
|
||||
func GetSetting(ctx context.Context, key string) (string, error) {
|
||||
// GetSettingWithCache returns the setting value via the key
|
||||
func GetSettingWithCache(ctx context.Context, key string) (string, error) {
|
||||
return cache.GetWithContextCache(ctx, contextCacheKey, key, func() (string, error) {
|
||||
return cache.GetString(genSettingCacheKey(key), func() (string, error) {
|
||||
res, err := GetSettingNoCache(ctx, key)
|
||||
res, err := GetSetting(ctx, key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -110,6 +110,15 @@ func GetSetting(ctx context.Context, key string) (string, error) {
|
||||
// none existing keys and errors are ignored and result in false
|
||||
func GetSettingBool(ctx context.Context, key string) bool {
|
||||
s, _ := GetSetting(ctx, key)
|
||||
if s == nil {
|
||||
return false
|
||||
}
|
||||
v, _ := strconv.ParseBool(s.SettingValue)
|
||||
return v
|
||||
}
|
||||
|
||||
func GetSettingWithCacheBool(ctx context.Context, key string) bool {
|
||||
s, _ := GetSettingWithCache(ctx, key)
|
||||
v, _ := strconv.ParseBool(s)
|
||||
return v
|
||||
}
|
||||
@@ -120,7 +129,7 @@ func GetSettings(ctx context.Context, keys []string) (map[string]*Setting, error
|
||||
keys[i] = strings.ToLower(keys[i])
|
||||
}
|
||||
settings := make([]*Setting, 0, len(keys))
|
||||
if err := db.GetEngine(db.DefaultContext).
|
||||
if err := db.GetEngine(ctx).
|
||||
Where(builder.In("setting_key", keys)).
|
||||
Find(&settings); err != nil {
|
||||
return nil, err
|
||||
@@ -151,9 +160,9 @@ func (settings AllSettings) GetVersion(key string) int {
|
||||
}
|
||||
|
||||
// GetAllSettings returns all settings from user
|
||||
func GetAllSettings() (AllSettings, error) {
|
||||
func GetAllSettings(ctx context.Context) (AllSettings, error) {
|
||||
settings := make([]*Setting, 0, 5)
|
||||
if err := db.GetEngine(db.DefaultContext).
|
||||
if err := db.GetEngine(ctx).
|
||||
Find(&settings); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -168,12 +177,12 @@ func GetAllSettings() (AllSettings, error) {
|
||||
func DeleteSetting(ctx context.Context, setting *Setting) error {
|
||||
cache.RemoveContextData(ctx, contextCacheKey, setting.SettingKey)
|
||||
cache.Remove(genSettingCacheKey(setting.SettingKey))
|
||||
_, err := db.GetEngine(db.DefaultContext).Delete(setting)
|
||||
_, err := db.GetEngine(ctx).Delete(setting)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetSettingNoVersion(ctx context.Context, key, value string) error {
|
||||
s, err := GetSettingNoCache(ctx, key)
|
||||
s, err := GetSetting(ctx, key)
|
||||
if IsErrSettingIsNotExist(err) {
|
||||
return SetSetting(ctx, &Setting{
|
||||
SettingKey: key,
|
||||
@@ -189,7 +198,7 @@ func SetSettingNoVersion(ctx context.Context, key, value string) error {
|
||||
|
||||
// SetSetting updates a users' setting for a specific key
|
||||
func SetSetting(ctx context.Context, setting *Setting) error {
|
||||
if err := upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version); err != nil {
|
||||
if err := upsertSettingValue(ctx, strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -205,8 +214,8 @@ func SetSetting(ctx context.Context, setting *Setting) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func upsertSettingValue(key, value string, version int) error {
|
||||
return db.WithTx(db.DefaultContext, func(ctx context.Context) error {
|
||||
func upsertSettingValue(parentCtx context.Context, key, value string, version int) error {
|
||||
return db.WithTx(parentCtx, func(ctx context.Context) error {
|
||||
e := db.GetEngine(ctx)
|
||||
|
||||
// here we use a general method to do a safe upsert for different databases (and most transaction levels)
|
||||
@@ -249,9 +258,9 @@ var (
|
||||
LibravatarService *libravatar.Libravatar
|
||||
)
|
||||
|
||||
func Init() error {
|
||||
func Init(ctx context.Context) error {
|
||||
var disableGravatar bool
|
||||
disableGravatarSetting, err := GetSettingNoCache(db.DefaultContext, KeyPictureDisableGravatar)
|
||||
disableGravatarSetting, err := GetSetting(ctx, KeyPictureDisableGravatar)
|
||||
if IsErrSettingIsNotExist(err) {
|
||||
disableGravatar = setting_module.GetDefaultDisableGravatar()
|
||||
disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)}
|
||||
@@ -262,7 +271,7 @@ func Init() error {
|
||||
}
|
||||
|
||||
var enableFederatedAvatar bool
|
||||
enableFederatedAvatarSetting, err := GetSettingNoCache(db.DefaultContext, KeyPictureEnableFederatedAvatar)
|
||||
enableFederatedAvatarSetting, err := GetSetting(ctx, KeyPictureEnableFederatedAvatar)
|
||||
if IsErrSettingIsNotExist(err) {
|
||||
enableFederatedAvatar = setting_module.GetDefaultEnableFederatedAvatar(disableGravatar)
|
||||
enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)}
|
||||
@@ -275,13 +284,13 @@ func Init() error {
|
||||
if setting_module.OfflineMode {
|
||||
disableGravatar = true
|
||||
enableFederatedAvatar = false
|
||||
if !GetSettingBool(db.DefaultContext, KeyPictureDisableGravatar) {
|
||||
if err := SetSettingNoVersion(db.DefaultContext, KeyPictureDisableGravatar, "true"); err != nil {
|
||||
if !GetSettingBool(ctx, KeyPictureDisableGravatar) {
|
||||
if err := SetSettingNoVersion(ctx, KeyPictureDisableGravatar, "true"); err != nil {
|
||||
return fmt.Errorf("Failed to set setting %q: %w", KeyPictureDisableGravatar, err)
|
||||
}
|
||||
}
|
||||
if GetSettingBool(db.DefaultContext, KeyPictureEnableFederatedAvatar) {
|
||||
if err := SetSettingNoVersion(db.DefaultContext, KeyPictureEnableFederatedAvatar, "false"); err != nil {
|
||||
if GetSettingBool(ctx, KeyPictureEnableFederatedAvatar) {
|
||||
if err := SetSettingNoVersion(ctx, KeyPictureEnableFederatedAvatar, "false"); err != nil {
|
||||
return fmt.Errorf("Failed to set setting %q: %w", KeyPictureEnableFederatedAvatar, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +40,10 @@ func TestSettings(t *testing.T) {
|
||||
|
||||
value, err := system.GetSetting(db.DefaultContext, keyName)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, updatedSetting.SettingValue, value)
|
||||
assert.EqualValues(t, updatedSetting.SettingValue, value.SettingValue)
|
||||
|
||||
// get all settings
|
||||
settings, err = system.GetAllSettings()
|
||||
settings, err = system.GetAllSettings(db.DefaultContext)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, settings, 3)
|
||||
assert.EqualValues(t, updatedSetting.SettingValue, settings[strings.ToLower(updatedSetting.SettingKey)].SettingValue)
|
||||
@@ -51,7 +51,7 @@ func TestSettings(t *testing.T) {
|
||||
// delete setting
|
||||
err = system.DeleteSetting(db.DefaultContext, &system.Setting{SettingKey: strings.ToLower(keyName)})
|
||||
assert.NoError(t, err)
|
||||
settings, err = system.GetAllSettings()
|
||||
settings, err = system.GetAllSettings(db.DefaultContext)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, settings, 2)
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
||||
setting.SSH.BuiltinServerUser = "builtinuser"
|
||||
setting.SSH.Port = 3000
|
||||
setting.SSH.Domain = "try.gitea.io"
|
||||
setting.Database.UseSQLite3 = true
|
||||
setting.Database.Type = "sqlite3"
|
||||
setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
|
||||
repoRootPath, err := os.MkdirTemp(os.TempDir(), "repos")
|
||||
if err != nil {
|
||||
@@ -113,7 +113,7 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
||||
if err = storage.Init(); err != nil {
|
||||
fatalTestError("storage.Init: %v\n", err)
|
||||
}
|
||||
if err = system_model.Init(); err != nil {
|
||||
if err = system_model.Init(db.DefaultContext); err != nil {
|
||||
fatalTestError("models.Init: %v\n", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ func (u *User) AvatarLinkWithSize(ctx context.Context, size int) string {
|
||||
useLocalAvatar := false
|
||||
autoGenerateAvatar := false
|
||||
|
||||
disableGravatar := system_model.GetSettingBool(ctx, system_model.KeyPictureDisableGravatar)
|
||||
disableGravatar := system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar)
|
||||
|
||||
switch {
|
||||
case u.UseCustomAvatar:
|
||||
|
||||
@@ -393,6 +393,11 @@ func (u *User) IsOrganization() bool {
|
||||
return u.Type == UserTypeOrganization
|
||||
}
|
||||
|
||||
// IsIndividual returns true if user is actually a individual user.
|
||||
func (u *User) IsIndividual() bool {
|
||||
return u.Type == UserTypeIndividual
|
||||
}
|
||||
|
||||
// DisplayName returns full name if it's not empty,
|
||||
// returns username otherwise.
|
||||
func (u *User) DisplayName() string {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package actions
|
||||
|
||||
import (
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
"github.com/nektos/act/pkg/jobparser"
|
||||
)
|
||||
|
||||
const (
|
||||
githubEventPullRequest = "pull_request"
|
||||
githubEventPullRequestTarget = "pull_request_target"
|
||||
githubEventPullRequestReviewComment = "pull_request_review_comment"
|
||||
githubEventPullRequestReview = "pull_request_review"
|
||||
githubEventRegistryPackage = "registry_package"
|
||||
githubEventCreate = "create"
|
||||
githubEventDelete = "delete"
|
||||
githubEventFork = "fork"
|
||||
githubEventPush = "push"
|
||||
githubEventIssues = "issues"
|
||||
githubEventIssueComment = "issue_comment"
|
||||
githubEventRelease = "release"
|
||||
githubEventPullRequestComment = "pull_request_comment"
|
||||
)
|
||||
|
||||
func convertFromGithubEvent(evt *jobparser.Event) string {
|
||||
switch evt.Name {
|
||||
case githubEventPullRequest, githubEventPullRequestTarget, githubEventPullRequestReview,
|
||||
githubEventPullRequestReviewComment:
|
||||
return string(webhook_module.HookEventPullRequest)
|
||||
case githubEventRegistryPackage:
|
||||
return string(webhook_module.HookEventPackage)
|
||||
case githubEventCreate, githubEventDelete, githubEventFork, githubEventPush,
|
||||
githubEventIssues, githubEventIssueComment, githubEventRelease, githubEventPullRequestComment:
|
||||
fallthrough
|
||||
default:
|
||||
return evt.Name
|
||||
}
|
||||
}
|
||||
+179
-122
@@ -72,9 +72,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
|
||||
continue
|
||||
}
|
||||
for _, evt := range events {
|
||||
if evt.Name != triggedEvent.Event() {
|
||||
continue
|
||||
}
|
||||
log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent)
|
||||
if detectMatched(commit, triggedEvent, payload, evt) {
|
||||
workflows[entry.Name()] = content
|
||||
}
|
||||
@@ -85,138 +83,197 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
|
||||
}
|
||||
|
||||
func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool {
|
||||
if convertFromGithubEvent(evt) != string(triggedEvent) {
|
||||
return false
|
||||
}
|
||||
|
||||
switch triggedEvent {
|
||||
case webhook_module.HookEventCreate,
|
||||
webhook_module.HookEventDelete,
|
||||
webhook_module.HookEventFork,
|
||||
webhook_module.HookEventIssueAssign,
|
||||
webhook_module.HookEventIssueLabel,
|
||||
webhook_module.HookEventIssueMilestone,
|
||||
webhook_module.HookEventPullRequestAssign,
|
||||
webhook_module.HookEventPullRequestLabel,
|
||||
webhook_module.HookEventPullRequestMilestone,
|
||||
webhook_module.HookEventPullRequestComment,
|
||||
webhook_module.HookEventPullRequestReviewApproved,
|
||||
webhook_module.HookEventPullRequestReviewRejected,
|
||||
webhook_module.HookEventPullRequestReviewComment,
|
||||
webhook_module.HookEventWiki,
|
||||
webhook_module.HookEventRepository,
|
||||
webhook_module.HookEventRelease,
|
||||
webhook_module.HookEventPackage:
|
||||
if len(evt.Acts) != 0 {
|
||||
log.Warn("Ignore unsupported %s event arguments %q", triggedEvent, evt.Acts)
|
||||
}
|
||||
// no special filter parameters for these events, just return true if name matched
|
||||
return true
|
||||
|
||||
case webhook_module.HookEventPush:
|
||||
return matchPushEvent(commit, payload.(*api.PushPayload), evt)
|
||||
|
||||
case webhook_module.HookEventIssues:
|
||||
return matchIssuesEvent(commit, payload.(*api.IssuePayload), evt)
|
||||
|
||||
case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync:
|
||||
return matchPullRequestEvent(commit, payload.(*api.PullRequestPayload), evt)
|
||||
|
||||
case webhook_module.HookEventIssueComment:
|
||||
return matchIssueCommentEvent(commit, payload.(*api.IssueCommentPayload), evt)
|
||||
|
||||
default:
|
||||
log.Warn("unsupported event %q", triggedEvent)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobparser.Event) bool {
|
||||
// with no special filter parameters
|
||||
if len(evt.Acts) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
switch triggedEvent {
|
||||
case webhook_module.HookEventCreate:
|
||||
fallthrough
|
||||
case webhook_module.HookEventDelete:
|
||||
fallthrough
|
||||
case webhook_module.HookEventFork:
|
||||
log.Warn("unsupported event %q", triggedEvent.Event())
|
||||
return false
|
||||
case webhook_module.HookEventPush:
|
||||
pushPayload := payload.(*api.PushPayload)
|
||||
matchTimes := 0
|
||||
// all acts conditions should be satisfied
|
||||
for cond, vals := range evt.Acts {
|
||||
switch cond {
|
||||
case "branches", "tags":
|
||||
refShortName := git.RefName(pushPayload.Ref).ShortName()
|
||||
for _, val := range vals {
|
||||
if glob.MustCompile(val, '/').Match(refShortName) {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
matchTimes := 0
|
||||
// all acts conditions should be satisfied
|
||||
for cond, vals := range evt.Acts {
|
||||
switch cond {
|
||||
case "branches", "tags":
|
||||
refShortName := git.RefName(pushPayload.Ref).ShortName()
|
||||
for _, val := range vals {
|
||||
if glob.MustCompile(val, '/').Match(refShortName) {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
case "paths":
|
||||
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
|
||||
if err != nil {
|
||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
||||
} else {
|
||||
for _, val := range vals {
|
||||
matched := false
|
||||
for _, file := range filesChanged {
|
||||
if glob.MustCompile(val, '/').Match(file) {
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if matched {
|
||||
matchTimes++
|
||||
}
|
||||
case "paths":
|
||||
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
|
||||
if err != nil {
|
||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
||||
} else {
|
||||
for _, val := range vals {
|
||||
matched := false
|
||||
for _, file := range filesChanged {
|
||||
if glob.MustCompile(val, '/').Match(file) {
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Warn("unsupported condition %q", cond)
|
||||
}
|
||||
}
|
||||
return matchTimes == len(evt.Acts)
|
||||
|
||||
case webhook_module.HookEventIssues:
|
||||
fallthrough
|
||||
case webhook_module.HookEventIssueAssign:
|
||||
fallthrough
|
||||
case webhook_module.HookEventIssueLabel:
|
||||
fallthrough
|
||||
case webhook_module.HookEventIssueMilestone:
|
||||
fallthrough
|
||||
case webhook_module.HookEventIssueComment:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPullRequest:
|
||||
prPayload := payload.(*api.PullRequestPayload)
|
||||
matchTimes := 0
|
||||
// all acts conditions should be satisfied
|
||||
for cond, vals := range evt.Acts {
|
||||
switch cond {
|
||||
case "types":
|
||||
for _, val := range vals {
|
||||
if glob.MustCompile(val, '/').Match(string(prPayload.Action)) {
|
||||
if matched {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
}
|
||||
case "branches":
|
||||
refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName()
|
||||
for _, val := range vals {
|
||||
if glob.MustCompile(val, '/').Match(refShortName) {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
}
|
||||
case "paths":
|
||||
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
|
||||
if err != nil {
|
||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
||||
} else {
|
||||
for _, val := range vals {
|
||||
matched := false
|
||||
for _, file := range filesChanged {
|
||||
if glob.MustCompile(val, '/').Match(file) {
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if matched {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Warn("unsupported condition %q", cond)
|
||||
}
|
||||
default:
|
||||
log.Warn("push event unsupported condition %q", cond)
|
||||
}
|
||||
return matchTimes == len(evt.Acts)
|
||||
case webhook_module.HookEventPullRequestAssign:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPullRequestLabel:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPullRequestMilestone:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPullRequestComment:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPullRequestReviewApproved:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPullRequestReviewRejected:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPullRequestReviewComment:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPullRequestSync:
|
||||
fallthrough
|
||||
case webhook_module.HookEventWiki:
|
||||
fallthrough
|
||||
case webhook_module.HookEventRepository:
|
||||
fallthrough
|
||||
case webhook_module.HookEventRelease:
|
||||
fallthrough
|
||||
case webhook_module.HookEventPackage:
|
||||
fallthrough
|
||||
default:
|
||||
log.Warn("unsupported event %q", triggedEvent.Event())
|
||||
}
|
||||
return false
|
||||
return matchTimes == len(evt.Acts)
|
||||
}
|
||||
|
||||
func matchIssuesEvent(commit *git.Commit, issuePayload *api.IssuePayload, evt *jobparser.Event) bool {
|
||||
// with no special filter parameters
|
||||
if len(evt.Acts) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
matchTimes := 0
|
||||
// all acts conditions should be satisfied
|
||||
for cond, vals := range evt.Acts {
|
||||
switch cond {
|
||||
case "types":
|
||||
for _, val := range vals {
|
||||
if glob.MustCompile(val, '/').Match(string(issuePayload.Action)) {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Warn("issue event unsupported condition %q", cond)
|
||||
}
|
||||
}
|
||||
return matchTimes == len(evt.Acts)
|
||||
}
|
||||
|
||||
func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
|
||||
// with no special filter parameters
|
||||
if len(evt.Acts) == 0 {
|
||||
// defaultly, only pull request opened and synchronized will trigger workflow
|
||||
return prPayload.Action == api.HookIssueSynchronized || prPayload.Action == api.HookIssueOpened
|
||||
}
|
||||
|
||||
matchTimes := 0
|
||||
// all acts conditions should be satisfied
|
||||
for cond, vals := range evt.Acts {
|
||||
switch cond {
|
||||
case "types":
|
||||
action := prPayload.Action
|
||||
if prPayload.Action == api.HookIssueSynchronized {
|
||||
action = "synchronize"
|
||||
}
|
||||
log.Trace("matching pull_request %s with %v", action, vals)
|
||||
for _, val := range vals {
|
||||
if glob.MustCompile(val, '/').Match(string(action)) {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
}
|
||||
case "branches":
|
||||
refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName()
|
||||
for _, val := range vals {
|
||||
if glob.MustCompile(val, '/').Match(refShortName) {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
}
|
||||
case "paths":
|
||||
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
|
||||
if err != nil {
|
||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
||||
} else {
|
||||
for _, val := range vals {
|
||||
matched := false
|
||||
for _, file := range filesChanged {
|
||||
if glob.MustCompile(val, '/').Match(file) {
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if matched {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Warn("pull request event unsupported condition %q", cond)
|
||||
}
|
||||
}
|
||||
return matchTimes == len(evt.Acts)
|
||||
}
|
||||
|
||||
func matchIssueCommentEvent(commit *git.Commit, issueCommentPayload *api.IssueCommentPayload, evt *jobparser.Event) bool {
|
||||
// with no special filter parameters
|
||||
if len(evt.Acts) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
matchTimes := 0
|
||||
// all acts conditions should be satisfied
|
||||
for cond, vals := range evt.Acts {
|
||||
switch cond {
|
||||
case "types":
|
||||
for _, val := range vals {
|
||||
if glob.MustCompile(val, '/').Match(string(issueCommentPayload.Action)) {
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Warn("issue comment unsupported condition %q", cond)
|
||||
}
|
||||
}
|
||||
return matchTimes == len(evt.Acts)
|
||||
}
|
||||
@@ -41,9 +41,8 @@ var RecommendedHashAlgorithms = []string{
|
||||
"pbkdf2_hi",
|
||||
}
|
||||
|
||||
// SetDefaultPasswordHashAlgorithm will take a provided algorithmName and dealias it to
|
||||
// a complete algorithm specification.
|
||||
func SetDefaultPasswordHashAlgorithm(algorithmName string) (string, *PasswordHashAlgorithm) {
|
||||
// hashAlgorithmToSpec converts an algorithm name or a specification to a full algorithm specification
|
||||
func hashAlgorithmToSpec(algorithmName string) string {
|
||||
if algorithmName == "" {
|
||||
algorithmName = DefaultHashAlgorithmName
|
||||
}
|
||||
@@ -52,10 +51,26 @@ func SetDefaultPasswordHashAlgorithm(algorithmName string) (string, *PasswordHas
|
||||
algorithmName = alias
|
||||
alias, has = aliasAlgorithmNames[algorithmName]
|
||||
}
|
||||
|
||||
// algorithmName should now be a full algorithm specification
|
||||
// e.g. pbkdf2$50000$50 rather than pbdkf2
|
||||
DefaultHashAlgorithm = Parse(algorithmName)
|
||||
|
||||
return algorithmName, DefaultHashAlgorithm
|
||||
return algorithmName
|
||||
}
|
||||
|
||||
// SetDefaultPasswordHashAlgorithm will take a provided algorithmName and de-alias it to
|
||||
// a complete algorithm specification.
|
||||
func SetDefaultPasswordHashAlgorithm(algorithmName string) (string, *PasswordHashAlgorithm) {
|
||||
algoSpec := hashAlgorithmToSpec(algorithmName)
|
||||
// now we get a full specification, e.g. pbkdf2$50000$50 rather than pbdkf2
|
||||
DefaultHashAlgorithm = Parse(algoSpec)
|
||||
return algoSpec, DefaultHashAlgorithm
|
||||
}
|
||||
|
||||
// ConfigHashAlgorithm will try to find a "recommended algorithm name" defined by RecommendedHashAlgorithms for config
|
||||
// This function is not fast and is only used for the installation page
|
||||
func ConfigHashAlgorithm(algorithm string) string {
|
||||
algorithm = hashAlgorithmToSpec(algorithm)
|
||||
for _, recommAlgo := range RecommendedHashAlgorithms {
|
||||
if algorithm == hashAlgorithmToSpec(recommAlgo) {
|
||||
return recommAlgo
|
||||
}
|
||||
}
|
||||
return algorithm
|
||||
}
|
||||
@@ -244,7 +244,7 @@ func APIContexter() func(http.Handler) http.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, "no-transform")
|
||||
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), 0, "no-transform")
|
||||
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
||||
|
||||
ctx.Data["Context"] = &ctx
|
||||
|
||||
@@ -388,7 +388,7 @@ func (ctx *Context) SetServeHeaders(opts *ServeHeaderOptions) {
|
||||
if duration == 0 {
|
||||
duration = 5 * time.Minute
|
||||
}
|
||||
httpcache.AddCacheControlToHeader(header, duration)
|
||||
httpcache.SetCacheControlInHeader(header, duration)
|
||||
|
||||
if !opts.LastModified.IsZero() {
|
||||
header.Set("Last-Modified", opts.LastModified.UTC().Format(http.TimeFormat))
|
||||
@@ -753,7 +753,7 @@ func Contexter(ctx context.Context) func(next http.Handler) http.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, "no-transform")
|
||||
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), 0, "no-transform")
|
||||
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
||||
|
||||
ctx.Data["CsrfToken"] = ctx.csrf.GetToken()
|
||||
|
||||
+44
-34
@@ -11,7 +11,6 @@ import (
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
@@ -31,29 +30,34 @@ type Organization struct {
|
||||
}
|
||||
|
||||
func (org *Organization) CanWriteUnit(ctx *Context, unitType unit.Type) bool {
|
||||
if ctx.Doer == nil {
|
||||
return false
|
||||
}
|
||||
return org.UnitPermission(ctx, ctx.Doer.ID, unitType) >= perm.AccessModeWrite
|
||||
return org.Organization.UnitPermission(ctx, ctx.Doer, unitType) >= perm.AccessModeWrite
|
||||
}
|
||||
|
||||
func (org *Organization) UnitPermission(ctx *Context, doerID int64, unitType unit.Type) perm.AccessMode {
|
||||
if doerID > 0 {
|
||||
teams, err := organization.GetUserOrgTeams(ctx, org.Organization.ID, doerID)
|
||||
if err != nil {
|
||||
log.Error("GetUserOrgTeams: %v", err)
|
||||
return perm.AccessModeNone
|
||||
}
|
||||
if len(teams) > 0 {
|
||||
return teams.UnitMaxAccess(unitType)
|
||||
}
|
||||
}
|
||||
func (org *Organization) CanReadUnit(ctx *Context, unitType unit.Type) bool {
|
||||
return org.Organization.UnitPermission(ctx, ctx.Doer, unitType) >= perm.AccessModeRead
|
||||
}
|
||||
|
||||
if org.Organization.Visibility == structs.VisibleTypePublic {
|
||||
return perm.AccessModeRead
|
||||
}
|
||||
func GetOrganizationByParams(ctx *Context) {
|
||||
orgName := ctx.Params(":org")
|
||||
|
||||
return perm.AccessModeNone
|
||||
var err error
|
||||
|
||||
ctx.Org.Organization, err = organization.GetOrgByName(ctx, orgName)
|
||||
if err != nil {
|
||||
if organization.IsErrOrgNotExist(err) {
|
||||
redirectUserID, err := user_model.LookupUserRedirect(orgName)
|
||||
if err == nil {
|
||||
RedirectToUser(ctx, orgName, redirectUserID)
|
||||
} else if user_model.IsErrUserRedirectNotExist(err) {
|
||||
ctx.NotFound("GetUserByName", err)
|
||||
} else {
|
||||
ctx.ServerError("LookupUserRedirect", err)
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("GetUserByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// HandleOrgAssignment handles organization assignment
|
||||
@@ -77,25 +81,26 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
||||
requireTeamAdmin = args[3]
|
||||
}
|
||||
|
||||
orgName := ctx.Params(":org")
|
||||
|
||||
var err error
|
||||
ctx.Org.Organization, err = organization.GetOrgByName(ctx, orgName)
|
||||
if err != nil {
|
||||
if organization.IsErrOrgNotExist(err) {
|
||||
redirectUserID, err := user_model.LookupUserRedirect(orgName)
|
||||
if err == nil {
|
||||
RedirectToUser(ctx, orgName, redirectUserID)
|
||||
} else if user_model.IsErrUserRedirectNotExist(err) {
|
||||
ctx.NotFound("GetUserByName", err)
|
||||
} else {
|
||||
ctx.ServerError("LookupUserRedirect", err)
|
||||
|
||||
if ctx.ContextUser == nil {
|
||||
// if Organization is not defined, get it from params
|
||||
if ctx.Org.Organization == nil {
|
||||
GetOrganizationByParams(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("GetUserByName", err)
|
||||
}
|
||||
} else if ctx.ContextUser.IsOrganization() {
|
||||
if ctx.Org == nil {
|
||||
ctx.Org = &Organization{}
|
||||
}
|
||||
ctx.Org.Organization = (*organization.Organization)(ctx.ContextUser)
|
||||
} else {
|
||||
// ContextUser is an individual User
|
||||
return
|
||||
}
|
||||
|
||||
org := ctx.Org.Organization
|
||||
|
||||
// Handle Visibility
|
||||
@@ -156,6 +161,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
||||
}
|
||||
ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
|
||||
ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
|
||||
ctx.Data["IsProjectEnabled"] = true
|
||||
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
|
||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
ctx.Data["IsPublicMember"] = func(uid int64) bool {
|
||||
@@ -231,6 +237,10 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["CanReadProjects"] = ctx.Org.CanReadUnit(ctx, unit.TypeProjects)
|
||||
ctx.Data["CanReadPackages"] = ctx.Org.CanReadUnit(ctx, unit.TypePackages)
|
||||
ctx.Data["CanReadCode"] = ctx.Org.CanReadUnit(ctx, unit.TypeCode)
|
||||
}
|
||||
|
||||
// OrgAssignment returns a middleware to handle organization assignment
|
||||
|
||||
@@ -18,10 +18,11 @@ type Pagination struct {
|
||||
urlParams []string
|
||||
}
|
||||
|
||||
// NewPagination creates a new instance of the Pagination struct
|
||||
func NewPagination(total, page, issueNum, numPages int) *Pagination {
|
||||
// NewPagination creates a new instance of the Pagination struct.
|
||||
// "pagingNum" is "page size" or "limit", "current" is "page"
|
||||
func NewPagination(total, pagingNum, current, numPages int) *Pagination {
|
||||
p := &Pagination{}
|
||||
p.Paginater = paginator.New(total, page, issueNum, numPages)
|
||||
p.Paginater = paginator.New(total, pagingNum, current, numPages)
|
||||
return p
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -229,7 +230,10 @@ John Doe john@doe.com This,note,had,a,lot,of,commas,to,test,delimiters`,
|
||||
}
|
||||
|
||||
for n, c := range cases {
|
||||
delimiter := determineDelimiter(&markup.RenderContext{RelativePath: c.filename}, []byte(decodeSlashes(t, c.csv)))
|
||||
delimiter := determineDelimiter(&markup.RenderContext{
|
||||
Ctx: git.DefaultContext,
|
||||
RelativePath: c.filename,
|
||||
}, []byte(decodeSlashes(t, c.csv)))
|
||||
assert.EqualValues(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er
|
||||
|
||||
// TODO: function to recalc all counters
|
||||
|
||||
if setting.Database.UsePostgreSQL {
|
||||
if setting.Database.Type.IsPostgreSQL() {
|
||||
consistencyChecks = append(consistencyChecks, consistencyCheck{
|
||||
Name: "Sequence values",
|
||||
Counter: db.CountBadSequences,
|
||||
|
||||
@@ -179,7 +179,7 @@ func (c *Command) AddDashesAndList(list ...string) *Command {
|
||||
}
|
||||
|
||||
// ToTrustedCmdArgs converts a list of strings (trusted as argument) to TrustedCmdArgs
|
||||
// In most cases, it shouldn't be used. Use AddXxx function instead
|
||||
// In most cases, it shouldn't be used. Use NewCommand().AddXxx() function instead
|
||||
func ToTrustedCmdArgs(args []string) TrustedCmdArgs {
|
||||
ret := make(TrustedCmdArgs, len(args))
|
||||
for i, arg := range args {
|
||||
|
||||
+31
-4
@@ -201,6 +201,23 @@ func InitFull(ctx context.Context) (err error) {
|
||||
return syncGitConfig()
|
||||
}
|
||||
|
||||
func enableReflogs() error {
|
||||
if err := configSet("core.logAllRefUpdates", "true"); err != nil {
|
||||
return err
|
||||
}
|
||||
err := configSet("gc.reflogExpire", fmt.Sprintf("%d", setting.Git.Reflog.Expiration))
|
||||
return err
|
||||
}
|
||||
|
||||
func disableReflogs() error {
|
||||
if err := configUnsetAll("core.logAllRefUpdates", "true"); err != nil {
|
||||
return err
|
||||
} else if err := configUnsetAll("gc.reflogExpire", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// syncGitConfig only modifies gitconfig, won't change global variables (otherwise there will be data-race problem)
|
||||
func syncGitConfig() (err error) {
|
||||
if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil {
|
||||
@@ -224,6 +241,16 @@ func syncGitConfig() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Git.Reflog.Enabled {
|
||||
if err := enableReflogs(); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := disableReflogs(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if CheckGitVersionAtLeast("2.10") == nil {
|
||||
if err := configSet("receive.advertisePushOptions", "true"); err != nil {
|
||||
return err
|
||||
@@ -312,7 +339,7 @@ func CheckGitVersionAtLeast(atLeast string) error {
|
||||
}
|
||||
|
||||
func configSet(key, value string) error {
|
||||
stdout, _, err := NewCommand(DefaultContext, "config", "--get").AddDynamicArguments(key).RunStdString(nil)
|
||||
stdout, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil)
|
||||
if err != nil && !err.IsExitCode(1) {
|
||||
return fmt.Errorf("failed to get git config %s, err: %w", key, err)
|
||||
}
|
||||
@@ -331,7 +358,7 @@ func configSet(key, value string) error {
|
||||
}
|
||||
|
||||
func configSetNonExist(key, value string) error {
|
||||
_, _, err := NewCommand(DefaultContext, "config", "--get").AddDynamicArguments(key).RunStdString(nil)
|
||||
_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil)
|
||||
if err == nil {
|
||||
// already exist
|
||||
return nil
|
||||
@@ -349,7 +376,7 @@ func configSetNonExist(key, value string) error {
|
||||
}
|
||||
|
||||
func configAddNonExist(key, value string) error {
|
||||
_, _, err := NewCommand(DefaultContext, "config", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil)
|
||||
_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil)
|
||||
if err == nil {
|
||||
// already exist
|
||||
return nil
|
||||
@@ -366,7 +393,7 @@ func configAddNonExist(key, value string) error {
|
||||
}
|
||||
|
||||
func configUnsetAll(key, value string) error {
|
||||
_, _, err := NewCommand(DefaultContext, "config", "--get").AddDynamicArguments(key).RunStdString(nil)
|
||||
_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil)
|
||||
if err == nil {
|
||||
// exist, need to remove
|
||||
_, _, err = NewCommand(DefaultContext, "config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil)
|
||||
|
||||
@@ -42,7 +42,10 @@ func RevListObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sync.
|
||||
defer revListWriter.Close()
|
||||
stderr := new(bytes.Buffer)
|
||||
var errbuf strings.Builder
|
||||
cmd := git.NewCommand(ctx, "rev-list", "--objects").AddDynamicArguments(headSHA).AddArguments("--not").AddDynamicArguments(baseSHA)
|
||||
cmd := git.NewCommand(ctx, "rev-list", "--objects").AddDynamicArguments(headSHA)
|
||||
if baseSHA != "" {
|
||||
cmd = cmd.AddArguments("--not").AddDynamicArguments(baseSHA)
|
||||
}
|
||||
if err := cmd.Run(&git.RunOpts{
|
||||
Dir: tmpBasePath,
|
||||
Stdout: revListWriter,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
@@ -67,38 +66,6 @@ func (repo *Repository) IsCommitExist(name string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func convertPGPSignatureForTag(t *object.Tag) *CommitGPGSignature {
|
||||
if t.PGPSignature == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var w strings.Builder
|
||||
var err error
|
||||
|
||||
if _, err = fmt.Fprintf(&w,
|
||||
"object %s\ntype %s\ntag %s\ntagger ",
|
||||
t.Target.String(), t.TargetType.Bytes(), t.Name); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = t.Tagger.Encode(&w); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err = fmt.Fprintf(&w, "\n\n"); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err = fmt.Fprintf(&w, t.Message); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &CommitGPGSignature{
|
||||
Signature: t.PGPSignature,
|
||||
Payload: strings.TrimSpace(w.String()) + "\n",
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
|
||||
var tagObject *object.Tag
|
||||
|
||||
@@ -122,12 +89,6 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
|
||||
commit := convertCommit(gogitCommit)
|
||||
commit.repo = repo
|
||||
|
||||
if tagObject != nil {
|
||||
commit.CommitMessage = strings.TrimSpace(tagObject.Message)
|
||||
commit.Author = &tagObject.Tagger
|
||||
commit.Signature = convertPGPSignatureForTag(tagObject)
|
||||
}
|
||||
|
||||
tree, err := gogitCommit.Tree()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -107,10 +107,6 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commit.CommitMessage = strings.TrimSpace(tag.Message)
|
||||
commit.Author = tag.Tagger
|
||||
commit.Signature = tag.Signature
|
||||
|
||||
return commit, nil
|
||||
case "commit":
|
||||
commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
|
||||
|
||||
@@ -43,12 +43,13 @@ func TestGetTagCommitWithSignature(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
defer bareRepo1.Close()
|
||||
|
||||
commit, err := bareRepo1.GetCommit("3ad28a9149a2864384548f3d17ed7f38014c9e8a")
|
||||
// both the tag and the commit are signed here, this validates only the commit signature
|
||||
commit, err := bareRepo1.GetCommit("28b55526e7100924d864dd89e35c1ea62e7a5a32")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, commit)
|
||||
assert.NotNil(t, commit.Signature)
|
||||
// test that signature is not in message
|
||||
assert.Equal(t, "tag", commit.CommitMessage)
|
||||
assert.Equal(t, "signed-commit\n", commit.CommitMessage)
|
||||
}
|
||||
|
||||
func TestGetCommitWithBadCommitID(t *testing.T) {
|
||||
|
||||
@@ -277,11 +277,18 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error {
|
||||
|
||||
// GetFilesChangedBetween returns a list of all files that have been changed between the given commits
|
||||
func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) {
|
||||
stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path})
|
||||
stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return strings.Split(stdout, "\n"), err
|
||||
split := strings.Split(stdout, "\000")
|
||||
|
||||
// Because Git will always emit filenames with a terminal NUL ignore the last entry in the split - which will always be empty.
|
||||
if len(split) > 0 {
|
||||
split = split[:len(split)-1]
|
||||
}
|
||||
|
||||
return split, err
|
||||
}
|
||||
|
||||
// GetDiffFromMergeBase generates and return patch data from merge base to head
|
||||
|
||||
@@ -19,13 +19,14 @@ func TestRepository_GetRefs(t *testing.T) {
|
||||
refs, err := bareRepo1.GetRefs()
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, refs, 5)
|
||||
assert.Len(t, refs, 6)
|
||||
|
||||
expectedRefs := []string{
|
||||
BranchPrefix + "branch1",
|
||||
BranchPrefix + "branch2",
|
||||
BranchPrefix + "master",
|
||||
TagPrefix + "test",
|
||||
TagPrefix + "signed-tag",
|
||||
NotesRef,
|
||||
}
|
||||
|
||||
@@ -43,9 +44,12 @@ func TestRepository_GetRefsFiltered(t *testing.T) {
|
||||
refs, err := bareRepo1.GetRefsFiltered(TagPrefix)
|
||||
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, refs, 1) {
|
||||
assert.Equal(t, TagPrefix+"test", refs[0].Name)
|
||||
if assert.Len(t, refs, 2) {
|
||||
assert.Equal(t, TagPrefix+"signed-tag", refs[0].Name)
|
||||
assert.Equal(t, "tag", refs[0].Type)
|
||||
assert.Equal(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", refs[0].Object.String())
|
||||
assert.Equal(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", refs[0].Object.String())
|
||||
assert.Equal(t, TagPrefix+"test", refs[1].Name)
|
||||
assert.Equal(t, "tag", refs[1].Type)
|
||||
assert.Equal(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", refs[1].Object.String())
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,9 @@ func TestRepository_GetCodeActivityStats(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, code)
|
||||
|
||||
assert.EqualValues(t, 9, code.CommitCount)
|
||||
assert.EqualValues(t, 10, code.CommitCount)
|
||||
assert.EqualValues(t, 3, code.AuthorCount)
|
||||
assert.EqualValues(t, 9, code.CommitCountInAllBranches)
|
||||
assert.EqualValues(t, 10, code.CommitCountInAllBranches)
|
||||
assert.EqualValues(t, 10, code.Additions)
|
||||
assert.EqualValues(t, 1, code.Deletions)
|
||||
assert.Len(t, code.Authors, 3)
|
||||
|
||||
@@ -25,11 +25,14 @@ func TestRepository_GetTags(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
return
|
||||
}
|
||||
assert.Len(t, tags, 1)
|
||||
assert.Len(t, tags, 2)
|
||||
assert.Equal(t, len(tags), total)
|
||||
assert.EqualValues(t, "test", tags[0].Name)
|
||||
assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[0].ID.String())
|
||||
assert.EqualValues(t, "signed-tag", tags[0].Name)
|
||||
assert.EqualValues(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", tags[0].ID.String())
|
||||
assert.EqualValues(t, "tag", tags[0].Type)
|
||||
assert.EqualValues(t, "test", tags[1].Name)
|
||||
assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[1].ID.String())
|
||||
assert.EqualValues(t, "tag", tags[1].Type)
|
||||
}
|
||||
|
||||
func TestRepository_GetTag(t *testing.T) {
|
||||
|
||||
@@ -14,10 +14,10 @@ func TestGetLatestCommitTime(t *testing.T) {
|
||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||
lct, err := GetLatestCommitTime(DefaultContext, bareRepo1Path)
|
||||
assert.NoError(t, err)
|
||||
// Time is Sun Jul 21 22:43:13 2019 +0200
|
||||
// Time is Sun Nov 13 16:40:14 2022 +0100
|
||||
// which is the time of commit
|
||||
// feaf4ba6bc635fec442f46ddd4512416ec43c2c2 (refs/heads/master)
|
||||
assert.EqualValues(t, 1563741793, lct.Unix())
|
||||
// ce064814f4a0d337b333e646ece456cd39fab612 (refs/heads/master)
|
||||
assert.EqualValues(t, 1668354014, lct.Unix())
|
||||
}
|
||||
|
||||
func TestRepoIsEmpty(t *testing.T) {
|
||||
|
||||
Binary file not shown.
@@ -1 +1,2 @@
|
||||
37991dec2c8e592043f47155ce4808d4580f9123 feaf4ba6bc635fec442f46ddd4512416ec43c2c2 silverwind <me@silverwind.io> 1563741799 +0200 push
|
||||
feaf4ba6bc635fec442f46ddd4512416ec43c2c2 ce064814f4a0d337b333e646ece456cd39fab612 silverwind <me@silverwind.io> 1668354026 +0100 push
|
||||
@@ -1 +1,2 @@
|
||||
37991dec2c8e592043f47155ce4808d4580f9123 feaf4ba6bc635fec442f46ddd4512416ec43c2c2 silverwind <me@silverwind.io> 1563741799 +0200 push
|
||||
feaf4ba6bc635fec442f46ddd4512416ec43c2c2 ce064814f4a0d337b333e646ece456cd39fab612 silverwind <me@silverwind.io> 1668354026 +0100 push
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
feaf4ba6bc635fec442f46ddd4512416ec43c2c2
|
||||
ce064814f4a0d337b333e646ece456cd39fab612
|
||||
@@ -0,0 +1 @@
|
||||
36f97d9a96457e2bab511db30fe2db03893ebc64
|
||||
Loaded 100 of 355 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user