mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-03 08:02:36 +09:00
Compare commits
114 Commits
v1.20.0-de
...
v1.19.0
| 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 |
129
.drone.yml
129
.drone.yml
@@ -43,7 +43,7 @@ steps:
|
|||||||
depends_on: [deps-frontend]
|
depends_on: [deps-frontend]
|
||||||
|
|
||||||
- name: lint-backend
|
- 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
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- make lint-backend
|
- make lint-backend
|
||||||
@@ -57,7 +57,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: lint-backend-windows
|
- 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:
|
commands:
|
||||||
- make golangci-lint-windows vet
|
- make golangci-lint-windows vet
|
||||||
environment:
|
environment:
|
||||||
@@ -72,7 +72,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: lint-backend-gogit
|
- 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:
|
commands:
|
||||||
- make lint-backend
|
- make lint-backend
|
||||||
environment:
|
environment:
|
||||||
@@ -264,13 +264,13 @@ steps:
|
|||||||
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
|
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
|
||||||
|
|
||||||
- name: prepare-test-env
|
- 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
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- ./build/test-env-prepare.sh
|
- ./build/test-env-prepare.sh
|
||||||
|
|
||||||
- name: build
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- ./build/test-env-check.sh
|
- ./build/test-env-check.sh
|
||||||
@@ -285,7 +285,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: unit-test
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- make unit-test-coverage test-check
|
- make unit-test-coverage test-check
|
||||||
@@ -301,7 +301,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: unit-test-gogit
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- make unit-test-coverage test-check
|
- make unit-test-coverage test-check
|
||||||
@@ -317,7 +317,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: test-mysql
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- make test-mysql-migration integration-test-coverage
|
- make test-mysql-migration integration-test-coverage
|
||||||
@@ -334,7 +334,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: test-mysql8
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- timeout -s ABRT 50m make test-mysql8-migration test-mysql8
|
- timeout -s ABRT 50m make test-mysql8-migration test-mysql8
|
||||||
@@ -350,7 +350,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: test-mssql
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- make test-mssql-migration test-mssql
|
- make test-mssql-migration test-mssql
|
||||||
@@ -454,13 +454,13 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: prepare-test-env
|
- 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
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- ./build/test-env-prepare.sh
|
- ./build/test-env-prepare.sh
|
||||||
|
|
||||||
- name: build
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- ./build/test-env-check.sh
|
- ./build/test-env-check.sh
|
||||||
@@ -475,7 +475,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: test-sqlite
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- timeout -s ABRT 50m make test-sqlite-migration test-sqlite
|
- timeout -s ABRT 50m make test-sqlite-migration test-sqlite
|
||||||
@@ -491,7 +491,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: test-pgsql
|
- 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
|
user: gitea
|
||||||
commands:
|
commands:
|
||||||
- timeout -s ABRT 50m make test-pgsql-migration test-pgsql
|
- timeout -s ABRT 50m make test-pgsql-migration test-pgsql
|
||||||
@@ -1016,7 +1016,7 @@ steps:
|
|||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
@@ -1028,13 +1028,17 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
@@ -1046,6 +1050,10 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
@@ -1080,7 +1088,7 @@ steps:
|
|||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
tags: ${DRONE_TAG##v}-linux-amd64
|
tags: ${DRONE_TAG##v}-linux-amd64
|
||||||
@@ -1091,13 +1099,17 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
tags: ${DRONE_TAG##v}-linux-amd64-rootless
|
tags: ${DRONE_TAG##v}-linux-amd64-rootless
|
||||||
@@ -1108,6 +1120,10 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
@@ -1142,7 +1158,7 @@ steps:
|
|||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
auto_tag: false
|
auto_tag: false
|
||||||
@@ -1154,13 +1170,17 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
auto_tag: false
|
auto_tag: false
|
||||||
@@ -1172,6 +1192,10 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
@@ -1205,7 +1229,7 @@ steps:
|
|||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
auto_tag: false
|
auto_tag: false
|
||||||
@@ -1217,13 +1241,17 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
auto_tag: false
|
auto_tag: false
|
||||||
@@ -1235,6 +1263,10 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
@@ -1243,7 +1275,7 @@ steps:
|
|||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: docker-linux-arm64-dry-run
|
name: docker-linux-amd64-dry-run
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
os: linux
|
os: linux
|
||||||
@@ -1261,7 +1293,7 @@ trigger:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: dryrun
|
- name: dryrun
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
dry_run: true
|
dry_run: true
|
||||||
@@ -1272,6 +1304,7 @@ steps:
|
|||||||
environment:
|
environment:
|
||||||
PLUGIN_MIRROR:
|
PLUGIN_MIRROR:
|
||||||
from_secret: plugin_mirror
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
- pull_request
|
- pull_request
|
||||||
@@ -1308,7 +1341,7 @@ steps:
|
|||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
@@ -1320,13 +1353,17 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
@@ -1338,6 +1375,10 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
@@ -1372,7 +1413,7 @@ steps:
|
|||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
tags: ${DRONE_TAG##v}-linux-arm64
|
tags: ${DRONE_TAG##v}-linux-arm64
|
||||||
@@ -1383,13 +1424,17 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
tags: ${DRONE_TAG##v}-linux-arm64-rootless
|
tags: ${DRONE_TAG##v}-linux-arm64-rootless
|
||||||
@@ -1400,6 +1445,10 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
@@ -1434,7 +1483,7 @@ steps:
|
|||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
auto_tag: false
|
auto_tag: false
|
||||||
@@ -1446,13 +1495,17 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
auto_tag: false
|
auto_tag: false
|
||||||
@@ -1464,6 +1517,10 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
@@ -1497,7 +1554,7 @@ steps:
|
|||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
auto_tag: false
|
auto_tag: false
|
||||||
@@ -1509,13 +1566,17 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:latest
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
auto_tag: false
|
auto_tag: false
|
||||||
@@ -1527,6 +1588,10 @@ steps:
|
|||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
|
environment:
|
||||||
|
PLUGIN_MIRROR:
|
||||||
|
from_secret: plugin_mirror
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
plugins:
|
plugins:
|
||||||
- stylelint-declaration-strict-value
|
- stylelint-declaration-strict-value
|
||||||
|
|
||||||
|
ignoreFiles:
|
||||||
|
- "**/*.go"
|
||||||
|
|
||||||
overrides:
|
overrides:
|
||||||
- files: ["**/*.less"]
|
|
||||||
customSyntax: postcss-less
|
|
||||||
- files: ["**/chroma/*", "**/codemirror/*", "**/standalone/*", "**/console/*"]
|
- files: ["**/chroma/*", "**/codemirror/*", "**/standalone/*", "**/console/*"]
|
||||||
rules:
|
rules:
|
||||||
scale-unlimited/declaration-strict-value: null
|
scale-unlimited/declaration-strict-value: null
|
||||||
|
- files: ["**/chroma/*", "**/codemirror/*"]
|
||||||
|
rules:
|
||||||
|
block-no-empty: null
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
alpha-value-notation: null
|
alpha-value-notation: null
|
||||||
|
|||||||
350
CHANGELOG.md
350
CHANGELOG.md
@@ -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
|
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).
|
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
|
## [1.18.5](https://github.com/go-gitea/gitea/releases/tag/v1.18.5) - 2023-02-21
|
||||||
|
|
||||||
* ENHANCEMENTS
|
* ENHANCEMENTS
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -105,7 +105,7 @@ GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/m
|
|||||||
|
|
||||||
FOMANTIC_WORK_DIR := web_src/fomantic
|
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_CONFIGS := webpack.config.js
|
||||||
WEBPACK_DEST := public/js/index.js public/css/index.css
|
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
|
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)
|
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
|
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 := $(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)
|
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
|
.PHONY: lint-frontend
|
||||||
lint-frontend: node_modules
|
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 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 spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||||
npx markdownlint docs *.md
|
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 -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/
|
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
|
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
|
$(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.*
|
rm -f $(FOMANTIC_WORK_DIR)/build/*.min.*
|
||||||
|
|
||||||
|
|||||||
5
assets/go-licenses.json
generated
5
assets/go-licenses.json
generated
File diff suppressed because one or more lines are too long
11
cmd/admin.go
11
cmd/admin.go
@@ -7,6 +7,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
@@ -469,11 +470,19 @@ func runAddOauth(c *cli.Context) error {
|
|||||||
return err
|
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{
|
return auth_model.CreateSource(&auth_model.Source{
|
||||||
Type: auth_model.OAuth2,
|
Type: auth_model.OAuth2,
|
||||||
Name: c.String("name"),
|
Name: c.String("name"),
|
||||||
IsActive: true,
|
IsActive: true,
|
||||||
Cfg: parseOAuth2Config(c),
|
Cfg: config,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ func runConvert(ctx *cli.Context) error {
|
|||||||
log.Info("Log path: %s", setting.Log.RootPath)
|
log.Info("Log path: %s", setting.Log.RootPath)
|
||||||
log.Info("Configuration file: %s", setting.CustomConf)
|
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")
|
fmt.Println("This command can only be used with a MySQL database")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,13 +272,14 @@ func runDump(ctx *cli.Context) error {
|
|||||||
fatal("Failed to create tmp file: %v", err)
|
fatal("Failed to create tmp file: %v", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
|
_ = dbDump.Close()
|
||||||
if err := util.Remove(dbDump.Name()); err != nil {
|
if err := util.Remove(dbDump.Name()); err != nil {
|
||||||
log.Warn("Unable to remove temporary file: %s: Error: %v", dbDump.Name(), err)
|
log.Warn("Unable to remove temporary file: %s: Error: %v", dbDump.Name(), err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
targetDBType := ctx.String("database")
|
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)
|
log.Info("Dumping database %s => %s...", setting.Database.Type, targetDBType)
|
||||||
} else {
|
} else {
|
||||||
log.Info("Dumping database...")
|
log.Info("Dumping database...")
|
||||||
|
|||||||
25
cmd/serv.go
25
cmd/serv.go
@@ -11,6 +11,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -290,17 +291,21 @@ func runServ(c *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special handle for Windows.
|
|
||||||
if setting.IsWindows {
|
|
||||||
verb = strings.Replace(verb, "-", " ", 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
var gitcmd *exec.Cmd
|
var gitcmd *exec.Cmd
|
||||||
verbs := strings.Split(verb, " ")
|
gitBinPath := filepath.Dir(git.GitExecutable) // e.g. /usr/bin
|
||||||
if len(verbs) == 2 {
|
gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack
|
||||||
gitcmd = exec.CommandContext(ctx, verbs[0], verbs[1], repoPath)
|
if _, err := os.Stat(gitBinVerb); err != nil {
|
||||||
} else {
|
// if the command "git-upload-pack" doesn't exist, try to split "git-upload-pack" to use the sub-command with git
|
||||||
gitcmd = exec.CommandContext(ctx, verb, repoPath)
|
// 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)
|
process.SetSysProcAttribute(gitcmd)
|
||||||
|
|||||||
@@ -1832,7 +1832,7 @@ ROUTER = console
|
|||||||
;ENABLED = true
|
;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.
|
;; 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 of each file. Defaults to 4MB
|
||||||
;MAX_SIZE = 4
|
;MAX_SIZE = 4
|
||||||
@@ -1871,6 +1871,9 @@ ROUTER = console
|
|||||||
;;
|
;;
|
||||||
;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||||
;MINIO_USE_SSL = false
|
;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
|
;PULL = 300
|
||||||
;GC = 60
|
;GC = 60
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Git Reflog timeout in days
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;[git.reflog]
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;ENABLED = true
|
||||||
|
;EXPIRATION = 90
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;[mirror]
|
;[mirror]
|
||||||
@@ -2552,6 +2566,9 @@ ROUTER = console
|
|||||||
;;
|
;;
|
||||||
;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||||
;MINIO_USE_SSL = false
|
;MINIO_USE_SSL = false
|
||||||
|
;;
|
||||||
|
;; Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||||
|
;MINIO_INSECURE_SKIP_VERIFY = false
|
||||||
|
|
||||||
;[proxy]
|
;[proxy]
|
||||||
;; Enable the proxy, all requests to external via HTTP will be affected
|
;; 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
|
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}}
|
{{#if build.tags}}
|
||||||
{{#unless contains "-rc" build.tag}}
|
{{#unless (contains "-rc" build.tag)}}
|
||||||
tags:
|
tags:
|
||||||
{{#each build.tags}}
|
{{#each build.tags}}
|
||||||
- {{this}}-rootless
|
- {{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}}
|
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}}
|
{{#if build.tags}}
|
||||||
{{#unless contains "-rc" build.tag }}
|
{{#unless (contains "-rc" build.tag)}}
|
||||||
tags:
|
tags:
|
||||||
{{#each build.tags}}
|
{{#each build.tags}}
|
||||||
- {{this}}
|
- {{this}}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
THEME := themes/gitea
|
THEME := themes/gitea
|
||||||
PUBLIC := public
|
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
|
HUGO_PACKAGE := github.com/gohugoio/hugo@v0.82.0
|
||||||
|
|
||||||
|
|||||||
@@ -841,7 +841,7 @@ Default templates for project boards:
|
|||||||
## Issue and pull request attachments (`attachment`)
|
## Issue and pull request attachments (`attachment`)
|
||||||
|
|
||||||
- `ENABLED`: **true**: Whether issue and pull request attachments are enabled.
|
- `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_SIZE`: **4**: Maximum size (MB).
|
||||||
- `MAX_FILES`: **5**: Maximum number of attachments that can be uploaded at once.
|
- `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]`
|
- `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_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_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_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`)
|
## 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_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.
|
- `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`)
|
## Git - Timeout settings (`git.timeout`)
|
||||||
|
|
||||||
- `DEFAULT`: **360**: Git operations default timeout seconds.
|
- `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_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_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_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`)
|
## 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_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_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_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:
|
And you can also define a customize storage like below:
|
||||||
|
|
||||||
@@ -1298,6 +1306,8 @@ MINIO_BUCKET = gitea
|
|||||||
MINIO_LOCATION = us-east-1
|
MINIO_LOCATION = us-east-1
|
||||||
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||||
MINIO_USE_SSL = false
|
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`.
|
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_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_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_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`)
|
## Proxy (`proxy`)
|
||||||
|
|
||||||
|
|||||||
@@ -431,6 +431,8 @@ MINIO_BUCKET = gitea
|
|||||||
MINIO_LOCATION = us-east-1
|
MINIO_LOCATION = us-east-1
|
||||||
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||||
MINIO_USE_SSL = false
|
MINIO_USE_SSL = false
|
||||||
|
; Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||||
|
MINIO_INSECURE_SKIP_VERIFY = false
|
||||||
```
|
```
|
||||||
|
|
||||||
然后你在 `[attachment]`, `[lfs]` 等中可以把这个名字用作 `STORAGE_TYPE` 的值。
|
然后你在 `[attachment]`, `[lfs]` 等中可以把这个名字用作 `STORAGE_TYPE` 的值。
|
||||||
|
|||||||
@@ -282,9 +282,22 @@ To add custom .gitignore, add a file with existing [.gitignore rules](https://gi
|
|||||||
|
|
||||||
### Labels
|
### 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`
|
`#hex-color label name ; label description`
|
||||||
|
|
||||||
|
For more information, see the [labels documentation]({{< relref "doc/usage/labels.en-us.md" >}}).
|
||||||
|
|
||||||
### Licenses
|
### Licenses
|
||||||
|
|
||||||
To add a custom license, add a file with the license text to `$GITEA_CUSTOM/options/license`
|
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).
|
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`.
|
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.
|
This allows Gitea to adjust the Monaco code editor's theme accordingly.
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ menu:
|
|||||||
|
|
||||||
## Background
|
## 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 HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template).
|
||||||
|
|
||||||
The source files can be found in the following directories:
|
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/`
|
* **JavaScript files:** `web_src/js/`
|
||||||
* **Vue components:** `web_src/js/components/`
|
* **Vue components:** `web_src/js/components/`
|
||||||
* **Go HTML templates:** `templates/`
|
* **Go HTML templates:** `templates/`
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ weight: 20
|
|||||||
toc: false
|
toc: false
|
||||||
draft: false
|
draft: false
|
||||||
menu:
|
menu:
|
||||||
sidebar:
|
sidebar:
|
||||||
parent: "developers"
|
parent: "developers"
|
||||||
name: "Guidelines for Refactoring"
|
name: "Guidelines for Refactoring"
|
||||||
weight: 20
|
weight: 20
|
||||||
identifier: "guidelines-refactoring"
|
identifier: "guidelines-refactoring"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Guidelines for Refactoring
|
# Guidelines for Refactoring
|
||||||
|
|||||||
349
docs/content/doc/developers/hacking-on-gitea.zh-cn.md
Normal file
349
docs/content/doc/developers/hacking-on-gitea.zh-cn.md
Normal file
@@ -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"
|
parent: "packages"
|
||||||
name: "Overview"
|
name: "Overview"
|
||||||
weight: 1
|
weight: 1
|
||||||
identifier: "overview"
|
identifier: "packages-overview"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Package Registry
|
# Package Registry
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ menu:
|
|||||||
parent: "secrets"
|
parent: "secrets"
|
||||||
name: "Overview"
|
name: "Overview"
|
||||||
weight: 1
|
weight: 1
|
||||||
identifier: "overview"
|
identifier: "secrets-overview"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
|
|||||||
40
docs/content/doc/usage/labels.en-us.md
Normal file
40
docs/content/doc/usage/labels.en-us.md
Normal file
@@ -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.
|
||||||
13
go.mod
13
go.mod
@@ -41,7 +41,7 @@ require (
|
|||||||
github.com/go-chi/cors v1.2.1
|
github.com/go-chi/cors v1.2.1
|
||||||
github.com/go-enry/go-enry/v2 v2.8.3
|
github.com/go-enry/go-enry/v2 v2.8.3
|
||||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
|
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-git/go-git/v5 v5.5.2
|
||||||
github.com/go-ldap/ldap/v3 v3.4.4
|
github.com/go-ldap/ldap/v3 v3.4.4
|
||||||
github.com/go-redis/redis/v8 v8.11.5
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
@@ -77,7 +77,7 @@ require (
|
|||||||
github.com/microcosm-cc/bluemonday v1.0.21
|
github.com/microcosm-cc/bluemonday v1.0.21
|
||||||
github.com/minio/minio-go/v7 v7.0.46
|
github.com/minio/minio-go/v7 v7.0.46
|
||||||
github.com/msteinert/pam v1.1.0
|
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/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/niklasfasching/go-org v1.6.5
|
github.com/niklasfasching/go-org v1.6.5
|
||||||
github.com/oliamb/cutter v0.2.2
|
github.com/oliamb/cutter v0.2.2
|
||||||
@@ -105,7 +105,7 @@ require (
|
|||||||
golang.org/x/crypto v0.4.0
|
golang.org/x/crypto v0.4.0
|
||||||
golang.org/x/net v0.7.0
|
golang.org/x/net v0.7.0
|
||||||
golang.org/x/oauth2 v0.3.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/text v0.7.0
|
||||||
golang.org/x/tools v0.1.12
|
golang.org/x/tools v0.1.12
|
||||||
google.golang.org/grpc v1.47.0
|
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-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||||
github.com/go-enry/go-oniguruma v1.2.1 // indirect
|
github.com/go-enry/go-oniguruma v1.2.1 // indirect
|
||||||
github.com/go-git/gcfg v1.5.0 // 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/analysis v0.21.4 // indirect
|
||||||
github.com/go-openapi/errors v0.20.3 // indirect
|
github.com/go-openapi/errors v0.20.3 // indirect
|
||||||
github.com/go-openapi/inflect v0.19.0 // 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/client_model v0.3.0 // indirect
|
||||||
github.com/prometheus/common v0.37.0 // indirect
|
github.com/prometheus/common v0.37.0 // indirect
|
||||||
github.com/prometheus/procfs v0.8.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/rivo/uniseg v0.4.3 // indirect
|
||||||
github.com/robfig/cron v1.2.0 // indirect
|
github.com/robfig/cron v1.2.0 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.9.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/multierr v1.9.0 // indirect
|
||||||
go.uber.org/zap v1.24.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
golang.org/x/mod v0.7.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
|
golang.org/x/time v0.3.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // 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/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
|
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
||||||
|
|
||||||
|
|||||||
25
go.sum
25
go.sum
@@ -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=
|
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 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
|
||||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
|
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.243.1 h1:zIVlhGOLE4SHFPW++u3+5Y/jX5mub3QIhB13oNf6rtA=
|
||||||
gitea.com/gitea/act v0.234.2-0.20230131074955-e46ede1b1744/go.mod h1:2C/WbTalu1VPNgbVaZJaZDzlOtAKqkXJhdOClxkMy14=
|
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 h1:MMSPgnVULVwV9kEBgvyEUhC9v/uviZ55hPJEMjpbNR4=
|
||||||
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc=
|
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=
|
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 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
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.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.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 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-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
|
||||||
github.com/go-git/go-git/v5 v5.5.2 h1:v8lgZa5k9ylUw+OR/roJHTxR4QItsNFI5nKtAXFuynw=
|
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 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-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-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.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.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
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/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/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.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/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 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
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/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 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
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.23 h1:041VOXgZddfvSJa9Il+WT3Iwuo/j0Nmu4bhpAScrds4=
|
||||||
github.com/rhysd/actionlint v1.6.22/go.mod h1:gIKOdxtV40mBOcD0ZR8EBa8NqjEXToAZioroS3oedMg=
|
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.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.2.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=
|
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-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-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-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.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
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-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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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.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.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.3.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.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
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-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-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-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.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.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.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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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)
|
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 {
|
func updateRepoRunsNumbers(ctx context.Context, repo *repo_model.Repository) error {
|
||||||
_, err := db.GetEngine(ctx).ID(repo.ID).
|
_, err := db.GetEngine(ctx).ID(repo.ID).
|
||||||
SetExpr("num_action_runs",
|
SetExpr("num_action_runs",
|
||||||
@@ -194,6 +205,7 @@ func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWork
|
|||||||
if len(needs) > 0 {
|
if len(needs) > 0 {
|
||||||
status = StatusBlocked
|
status = StatusBlocked
|
||||||
}
|
}
|
||||||
|
job.Name, _ = util.SplitStringAtByteN(job.Name, 255)
|
||||||
runJobs = append(runJobs, &ActionRunJob{
|
runJobs = append(runJobs, &ActionRunJob{
|
||||||
RunID: run.ID,
|
RunID: run.ID,
|
||||||
RepoID: run.RepoID,
|
RepoID: run.RepoID,
|
||||||
|
|||||||
@@ -298,8 +298,9 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
|
|||||||
if len(workflowJob.Steps) > 0 {
|
if len(workflowJob.Steps) > 0 {
|
||||||
steps := make([]*ActionTaskStep, len(workflowJob.Steps))
|
steps := make([]*ActionTaskStep, len(workflowJob.Steps))
|
||||||
for i, v := range workflowJob.Steps {
|
for i, v := range workflowJob.Steps {
|
||||||
|
name, _ := util.SplitStringAtByteN(v.String(), 255)
|
||||||
steps[i] = &ActionTaskStep{
|
steps[i] = &ActionTaskStep{
|
||||||
Name: v.String(),
|
Name: name,
|
||||||
TaskID: task.ID,
|
TaskID: task.ID,
|
||||||
Index: int64(i),
|
Index: int64(i),
|
||||||
RepoID: task.RepoID,
|
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")
|
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")
|
||||||
|
|
||||||
indices := []*schemas.Index{actUserIndex, repoIndex}
|
indices := []*schemas.Index{actUserIndex, repoIndex}
|
||||||
if setting.Database.UsePostgreSQL {
|
if setting.Database.Type.IsPostgreSQL() {
|
||||||
cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
|
cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
|
||||||
cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
|
cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
|
||||||
indices = append(indices, cudIndex)
|
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
|
// CountActionCreatedUnixString count actions where created_unix is an empty string
|
||||||
func CountActionCreatedUnixString(ctx context.Context) (int64, error) {
|
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 db.GetEngine(ctx).Where(`created_unix = ""`).Count(new(Action))
|
||||||
}
|
}
|
||||||
return 0, nil
|
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
|
// FixActionCreatedUnixString set created_unix to zero if it is an empty string
|
||||||
func FixActionCreatedUnixString(ctx context.Context) (int64, error) {
|
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 = ""`)
|
res, err := db.GetEngine(ctx).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ func TestGetFeedsCorrupted(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestConsistencyUpdateAction(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.")
|
t.Skip("Test is only for SQLite database.")
|
||||||
}
|
}
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
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"
|
groupBy := "created_unix / 900 * 900"
|
||||||
groupByName := "timestamp" // We need this extra case because mssql doesn't allow grouping by alias
|
groupByName := "timestamp" // We need this extra case because mssql doesn't allow grouping by alias
|
||||||
switch {
|
switch {
|
||||||
case setting.Database.UseMySQL:
|
case setting.Database.Type.IsMySQL():
|
||||||
groupBy = "created_unix DIV 900 * 900"
|
groupBy = "created_unix DIV 900 * 900"
|
||||||
case setting.Database.UseMSSQL:
|
case setting.Database.Type.IsMSSQL():
|
||||||
groupByName = groupBy
|
groupByName = groupBy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ func generateEmailAvatarLink(ctx context.Context, email string, size int, final
|
|||||||
return DefaultAvatarLink()
|
return DefaultAvatarLink()
|
||||||
}
|
}
|
||||||
|
|
||||||
enableFederatedAvatar := system_model.GetSettingBool(ctx, system_model.KeyPictureEnableFederatedAvatar)
|
enableFederatedAvatar := system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureEnableFederatedAvatar)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if enableFederatedAvatar && system_model.LibravatarService != nil {
|
if enableFederatedAvatar && system_model.LibravatarService != nil {
|
||||||
@@ -174,7 +174,7 @@ func generateEmailAvatarLink(ctx context.Context, email string, size int, final
|
|||||||
return urlStr
|
return urlStr
|
||||||
}
|
}
|
||||||
|
|
||||||
disableGravatar := system_model.GetSettingBool(ctx, system_model.KeyPictureDisableGravatar)
|
disableGravatar := system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar)
|
||||||
if !disableGravatar {
|
if !disableGravatar {
|
||||||
// copy GravatarSourceURL, because we will modify its Path.
|
// copy GravatarSourceURL, because we will modify its Path.
|
||||||
avatarURLCopy := *system_model.GravatarSourceURL
|
avatarURLCopy := *system_model.GravatarSourceURL
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func enableGravatar(t *testing.T) {
|
|||||||
err := system_model.SetSettingNoVersion(db.DefaultContext, system_model.KeyPictureDisableGravatar, "false")
|
err := system_model.SetSettingNoVersion(db.DefaultContext, system_model.KeyPictureDisableGravatar, "false")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
setting.GravatarSource = gravatarSource
|
setting.GravatarSource = gravatarSource
|
||||||
err = system_model.Init()
|
err = system_model.Init(db.DefaultContext)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
// BuildCaseInsensitiveLike returns a condition to check if the given value is like the given key case-insensitively.
|
// 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.
|
// Handles especially SQLite correctly as UPPER there only transforms ASCII letters.
|
||||||
func BuildCaseInsensitiveLike(key, value string) builder.Cond {
|
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 + ")", util.ToUpperASCII(value)}
|
||||||
}
|
}
|
||||||
return builder.Like{"UPPER(" + key + ")", strings.ToUpper(value)}
|
return builder.Like{"UPPER(" + key + ")", strings.ToUpper(value)}
|
||||||
|
|||||||
@@ -100,12 +100,12 @@ func newXORMEngine() (*xorm.Engine, error) {
|
|||||||
|
|
||||||
var engine *xorm.Engine
|
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
|
// OK whilst we sort out our schema issues - create a schema aware postgres
|
||||||
registerPostgresSchemaDriver()
|
registerPostgresSchemaDriver()
|
||||||
engine, err = xorm.NewEngine("postgresschema", connStr)
|
engine, err = xorm.NewEngine("postgresschema", connStr)
|
||||||
} else {
|
} else {
|
||||||
engine, err = xorm.NewEngine(setting.Database.Type, connStr)
|
engine, err = xorm.NewEngine(setting.Database.Type.String(), connStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -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
|
// 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) {
|
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)
|
return postgresGetNextResourceIndex(ctx, tableName, groupID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ func Find[T any](ctx context.Context, opts FindOptions, objects *[]T) error {
|
|||||||
if !opts.IsListAll() {
|
if !opts.IsListAll() {
|
||||||
sess.Limit(opts.GetSkipTake())
|
sess.Limit(opts.GetSkipTake())
|
||||||
}
|
}
|
||||||
return sess.Find(&objects)
|
return sess.Find(objects)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count represents a common count function which accept an options interface
|
// 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() {
|
if !opts.IsListAll() {
|
||||||
sess.Limit(opts.GetSkipTake())
|
sess.Limit(opts.GetSkipTake())
|
||||||
}
|
}
|
||||||
return sess.FindAndCount(&objects)
|
return sess.FindAndCount(objects)
|
||||||
}
|
}
|
||||||
48
models/db/list_test.go
Normal file
48
models/db/list_test.go
Normal file
@@ -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
|
// CountBadSequences looks for broken sequences from recreate-table mistakes
|
||||||
func CountBadSequences(_ context.Context) (int64, error) {
|
func CountBadSequences(_ context.Context) (int64, error) {
|
||||||
if !setting.Database.UsePostgreSQL {
|
if !setting.Database.Type.IsPostgreSQL() {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ func CountBadSequences(_ context.Context) (int64, error) {
|
|||||||
|
|
||||||
// FixBadSequences fixes for broken sequences from recreate-table mistakes
|
// FixBadSequences fixes for broken sequences from recreate-table mistakes
|
||||||
func FixBadSequences(_ context.Context) error {
|
func FixBadSequences(_ context.Context) error {
|
||||||
if !setting.Database.UsePostgreSQL {
|
if !setting.Database.Type.IsPostgreSQL() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
fork_id: 0
|
fork_id: 0
|
||||||
is_template: false
|
is_template: false
|
||||||
template_id: 0
|
template_id: 0
|
||||||
size: 6708
|
size: 7028
|
||||||
is_fsck_enabled: true
|
is_fsck_enabled: true
|
||||||
close_issues_via_commit_in_any_branch: false
|
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
|
// GetNextCommitStatusIndex retried 3 times to generate a resource index
|
||||||
func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (int64, error) {
|
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)
|
return postgresGetCommitStatusIndex(ctx, repoID, sha)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ package issues
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
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/timeutil"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
@@ -78,9 +78,6 @@ func (err ErrLabelNotExist) Unwrap() error {
|
|||||||
return util.ErrNotExist
|
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.
|
// Label represents a label of repository for issues.
|
||||||
type Label struct {
|
type Label struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
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.
|
// CalOpenIssues sets the number of open issues of a label based on the already stored number of closed issues.
|
||||||
func (label *Label) CalOpenIssues() {
|
func (l *Label) CalOpenIssues() {
|
||||||
label.NumOpenIssues = label.NumIssues - label.NumClosedIssues
|
l.NumOpenIssues = l.NumIssues - l.NumClosedIssues
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalOpenOrgIssues calculates the open issues of a label for a specific repo
|
// 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{
|
counts, _ := CountIssuesByRepo(ctx, &IssuesOptions{
|
||||||
RepoID: repoID,
|
RepoID: repoID,
|
||||||
LabelIDs: []int64{labelID},
|
LabelIDs: []int64{labelID},
|
||||||
@@ -122,22 +119,22 @@ func (label *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64)
|
|||||||
})
|
})
|
||||||
|
|
||||||
for _, count := range counts {
|
for _, count := range counts {
|
||||||
label.NumOpenRepoIssues += count
|
l.NumOpenRepoIssues += count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadSelectedLabelsAfterClick calculates the set of selected labels when a label is clicked
|
// 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
|
var labelQuerySlice []string
|
||||||
labelSelected := false
|
labelSelected := false
|
||||||
labelID := strconv.FormatInt(label.ID, 10)
|
labelID := strconv.FormatInt(l.ID, 10)
|
||||||
labelScope := label.ExclusiveScope()
|
labelScope := l.ExclusiveScope()
|
||||||
for i, s := range currentSelectedLabels {
|
for i, s := range currentSelectedLabels {
|
||||||
if s == label.ID {
|
if s == l.ID {
|
||||||
labelSelected = true
|
labelSelected = true
|
||||||
} else if -s == label.ID {
|
} else if -s == l.ID {
|
||||||
labelSelected = true
|
labelSelected = true
|
||||||
label.IsExcluded = true
|
l.IsExcluded = true
|
||||||
} else if s != 0 {
|
} else if s != 0 {
|
||||||
// Exclude other labels in the same scope from selection
|
// Exclude other labels in the same scope from selection
|
||||||
if s < 0 || labelScope == "" || labelScope != currentSelectedExclusiveScopes[i] {
|
if s < 0 || labelScope == "" || labelScope != currentSelectedExclusiveScopes[i] {
|
||||||
@@ -148,23 +145,23 @@ func (label *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64,
|
|||||||
if !labelSelected {
|
if !labelSelected {
|
||||||
labelQuerySlice = append(labelQuerySlice, labelID)
|
labelQuerySlice = append(labelQuerySlice, labelID)
|
||||||
}
|
}
|
||||||
label.IsSelected = labelSelected
|
l.IsSelected = labelSelected
|
||||||
label.QueryString = strings.Join(labelQuerySlice, ",")
|
l.QueryString = strings.Join(labelQuerySlice, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
// BelongsToOrg returns true if label is an organization label
|
// BelongsToOrg returns true if label is an organization label
|
||||||
func (label *Label) BelongsToOrg() bool {
|
func (l *Label) BelongsToOrg() bool {
|
||||||
return label.OrgID > 0
|
return l.OrgID > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// BelongsToRepo returns true if label is a repository label
|
// BelongsToRepo returns true if label is a repository label
|
||||||
func (label *Label) BelongsToRepo() bool {
|
func (l *Label) BelongsToRepo() bool {
|
||||||
return label.RepoID > 0
|
return l.RepoID > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get color as RGB values in 0..255 range
|
// Get color as RGB values in 0..255 range
|
||||||
func (label *Label) ColorRGB() (float64, float64, float64, error) {
|
func (l *Label) ColorRGB() (float64, float64, float64, error) {
|
||||||
color, err := strconv.ParseUint(label.Color[1:], 16, 64)
|
color, err := strconv.ParseUint(l.Color[1:], 16, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, 0, err
|
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
|
// Determine if label text should be light or dark to be readable on background color
|
||||||
func (label *Label) UseLightTextColor() bool {
|
func (l *Label) UseLightTextColor() bool {
|
||||||
if strings.HasPrefix(label.Color, "#") {
|
if strings.HasPrefix(l.Color, "#") {
|
||||||
if r, g, b, err := label.ColorRGB(); err == nil {
|
if r, g, b, err := l.ColorRGB(); err == nil {
|
||||||
// Perceived brightness from: https://www.w3.org/TR/AERT/#color-contrast
|
// Perceived brightness from: https://www.w3.org/TR/AERT/#color-contrast
|
||||||
// In the future WCAG 3 APCA may be a better solution
|
// In the future WCAG 3 APCA may be a better solution
|
||||||
brightness := (0.299*r + 0.587*g + 0.114*b) / 255
|
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
|
// Return scope substring of label name, or empty string if none exists
|
||||||
func (label *Label) ExclusiveScope() string {
|
func (l *Label) ExclusiveScope() string {
|
||||||
if !label.Exclusive {
|
if !l.Exclusive {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
lastIndex := strings.LastIndex(label.Name, "/")
|
lastIndex := strings.LastIndex(l.Name, "/")
|
||||||
if lastIndex == -1 || lastIndex == 0 || lastIndex == len(label.Name)-1 {
|
if lastIndex == -1 || lastIndex == 0 || lastIndex == len(l.Name)-1 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return label.Name[:lastIndex]
|
return l.Name[:lastIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLabel creates a new label
|
// NewLabel creates a new label
|
||||||
func NewLabel(ctx context.Context, label *Label) error {
|
func NewLabel(ctx context.Context, l *Label) error {
|
||||||
if !LabelColorPattern.MatchString(label.Color) {
|
color, err := label.NormalizeColor(l.Color)
|
||||||
return fmt.Errorf("bad color code: %s", label.Color)
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
l.Color = color
|
||||||
|
|
||||||
// normalize case
|
return db.Insert(ctx, l)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLabels creates new labels
|
// NewLabels creates new labels
|
||||||
@@ -234,11 +217,14 @@ func NewLabels(labels ...*Label) error {
|
|||||||
}
|
}
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
for _, label := range labels {
|
for _, l := range labels {
|
||||||
if !LabelColorPattern.MatchString(label.Color) {
|
color, err := label.NormalizeColor(l.Color)
|
||||||
return fmt.Errorf("bad color code: %s", label.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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,15 +233,18 @@ func NewLabels(labels ...*Label) error {
|
|||||||
|
|
||||||
// UpdateLabel updates label information.
|
// UpdateLabel updates label information.
|
||||||
func UpdateLabel(l *Label) error {
|
func UpdateLabel(l *Label) error {
|
||||||
if !LabelColorPattern.MatchString(l.Color) {
|
color, err := label.NormalizeColor(l.Color)
|
||||||
return fmt.Errorf("bad color code: %s", l.Color)
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
l.Color = color
|
||||||
|
|
||||||
return updateLabelCols(db.DefaultContext, l, "name", "description", "color", "exclusive")
|
return updateLabelCols(db.DefaultContext, l, "name", "description", "color", "exclusive")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteLabel delete a label
|
// DeleteLabel delete a label
|
||||||
func DeleteLabel(id, labelID int64) error {
|
func DeleteLabel(id, labelID int64) error {
|
||||||
label, err := GetLabelByID(db.DefaultContext, labelID)
|
l, err := GetLabelByID(db.DefaultContext, labelID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if IsErrLabelNotExist(err) {
|
if IsErrLabelNotExist(err) {
|
||||||
return nil
|
return nil
|
||||||
@@ -271,10 +260,10 @@ func DeleteLabel(id, labelID int64) error {
|
|||||||
|
|
||||||
sess := db.GetEngine(ctx)
|
sess := db.GetEngine(ctx)
|
||||||
|
|
||||||
if label.BelongsToOrg() && label.OrgID != id {
|
if l.BelongsToOrg() && l.OrgID != id {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if label.BelongsToRepo() && label.RepoID != id {
|
if l.BelongsToRepo() && l.RepoID != id {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,14 +671,14 @@ func newIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer *us
|
|||||||
if err = issue.LoadRepo(ctx); err != nil {
|
if err = issue.LoadRepo(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, label := range labels {
|
for _, l := range labels {
|
||||||
// Don't add already present labels and invalid labels
|
// Don't add already present labels and invalid labels
|
||||||
if HasIssueLabel(ctx, issue.ID, label.ID) ||
|
if HasIssueLabel(ctx, issue.ID, l.ID) ||
|
||||||
(label.RepoID != issue.RepoID && label.OrgID != issue.Repo.OwnerID) {
|
(l.RepoID != issue.RepoID && l.OrgID != issue.Repo.OwnerID) {
|
||||||
continue
|
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)
|
return fmt.Errorf("newIssueLabel: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -778,7 +767,7 @@ func CountOrphanedLabels(ctx context.Context) (int64, error) {
|
|||||||
norepo, err := db.GetEngine(ctx).Table("label").
|
norepo, err := db.GetEngine(ctx).Table("label").
|
||||||
Where(builder.And(
|
Where(builder.And(
|
||||||
builder.Gt{"repo_id": 0},
|
builder.Gt{"repo_id": 0},
|
||||||
builder.NotIn("repo_id", builder.Select("id").From("repository")),
|
builder.NotIn("repo_id", builder.Select("id").From("`repository`")),
|
||||||
)).
|
)).
|
||||||
Count()
|
Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -788,7 +777,7 @@ func CountOrphanedLabels(ctx context.Context) (int64, error) {
|
|||||||
noorg, err := db.GetEngine(ctx).Table("label").
|
noorg, err := db.GetEngine(ctx).Table("label").
|
||||||
Where(builder.And(
|
Where(builder.And(
|
||||||
builder.Gt{"org_id": 0},
|
builder.Gt{"org_id": 0},
|
||||||
builder.NotIn("org_id", builder.Select("id").From("user")),
|
builder.NotIn("org_id", builder.Select("id").From("`user`")),
|
||||||
)).
|
)).
|
||||||
Count()
|
Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -809,7 +798,7 @@ func DeleteOrphanedLabels(ctx context.Context) error {
|
|||||||
if _, err := db.GetEngine(ctx).
|
if _, err := db.GetEngine(ctx).
|
||||||
Where(builder.And(
|
Where(builder.And(
|
||||||
builder.Gt{"repo_id": 0},
|
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 {
|
Delete(Label{}); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -819,7 +808,7 @@ func DeleteOrphanedLabels(ctx context.Context) error {
|
|||||||
if _, err := db.GetEngine(ctx).
|
if _, err := db.GetEngine(ctx).
|
||||||
Where(builder.And(
|
Where(builder.And(
|
||||||
builder.Gt{"org_id": 0},
|
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 {
|
Delete(Label{}); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO TestGetLabelTemplateFile
|
|
||||||
|
|
||||||
func TestLabel_CalOpenIssues(t *testing.T) {
|
func TestLabel_CalOpenIssues(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
|
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
|
// GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged
|
||||||
// by given head information (repo and branch).
|
// 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)
|
prs := make([]*PullRequest, 0, 2)
|
||||||
return prs, db.GetEngine(db.DefaultContext).
|
sess := 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).
|
|
||||||
Join("INNER", "issue", "issue.id = pull_request.issue_id").
|
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
|
// 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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch)
|
prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -111,6 +114,7 @@ func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequ
|
|||||||
return prs, db.GetEngine(db.DefaultContext).
|
return prs, db.GetEngine(db.DefaultContext).
|
||||||
Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
|
Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
|
||||||
repoID, branch, false, false).
|
repoID, branch, false, false).
|
||||||
|
OrderBy("issue.updated_unix DESC").
|
||||||
Join("INNER", "issue", "issue.id=pull_request.issue_id").
|
Join("INNER", "issue", "issue.id=pull_request.issue_id").
|
||||||
Find(&prs)
|
Find(&prs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
|||||||
|
|
||||||
func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
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.NoError(t, err)
|
||||||
assert.Len(t, prs, 1)
|
assert.Len(t, prs, 1)
|
||||||
for _, pr := range prs {
|
for _, pr := range prs {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
|||||||
hasID = hasID || (column.IsPrimaryKey && column.IsAutoIncrement)
|
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 {
|
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)
|
log.Error("Unable to set identity insert for table %s. Error: %v", tempTableName, err)
|
||||||
return err
|
return err
|
||||||
@@ -143,7 +143,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
|||||||
return err
|
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 {
|
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)
|
log.Error("Unable to switch off identity insert for table %s. Error: %v", tempTableName, err)
|
||||||
return err
|
return err
|
||||||
@@ -151,7 +151,7 @@ func RecreateTable(sess *xorm.Session, bean interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case setting.Database.UseSQLite3:
|
case setting.Database.Type.IsSQLite3():
|
||||||
// SQLite will drop all the constraints on the old table
|
// SQLite will drop all the constraints on the old table
|
||||||
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
||||||
log.Error("Unable to drop old table %s. Error: %v", tableName, err)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
case setting.Database.UseMySQL:
|
case setting.Database.Type.IsMySQL():
|
||||||
// MySQL will drop all the constraints on the old table
|
// MySQL will drop all the constraints on the old table
|
||||||
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
||||||
log.Error("Unable to drop old table %s. Error: %v", tableName, err)
|
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)
|
log.Error("Unable to recreate uniques on table %s. Error: %v", tableName, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case setting.Database.UsePostgreSQL:
|
case setting.Database.Type.IsPostgreSQL():
|
||||||
var originalSequences []string
|
var originalSequences []string
|
||||||
type sequenceData struct {
|
type sequenceData struct {
|
||||||
LastValue int `xorm:"'last_value'"`
|
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
|
// MSSQL will drop all the constraints on the old table
|
||||||
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
||||||
log.Error("Unable to drop old table %s. Error: %v", tableName, err)
|
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
|
// TODO: This will not work if there are foreign keys
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case setting.Database.UseSQLite3:
|
case setting.Database.Type.IsSQLite3():
|
||||||
// First drop the indexes on the columns
|
// First drop the indexes on the columns
|
||||||
res, errIndex := sess.Query(fmt.Sprintf("PRAGMA index_list(`%s`)", tableName))
|
res, errIndex := sess.Query(fmt.Sprintf("PRAGMA index_list(`%s`)", tableName))
|
||||||
if errIndex != nil {
|
if errIndex != nil {
|
||||||
@@ -405,7 +405,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
case setting.Database.UsePostgreSQL:
|
case setting.Database.Type.IsPostgreSQL():
|
||||||
cols := ""
|
cols := ""
|
||||||
for _, col := range columnNames {
|
for _, col := range columnNames {
|
||||||
if cols != "" {
|
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 {
|
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)
|
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
|
// Drop indexes on columns first
|
||||||
sql := fmt.Sprintf("SHOW INDEX FROM %s WHERE column_name IN ('%s')", tableName, strings.Join(columnNames, "','"))
|
sql := fmt.Sprintf("SHOW INDEX FROM %s WHERE column_name IN ('%s')", tableName, strings.Join(columnNames, "','"))
|
||||||
res, err := sess.Query(sql)
|
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 {
|
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)
|
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
|
||||||
}
|
}
|
||||||
case setting.Database.UseMSSQL:
|
case setting.Database.Type.IsMSSQL():
|
||||||
cols := ""
|
cols := ""
|
||||||
for _, col := range columnNames {
|
for _, col := range columnNames {
|
||||||
if cols != "" {
|
if cols != "" {
|
||||||
@@ -543,13 +543,13 @@ func newXORMEngine() (*xorm.Engine, error) {
|
|||||||
|
|
||||||
func deleteDB() error {
|
func deleteDB() error {
|
||||||
switch {
|
switch {
|
||||||
case setting.Database.UseSQLite3:
|
case setting.Database.Type.IsSQLite3():
|
||||||
if err := util.Remove(setting.Database.Path); err != nil {
|
if err := util.Remove(setting.Database.Path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.MkdirAll(path.Dir(setting.Database.Path), os.ModePerm)
|
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)/",
|
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/",
|
||||||
setting.Database.User, setting.Database.Passwd, setting.Database.Host))
|
setting.Database.User, setting.Database.Passwd, setting.Database.Host))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -565,7 +565,7 @@ func deleteDB() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case setting.Database.UsePostgreSQL:
|
case setting.Database.Type.IsPostgreSQL():
|
||||||
db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/?sslmode=%s",
|
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))
|
setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.SSLMode))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -612,7 +612,7 @@ func deleteDB() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case setting.Database.UseMSSQL:
|
case setting.Database.Type.IsMSSQL():
|
||||||
host, port := setting.ParseMSSQLHostPort(setting.Database.Host)
|
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;",
|
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))
|
host, port, "master", setting.Database.User, setting.Database.Passwd))
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
org_id: 0
|
org_id: 0
|
||||||
name: label1
|
name: label1
|
||||||
color: '#abcdef'
|
color: '#abcdef'
|
||||||
exclusive: false
|
|
||||||
num_issues: 2
|
num_issues: 2
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
|
||||||
@@ -14,7 +13,6 @@
|
|||||||
org_id: 0
|
org_id: 0
|
||||||
name: label2
|
name: label2
|
||||||
color: '#000000'
|
color: '#000000'
|
||||||
exclusive: false
|
|
||||||
num_issues: 1
|
num_issues: 1
|
||||||
num_closed_issues: 1
|
num_closed_issues: 1
|
||||||
-
|
-
|
||||||
@@ -23,7 +21,6 @@
|
|||||||
org_id: 3
|
org_id: 3
|
||||||
name: orglabel3
|
name: orglabel3
|
||||||
color: '#abcdef'
|
color: '#abcdef'
|
||||||
exclusive: false
|
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
|
||||||
@@ -33,7 +30,6 @@
|
|||||||
org_id: 3
|
org_id: 3
|
||||||
name: orglabel4
|
name: orglabel4
|
||||||
color: '#000000'
|
color: '#000000'
|
||||||
exclusive: false
|
|
||||||
num_issues: 1
|
num_issues: 1
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
|
||||||
@@ -43,6 +39,5 @@
|
|||||||
org_id: 0
|
org_id: 0
|
||||||
name: pull-test-label
|
name: pull-test-label
|
||||||
color: '#000000'
|
color: '#000000'
|
||||||
exclusive: false
|
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ func PrependRefsHeadsToIssueRefs(x *xorm.Engine) error {
|
|||||||
var query string
|
var query string
|
||||||
|
|
||||||
switch {
|
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/%'"
|
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/%';"
|
query = "UPDATE `issue` SET `ref` = CONCAT('refs/heads/', `ref`) WHERE `ref` IS NOT NULL AND `ref` <> '' AND `ref` NOT LIKE 'refs/%';"
|
||||||
default:
|
default:
|
||||||
query = "UPDATE `issue` SET `ref` = 'refs/heads/' || `ref` WHERE `ref` IS NOT NULL AND `ref` <> '' AND `ref` NOT LIKE 'refs/%'"
|
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
|
// Delete language stat statuses
|
||||||
truncExpr := "TRUNCATE TABLE"
|
truncExpr := "TRUNCATE TABLE"
|
||||||
if setting.Database.UseSQLite3 {
|
if setting.Database.Type.IsSQLite3() {
|
||||||
truncExpr = "DELETE FROM"
|
truncExpr = "DELETE FROM"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func IncreaseLanguageField(x *xorm.Engine) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.Database.UseSQLite3 {
|
if setting.Database.Type.IsSQLite3() {
|
||||||
// SQLite maps VARCHAR to TEXT without size so we're done
|
// SQLite maps VARCHAR to TEXT without size so we're done
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -41,11 +41,11 @@ func IncreaseLanguageField(x *xorm.Engine) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
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 {
|
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat MODIFY COLUMN language %s", sqlType)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case setting.Database.UseMSSQL:
|
case setting.Database.Type.IsMSSQL():
|
||||||
// Yet again MSSQL just has to be awkward.
|
// Yet again MSSQL just has to be awkward.
|
||||||
// Here we have to drop the constraints first and then rebuild them
|
// Here we have to drop the constraints first and then rebuild them
|
||||||
constraints := make([]string, 0)
|
constraints := make([]string, 0)
|
||||||
@@ -71,7 +71,7 @@ func IncreaseLanguageField(x *xorm.Engine) error {
|
|||||||
if err := sess.CreateUniques(new(LanguageStat)); err != nil {
|
if err := sess.CreateUniques(new(LanguageStat)); err != nil {
|
||||||
return err
|
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 {
|
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat ALTER COLUMN language TYPE %s", sqlType)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ import (
|
|||||||
|
|
||||||
func SetDefaultPasswordToArgon2(x *xorm.Engine) error {
|
func SetDefaultPasswordToArgon2(x *xorm.Engine) error {
|
||||||
switch {
|
switch {
|
||||||
case setting.Database.UseMySQL:
|
case setting.Database.Type.IsMySQL():
|
||||||
_, err := x.Exec("ALTER TABLE `user` ALTER passwd_hash_algo SET DEFAULT 'argon2';")
|
_, err := x.Exec("ALTER TABLE `user` ALTER passwd_hash_algo SET DEFAULT 'argon2';")
|
||||||
return err
|
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';")
|
_, err := x.Exec("ALTER TABLE `user` ALTER COLUMN passwd_hash_algo SET DEFAULT 'argon2';")
|
||||||
return err
|
return err
|
||||||
case setting.Database.UseMSSQL:
|
case setting.Database.Type.IsMSSQL():
|
||||||
// need to find the constraint and drop it, then recreate it.
|
// need to find the constraint and drop it, then recreate it.
|
||||||
sess := x.NewSession()
|
sess := x.NewSession()
|
||||||
defer sess.Close()
|
defer sess.Close()
|
||||||
@@ -53,7 +53,7 @@ func SetDefaultPasswordToArgon2(x *xorm.Engine) error {
|
|||||||
}
|
}
|
||||||
return sess.Commit()
|
return sess.Commit()
|
||||||
|
|
||||||
case setting.Database.UseSQLite3:
|
case setting.Database.Type.IsSQLite3():
|
||||||
// drop through
|
// drop through
|
||||||
default:
|
default:
|
||||||
log.Fatal("Unrecognized DB")
|
log.Fatal("Unrecognized DB")
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ func UpdateCodeCommentReplies(x *xorm.Engine) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.Database.UseMSSQL {
|
if setting.Database.Type.IsMSSQL() {
|
||||||
if _, err := sess.Exec(sqlSelect + " INTO #temp_comments" + sqlTail); err != nil {
|
if _, err := sess.Exec(sqlSelect + " INTO #temp_comments" + sqlTail); err != nil {
|
||||||
log.Error("unable to create temporary table")
|
log.Error("unable to create temporary table")
|
||||||
return err
|
return err
|
||||||
@@ -72,13 +72,13 @@ func UpdateCodeCommentReplies(x *xorm.Engine) error {
|
|||||||
comments := make([]*Comment, 0, batchSize)
|
comments := make([]*Comment, 0, batchSize)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case setting.Database.UseMySQL:
|
case setting.Database.Type.IsMySQL():
|
||||||
sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + ", " + strconv.Itoa(start)
|
sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + ", " + strconv.Itoa(start)
|
||||||
case setting.Database.UsePostgreSQL:
|
case setting.Database.Type.IsPostgreSQL():
|
||||||
fallthrough
|
fallthrough
|
||||||
case setting.Database.UseSQLite3:
|
case setting.Database.Type.IsSQLite3():
|
||||||
sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + " OFFSET " + strconv.Itoa(start)
|
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 " +
|
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"
|
"(id NOT IN ( SELECT TOP " + strconv.Itoa(start) + " id FROM #temp_comments ORDER BY id )) ORDER BY id"
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func FixPostgresIDSequences(x *xorm.Engine) error {
|
func FixPostgresIDSequences(x *xorm.Engine) error {
|
||||||
if !setting.Database.UsePostgreSQL {
|
if !setting.Database.Type.IsPostgreSQL() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ func RenameTaskErrorsToMessage(x *xorm.Engine) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case setting.Database.UseMySQL:
|
case setting.Database.Type.IsMySQL():
|
||||||
if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil {
|
if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case setting.Database.UseMSSQL:
|
case setting.Database.Type.IsMSSQL():
|
||||||
if _, err := sess.Exec("sp_rename 'task.errors', 'message', 'COLUMN'"); err != nil {
|
if _, err := sess.Exec("sp_rename 'task.errors', 'message', 'COLUMN'"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func AlterIssueAndCommentTextFieldsToLongText(x *xorm.Engine) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.Database.UseMySQL {
|
if setting.Database.Type.IsMySQL() {
|
||||||
if _, err := sess.Exec("ALTER TABLE `issue` CHANGE `content` `content` LONGTEXT"); err != nil {
|
if _, err := sess.Exec("ALTER TABLE `issue` CHANGE `content` `content` LONGTEXT"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func AlterHookTaskTextFieldsToLongText(x *xorm.Engine) error {
|
|||||||
return err
|
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 {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func (*improveActionTableIndicesAction) TableIndices() []*schemas.Index {
|
|||||||
actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType)
|
actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType)
|
||||||
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")
|
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")
|
||||||
indices := []*schemas.Index{actUserIndex, repoIndex}
|
indices := []*schemas.Index{actUserIndex, repoIndex}
|
||||||
if setting.Database.UsePostgreSQL {
|
if setting.Database.Type.IsPostgreSQL() {
|
||||||
cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
|
cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
|
||||||
cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
|
cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
|
||||||
indices = append(indices, cudIndex)
|
indices = append(indices, cudIndex)
|
||||||
|
|||||||
@@ -65,11 +65,11 @@ func RenameCredentialIDBytes(x *xorm.Engine) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
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 {
|
if _, err := sess.Exec("ALTER TABLE `webauthn_credential` CHANGE credential_id_bytes credential_id VARBINARY(1024)"); err != nil {
|
||||||
return err
|
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 {
|
if _, err := sess.Exec("sp_rename 'webauthn_credential.credential_id_bytes', 'credential_id', 'COLUMN'"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func AlterPublicGPGKeyContentFieldsToMediumText(x *xorm.Engine) error {
|
|||||||
return err
|
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 {
|
if _, err := sess.Exec("ALTER TABLE `gpg_key` CHANGE `content` `content` MEDIUMTEXT"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func AlterPackageVersionMetadataToLongText(x *xorm.Engine) error {
|
|||||||
return err
|
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 {
|
if _, err := sess.Exec("ALTER TABLE `package_version` MODIFY COLUMN `metadata_json` LONGTEXT"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func AlterPublicGPGKeyImportContentFieldToMediumText(x *xorm.Engine) error {
|
|||||||
return err
|
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 {
|
if _, err := sess.Exec("ALTER TABLE `gpg_key_import` CHANGE `content` `content` MEDIUMTEXT"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,6 +239,32 @@ func (org *Organization) CustomAvatarRelativePath() string {
|
|||||||
return org.Avatar
|
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.
|
// CreateOrganization creates record of a new organization.
|
||||||
func CreateOrganization(org *Organization, owner *user_model.User) (err error) {
|
func CreateOrganization(org *Organization, owner *user_model.User) (err error) {
|
||||||
if !owner.CanCreateOrganization() {
|
if !owner.CanCreateOrganization() {
|
||||||
|
|||||||
@@ -416,7 +416,7 @@ func DeleteProjectByID(ctx context.Context, id int64) error {
|
|||||||
|
|
||||||
func DeleteProjectByRepoID(ctx context.Context, repoID int64) error {
|
func DeleteProjectByRepoID(ctx context.Context, repoID int64) error {
|
||||||
switch {
|
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 {
|
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
|
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 {
|
if _, err := db.GetEngine(ctx).Table("project").Where("repo_id = ? ", repoID).Delete(&Project{}); err != nil {
|
||||||
return err
|
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 {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ import (
|
|||||||
var ItemsPerPage = 40
|
var ItemsPerPage = 40
|
||||||
|
|
||||||
// Init initialize model
|
// Init initialize model
|
||||||
func Init() error {
|
func Init(ctx context.Context) error {
|
||||||
unit.LoadUnitConfig()
|
unit.LoadUnitConfig()
|
||||||
return system_model.Init()
|
return system_model.Init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRepository deletes a repository for a user or organization.
|
// DeleteRepository deletes a repository for a user or organization.
|
||||||
|
|||||||
@@ -498,7 +498,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
|
|||||||
subQueryCond := builder.NewCond()
|
subQueryCond := builder.NewCond()
|
||||||
|
|
||||||
// Topic checking. Topics are present.
|
// 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": "[]"}))
|
subQueryCond = subQueryCond.Or(builder.And(builder.NotNull{"topics"}, builder.Neq{"(topics)::text": "[]"}))
|
||||||
} else {
|
} else {
|
||||||
subQueryCond = subQueryCond.Or(builder.And(builder.Neq{"topics": "null"}, builder.Neq{"topics": "[]"}))
|
subQueryCond = subQueryCond.Or(builder.And(builder.Neq{"topics": "null"}, builder.Neq{"topics": "[]"}))
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ func IsErrDataExpired(err error) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSettingNoCache returns specific setting without using the cache
|
// GetSetting returns specific setting without using the cache
|
||||||
func GetSettingNoCache(ctx context.Context, key string) (*Setting, error) {
|
func GetSetting(ctx context.Context, key string) (*Setting, error) {
|
||||||
v, err := GetSettings(ctx, []string{key})
|
v, err := GetSettings(ctx, []string{key})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -93,11 +93,11 @@ func GetSettingNoCache(ctx context.Context, key string) (*Setting, error) {
|
|||||||
|
|
||||||
const contextCacheKey = "system_setting"
|
const contextCacheKey = "system_setting"
|
||||||
|
|
||||||
// GetSetting returns the setting value via the key
|
// GetSettingWithCache returns the setting value via the key
|
||||||
func GetSetting(ctx context.Context, key string) (string, error) {
|
func GetSettingWithCache(ctx context.Context, key string) (string, error) {
|
||||||
return cache.GetWithContextCache(ctx, contextCacheKey, key, func() (string, error) {
|
return cache.GetWithContextCache(ctx, contextCacheKey, key, func() (string, error) {
|
||||||
return cache.GetString(genSettingCacheKey(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 {
|
if err != nil {
|
||||||
return "", err
|
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
|
// none existing keys and errors are ignored and result in false
|
||||||
func GetSettingBool(ctx context.Context, key string) bool {
|
func GetSettingBool(ctx context.Context, key string) bool {
|
||||||
s, _ := GetSetting(ctx, key)
|
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)
|
v, _ := strconv.ParseBool(s)
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
@@ -120,7 +129,7 @@ func GetSettings(ctx context.Context, keys []string) (map[string]*Setting, error
|
|||||||
keys[i] = strings.ToLower(keys[i])
|
keys[i] = strings.ToLower(keys[i])
|
||||||
}
|
}
|
||||||
settings := make([]*Setting, 0, len(keys))
|
settings := make([]*Setting, 0, len(keys))
|
||||||
if err := db.GetEngine(db.DefaultContext).
|
if err := db.GetEngine(ctx).
|
||||||
Where(builder.In("setting_key", keys)).
|
Where(builder.In("setting_key", keys)).
|
||||||
Find(&settings); err != nil {
|
Find(&settings); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -151,9 +160,9 @@ func (settings AllSettings) GetVersion(key string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAllSettings returns all settings from user
|
// GetAllSettings returns all settings from user
|
||||||
func GetAllSettings() (AllSettings, error) {
|
func GetAllSettings(ctx context.Context) (AllSettings, error) {
|
||||||
settings := make([]*Setting, 0, 5)
|
settings := make([]*Setting, 0, 5)
|
||||||
if err := db.GetEngine(db.DefaultContext).
|
if err := db.GetEngine(ctx).
|
||||||
Find(&settings); err != nil {
|
Find(&settings); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -168,12 +177,12 @@ func GetAllSettings() (AllSettings, error) {
|
|||||||
func DeleteSetting(ctx context.Context, setting *Setting) error {
|
func DeleteSetting(ctx context.Context, setting *Setting) error {
|
||||||
cache.RemoveContextData(ctx, contextCacheKey, setting.SettingKey)
|
cache.RemoveContextData(ctx, contextCacheKey, setting.SettingKey)
|
||||||
cache.Remove(genSettingCacheKey(setting.SettingKey))
|
cache.Remove(genSettingCacheKey(setting.SettingKey))
|
||||||
_, err := db.GetEngine(db.DefaultContext).Delete(setting)
|
_, err := db.GetEngine(ctx).Delete(setting)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetSettingNoVersion(ctx context.Context, key, value string) error {
|
func SetSettingNoVersion(ctx context.Context, key, value string) error {
|
||||||
s, err := GetSettingNoCache(ctx, key)
|
s, err := GetSetting(ctx, key)
|
||||||
if IsErrSettingIsNotExist(err) {
|
if IsErrSettingIsNotExist(err) {
|
||||||
return SetSetting(ctx, &Setting{
|
return SetSetting(ctx, &Setting{
|
||||||
SettingKey: key,
|
SettingKey: key,
|
||||||
@@ -189,7 +198,7 @@ func SetSettingNoVersion(ctx context.Context, key, value string) error {
|
|||||||
|
|
||||||
// SetSetting updates a users' setting for a specific key
|
// SetSetting updates a users' setting for a specific key
|
||||||
func SetSetting(ctx context.Context, setting *Setting) error {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,8 +214,8 @@ func SetSetting(ctx context.Context, setting *Setting) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func upsertSettingValue(key, value string, version int) error {
|
func upsertSettingValue(parentCtx context.Context, key, value string, version int) error {
|
||||||
return db.WithTx(db.DefaultContext, func(ctx context.Context) error {
|
return db.WithTx(parentCtx, func(ctx context.Context) error {
|
||||||
e := db.GetEngine(ctx)
|
e := db.GetEngine(ctx)
|
||||||
|
|
||||||
// here we use a general method to do a safe upsert for different databases (and most transaction levels)
|
// 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
|
LibravatarService *libravatar.Libravatar
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() error {
|
func Init(ctx context.Context) error {
|
||||||
var disableGravatar bool
|
var disableGravatar bool
|
||||||
disableGravatarSetting, err := GetSettingNoCache(db.DefaultContext, KeyPictureDisableGravatar)
|
disableGravatarSetting, err := GetSetting(ctx, KeyPictureDisableGravatar)
|
||||||
if IsErrSettingIsNotExist(err) {
|
if IsErrSettingIsNotExist(err) {
|
||||||
disableGravatar = setting_module.GetDefaultDisableGravatar()
|
disableGravatar = setting_module.GetDefaultDisableGravatar()
|
||||||
disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)}
|
disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)}
|
||||||
@@ -262,7 +271,7 @@ func Init() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var enableFederatedAvatar bool
|
var enableFederatedAvatar bool
|
||||||
enableFederatedAvatarSetting, err := GetSettingNoCache(db.DefaultContext, KeyPictureEnableFederatedAvatar)
|
enableFederatedAvatarSetting, err := GetSetting(ctx, KeyPictureEnableFederatedAvatar)
|
||||||
if IsErrSettingIsNotExist(err) {
|
if IsErrSettingIsNotExist(err) {
|
||||||
enableFederatedAvatar = setting_module.GetDefaultEnableFederatedAvatar(disableGravatar)
|
enableFederatedAvatar = setting_module.GetDefaultEnableFederatedAvatar(disableGravatar)
|
||||||
enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)}
|
enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)}
|
||||||
@@ -275,13 +284,13 @@ func Init() error {
|
|||||||
if setting_module.OfflineMode {
|
if setting_module.OfflineMode {
|
||||||
disableGravatar = true
|
disableGravatar = true
|
||||||
enableFederatedAvatar = false
|
enableFederatedAvatar = false
|
||||||
if !GetSettingBool(db.DefaultContext, KeyPictureDisableGravatar) {
|
if !GetSettingBool(ctx, KeyPictureDisableGravatar) {
|
||||||
if err := SetSettingNoVersion(db.DefaultContext, KeyPictureDisableGravatar, "true"); err != nil {
|
if err := SetSettingNoVersion(ctx, KeyPictureDisableGravatar, "true"); err != nil {
|
||||||
return fmt.Errorf("Failed to set setting %q: %w", KeyPictureDisableGravatar, err)
|
return fmt.Errorf("Failed to set setting %q: %w", KeyPictureDisableGravatar, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if GetSettingBool(db.DefaultContext, KeyPictureEnableFederatedAvatar) {
|
if GetSettingBool(ctx, KeyPictureEnableFederatedAvatar) {
|
||||||
if err := SetSettingNoVersion(db.DefaultContext, KeyPictureEnableFederatedAvatar, "false"); err != nil {
|
if err := SetSettingNoVersion(ctx, KeyPictureEnableFederatedAvatar, "false"); err != nil {
|
||||||
return fmt.Errorf("Failed to set setting %q: %w", KeyPictureEnableFederatedAvatar, err)
|
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)
|
value, err := system.GetSetting(db.DefaultContext, keyName)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, updatedSetting.SettingValue, value)
|
assert.EqualValues(t, updatedSetting.SettingValue, value.SettingValue)
|
||||||
|
|
||||||
// get all settings
|
// get all settings
|
||||||
settings, err = system.GetAllSettings()
|
settings, err = system.GetAllSettings(db.DefaultContext)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, settings, 3)
|
assert.Len(t, settings, 3)
|
||||||
assert.EqualValues(t, updatedSetting.SettingValue, settings[strings.ToLower(updatedSetting.SettingKey)].SettingValue)
|
assert.EqualValues(t, updatedSetting.SettingValue, settings[strings.ToLower(updatedSetting.SettingKey)].SettingValue)
|
||||||
@@ -51,7 +51,7 @@ func TestSettings(t *testing.T) {
|
|||||||
// delete setting
|
// delete setting
|
||||||
err = system.DeleteSetting(db.DefaultContext, &system.Setting{SettingKey: strings.ToLower(keyName)})
|
err = system.DeleteSetting(db.DefaultContext, &system.Setting{SettingKey: strings.ToLower(keyName)})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
settings, err = system.GetAllSettings()
|
settings, err = system.GetAllSettings(db.DefaultContext)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, settings, 2)
|
assert.Len(t, settings, 2)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
|||||||
setting.SSH.BuiltinServerUser = "builtinuser"
|
setting.SSH.BuiltinServerUser = "builtinuser"
|
||||||
setting.SSH.Port = 3000
|
setting.SSH.Port = 3000
|
||||||
setting.SSH.Domain = "try.gitea.io"
|
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"
|
setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
|
||||||
repoRootPath, err := os.MkdirTemp(os.TempDir(), "repos")
|
repoRootPath, err := os.MkdirTemp(os.TempDir(), "repos")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -113,7 +113,7 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
|||||||
if err = storage.Init(); err != nil {
|
if err = storage.Init(); err != nil {
|
||||||
fatalTestError("storage.Init: %v\n", err)
|
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)
|
fatalTestError("models.Init: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func (u *User) AvatarLinkWithSize(ctx context.Context, size int) string {
|
|||||||
useLocalAvatar := false
|
useLocalAvatar := false
|
||||||
autoGenerateAvatar := false
|
autoGenerateAvatar := false
|
||||||
|
|
||||||
disableGravatar := system_model.GetSettingBool(ctx, system_model.KeyPictureDisableGravatar)
|
disableGravatar := system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case u.UseCustomAvatar:
|
case u.UseCustomAvatar:
|
||||||
|
|||||||
@@ -393,6 +393,11 @@ func (u *User) IsOrganization() bool {
|
|||||||
return u.Type == UserTypeOrganization
|
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,
|
// DisplayName returns full name if it's not empty,
|
||||||
// returns username otherwise.
|
// returns username otherwise.
|
||||||
func (u *User) DisplayName() string {
|
func (u *User) DisplayName() string {
|
||||||
|
|||||||
41
modules/actions/github.go
Normal file
41
modules/actions/github.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,9 +72,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, evt := range events {
|
for _, evt := range events {
|
||||||
if evt.Name != triggedEvent.Event() {
|
log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent)
|
||||||
continue
|
|
||||||
}
|
|
||||||
if detectMatched(commit, triggedEvent, payload, evt) {
|
if detectMatched(commit, triggedEvent, payload, evt) {
|
||||||
workflows[entry.Name()] = content
|
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 {
|
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 {
|
if len(evt.Acts) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
switch triggedEvent {
|
matchTimes := 0
|
||||||
case webhook_module.HookEventCreate:
|
// all acts conditions should be satisfied
|
||||||
fallthrough
|
for cond, vals := range evt.Acts {
|
||||||
case webhook_module.HookEventDelete:
|
switch cond {
|
||||||
fallthrough
|
case "branches", "tags":
|
||||||
case webhook_module.HookEventFork:
|
refShortName := git.RefName(pushPayload.Ref).ShortName()
|
||||||
log.Warn("unsupported event %q", triggedEvent.Event())
|
for _, val := range vals {
|
||||||
return false
|
if glob.MustCompile(val, '/').Match(refShortName) {
|
||||||
case webhook_module.HookEventPush:
|
matchTimes++
|
||||||
pushPayload := payload.(*api.PushPayload)
|
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)
|
case "paths":
|
||||||
if err != nil {
|
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
|
||||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
if err != nil {
|
||||||
} else {
|
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
||||||
for _, val := range vals {
|
} else {
|
||||||
matched := false
|
for _, val := range vals {
|
||||||
for _, file := range filesChanged {
|
matched := false
|
||||||
if glob.MustCompile(val, '/').Match(file) {
|
for _, file := range filesChanged {
|
||||||
matched = true
|
if glob.MustCompile(val, '/').Match(file) {
|
||||||
break
|
matched = true
|
||||||
}
|
|
||||||
}
|
|
||||||
if matched {
|
|
||||||
matchTimes++
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if matched {
|
||||||
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)) {
|
|
||||||
matchTimes++
|
matchTimes++
|
||||||
break
|
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",
|
"pbkdf2_hi",
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaultPasswordHashAlgorithm will take a provided algorithmName and dealias it to
|
// hashAlgorithmToSpec converts an algorithm name or a specification to a full algorithm specification
|
||||||
// a complete algorithm specification.
|
func hashAlgorithmToSpec(algorithmName string) string {
|
||||||
func SetDefaultPasswordHashAlgorithm(algorithmName string) (string, *PasswordHashAlgorithm) {
|
|
||||||
if algorithmName == "" {
|
if algorithmName == "" {
|
||||||
algorithmName = DefaultHashAlgorithmName
|
algorithmName = DefaultHashAlgorithmName
|
||||||
}
|
}
|
||||||
@@ -52,10 +51,26 @@ func SetDefaultPasswordHashAlgorithm(algorithmName string) (string, *PasswordHas
|
|||||||
algorithmName = alias
|
algorithmName = alias
|
||||||
alias, has = aliasAlgorithmNames[algorithmName]
|
alias, has = aliasAlgorithmNames[algorithmName]
|
||||||
}
|
}
|
||||||
|
return algorithmName
|
||||||
// algorithmName should now be a full algorithm specification
|
}
|
||||||
// e.g. pbkdf2$50000$50 rather than pbdkf2
|
|
||||||
DefaultHashAlgorithm = Parse(algorithmName)
|
// SetDefaultPasswordHashAlgorithm will take a provided algorithmName and de-alias it to
|
||||||
|
// a complete algorithm specification.
|
||||||
return algorithmName, DefaultHashAlgorithm
|
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.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
||||||
|
|
||||||
ctx.Data["Context"] = &ctx
|
ctx.Data["Context"] = &ctx
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ func (ctx *Context) SetServeHeaders(opts *ServeHeaderOptions) {
|
|||||||
if duration == 0 {
|
if duration == 0 {
|
||||||
duration = 5 * time.Minute
|
duration = 5 * time.Minute
|
||||||
}
|
}
|
||||||
httpcache.AddCacheControlToHeader(header, duration)
|
httpcache.SetCacheControlInHeader(header, duration)
|
||||||
|
|
||||||
if !opts.LastModified.IsZero() {
|
if !opts.LastModified.IsZero() {
|
||||||
header.Set("Last-Modified", opts.LastModified.UTC().Format(http.TimeFormat))
|
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.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
||||||
|
|
||||||
ctx.Data["CsrfToken"] = ctx.csrf.GetToken()
|
ctx.Data["CsrfToken"] = ctx.csrf.GetToken()
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"code.gitea.io/gitea/models/perm"
|
"code.gitea.io/gitea/models/perm"
|
||||||
"code.gitea.io/gitea/models/unit"
|
"code.gitea.io/gitea/models/unit"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
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/setting"
|
||||||
"code.gitea.io/gitea/modules/structs"
|
"code.gitea.io/gitea/modules/structs"
|
||||||
)
|
)
|
||||||
@@ -31,29 +30,34 @@ type Organization struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (org *Organization) CanWriteUnit(ctx *Context, unitType unit.Type) bool {
|
func (org *Organization) CanWriteUnit(ctx *Context, unitType unit.Type) bool {
|
||||||
if ctx.Doer == nil {
|
return org.Organization.UnitPermission(ctx, ctx.Doer, unitType) >= perm.AccessModeWrite
|
||||||
return false
|
|
||||||
}
|
|
||||||
return org.UnitPermission(ctx, ctx.Doer.ID, unitType) >= perm.AccessModeWrite
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (org *Organization) UnitPermission(ctx *Context, doerID int64, unitType unit.Type) perm.AccessMode {
|
func (org *Organization) CanReadUnit(ctx *Context, unitType unit.Type) bool {
|
||||||
if doerID > 0 {
|
return org.Organization.UnitPermission(ctx, ctx.Doer, unitType) >= perm.AccessModeRead
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if org.Organization.Visibility == structs.VisibleTypePublic {
|
func GetOrganizationByParams(ctx *Context) {
|
||||||
return perm.AccessModeRead
|
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
|
// HandleOrgAssignment handles organization assignment
|
||||||
@@ -77,25 +81,26 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
|||||||
requireTeamAdmin = args[3]
|
requireTeamAdmin = args[3]
|
||||||
}
|
}
|
||||||
|
|
||||||
orgName := ctx.Params(":org")
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
ctx.Org.Organization, err = organization.GetOrgByName(ctx, orgName)
|
|
||||||
if err != nil {
|
if ctx.ContextUser == nil {
|
||||||
if organization.IsErrOrgNotExist(err) {
|
// if Organization is not defined, get it from params
|
||||||
redirectUserID, err := user_model.LookupUserRedirect(orgName)
|
if ctx.Org.Organization == nil {
|
||||||
if err == nil {
|
GetOrganizationByParams(ctx)
|
||||||
RedirectToUser(ctx, orgName, redirectUserID)
|
if ctx.Written() {
|
||||||
} else if user_model.IsErrUserRedirectNotExist(err) {
|
return
|
||||||
ctx.NotFound("GetUserByName", err)
|
|
||||||
} else {
|
|
||||||
ctx.ServerError("LookupUserRedirect", err)
|
|
||||||
}
|
}
|
||||||
} 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
org := ctx.Org.Organization
|
org := ctx.Org.Organization
|
||||||
|
|
||||||
// Handle Visibility
|
// Handle Visibility
|
||||||
@@ -156,6 +161,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
|||||||
}
|
}
|
||||||
ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
|
ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
|
||||||
ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
|
ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
|
||||||
|
ctx.Data["IsProjectEnabled"] = true
|
||||||
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
|
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
|
||||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||||
ctx.Data["IsPublicMember"] = func(uid int64) bool {
|
ctx.Data["IsPublicMember"] = func(uid int64) bool {
|
||||||
@@ -231,6 +237,10 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
|||||||
return
|
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
|
// OrgAssignment returns a middleware to handle organization assignment
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ type Pagination struct {
|
|||||||
urlParams []string
|
urlParams []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPagination creates a new instance of the Pagination struct
|
// NewPagination creates a new instance of the Pagination struct.
|
||||||
func NewPagination(total, page, issueNum, numPages int) *Pagination {
|
// "pagingNum" is "page size" or "limit", "current" is "page"
|
||||||
|
func NewPagination(total, pagingNum, current, numPages int) *Pagination {
|
||||||
p := &Pagination{}
|
p := &Pagination{}
|
||||||
p.Paginater = paginator.New(total, page, issueNum, numPages)
|
p.Paginater = paginator.New(total, pagingNum, current, numPages)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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 {
|
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)
|
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
|
// TODO: function to recalc all counters
|
||||||
|
|
||||||
if setting.Database.UsePostgreSQL {
|
if setting.Database.Type.IsPostgreSQL() {
|
||||||
consistencyChecks = append(consistencyChecks, consistencyCheck{
|
consistencyChecks = append(consistencyChecks, consistencyCheck{
|
||||||
Name: "Sequence values",
|
Name: "Sequence values",
|
||||||
Counter: db.CountBadSequences,
|
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
|
// 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 {
|
func ToTrustedCmdArgs(args []string) TrustedCmdArgs {
|
||||||
ret := make(TrustedCmdArgs, len(args))
|
ret := make(TrustedCmdArgs, len(args))
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
|
|||||||
@@ -201,6 +201,23 @@ func InitFull(ctx context.Context) (err error) {
|
|||||||
return syncGitConfig()
|
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)
|
// syncGitConfig only modifies gitconfig, won't change global variables (otherwise there will be data-race problem)
|
||||||
func syncGitConfig() (err error) {
|
func syncGitConfig() (err error) {
|
||||||
if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil {
|
if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil {
|
||||||
@@ -224,6 +241,16 @@ func syncGitConfig() (err error) {
|
|||||||
return err
|
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 CheckGitVersionAtLeast("2.10") == nil {
|
||||||
if err := configSet("receive.advertisePushOptions", "true"); err != nil {
|
if err := configSet("receive.advertisePushOptions", "true"); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -312,7 +339,7 @@ func CheckGitVersionAtLeast(atLeast string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configSet(key, value 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) {
|
if err != nil && !err.IsExitCode(1) {
|
||||||
return fmt.Errorf("failed to get git config %s, err: %w", key, err)
|
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 {
|
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 {
|
if err == nil {
|
||||||
// already exist
|
// already exist
|
||||||
return nil
|
return nil
|
||||||
@@ -349,7 +376,7 @@ func configSetNonExist(key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configAddNonExist(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 {
|
if err == nil {
|
||||||
// already exist
|
// already exist
|
||||||
return nil
|
return nil
|
||||||
@@ -366,7 +393,7 @@ func configAddNonExist(key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configUnsetAll(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 {
|
if err == nil {
|
||||||
// exist, need to remove
|
// exist, need to remove
|
||||||
_, _, err = NewCommand(DefaultContext, "config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil)
|
_, _, 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()
|
defer revListWriter.Close()
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
var errbuf strings.Builder
|
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{
|
if err := cmd.Run(&git.RunOpts{
|
||||||
Dir: tmpBasePath,
|
Dir: tmpBasePath,
|
||||||
Stdout: revListWriter,
|
Stdout: revListWriter,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
@@ -67,38 +66,6 @@ func (repo *Repository) IsCommitExist(name string) bool {
|
|||||||
return err == nil
|
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) {
|
func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
|
||||||
var tagObject *object.Tag
|
var tagObject *object.Tag
|
||||||
|
|
||||||
@@ -122,12 +89,6 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
|
|||||||
commit := convertCommit(gogitCommit)
|
commit := convertCommit(gogitCommit)
|
||||||
commit.repo = repo
|
commit.repo = repo
|
||||||
|
|
||||||
if tagObject != nil {
|
|
||||||
commit.CommitMessage = strings.TrimSpace(tagObject.Message)
|
|
||||||
commit.Author = &tagObject.Tagger
|
|
||||||
commit.Signature = convertPGPSignatureForTag(tagObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
tree, err := gogitCommit.Tree()
|
tree, err := gogitCommit.Tree()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -107,10 +107,6 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.CommitMessage = strings.TrimSpace(tag.Message)
|
|
||||||
commit.Author = tag.Tagger
|
|
||||||
commit.Signature = tag.Signature
|
|
||||||
|
|
||||||
return commit, nil
|
return commit, nil
|
||||||
case "commit":
|
case "commit":
|
||||||
commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
|
commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
|
||||||
|
|||||||
@@ -43,12 +43,13 @@ func TestGetTagCommitWithSignature(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
defer bareRepo1.Close()
|
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.NoError(t, err)
|
||||||
assert.NotNil(t, commit)
|
assert.NotNil(t, commit)
|
||||||
assert.NotNil(t, commit.Signature)
|
assert.NotNil(t, commit.Signature)
|
||||||
// test that signature is not in message
|
// 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) {
|
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
|
// GetFilesChangedBetween returns a list of all files that have been changed between the given commits
|
||||||
func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// 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()
|
refs, err := bareRepo1.GetRefs()
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, refs, 5)
|
assert.Len(t, refs, 6)
|
||||||
|
|
||||||
expectedRefs := []string{
|
expectedRefs := []string{
|
||||||
BranchPrefix + "branch1",
|
BranchPrefix + "branch1",
|
||||||
BranchPrefix + "branch2",
|
BranchPrefix + "branch2",
|
||||||
BranchPrefix + "master",
|
BranchPrefix + "master",
|
||||||
TagPrefix + "test",
|
TagPrefix + "test",
|
||||||
|
TagPrefix + "signed-tag",
|
||||||
NotesRef,
|
NotesRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,9 +44,12 @@ func TestRepository_GetRefsFiltered(t *testing.T) {
|
|||||||
refs, err := bareRepo1.GetRefsFiltered(TagPrefix)
|
refs, err := bareRepo1.GetRefsFiltered(TagPrefix)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if assert.Len(t, refs, 1) {
|
if assert.Len(t, refs, 2) {
|
||||||
assert.Equal(t, TagPrefix+"test", refs[0].Name)
|
assert.Equal(t, TagPrefix+"signed-tag", refs[0].Name)
|
||||||
assert.Equal(t, "tag", refs[0].Type)
|
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.NoError(t, err)
|
||||||
assert.NotNil(t, code)
|
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, 3, code.AuthorCount)
|
||||||
assert.EqualValues(t, 9, code.CommitCountInAllBranches)
|
assert.EqualValues(t, 10, code.CommitCountInAllBranches)
|
||||||
assert.EqualValues(t, 10, code.Additions)
|
assert.EqualValues(t, 10, code.Additions)
|
||||||
assert.EqualValues(t, 1, code.Deletions)
|
assert.EqualValues(t, 1, code.Deletions)
|
||||||
assert.Len(t, code.Authors, 3)
|
assert.Len(t, code.Authors, 3)
|
||||||
|
|||||||
@@ -25,11 +25,14 @@ func TestRepository_GetTags(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert.Len(t, tags, 1)
|
assert.Len(t, tags, 2)
|
||||||
assert.Equal(t, len(tags), total)
|
assert.Equal(t, len(tags), total)
|
||||||
assert.EqualValues(t, "test", tags[0].Name)
|
assert.EqualValues(t, "signed-tag", tags[0].Name)
|
||||||
assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[0].ID.String())
|
assert.EqualValues(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", tags[0].ID.String())
|
||||||
assert.EqualValues(t, "tag", tags[0].Type)
|
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) {
|
func TestRepository_GetTag(t *testing.T) {
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ func TestGetLatestCommitTime(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
lct, err := GetLatestCommitTime(DefaultContext, bareRepo1Path)
|
lct, err := GetLatestCommitTime(DefaultContext, bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
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
|
// which is the time of commit
|
||||||
// feaf4ba6bc635fec442f46ddd4512416ec43c2c2 (refs/heads/master)
|
// ce064814f4a0d337b333e646ece456cd39fab612 (refs/heads/master)
|
||||||
assert.EqualValues(t, 1563741793, lct.Unix())
|
assert.EqualValues(t, 1668354014, lct.Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRepoIsEmpty(t *testing.T) {
|
func TestRepoIsEmpty(t *testing.T) {
|
||||||
|
|||||||
BIN
modules/git/tests/repos/repo1_bare/index
Normal file
BIN
modules/git/tests/repos/repo1_bare/index
Normal file
Binary file not shown.
@@ -1 +1,2 @@
|
|||||||
37991dec2c8e592043f47155ce4808d4580f9123 feaf4ba6bc635fec442f46ddd4512416ec43c2c2 silverwind <me@silverwind.io> 1563741799 +0200 push
|
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
|
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
|
||||||
|
|||||||
1
modules/git/tests/repos/repo1_bare/refs/tags/signed-tag
Normal file
1
modules/git/tests/repos/repo1_bare/refs/tags/signed-tag
Normal file
@@ -0,0 +1 @@
|
|||||||
|
36f97d9a96457e2bab511db30fe2db03893ebc64
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user