Compare commits
No commits in common. "main" and "master" have entirely different histories.
|
@ -14,28 +14,28 @@ groups:
|
||||||
name: BREAKING
|
name: BREAKING
|
||||||
labels:
|
labels:
|
||||||
- kind/breaking
|
- kind/breaking
|
||||||
-
|
|
||||||
name: SECURITY
|
|
||||||
labels:
|
|
||||||
- kind/security
|
|
||||||
-
|
-
|
||||||
name: FEATURES
|
name: FEATURES
|
||||||
labels:
|
labels:
|
||||||
- kind/feature
|
- kind/feature
|
||||||
|
-
|
||||||
|
name: SECURITY
|
||||||
|
labels:
|
||||||
|
- kind/security
|
||||||
-
|
-
|
||||||
name: API
|
name: API
|
||||||
labels:
|
labels:
|
||||||
- kind/api
|
- kind/api
|
||||||
|
-
|
||||||
|
name: BUGFIXES
|
||||||
|
labels:
|
||||||
|
- kind/bug
|
||||||
-
|
-
|
||||||
name: ENHANCEMENTS
|
name: ENHANCEMENTS
|
||||||
labels:
|
labels:
|
||||||
- kind/enhancement
|
- kind/enhancement
|
||||||
- kind/refactor
|
- kind/refactor
|
||||||
- kind/ui
|
- kind/ui
|
||||||
-
|
|
||||||
name: BUGFIXES
|
|
||||||
labels:
|
|
||||||
- kind/bug
|
|
||||||
-
|
-
|
||||||
name: TESTING
|
name: TESTING
|
||||||
labels:
|
labels:
|
||||||
|
|
421
.drone.yml
421
.drone.yml
|
@ -4,30 +4,28 @@ name: compliance
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
os: linux
|
os: linux
|
||||||
arch: amd64
|
arch: arm64
|
||||||
|
|
||||||
trigger:
|
workspace:
|
||||||
event:
|
base: /go
|
||||||
- push
|
path: src/code.gitea.io/gitea
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: deps-frontend
|
- name: deps-frontend
|
||||||
pull: always
|
pull: always
|
||||||
image: node:16
|
image: node:14
|
||||||
commands:
|
commands:
|
||||||
- make node_modules
|
- make node_modules
|
||||||
|
|
||||||
- name: lint-frontend
|
- name: lint-frontend
|
||||||
image: node:16
|
image: node:14
|
||||||
commands:
|
commands:
|
||||||
- make lint-frontend
|
- make lint-frontend
|
||||||
depends_on: [deps-frontend]
|
depends_on: [deps-frontend]
|
||||||
|
|
||||||
- name: lint-backend
|
- name: lint-backend
|
||||||
pull: always
|
pull: always
|
||||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
- make lint-backend
|
- make lint-backend
|
||||||
environment:
|
environment:
|
||||||
|
@ -37,7 +35,7 @@ steps:
|
||||||
|
|
||||||
- name: lint-backend-windows
|
- name: lint-backend-windows
|
||||||
pull: always
|
pull: always
|
||||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
- make golangci-lint vet
|
- make golangci-lint vet
|
||||||
environment:
|
environment:
|
||||||
|
@ -49,7 +47,7 @@ steps:
|
||||||
|
|
||||||
- name: lint-backend-gogit
|
- name: lint-backend-gogit
|
||||||
pull: always
|
pull: always
|
||||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
- make lint-backend
|
- make lint-backend
|
||||||
environment:
|
environment:
|
||||||
|
@ -58,33 +56,27 @@ steps:
|
||||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||||
|
|
||||||
- name: checks-frontend
|
- name: checks-frontend
|
||||||
image: node:16
|
image: node:14
|
||||||
commands:
|
commands:
|
||||||
- make checks-frontend
|
- make checks-frontend
|
||||||
depends_on: [deps-frontend]
|
depends_on: [deps-frontend]
|
||||||
|
|
||||||
- name: checks-backend
|
- name: checks-backend
|
||||||
pull: always
|
pull: always
|
||||||
image: golang:1.17
|
image: golang:1.14
|
||||||
commands:
|
commands:
|
||||||
- make checks-backend
|
- make checks-backend
|
||||||
depends_on: [lint-backend]
|
depends_on: [lint-backend]
|
||||||
|
|
||||||
- name: test-frontend
|
|
||||||
image: node:16
|
|
||||||
commands:
|
|
||||||
- make test-frontend
|
|
||||||
depends_on: [lint-frontend]
|
|
||||||
|
|
||||||
- name: build-frontend
|
- name: build-frontend
|
||||||
image: node:16
|
image: node:14
|
||||||
commands:
|
commands:
|
||||||
- make frontend
|
- make frontend
|
||||||
depends_on: [test-frontend]
|
depends_on: [lint-frontend]
|
||||||
|
|
||||||
- name: build-backend-no-gcc
|
- name: build-backend-no-gcc
|
||||||
pull: always
|
pull: always
|
||||||
image: golang:1.16 # this step is kept as the lowest version of golang that we support
|
image: golang:1.13 # this step is kept as the lowest version of golang that we support
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: on
|
GO111MODULE: on
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
|
@ -93,7 +85,7 @@ steps:
|
||||||
depends_on: [checks-backend]
|
depends_on: [checks-backend]
|
||||||
|
|
||||||
- name: build-backend-arm64
|
- name: build-backend-arm64
|
||||||
image: golang:1.17
|
image: golang:1.15
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: on
|
GO111MODULE: on
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
|
@ -106,7 +98,7 @@ steps:
|
||||||
depends_on: [checks-backend]
|
depends_on: [checks-backend]
|
||||||
|
|
||||||
- name: build-backend-windows
|
- name: build-backend-windows
|
||||||
image: golang:1.17
|
image: golang:1.15
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: on
|
GO111MODULE: on
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
|
@ -118,7 +110,7 @@ steps:
|
||||||
depends_on: [checks-backend]
|
depends_on: [checks-backend]
|
||||||
|
|
||||||
- name: build-backend-386
|
- name: build-backend-386
|
||||||
image: golang:1.17
|
image: golang:1.15
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: on
|
GO111MODULE: on
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
|
@ -139,11 +131,9 @@ platform:
|
||||||
depends_on:
|
depends_on:
|
||||||
- compliance
|
- compliance
|
||||||
|
|
||||||
trigger:
|
workspace:
|
||||||
event:
|
base: /go
|
||||||
- push
|
path: src/code.gitea.io/gitea
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- name: mysql
|
- name: mysql
|
||||||
|
@ -153,7 +143,7 @@ services:
|
||||||
MYSQL_DATABASE: test
|
MYSQL_DATABASE: test
|
||||||
|
|
||||||
- name: mysql8
|
- name: mysql8
|
||||||
image: mysql:8
|
image: mysql:8.0
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||||
MYSQL_DATABASE: testgitea
|
MYSQL_DATABASE: testgitea
|
||||||
|
@ -174,7 +164,7 @@ services:
|
||||||
image: elasticsearch:7.5.0
|
image: elasticsearch:7.5.0
|
||||||
|
|
||||||
- name: minio
|
- name: minio
|
||||||
image: minio/minio:RELEASE.2021-03-12T00-00-47Z
|
image: minio/minio:RELEASE.2020-10-09T22-55-05Z
|
||||||
commands:
|
commands:
|
||||||
- minio server /data
|
- minio server /data
|
||||||
environment:
|
environment:
|
||||||
|
@ -193,7 +183,7 @@ steps:
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
pull: always
|
pull: always
|
||||||
image: golang:1.17
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
- make backend
|
- make backend
|
||||||
environment:
|
environment:
|
||||||
|
@ -208,36 +198,35 @@ steps:
|
||||||
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
|
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
|
||||||
|
|
||||||
- name: unit-test
|
- name: unit-test
|
||||||
image: golang:1.17
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
- make unit-test-coverage test-check
|
- make unit-test-coverage test-check
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
TAGS: bindata sqlite sqlite_unlock_notify
|
TAGS: bindata sqlite sqlite_unlock_notify
|
||||||
RACE_ENABLED: true
|
|
||||||
GITHUB_READ_TOKEN:
|
GITHUB_READ_TOKEN:
|
||||||
from_secret: github_read_token
|
from_secret: github_read_token
|
||||||
|
|
||||||
- name: unit-test-gogit
|
- name: unit-test-gogit
|
||||||
pull: always
|
pull: always
|
||||||
image: golang:1.17
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
- make unit-test-coverage test-check
|
- make unit-test-coverage test-check
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||||
RACE_ENABLED: true
|
|
||||||
GITHUB_READ_TOKEN:
|
GITHUB_READ_TOKEN:
|
||||||
from_secret: github_read_token
|
from_secret: github_read_token
|
||||||
|
|
||||||
- name: test-mysql
|
- name: test-mysql
|
||||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
|
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
|
||||||
|
- apt-get install -y git-lfs
|
||||||
- make test-mysql-migration integration-test-coverage
|
- make test-mysql-migration integration-test-coverage
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
TAGS: bindata
|
TAGS: bindata
|
||||||
RACE_ENABLED: true
|
|
||||||
TEST_LDAP: 1
|
TEST_LDAP: 1
|
||||||
USE_REPO_TEST_DIR: 1
|
USE_REPO_TEST_DIR: 1
|
||||||
TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200"
|
TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200"
|
||||||
|
@ -245,33 +234,35 @@ steps:
|
||||||
- build
|
- build
|
||||||
|
|
||||||
- name: test-mysql8
|
- name: test-mysql8
|
||||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
|
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
|
||||||
|
- apt-get install -y git-lfs
|
||||||
- timeout -s ABRT 40m make test-mysql8-migration test-mysql8
|
- timeout -s ABRT 40m make test-mysql8-migration test-mysql8
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
TAGS: bindata
|
TAGS: bindata
|
||||||
RACE_ENABLED: true
|
|
||||||
TEST_LDAP: 1
|
TEST_LDAP: 1
|
||||||
USE_REPO_TEST_DIR: 1
|
USE_REPO_TEST_DIR: 1
|
||||||
depends_on:
|
depends_on:
|
||||||
- build
|
- build
|
||||||
|
|
||||||
- name: test-mssql
|
- name: test-mssql
|
||||||
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
|
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
|
||||||
|
- apt-get install -y git-lfs
|
||||||
- make test-mssql-migration test-mssql
|
- make test-mssql-migration test-mssql
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
TAGS: bindata
|
TAGS: bindata
|
||||||
RACE_ENABLED: true
|
|
||||||
TEST_LDAP: 1
|
TEST_LDAP: 1
|
||||||
USE_REPO_TEST_DIR: 1
|
USE_REPO_TEST_DIR: 1
|
||||||
depends_on:
|
depends_on:
|
||||||
- build
|
- build
|
||||||
|
|
||||||
- name: generate-coverage
|
- name: generate-coverage
|
||||||
image: golang:1.17
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
- make coverage
|
- make coverage
|
||||||
environment:
|
environment:
|
||||||
|
@ -282,7 +273,7 @@ steps:
|
||||||
- test-mysql
|
- test-mysql
|
||||||
when:
|
when:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- master
|
||||||
event:
|
event:
|
||||||
- push
|
- push
|
||||||
- pull_request
|
- pull_request
|
||||||
|
@ -299,7 +290,7 @@ steps:
|
||||||
- generate-coverage
|
- generate-coverage
|
||||||
when:
|
when:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- master
|
||||||
event:
|
event:
|
||||||
- push
|
- push
|
||||||
- pull_request
|
- pull_request
|
||||||
|
@ -315,16 +306,14 @@ platform:
|
||||||
depends_on:
|
depends_on:
|
||||||
- compliance
|
- compliance
|
||||||
|
|
||||||
trigger:
|
workspace:
|
||||||
event:
|
base: /go
|
||||||
- push
|
path: src/code.gitea.io/gitea
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- name: pgsql
|
- name: pgsql
|
||||||
pull: default
|
pull: default
|
||||||
image: postgres:10
|
image: postgres:9.5
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: test
|
POSTGRES_DB: test
|
||||||
POSTGRES_PASSWORD: postgres
|
POSTGRES_PASSWORD: postgres
|
||||||
|
@ -345,35 +334,37 @@ steps:
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
pull: always
|
pull: always
|
||||||
image: golang:1.17
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
- make backend
|
- make backend
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: https://goproxy.cn # proxy.golang.org is blocked in China, this proxy is not
|
GOPROXY: https://goproxy.cn # proxy.golang.org is blocked in China, this proxy is not
|
||||||
GOSUMDB: sum.golang.org
|
GOSUMDB: sum.golang.org
|
||||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
TAGS: bindata sqlite sqlite_unlock_notify
|
||||||
|
|
||||||
- name: test-sqlite
|
- name: test-sqlite
|
||||||
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
|
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
|
||||||
|
- apt-get install -y git-lfs
|
||||||
- timeout -s ABRT 40m make test-sqlite-migration test-sqlite
|
- timeout -s ABRT 40m make test-sqlite-migration test-sqlite
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||||
RACE_ENABLED: true
|
|
||||||
TEST_TAGS: gogit sqlite sqlite_unlock_notify
|
TEST_TAGS: gogit sqlite sqlite_unlock_notify
|
||||||
USE_REPO_TEST_DIR: 1
|
USE_REPO_TEST_DIR: 1
|
||||||
depends_on:
|
depends_on:
|
||||||
- build
|
- build
|
||||||
|
|
||||||
- name: test-pgsql
|
- name: test-pgsql
|
||||||
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env
|
image: golang:1.15
|
||||||
commands:
|
commands:
|
||||||
|
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
|
||||||
|
- apt-get install -y git-lfs
|
||||||
- timeout -s ABRT 40m make test-pgsql-migration test-pgsql
|
- timeout -s ABRT 40m make test-pgsql-migration test-pgsql
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: off
|
GOPROXY: off
|
||||||
TAGS: bindata gogit
|
TAGS: bindata gogit
|
||||||
RACE_ENABLED: true
|
|
||||||
TEST_TAGS: gogit
|
TEST_TAGS: gogit
|
||||||
TEST_LDAP: 1
|
TEST_LDAP: 1
|
||||||
USE_REPO_TEST_DIR: 1
|
USE_REPO_TEST_DIR: 1
|
||||||
|
@ -382,19 +373,21 @@ steps:
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: update_translations
|
name: translations
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
os: linux
|
os: linux
|
||||||
arch: arm64
|
arch: arm64
|
||||||
|
|
||||||
|
workspace:
|
||||||
|
base: /go
|
||||||
|
path: src/code.gitea.io/gitea
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- master
|
||||||
event:
|
event:
|
||||||
- cron
|
- push
|
||||||
cron:
|
|
||||||
- update_translations
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: download
|
- name: download
|
||||||
|
@ -411,7 +404,7 @@ steps:
|
||||||
|
|
||||||
- name: update
|
- name: update
|
||||||
pull: default
|
pull: default
|
||||||
image: alpine:3.13
|
image: alpine:3.12
|
||||||
commands:
|
commands:
|
||||||
- ./build/update-locales.sh
|
- ./build/update-locales.sh
|
||||||
|
|
||||||
|
@ -421,7 +414,6 @@ steps:
|
||||||
settings:
|
settings:
|
||||||
author_email: "teabot@gitea.io"
|
author_email: "teabot@gitea.io"
|
||||||
author_name: GiteaBot
|
author_name: GiteaBot
|
||||||
branch: main
|
|
||||||
commit: true
|
commit: true
|
||||||
commit_message: "[skip ci] Updated translations via Crowdin"
|
commit_message: "[skip ci] Updated translations via Crowdin"
|
||||||
remote: "git@github.com:go-gitea/gitea.git"
|
remote: "git@github.com:go-gitea/gitea.git"
|
||||||
|
@ -441,42 +433,6 @@ steps:
|
||||||
CROWDIN_KEY:
|
CROWDIN_KEY:
|
||||||
from_secret: crowdin_key
|
from_secret: crowdin_key
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: update_gitignore_and_licenses
|
|
||||||
|
|
||||||
platform:
|
|
||||||
os: linux
|
|
||||||
arch: arm64
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
branch:
|
|
||||||
- main
|
|
||||||
event:
|
|
||||||
- cron
|
|
||||||
cron:
|
|
||||||
- update_gitignore_and_licenses
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: download
|
|
||||||
image: golang:1.17
|
|
||||||
commands:
|
|
||||||
- timeout -s ABRT 40m make generate-license generate-gitignore
|
|
||||||
|
|
||||||
- name: push
|
|
||||||
pull: always
|
|
||||||
image: appleboy/drone-git-push
|
|
||||||
settings:
|
|
||||||
author_email: "teabot@gitea.io"
|
|
||||||
author_name: GiteaBot
|
|
||||||
branch: main
|
|
||||||
commit: true
|
|
||||||
commit_message: "[skip ci] Updated licenses and gitignores "
|
|
||||||
remote: "git@github.com:go-gitea/gitea.git"
|
|
||||||
environment:
|
|
||||||
GIT_PUSH_SSH_KEY:
|
|
||||||
from_secret: git_push_ssh_key
|
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: release-latest
|
name: release-latest
|
||||||
|
@ -486,12 +442,12 @@ platform:
|
||||||
arch: amd64
|
arch: amd64
|
||||||
|
|
||||||
workspace:
|
workspace:
|
||||||
base: /source
|
base: /go
|
||||||
path: /
|
path: src/code.gitea.io/gitea
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- master
|
||||||
- "release/*"
|
- "release/*"
|
||||||
event:
|
event:
|
||||||
- push
|
- push
|
||||||
|
@ -499,6 +455,7 @@ trigger:
|
||||||
depends_on:
|
depends_on:
|
||||||
- testing-amd64
|
- testing-amd64
|
||||||
- testing-arm64
|
- testing-arm64
|
||||||
|
- translations
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: fetch-tags
|
- name: fetch-tags
|
||||||
|
@ -508,9 +465,9 @@ steps:
|
||||||
|
|
||||||
- name: static
|
- name: static
|
||||||
pull: always
|
pull: always
|
||||||
image: techknowlogick/xgo:go-1.16.x
|
image: techknowlogick/xgo:go-1.15.x
|
||||||
commands:
|
commands:
|
||||||
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
|
- curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt -y install nodejs
|
||||||
- export PATH=$PATH:$GOPATH/bin
|
- export PATH=$PATH:$GOPATH/bin
|
||||||
- make release
|
- make release
|
||||||
environment:
|
environment:
|
||||||
|
@ -537,7 +494,7 @@ steps:
|
||||||
image: plugins/s3:1
|
image: plugins/s3:1
|
||||||
settings:
|
settings:
|
||||||
acl: public-read
|
acl: public-read
|
||||||
bucket: gitea-artifacts
|
bucket: releases
|
||||||
endpoint: https://storage.gitea.io
|
endpoint: https://storage.gitea.io
|
||||||
path_style: true
|
path_style: true
|
||||||
source: "dist/release/*"
|
source: "dist/release/*"
|
||||||
|
@ -554,16 +511,16 @@ steps:
|
||||||
event:
|
event:
|
||||||
- push
|
- push
|
||||||
|
|
||||||
- name: release-main
|
- name: release-master
|
||||||
image: plugins/s3:1
|
image: plugins/s3:1
|
||||||
settings:
|
settings:
|
||||||
acl: public-read
|
acl: public-read
|
||||||
bucket: gitea-artifacts
|
bucket: releases
|
||||||
endpoint: https://storage.gitea.io
|
endpoint: https://storage.gitea.io
|
||||||
path_style: true
|
path_style: true
|
||||||
source: "dist/release/*"
|
source: "dist/release/*"
|
||||||
strip_prefix: dist/release/
|
strip_prefix: dist/release/
|
||||||
target: /gitea/main
|
target: /gitea/master
|
||||||
environment:
|
environment:
|
||||||
AWS_ACCESS_KEY_ID:
|
AWS_ACCESS_KEY_ID:
|
||||||
from_secret: aws_access_key_id
|
from_secret: aws_access_key_id
|
||||||
|
@ -571,7 +528,7 @@ steps:
|
||||||
from_secret: aws_secret_access_key
|
from_secret: aws_secret_access_key
|
||||||
when:
|
when:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- master
|
||||||
event:
|
event:
|
||||||
- push
|
- push
|
||||||
|
|
||||||
|
@ -584,8 +541,8 @@ platform:
|
||||||
arch: amd64
|
arch: amd64
|
||||||
|
|
||||||
workspace:
|
workspace:
|
||||||
base: /source
|
base: /go
|
||||||
path: /
|
path: src/code.gitea.io/gitea
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
event:
|
event:
|
||||||
|
@ -604,9 +561,9 @@ steps:
|
||||||
|
|
||||||
- name: static
|
- name: static
|
||||||
pull: always
|
pull: always
|
||||||
image: techknowlogick/xgo:go-1.16.x
|
image: techknowlogick/xgo:go-1.15.x
|
||||||
commands:
|
commands:
|
||||||
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
|
- curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt -y install nodejs
|
||||||
- export PATH=$PATH:$GOPATH/bin
|
- export PATH=$PATH:$GOPATH/bin
|
||||||
- make release
|
- make release
|
||||||
environment:
|
environment:
|
||||||
|
@ -633,7 +590,7 @@ steps:
|
||||||
image: plugins/s3:1
|
image: plugins/s3:1
|
||||||
settings:
|
settings:
|
||||||
acl: public-read
|
acl: public-read
|
||||||
bucket: gitea-artifacts
|
bucket: releases
|
||||||
endpoint: https://storage.gitea.io
|
endpoint: https://storage.gitea.io
|
||||||
path_style: true
|
path_style: true
|
||||||
source: "dist/release/*"
|
source: "dist/release/*"
|
||||||
|
@ -666,12 +623,6 @@ platform:
|
||||||
depends_on:
|
depends_on:
|
||||||
- compliance
|
- compliance
|
||||||
|
|
||||||
trigger:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: build-docs
|
- name: build-docs
|
||||||
pull: always
|
pull: always
|
||||||
|
@ -692,28 +643,30 @@ steps:
|
||||||
from_secret: netlify_token
|
from_secret: netlify_token
|
||||||
when:
|
when:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- master
|
||||||
event:
|
event:
|
||||||
- push
|
- push
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: docker-linux-amd64-release-version
|
name: docker-linux-amd64-release
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
os: linux
|
os: linux
|
||||||
arch: amd64
|
arch: amd64
|
||||||
|
|
||||||
|
workspace:
|
||||||
|
base: /go
|
||||||
|
path: src/code.gitea.io/gitea
|
||||||
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- testing-amd64
|
- testing-amd64
|
||||||
- testing-arm64
|
- testing-arm64
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
ref:
|
ref:
|
||||||
|
- refs/heads/master
|
||||||
- "refs/tags/**"
|
- "refs/tags/**"
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- cron
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: fetch-tags
|
- name: fetch-tags
|
||||||
|
@ -723,7 +676,7 @@ steps:
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
pull: always
|
pull: always
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:linux-amd64
|
||||||
settings:
|
settings:
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
auto_tag_suffix: linux-amd64
|
auto_tag_suffix: linux-amd64
|
||||||
|
@ -740,7 +693,7 @@ steps:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:linux-amd64
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
|
@ -760,70 +713,6 @@ steps:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: docker-linux-amd64-release
|
|
||||||
|
|
||||||
platform:
|
|
||||||
os: linux
|
|
||||||
arch: amd64
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- testing-amd64
|
|
||||||
- testing-arm64
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
ref:
|
|
||||||
- refs/heads/main
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- cron
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: fetch-tags
|
|
||||||
image: docker:git
|
|
||||||
commands:
|
|
||||||
- git fetch --tags --force
|
|
||||||
|
|
||||||
- name: publish
|
|
||||||
pull: always
|
|
||||||
image: techknowlogick/drone-docker:latest
|
|
||||||
settings:
|
|
||||||
auto_tag: false
|
|
||||||
tags: dev-linux-amd64
|
|
||||||
repo: gitea/gitea
|
|
||||||
build_args:
|
|
||||||
- GOPROXY=off
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: publish-rootless
|
|
||||||
image: techknowlogick/drone-docker:latest
|
|
||||||
settings:
|
|
||||||
dockerfile: Dockerfile.rootless
|
|
||||||
auto_tag: false
|
|
||||||
tags: dev-linux-amd64-rootless
|
|
||||||
repo: gitea/gitea
|
|
||||||
build_args:
|
|
||||||
- GOPROXY=off
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
environment:
|
|
||||||
PLUGIN_MIRROR:
|
|
||||||
from_secret: plugin_mirror
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: docker-linux-arm64-dry-run
|
name: docker-linux-arm64-dry-run
|
||||||
|
@ -832,6 +721,10 @@ platform:
|
||||||
os: linux
|
os: linux
|
||||||
arch: arm64
|
arch: arm64
|
||||||
|
|
||||||
|
workspace:
|
||||||
|
base: /go
|
||||||
|
path: src/code.gitea.io/gitea
|
||||||
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- compliance
|
- compliance
|
||||||
|
|
||||||
|
@ -842,7 +735,7 @@ trigger:
|
||||||
steps:
|
steps:
|
||||||
- name: dryrun
|
- name: dryrun
|
||||||
pull: always
|
pull: always
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:linux-arm64
|
||||||
settings:
|
settings:
|
||||||
dry_run: true
|
dry_run: true
|
||||||
repo: gitea/gitea
|
repo: gitea/gitea
|
||||||
|
@ -858,23 +751,24 @@ steps:
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: docker-linux-arm64-release-version
|
name: docker-linux-arm64-release
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
os: linux
|
os: linux
|
||||||
arch: arm64
|
arch: arm64
|
||||||
|
|
||||||
|
workspace:
|
||||||
|
base: /go
|
||||||
|
path: src/code.gitea.io/gitea
|
||||||
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- testing-amd64
|
- testing-amd64
|
||||||
- testing-arm64
|
- testing-arm64
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
ref:
|
ref:
|
||||||
|
- refs/heads/master
|
||||||
- "refs/tags/**"
|
- "refs/tags/**"
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- cron
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: fetch-tags
|
- name: fetch-tags
|
||||||
image: docker:git
|
image: docker:git
|
||||||
|
@ -883,7 +777,7 @@ steps:
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
pull: always
|
pull: always
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:linux-arm64
|
||||||
settings:
|
settings:
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
auto_tag_suffix: linux-arm64
|
auto_tag_suffix: linux-arm64
|
||||||
|
@ -903,7 +797,7 @@ steps:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
- name: publish-rootless
|
- name: publish-rootless
|
||||||
image: techknowlogick/drone-docker:latest
|
image: plugins/docker:linux-arm64
|
||||||
settings:
|
settings:
|
||||||
dockerfile: Dockerfile.rootless
|
dockerfile: Dockerfile.rootless
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
|
@ -923,115 +817,6 @@ steps:
|
||||||
exclude:
|
exclude:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: docker-linux-arm64-release
|
|
||||||
|
|
||||||
platform:
|
|
||||||
os: linux
|
|
||||||
arch: arm64
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- testing-amd64
|
|
||||||
- testing-arm64
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
ref:
|
|
||||||
- refs/heads/main
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- cron
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: fetch-tags
|
|
||||||
image: docker:git
|
|
||||||
commands:
|
|
||||||
- git fetch --tags --force
|
|
||||||
|
|
||||||
- name: publish
|
|
||||||
pull: always
|
|
||||||
image: techknowlogick/drone-docker:latest
|
|
||||||
settings:
|
|
||||||
auto_tag: false
|
|
||||||
tags: dev-linux-arm64
|
|
||||||
repo: gitea/gitea
|
|
||||||
build_args:
|
|
||||||
- GOPROXY=off
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
environment:
|
|
||||||
PLUGIN_MIRROR:
|
|
||||||
from_secret: plugin_mirror
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: publish-rootless
|
|
||||||
image: techknowlogick/drone-docker:latest
|
|
||||||
settings:
|
|
||||||
dockerfile: Dockerfile.rootless
|
|
||||||
auto_tag: false
|
|
||||||
tags: dev-linux-arm64-rootless
|
|
||||||
repo: gitea/gitea
|
|
||||||
build_args:
|
|
||||||
- GOPROXY=off
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
environment:
|
|
||||||
PLUGIN_MIRROR:
|
|
||||||
from_secret: plugin_mirror
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- pull_request
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: docker-manifest-version
|
|
||||||
|
|
||||||
platform:
|
|
||||||
os: linux
|
|
||||||
arch: amd64
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: manifest-rootless
|
|
||||||
pull: always
|
|
||||||
image: plugins/manifest
|
|
||||||
settings:
|
|
||||||
auto_tag: true
|
|
||||||
ignore_missing: true
|
|
||||||
spec: docker/manifest.rootless.tmpl
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
|
|
||||||
- name: manifest
|
|
||||||
image: plugins/manifest
|
|
||||||
settings:
|
|
||||||
auto_tag: true
|
|
||||||
ignore_missing: true
|
|
||||||
spec: docker/manifest.tmpl
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
ref:
|
|
||||||
- "refs/tags/**"
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- cron
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- docker-linux-amd64-release-version
|
|
||||||
- docker-linux-arm64-release-version
|
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: docker-manifest
|
name: docker-manifest
|
||||||
|
@ -1045,7 +830,7 @@ steps:
|
||||||
pull: always
|
pull: always
|
||||||
image: plugins/manifest
|
image: plugins/manifest
|
||||||
settings:
|
settings:
|
||||||
auto_tag: false
|
auto_tag: true
|
||||||
ignore_missing: true
|
ignore_missing: true
|
||||||
spec: docker/manifest.rootless.tmpl
|
spec: docker/manifest.rootless.tmpl
|
||||||
password:
|
password:
|
||||||
|
@ -1056,7 +841,7 @@ steps:
|
||||||
- name: manifest
|
- name: manifest
|
||||||
image: plugins/manifest
|
image: plugins/manifest
|
||||||
settings:
|
settings:
|
||||||
auto_tag: false
|
auto_tag: true
|
||||||
ignore_missing: true
|
ignore_missing: true
|
||||||
spec: docker/manifest.tmpl
|
spec: docker/manifest.tmpl
|
||||||
password:
|
password:
|
||||||
|
@ -1066,10 +851,8 @@ steps:
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
ref:
|
ref:
|
||||||
- refs/heads/main
|
- refs/heads/master
|
||||||
event:
|
- "refs/tags/**"
|
||||||
exclude:
|
|
||||||
- cron
|
|
||||||
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- docker-linux-amd64-release
|
- docker-linux-amd64-release
|
||||||
|
@ -1088,7 +871,7 @@ clone:
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- master
|
||||||
- "release/*"
|
- "release/*"
|
||||||
event:
|
event:
|
||||||
- push
|
- push
|
||||||
|
@ -1100,14 +883,12 @@ trigger:
|
||||||
depends_on:
|
depends_on:
|
||||||
- testing-amd64
|
- testing-amd64
|
||||||
- testing-arm64
|
- testing-arm64
|
||||||
|
- translations
|
||||||
- release-version
|
- release-version
|
||||||
- release-latest
|
- release-latest
|
||||||
- docker-linux-amd64-release
|
- docker-linux-amd64-release
|
||||||
- docker-linux-arm64-release
|
- docker-linux-arm64-release
|
||||||
- docker-linux-amd64-release-version
|
|
||||||
- docker-linux-arm64-release-version
|
|
||||||
- docker-manifest
|
- docker-manifest
|
||||||
- docker-manifest-version
|
|
||||||
- docs
|
- docs
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -12,15 +12,6 @@ insert_final_newline = true
|
||||||
[*.{go,tmpl,html}]
|
[*.{go,tmpl,html}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
[templates/custom/*.tmpl]
|
|
||||||
insert_final_newline = false
|
|
||||||
|
|
||||||
[templates/swagger/v1_json.tmpl]
|
|
||||||
indent_style = space
|
|
||||||
|
|
||||||
[templates/user/auth/oidc_wellknown.tmpl]
|
|
||||||
indent_style = space
|
|
||||||
|
|
||||||
[Makefile]
|
[Makefile]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
|
|
35
.eslintrc
35
.eslintrc
|
@ -53,12 +53,6 @@ overrides:
|
||||||
rules:
|
rules:
|
||||||
import/no-unresolved: [0]
|
import/no-unresolved: [0]
|
||||||
import/no-extraneous-dependencies: [0]
|
import/no-extraneous-dependencies: [0]
|
||||||
- files: ["*.test.js"]
|
|
||||||
env:
|
|
||||||
jest: true
|
|
||||||
- files: ["*.config.js"]
|
|
||||||
rules:
|
|
||||||
import/no-unused-modules: [0]
|
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
accessor-pairs: [2]
|
accessor-pairs: [2]
|
||||||
|
@ -125,7 +119,6 @@ rules:
|
||||||
import/no-deprecated: [0]
|
import/no-deprecated: [0]
|
||||||
import/no-dynamic-require: [0]
|
import/no-dynamic-require: [0]
|
||||||
import/no-extraneous-dependencies: [2]
|
import/no-extraneous-dependencies: [2]
|
||||||
import/no-import-module-exports: [0]
|
|
||||||
import/no-internal-modules: [0]
|
import/no-internal-modules: [0]
|
||||||
import/no-mutable-exports: [2]
|
import/no-mutable-exports: [2]
|
||||||
import/no-named-as-default-member: [0]
|
import/no-named-as-default-member: [0]
|
||||||
|
@ -134,7 +127,6 @@ rules:
|
||||||
import/no-named-export: [0]
|
import/no-named-export: [0]
|
||||||
import/no-namespace: [0]
|
import/no-namespace: [0]
|
||||||
import/no-nodejs-modules: [0]
|
import/no-nodejs-modules: [0]
|
||||||
import/no-relative-packages: [0]
|
|
||||||
import/no-relative-parent-imports: [0]
|
import/no-relative-parent-imports: [0]
|
||||||
import/no-restricted-paths: [0]
|
import/no-restricted-paths: [0]
|
||||||
import/no-self-import: [2]
|
import/no-self-import: [2]
|
||||||
|
@ -352,7 +344,6 @@ rules:
|
||||||
unicode-bom: [2, never]
|
unicode-bom: [2, never]
|
||||||
unicorn/better-regex: [0]
|
unicorn/better-regex: [0]
|
||||||
unicorn/catch-error-name: [0]
|
unicorn/catch-error-name: [0]
|
||||||
unicorn/consistent-destructuring: [2]
|
|
||||||
unicorn/consistent-function-scoping: [2]
|
unicorn/consistent-function-scoping: [2]
|
||||||
unicorn/custom-error-definition: [0]
|
unicorn/custom-error-definition: [0]
|
||||||
unicorn/empty-brace-spaces: [2]
|
unicorn/empty-brace-spaces: [2]
|
||||||
|
@ -365,77 +356,51 @@ rules:
|
||||||
unicorn/import-style: [0]
|
unicorn/import-style: [0]
|
||||||
unicorn/new-for-builtins: [2]
|
unicorn/new-for-builtins: [2]
|
||||||
unicorn/no-abusive-eslint-disable: [0]
|
unicorn/no-abusive-eslint-disable: [0]
|
||||||
unicorn/no-array-for-each: [0]
|
|
||||||
unicorn/no-array-instanceof: [0]
|
unicorn/no-array-instanceof: [0]
|
||||||
unicorn/no-array-method-this-argument: [2]
|
|
||||||
unicorn/no-array-push-push: [2]
|
|
||||||
unicorn/no-console-spaces: [0]
|
unicorn/no-console-spaces: [0]
|
||||||
unicorn/no-document-cookie: [2]
|
|
||||||
unicorn/no-fn-reference-in-iterator: [0]
|
unicorn/no-fn-reference-in-iterator: [0]
|
||||||
unicorn/no-for-loop: [0]
|
unicorn/no-for-loop: [0]
|
||||||
unicorn/no-hex-escape: [0]
|
unicorn/no-hex-escape: [0]
|
||||||
unicorn/no-keyword-prefix: [0]
|
unicorn/no-keyword-prefix: [0]
|
||||||
unicorn/no-lonely-if: [2]
|
unicorn/no-lonely-if: [2]
|
||||||
unicorn/no-nested-ternary: [0]
|
unicorn/no-nested-ternary: [0]
|
||||||
unicorn/no-new-array: [0]
|
|
||||||
unicorn/no-new-buffer: [0]
|
unicorn/no-new-buffer: [0]
|
||||||
unicorn/no-null: [0]
|
unicorn/no-null: [0]
|
||||||
unicorn/no-object-as-default-parameter: [2]
|
unicorn/no-object-as-default-parameter: [2]
|
||||||
unicorn/no-process-exit: [0]
|
unicorn/no-process-exit: [0]
|
||||||
unicorn/no-reduce: [2]
|
unicorn/no-reduce: [2]
|
||||||
unicorn/no-static-only-class: [2]
|
|
||||||
unicorn/no-this-assignment: [2]
|
|
||||||
unicorn/no-unreadable-array-destructuring: [0]
|
unicorn/no-unreadable-array-destructuring: [0]
|
||||||
unicorn/no-unsafe-regex: [0]
|
unicorn/no-unsafe-regex: [0]
|
||||||
unicorn/no-unused-properties: [2]
|
unicorn/no-unused-properties: [2]
|
||||||
unicorn/no-useless-length-check: [2]
|
|
||||||
unicorn/no-useless-spread: [2]
|
|
||||||
unicorn/no-useless-undefined: [0]
|
unicorn/no-useless-undefined: [0]
|
||||||
unicorn/no-zero-fractions: [2]
|
unicorn/no-zero-fractions: [2]
|
||||||
unicorn/number-literal-case: [0]
|
unicorn/number-literal-case: [0]
|
||||||
unicorn/numeric-separators-style: [0]
|
unicorn/numeric-separators-style: [0]
|
||||||
unicorn/prefer-add-event-listener: [2]
|
unicorn/prefer-add-event-listener: [2]
|
||||||
unicorn/prefer-array-find: [2]
|
unicorn/prefer-array-find: [2]
|
||||||
unicorn/prefer-array-flat-map: [2]
|
|
||||||
unicorn/prefer-array-flat: [2]
|
|
||||||
unicorn/prefer-array-index-of: [2]
|
|
||||||
unicorn/prefer-array-some: [2]
|
|
||||||
unicorn/prefer-at: [0]
|
|
||||||
unicorn/prefer-dataset: [2]
|
unicorn/prefer-dataset: [2]
|
||||||
unicorn/prefer-date-now: [2]
|
unicorn/prefer-date-now: [2]
|
||||||
unicorn/prefer-default-parameters: [0]
|
|
||||||
unicorn/prefer-event-key: [2]
|
unicorn/prefer-event-key: [2]
|
||||||
unicorn/prefer-includes: [2]
|
unicorn/prefer-includes: [2]
|
||||||
unicorn/prefer-math-trunc: [2]
|
unicorn/prefer-math-trunc: [2]
|
||||||
unicorn/prefer-modern-dom-apis: [0]
|
unicorn/prefer-modern-dom-apis: [0]
|
||||||
unicorn/prefer-module: [2]
|
|
||||||
unicorn/prefer-negative-index: [2]
|
unicorn/prefer-negative-index: [2]
|
||||||
unicorn/prefer-node-append: [0]
|
unicorn/prefer-node-append: [0]
|
||||||
unicorn/prefer-node-protocol: [0]
|
|
||||||
unicorn/prefer-node-remove: [0]
|
unicorn/prefer-node-remove: [0]
|
||||||
unicorn/prefer-number-properties: [0]
|
unicorn/prefer-number-properties: [0]
|
||||||
unicorn/prefer-object-from-entries: [2]
|
|
||||||
unicorn/prefer-object-has-own: [0]
|
|
||||||
unicorn/prefer-optional-catch-binding: [2]
|
unicorn/prefer-optional-catch-binding: [2]
|
||||||
unicorn/prefer-prototype-methods: [0]
|
|
||||||
unicorn/prefer-query-selector: [0]
|
unicorn/prefer-query-selector: [0]
|
||||||
unicorn/prefer-reflect-apply: [0]
|
unicorn/prefer-reflect-apply: [0]
|
||||||
unicorn/prefer-regexp-test: [2]
|
|
||||||
unicorn/prefer-replace-all: [0]
|
unicorn/prefer-replace-all: [0]
|
||||||
unicorn/prefer-set-has: [0]
|
unicorn/prefer-set-has: [0]
|
||||||
unicorn/prefer-spread: [0]
|
unicorn/prefer-spread: [0]
|
||||||
unicorn/prefer-starts-ends-with: [2]
|
unicorn/prefer-starts-ends-with: [2]
|
||||||
unicorn/prefer-string-slice: [0]
|
unicorn/prefer-string-slice: [0]
|
||||||
unicorn/prefer-switch: [0]
|
|
||||||
unicorn/prefer-ternary: [0]
|
unicorn/prefer-ternary: [0]
|
||||||
unicorn/prefer-text-content: [2]
|
unicorn/prefer-text-content: [2]
|
||||||
unicorn/prefer-top-level-await: [0]
|
|
||||||
unicorn/prefer-trim-start-end: [2]
|
unicorn/prefer-trim-start-end: [2]
|
||||||
unicorn/prefer-type-error: [0]
|
unicorn/prefer-type-error: [0]
|
||||||
unicorn/prevent-abbreviations: [0]
|
unicorn/prevent-abbreviations: [0]
|
||||||
unicorn/require-array-join-separator: [2]
|
|
||||||
unicorn/require-number-to-fixed-digits-argument: [2]
|
|
||||||
unicorn/require-post-message-target-origin: [0]
|
|
||||||
unicorn/string-content: [0]
|
unicorn/string-content: [0]
|
||||||
unicorn/throw-new-error: [2]
|
unicorn/throw-new-error: [2]
|
||||||
use-isnan: [2]
|
use-isnan: [2]
|
||||||
|
|
|
@ -4,4 +4,3 @@
|
||||||
/templates/**/*.tmpl linguist-language=Handlebars
|
/templates/**/*.tmpl linguist-language=Handlebars
|
||||||
/.eslintrc linguist-language=YAML
|
/.eslintrc linguist-language=YAML
|
||||||
/.stylelintrc linguist-language=YAML
|
/.stylelintrc linguist-language=YAML
|
||||||
/web_src/fomantic/build/** linguist-generated
|
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
open_collective: gitea
|
open_collective: gitea
|
||||||
custom: https://www.bountysource.com/teams/gitea
|
|
||||||
|
|
|
@ -30,9 +30,6 @@
|
||||||
<!-- In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini -->
|
<!-- In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini -->
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
<!-- If using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please
|
|
||||||
disable the proxy/CDN fully and connect to gitea directly to confirm
|
|
||||||
the issue still persists without those services. -->
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Please check the following:
|
Please check the following:
|
||||||
|
|
||||||
1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for bug fixes.
|
1. Make sure you are targeting the `master` branch, pull requests on release branches are only allowed for bug fixes.
|
||||||
2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md
|
2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md
|
||||||
3. Describe what your pull request does and which issue you're targeting (if any)
|
3. Describe what your pull request does and which issue you're targeting (if any)
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ _testmain.go
|
||||||
|
|
||||||
*coverage.out
|
*coverage.out
|
||||||
coverage.all
|
coverage.all
|
||||||
cpu.out
|
|
||||||
|
|
||||||
/modules/options/bindata.go
|
/modules/options/bindata.go
|
||||||
/modules/options/bindata.go.hash
|
/modules/options/bindata.go.hash
|
||||||
|
@ -76,14 +75,11 @@ cpu.out
|
||||||
/integrations/mssql.ini
|
/integrations/mssql.ini
|
||||||
/node_modules
|
/node_modules
|
||||||
/yarn.lock
|
/yarn.lock
|
||||||
/yarn-error.log
|
|
||||||
/npm-debug.log*
|
|
||||||
/public/js
|
/public/js
|
||||||
/public/serviceworker.js
|
/public/serviceworker.js
|
||||||
/public/css
|
/public/css
|
||||||
/public/fonts
|
/public/fonts
|
||||||
/public/img/webpack
|
/public/img/webpack
|
||||||
/web_src/fomantic/node_modules
|
|
||||||
/web_src/fomantic/build/*
|
/web_src/fomantic/build/*
|
||||||
!/web_src/fomantic/build/semantic.js
|
!/web_src/fomantic/build/semantic.js
|
||||||
!/web_src/fomantic/build/semantic.css
|
!/web_src/fomantic/build/semantic.css
|
||||||
|
@ -110,6 +106,3 @@ prime/
|
||||||
|
|
||||||
# Make evidence files
|
# Make evidence files
|
||||||
/.make_evidence
|
/.make_evidence
|
||||||
|
|
||||||
# Manpage
|
|
||||||
/man
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ linters-settings:
|
||||||
gocritic:
|
gocritic:
|
||||||
disabled-checks:
|
disabled-checks:
|
||||||
- ifElseChain
|
- ifElseChain
|
||||||
- singleCaseSwitch # Every time this occurred in the code, there was no other way.
|
- singleCaseSwitch # Every time this occured in the code, there was no other way.
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
|
@ -70,6 +70,9 @@ issues:
|
||||||
- path: modules/log/
|
- path: modules/log/
|
||||||
linters:
|
linters:
|
||||||
- errcheck
|
- errcheck
|
||||||
|
- path: routers/routes/macaron.go
|
||||||
|
linters:
|
||||||
|
- dupl
|
||||||
- path: routers/api/v1/repo/issue_subscription.go
|
- path: routers/api/v1/repo/issue_subscription.go
|
||||||
linters:
|
linters:
|
||||||
- dupl
|
- dupl
|
||||||
|
@ -107,8 +110,3 @@ issues:
|
||||||
- text: "exitAfterDefer:"
|
- text: "exitAfterDefer:"
|
||||||
linters:
|
linters:
|
||||||
- gocritic
|
- gocritic
|
||||||
- path: modules/graceful/manager_windows.go
|
|
||||||
linters:
|
|
||||||
- staticcheck
|
|
||||||
text: "svc.IsAnInteractiveSession is deprecated: Use IsWindowsService instead."
|
|
||||||
|
|
||||||
|
|
1
.npmrc
1
.npmrc
|
@ -1,5 +1,4 @@
|
||||||
audit=false
|
audit=false
|
||||||
fund=false
|
fund=false
|
||||||
update-notifier=false
|
|
||||||
package-lock=true
|
package-lock=true
|
||||||
save-exact=true
|
save-exact=true
|
||||||
|
|
817
CHANGELOG.md
817
CHANGELOG.md
|
@ -4,823 +4,6 @@ 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.15.0](https://github.com/go-gitea/gitea/releases/tag/v1.15.0) - 2021-08-21
|
|
||||||
|
|
||||||
* BREAKING
|
|
||||||
* Make app.ini permissions more restrictive (#16266)
|
|
||||||
* Refactor Webhook + Add X-Hub-Signature (#16176)
|
|
||||||
* Add asymmetric JWT signing (#16010)
|
|
||||||
* Clean-up the settings hierarchy for issue_indexer queue (#16001)
|
|
||||||
* Change default queue settings to be low go-routines (#15964)
|
|
||||||
* Improve assets handler middleware (#15961)
|
|
||||||
* Rename StaticUrlPrefix to AssetUrlPrefix (#15779)
|
|
||||||
* Use a generic markup class to display externally rendered files and diffs (#15735)
|
|
||||||
* Add frontend testing, require node 12 (#15315)
|
|
||||||
* Move (custom) assets into subpath `/assets` (#15219)
|
|
||||||
* Use level config in log section when sub log section not set level (#15176)
|
|
||||||
* Links in markdown should be absolute to the repository not the server (#15088)
|
|
||||||
* Upgrade to the latest version of golang-jwt (#16590) (#16606)
|
|
||||||
* Set minimum supported version of go to 1.16 (#16710)
|
|
||||||
* SECURITY
|
|
||||||
* Encrypt LDAP bind password in db with SECRET_KEY (#15547)
|
|
||||||
* Remove random password in Dockerfiles (#15362)
|
|
||||||
* Upgrade to the latest version of golang-jwt and increase minimum go to 1.15 (#16590) (#16606)
|
|
||||||
* Correctly create of git-daemon-export-ok files (#16508) (#16514)
|
|
||||||
* Don't show private user's repo in explore view (#16550) (#16554)
|
|
||||||
* Update node tar dependency to 6.1.6 (#16622) (#16623)
|
|
||||||
* FEATURES
|
|
||||||
* Update Go-Git to take advantage of LargeObjectThreshold (#16316)
|
|
||||||
* Support custom mime type mapping for text files (#16304)
|
|
||||||
* Link to previous blames in file blame page (#16259)
|
|
||||||
* Add LRU mem cache implementation (#16226)
|
|
||||||
* Localize Email Templates (#16200)
|
|
||||||
* Make command in authorized keys a template (#16003)
|
|
||||||
* Add possibility to make branch in branch page (#15960)
|
|
||||||
* Add email headers (#15939)
|
|
||||||
* Make tasklist checkboxes clickable (#15791)
|
|
||||||
* Add selecting tags on the compare page (#15723)
|
|
||||||
* Add cron job to delete old actions from database (#15688)
|
|
||||||
* On open repository open common cat file batch and batch-check (#15667)
|
|
||||||
* Add tag protection (#15629)
|
|
||||||
* Add push to remote mirror repository (#15157)
|
|
||||||
* Add Image Diff for SVG files (#14867)
|
|
||||||
* Add dashboard milestone search and repo milestone search by name. (#14866)
|
|
||||||
* Add LFS Migration and Mirror (#14726)
|
|
||||||
* Improve notifications for WIP draft PR's (#14663)
|
|
||||||
* Disable Stars config option (#14653)
|
|
||||||
* GPG Key Ownership verification with Signed Token (#14054)
|
|
||||||
* OAuth2 auto-register (#5123)
|
|
||||||
* API
|
|
||||||
* Return updated repository when changing repository using API (#16420)
|
|
||||||
* Let branch/tag name be a valid ref to get CI status (#16400)
|
|
||||||
* Add endpoint to get commits of PR (#16300)
|
|
||||||
* Allow COMMENT reviews to not specify a body (#16229)
|
|
||||||
* Add subject-type filter to list notification API endpoints (#16177)
|
|
||||||
* ListReleases add filter for draft and pre-releases (#16175)
|
|
||||||
* ListIssues add more filters (#16174)
|
|
||||||
* Issue Search Add filter for MilestoneNames (#16173)
|
|
||||||
* GET / SET User Settings (#16169)
|
|
||||||
* Expose repo.GetReviewers() & repo.GetAssignees() (#16168)
|
|
||||||
* User expose counters (#16167)
|
|
||||||
* Add repoGetTag (#16166)
|
|
||||||
* Add repoCreateTag (#16165)
|
|
||||||
* Creating a repo from a template repo via API (#15958)
|
|
||||||
* Add Active and ProhibitLogin to API (#15689)
|
|
||||||
* Add Location, Website and Description to API (#15675)
|
|
||||||
* Expose resolver via API (#15167)
|
|
||||||
* Swagger AccessToken fixes (#16574) (#16597)
|
|
||||||
* Set AllowedHeaders on API CORS handler (#16524) (#16618)
|
|
||||||
* ENHANCEMENTS
|
|
||||||
* Support HTTP/2 in Let's Encrypt (#16371)
|
|
||||||
* Introduce NotifySubjectType (#16320)
|
|
||||||
* Add forge emojies (#16296)
|
|
||||||
* Implemented head_commit for webhooks (#16282)
|
|
||||||
* Upgrade Gliderlabs SSH to 0.3.3 and add FailedConnectionCallback (#16278)
|
|
||||||
* Add previous/next buttons to review comments (#16273)
|
|
||||||
* Review comments: break-word for long file names (#16272)
|
|
||||||
* Add configuration to restrict allowed user visibility modes (#16271)
|
|
||||||
* Add scroll-margin-top to account for sticky header (#16269)
|
|
||||||
* Add --quiet and --verbose to gitea web to control initial logging (#16260)
|
|
||||||
* Use gitea logging module for git module (#16243)
|
|
||||||
* Add tests for all webhooks (#16214)
|
|
||||||
* Add button to delete undeleted repositories from failed migrations (#16197)
|
|
||||||
* Speed up git diff highlight generation (#16180)
|
|
||||||
* Add OpenID claims "profile" and "email". (#16141)
|
|
||||||
* Reintroduce squash merge default comment as a config setting (#16134)
|
|
||||||
* Add sanitizer rules per renderer (#16110)
|
|
||||||
* Improve performance of dashboard list orgs (#16099)
|
|
||||||
* Refactor assert statements in tests (#16089)
|
|
||||||
* Add sso.Group, context.Auth, context.APIAuth to allow auth special routes (#16086)
|
|
||||||
* Remove unnecessary goroutine (#16080)
|
|
||||||
* Add attachments for PR reviews (#16075)
|
|
||||||
* Make the github migration less rate limit waiting to get comment per page from repository but not per issue (#16070)
|
|
||||||
* Add Visible modes function from Organisation to Users too (#16069)
|
|
||||||
* Add checkbox to delete pull branch after successful merge (#16049)
|
|
||||||
* Make commit info cancelable (#16032)
|
|
||||||
* Make modules/context.Context a context.Context (#16031)
|
|
||||||
* Unified custom config creation (#16012)
|
|
||||||
* Make sshd_config more flexible regarding connections (#16009)
|
|
||||||
* Append to existing trailers in generated squash commit message (#15980)
|
|
||||||
* Always store primary email address into email_address table and also the state (#15956)
|
|
||||||
* Load issue/PR context popup data only when needed (#15955)
|
|
||||||
* Remove remaining fontawesome usage in templates (#15952)
|
|
||||||
* Remove fomantic accordion module (#15951)
|
|
||||||
* Small refactoring of modules/private (#15947)
|
|
||||||
* Double the avatar size factor (#15941)
|
|
||||||
* Add curl to rootless docker image (#15908)
|
|
||||||
* Replace clipboard.js with async clipboard api (#15899)
|
|
||||||
* Allow custom highlight mapping beyond file extensions (#15808)
|
|
||||||
* Add trace logging to SSO methods (#15803)
|
|
||||||
* Refactor routers directory (#15800)
|
|
||||||
* Allow only internal registration (#15795)
|
|
||||||
* Add a new internal hook to save ssh log (#15787)
|
|
||||||
* Respect default merge message syntax when parsing item references (#15772)
|
|
||||||
* OAuth2 login: Set account link to "login" as default behavior (#15768)
|
|
||||||
* Use single shared random string generation function (#15741)
|
|
||||||
* Hold the event source when there are no listeners (#15725)
|
|
||||||
* Code comments improvements (#15722)
|
|
||||||
* Provide OIDC compliant user info endpoint (#15721)
|
|
||||||
* Fix webkit calendar icon color on arc-green (#15713)
|
|
||||||
* Improve Light Chroma style (#15699)
|
|
||||||
* Only use boost workers for leveldb shadow queues (#15696)
|
|
||||||
* Add compare tag dropdown to releases page (#15695)
|
|
||||||
* Add caret styling CSS (#15651)
|
|
||||||
* Remove x-ua-compatible meta tag (#15640)
|
|
||||||
* Refactor of link creation (#15619)
|
|
||||||
* Add a new table issue_index to store the max issue index so that issue could be deleted with no duplicated index (#15599)
|
|
||||||
* Rewrite of the LFS server (#15523)
|
|
||||||
* Display more repository type on admin repository management (#15440)
|
|
||||||
* Remove usage of some JS globals (#15378)
|
|
||||||
* SHA in merged commit comment should be rendered ui sha (#15376)
|
|
||||||
* Add well-known config for OIDC (#15355)
|
|
||||||
* Use route rather than use thus reducing the number of stack frames (#15301)
|
|
||||||
* Code Formats, Nits & Unused Func/Var deletions (#15286)
|
|
||||||
* Let package git depend on setting but not opposite (#15241)
|
|
||||||
* Fixed sanitize errors (#15240)
|
|
||||||
* response simple text message for not html request when 404 (#15229)
|
|
||||||
* Remove file-loader dependency (#15196)
|
|
||||||
* Refactor renders (#15175)
|
|
||||||
* Add mimetype mapping settings (#15133)
|
|
||||||
* Add Status Updates whilst Gitea migrations are occurring (#15076)
|
|
||||||
* Reload locales in initialisation if needed by utilizing i18n.Reset (#15073)
|
|
||||||
* Counterwork seemingly unclickable repo button labels (#15064)
|
|
||||||
* Add DefaultMergeStyle option to repository (#14789)
|
|
||||||
* Added support for gopher URLs. (#14749)
|
|
||||||
* Rework repository archive (#14723)
|
|
||||||
* Add links to toggle WIP status (#14677)
|
|
||||||
* Add Tabular Diff for CSV files (#14661)
|
|
||||||
* Use milestone deadline when sorting issues (#14551)
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix invalid params and typo of email templates (#16394)
|
|
||||||
* Fix activation of primary email addresses (#16385)
|
|
||||||
* Fix calculation for finalPage in repo-search component (#16382)
|
|
||||||
* Specify user in rootless container numerically (#16361)
|
|
||||||
* Detect encoding changes while parsing diff (#16330)
|
|
||||||
* Fix U2F error reasons always hidden (#16327)
|
|
||||||
* Prevent zombie processes (#16314)
|
|
||||||
* Escape reference to `user` table in models.SearchEmails (#16313)
|
|
||||||
* Fix default push instructions on empty repos (#16302)
|
|
||||||
* Fix modified files list in webhooks when there is a space (#16288)
|
|
||||||
* Fix webhook commits wrong hash on HEAD reset (#16283)
|
|
||||||
* Fuzzer finds an NPE due to incorrect URLPrefix (#16249)
|
|
||||||
* Don't WARN log UserNotExist errors on ExternalUserLogin failure (#16238)
|
|
||||||
* Do not show No match found for tribute (#16231)
|
|
||||||
* Fix "Copy Link" for pull requests (#16230)
|
|
||||||
* Fix diff expansion is missing final line in a file (#16222)
|
|
||||||
* Fix private repo permission problem (#16142)
|
|
||||||
* Fix not able to update local created non-urlencoded wiki pages (#16139)
|
|
||||||
* More efficiently parse shas for shaPostProcessor (#16101)
|
|
||||||
* Fix `doctor --run check-db-consistency --fix` with label fix (#16094)
|
|
||||||
* Prevent webhook action buttons from shifting (#16087)
|
|
||||||
* Change default TMPDIR path in rootless containers (#16077)
|
|
||||||
* Fix typo and add TODO notice (#16064)
|
|
||||||
* Use git log name-status in get last commit (#16059)
|
|
||||||
* Fix 500 Error with branch and tag sharing the same name (#16040)
|
|
||||||
* Fix get tag when migration (#16014)
|
|
||||||
* Add custom emoji support (#16004)
|
|
||||||
* Use filepath.ToSlash and Join in indexer defaults and queues (#15971)
|
|
||||||
* Add permission check for ``GenerateRepository`` (#15946)
|
|
||||||
* Ensure settings for Service and Mailer are read on the install page (#15943)
|
|
||||||
* Fix layout of milestone view (#15927)
|
|
||||||
* Unregister non-matching serviceworkers (#15834)
|
|
||||||
* Multiple Queue improvements: LevelDB Wait on empty, shutdown empty shadow level queue, reduce goroutines etc (#15693)
|
|
||||||
* Attachment support repository route (#15580)
|
|
||||||
* Fix missing icons and colorpicker when mounted on suburl (#15501)
|
|
||||||
* Create a session on ReverseProxy and ensure that ReverseProxy users cannot change username (#15304)
|
|
||||||
* Prevent double-login for Git HTTP and LFS and simplify login (#15303)
|
|
||||||
* Resolve Object { type: "error", data: undefined } in stopwatch.js (#15278)
|
|
||||||
* Fix heatmap activity (#15252)
|
|
||||||
* Remove vendored copy of fomantic-dropdown (#15193)
|
|
||||||
* Update repository size on cron gc task (#15177)
|
|
||||||
* Add NeedPostProcess for Parser interface to improve performance of csv parser and some external parser (#15153)
|
|
||||||
* Add code block highlight to orgmode back (#14222)
|
|
||||||
* Remove User.GetOrganizations() (#14032)
|
|
||||||
* Restore Accessibility for Dropdown (#16576) (#16617)
|
|
||||||
* Pass down SignedUserName down to AccessLogger context (#16605) (#16616)
|
|
||||||
* Fix table alignment in markdown (#16596) (#16602)
|
|
||||||
* Fix 500 on first wiki page (#16586) (#16598)
|
|
||||||
* Lock goth/gothic and Re-attempt OAuth2 registration on login if registration failed at startup (#16564) (#16570)
|
|
||||||
* Upgrade levelqueue to v0.4.0 (#16560) (#16561)
|
|
||||||
* Handle too long PR titles correctly (#16517) (#16549)
|
|
||||||
* Fix data race in bleve indexer (#16474) (#16509)
|
|
||||||
* Restore CORS on git smart http protocol (#16496) (#16506)
|
|
||||||
* Fix race in log (#16490) (#16505)
|
|
||||||
* Fix prepareWikiFileName to respect existing unescaped files (#16487) (#16498)
|
|
||||||
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16480)
|
|
||||||
* Update notification table with only latest data (#16445) (#16469)
|
|
||||||
* Fix crash following ldap authentication update (#16447) (#16448)
|
|
||||||
* Fix direct creation of external users on admin page (partial #16612) (#16613)
|
|
||||||
* Prevent 500 on draft releases without tag (#16634) (#16636)
|
|
||||||
* Restore creation of git-daemon-export-ok files (#16508) (#16514)
|
|
||||||
* Fix data race in bleve indexer (#16474) (#16509)
|
|
||||||
* Restore CORS on git smart http protocol (#16496) (#16506)
|
|
||||||
* Fix race in log (#16490) (#16505)
|
|
||||||
* Fix prepareWikiFileName to respect existing unescaped files (#16487) (#16498)
|
|
||||||
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16480)
|
|
||||||
* Update notification table with only latest data (#16445) (#16469)
|
|
||||||
* Fix crash following ldap authentication update (#16447) (#16448)
|
|
||||||
* Restore compatibility with SQLServer 2008 R2 in migrations (#16638)
|
|
||||||
* Fix direct creation of external users on admin page (#16613)
|
|
||||||
* Fix go-git implementation of GetNote when passed a non-existent commit (#16658) (#16659)
|
|
||||||
* Fix NPE in fuzzer (#16680) (#16682)
|
|
||||||
* Set issue_index when finishing migration (#16685) (#16687)
|
|
||||||
* Skip patch download when no patch file exists (#16356) (#16681)
|
|
||||||
* Ensure empty lines are copiable and final new line too (#16678) (#16692)
|
|
||||||
* Fix wrong user in OpenID response (#16736) (#16741)
|
|
||||||
* Do not use thin scrollbars on Firefox (#16738) (#16745)
|
|
||||||
* Recreate Tables should Recreate indexes on MySQL (#16718) (#16739)
|
|
||||||
* Keep attachments on tasklist update (#16750) (#16757)
|
|
||||||
* TESTING
|
|
||||||
* Bump `postgres` and `mysql` versions (#15710)
|
|
||||||
* Add tests for clone from wiki (#15513)
|
|
||||||
* Fix Benchmark tests, remove a broken one & add two new (#15250)
|
|
||||||
* Create Proper Migration tests (#15116)
|
|
||||||
* TRANSLATION
|
|
||||||
* Use a special name for update default branch on repository setting (#15893)
|
|
||||||
* Fix mirror_lfs source string in en-US locale (#15369)
|
|
||||||
* BUILD
|
|
||||||
* Upgrade xorm to v1.1.1 (#16339)
|
|
||||||
* Disable legal comments in esbuild (#15929)
|
|
||||||
* Switch to Node 16 to build fronted (#15804)
|
|
||||||
* Use esbuild to minify CSS (#15756)
|
|
||||||
* Use binary version of revive linter (#15739)
|
|
||||||
* Fix: npx webpack make: *** [Makefile:699: public/js/index.js] Error -… (#15465)
|
|
||||||
* Stop packaging node_modules in release tarballs (#15273)
|
|
||||||
* Introduce esbuild on webpack (#14578)
|
|
||||||
* DOCS
|
|
||||||
* Update queue workers documentation (#15999)
|
|
||||||
* Comment out app.example.ini (#15807)
|
|
||||||
* Improve logo customization docs (#15754)
|
|
||||||
* Add some response status on api docs (#15399)
|
|
||||||
* Rework Token API comments (#15162)
|
|
||||||
* Add better errors for disabled account recovery (#15117)
|
|
||||||
* MISC
|
|
||||||
* Remove utf8 option from installation page (#16126)
|
|
||||||
* Use Wants= over Requires= in systemd file (#15897)
|
|
||||||
|
|
||||||
## [1.14.6](https://github.com/go-gitea/gitea/releases/tag/v1.14.6) - 2021-08-04
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Bump github.com/markbates/goth from v1.67.1 to v1.68.0 (#16538) (#16540)
|
|
||||||
* Switch to maintained JWT lib (#16532) (#16535)
|
|
||||||
* Upgrade to latest version of golang-jwt (as forked for 1.14) (#16590) (#16607)
|
|
||||||
* BUGFIXES
|
|
||||||
* Add basic edit ldap auth test & actually fix #16252 (#16465) (#16495)
|
|
||||||
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16481)
|
|
||||||
|
|
||||||
## [1.14.5](https://github.com/go-gitea/gitea/releases/tag/v1.14.5) - 2021-07-16
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Hide mirror passwords on repo settings page (#16022) (#16355)
|
|
||||||
* Update bluemonday to v1.0.15 (#16379) (#16380)
|
|
||||||
* BUGFIXES
|
|
||||||
* Retry rename on lock induced failures (#16435) (#16439)
|
|
||||||
* Validate issue index before querying DB (#16406) (#16410)
|
|
||||||
* Fix crash following ldap authentication update (#16447) (#16449)
|
|
||||||
* ENHANCEMENTS
|
|
||||||
* Redirect on bad CSRF instead of presenting bad page (#14937) (#16378)
|
|
||||||
|
|
||||||
## [1.14.4](https://github.com/go-gitea/gitea/releases/tag/v1.14.4) - 2021-07-06
|
|
||||||
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix relative links in postprocessed images (#16334) (#16340)
|
|
||||||
* Fix list_options GetStartEnd (#16303) (#16305)
|
|
||||||
* Fix API to use author for commits instead of committer (#16276) (#16277)
|
|
||||||
* Handle misencoding of login_source cfg in mssql (#16268) (#16275)
|
|
||||||
* Fixed issues not updated by commits (#16254) (#16261)
|
|
||||||
* Improve efficiency in FindRenderizableReferenceNumeric and getReference (#16251) (#16255)
|
|
||||||
* Use html.Parse rather than html.ParseFragment (#16223) (#16225)
|
|
||||||
* Fix milestone counters on new issue (#16183) (#16224)
|
|
||||||
* reqOrgMembership calls need to be preceded by reqToken (#16198) (#16219)
|
|
||||||
|
|
||||||
## [1.14.3](https://github.com/go-gitea/gitea/releases/tag/v1.14.3) - 2021-06-18
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Encrypt migration credentials at rest (#15895) (#16187)
|
|
||||||
* Only check access tokens if they are likely to be tokens (#16164) (#16171)
|
|
||||||
* Add missing SameSite settings for the i_like_gitea cookie (#16037) (#16039)
|
|
||||||
* Fix setting of SameSite on cookies (#15989) (#15991)
|
|
||||||
* API
|
|
||||||
* Repository object only count releases as releases (#16184) (#16190)
|
|
||||||
* EditOrg respect RepoAdminChangeTeamAccess option (#16184) (#16190)
|
|
||||||
* Fix overly strict edit pr permissions (#15900) (#16081)
|
|
||||||
* BUGFIXES
|
|
||||||
* Run processors on whole of text (#16155) (#16185)
|
|
||||||
* Class `issue-keyword` is being incorrectly stripped off spans (#16163) (#16172)
|
|
||||||
* Fix language switch for install page (#16043) (#16128)
|
|
||||||
* Fix bug on getIssueIDsByRepoID (#16119) (#16124)
|
|
||||||
* Set self-adjusting deadline for connection writing (#16068) (#16123)
|
|
||||||
* Fix http path bug (#16117) (#16120)
|
|
||||||
* Fix data URI scramble (#16098) (#16118)
|
|
||||||
* Merge all deleteBranch as one function and also fix bug when delete branch don't close related PRs (#16067) (#16097)
|
|
||||||
* git migration: don't prompt interactively for clone credentials (#15902) (#16082)
|
|
||||||
* Fix case change in ownernames (#16045) (#16050)
|
|
||||||
* Don't manipulate input params in email notification (#16011) (#16033)
|
|
||||||
* Remove branch URL before IssueRefURL (#15968) (#15970)
|
|
||||||
* Fix layout of milestone view (#15927) (#15940)
|
|
||||||
* GitHub Migration, migrate draft releases too (#15884) (#15888)
|
|
||||||
* Close the gitrepo when deleting the repository (#15876) (#15887)
|
|
||||||
* Upgrade xorm to v1.1.0 (#15869) (#15885)
|
|
||||||
* Fix blame row height alignment (#15863) (#15883)
|
|
||||||
* Fix error message when saving generated LOCAL_ROOT_URL config (#15880) (#15882)
|
|
||||||
* Backport Fix LFS commit finder not working (#15856) (#15874)
|
|
||||||
* Stop calling WriteHeader in Write (#15862) (#15873)
|
|
||||||
* Add timeout to writing to responses (#15831) (#15872)
|
|
||||||
* Return go-get info on subdirs (#15642) (#15871)
|
|
||||||
* Restore PAM user autocreation functionality (#15825) (#15867)
|
|
||||||
* Fix truncate utf8 string (#15828) (#15854)
|
|
||||||
* Fix bound address/port for caddy's certmagic library (#15758) (#15848)
|
|
||||||
* Upgrade unrolled/render to v1.1.1 (#15845) (#15846)
|
|
||||||
* Queue manager FlushAll can loop rapidly - add delay (#15733) (#15840)
|
|
||||||
* Tagger can be empty, as can Commit and Author - tolerate this (#15835) (#15839)
|
|
||||||
* Set autocomplete off on branches selector (#15809) (#15833)
|
|
||||||
* Add missing error to Doctor log (#15813) (#15824)
|
|
||||||
* Move restore repo to internal router and invoke from command to avoid open the same db file or queues files (#15790) (#15816)
|
|
||||||
* ENHANCEMENTS
|
|
||||||
* Removable media support to snap package (#16136) (#16138)
|
|
||||||
* Move sans-serif fallback font higher than emoji fonts (#15855) (#15892)
|
|
||||||
* DOCKER
|
|
||||||
* Only write config in environment-to-ini if there are changes (#15861) (#15868)
|
|
||||||
* Only offer hostcertificates if they exist (#15849) (#15853)
|
|
||||||
|
|
||||||
## [1.14.2](https://github.com/go-gitea/gitea/releases/tag/v1.14.2) - 2021-05-09
|
|
||||||
|
|
||||||
* API
|
|
||||||
* Make change repo settings work on empty repos (#15778) (#15789)
|
|
||||||
* Add pull "merged" notification subject status to API (#15344) (#15654)
|
|
||||||
* BUGFIXES
|
|
||||||
* Ensure that ctx.Written is checked after issues(...) calls (#15797) (#15798)
|
|
||||||
* Use pulls in commit graph unless pulls are disabled (#15734 & #15740 & #15774) (#15775)
|
|
||||||
* Set GIT_DIR correctly if it is not set (#15751) (#15769)
|
|
||||||
* Fix bug where repositories appear unadopted (#15757) (#15767)
|
|
||||||
* Not show `ref-in-new-issue` pop when issue was disabled (#15761) (#15765)
|
|
||||||
* Drop back to use IsAnInteractiveSession for SVC (#15749) (#15762)
|
|
||||||
* Fix setting version table in dump (#15753) (#15759)
|
|
||||||
* Fix close button change on delete in simplemde area (#15737) (#15747)
|
|
||||||
* Defer closing the gitrepo until the end of the wrapped context functions (#15653) (#15746)
|
|
||||||
* Fix some ui bug about draft release (#15137) (#15745)
|
|
||||||
* Only log Error on getLastCommitStatus error to let pull list still be visible (#15716) (#15715)
|
|
||||||
* Move tooltip down to allow selection of Remove File on error (#15672) (#15714)
|
|
||||||
* Fix setting redis db path (#15698) (#15708)
|
|
||||||
* Fix DB session cleanup (#15697) (#15700)
|
|
||||||
* Fixed several activation bugs (#15473) (#15685)
|
|
||||||
* Delete references if repository gets deleted (#15681) (#15684)
|
|
||||||
* Fix orphaned objects deletion bug (#15657) (#15683)
|
|
||||||
* Delete protected branch if repository gets removed (#15658) (#15676)
|
|
||||||
* Remove spurious set name from eventsource.sharedworker.js (#15643) (#15652)
|
|
||||||
* Not update updated uinx for `git gc` (#15637) (#15641)
|
|
||||||
* Fix commit graph author link (#15627) (#15630)
|
|
||||||
* Fix webhook timeout bug (#15613) (#15621)
|
|
||||||
* Resolve panic on failed interface conversion in migration v156 (#15604) (#15610)
|
|
||||||
* Fix missing storage init (#15589) (#15598)
|
|
||||||
* If the default branch is not present do not report error on stats indexing (#15546 & #15583) (#15594)
|
|
||||||
* Fix lfs management find (#15537) (#15578)
|
|
||||||
* Fix NPE on view commit with notes (#15561) (#15573)
|
|
||||||
* Fix bug on commit graph (#15517) (#15530)
|
|
||||||
* Send size to /avatars if requested (#15459) (#15528)
|
|
||||||
* Prevent migration 156 failure if tag commit missing (#15519) (#15527)
|
|
||||||
* ENHANCEMENTS
|
|
||||||
* Display conflict-free merge messages for pull requests (#15773) (#15796)
|
|
||||||
* Exponential Backoff for ByteFIFO (#15724) (#15793)
|
|
||||||
* Issue list alignment tweaks (#15483) (#15766)
|
|
||||||
* Implement delete release attachments and update release attachments' name (#14130) (#15666)
|
|
||||||
* Add placeholder text to deploy key textarea (#15575) (#15576)
|
|
||||||
* Project board improvements (#15429) (#15560)
|
|
||||||
* Repo branch page: label size, PR ref, new PR button alignment (#15363) (#15365)
|
|
||||||
* MISC
|
|
||||||
* Fix webkit calendar icon color on arc-green (#15713) (#15728)
|
|
||||||
* Performance improvement for last commit cache and show-ref (#15455) (#15701)
|
|
||||||
* Bump unrolled/render to v1.1.0 (#15581) (#15608)
|
|
||||||
* Add ETag header (#15370) (#15552)
|
|
||||||
|
|
||||||
## [1.14.1](https://github.com/go-gitea/gitea/releases/tag/v1.14.1) - 2021-04-15
|
|
||||||
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix bug clone wiki (#15499) (#15502)
|
|
||||||
* Github Migration ignore rate limit, if not enabled (#15490) (#15495)
|
|
||||||
* Use subdir for URL (#15446) (#15493)
|
|
||||||
* Query the DB for the hash before inserting in to email_hash (#15457) (#15491)
|
|
||||||
* Ensure review dismissal only dismisses the correct review (#15477) (#15489)
|
|
||||||
* Use index of the supported tags to choose user lang (#15452) (#15488)
|
|
||||||
* Fix wrong file link in code search page (#15466) (#15486)
|
|
||||||
* Quick template fix for built-in SSH server in admin config (#15464) (#15481)
|
|
||||||
* Prevent superfluous response.WriteHeader (#15456) (#15476)
|
|
||||||
* Fix ambiguous argument error on tags (#15432) (#15474)
|
|
||||||
* Add created_unix instead of expiry to migration (#15458) (#15463)
|
|
||||||
* Fix repository search (#15428) (#15442)
|
|
||||||
* Prevent NPE on avatar direct rendering if federated avatars disabled (#15434) (#15439)
|
|
||||||
* Fix wiki clone urls (#15430) (#15431)
|
|
||||||
* Fix dingtalk icon url at webhook (#15417) (#15426)
|
|
||||||
* Standardise icon on projects PR page (#15387) (#15408)
|
|
||||||
* ENHANCEMENTS
|
|
||||||
* Add option to skip LFS/attachment files for `dump` (#15407) (#15492)
|
|
||||||
* Clone panel fixes (#15436)
|
|
||||||
* Use semantic dropdown for code search query type (#15276) (#15364)
|
|
||||||
* BUILD
|
|
||||||
* Build go-git variants for windows (#15482) (#15487)
|
|
||||||
* Lock down build-images dependencies (Partial #15479) (#15480)
|
|
||||||
* MISC
|
|
||||||
* Performance improvement for list pull requests (#15447) (#15500)
|
|
||||||
* Fix potential copy lfs records failure when fork a repository (#15441) (#15485)
|
|
||||||
|
|
||||||
## [1.14.0](https://github.com/go-gitea/gitea/releases/tag/v1.14.0) - 2021-04-11
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Respect approved email domain list for externally validated user registration (#15014)
|
|
||||||
* Add reverse proxy configuration support for remote IP address detection (#14959)
|
|
||||||
* Ensure validation occurs on clone addresses too (#14994)
|
|
||||||
* Fix several render issues highlighted during fuzzing (#14986)
|
|
||||||
* BREAKING
|
|
||||||
* Fix double 'push tag' action feed (#15078) (#15083)
|
|
||||||
* Remove possible resource leak (#15067) (#15082)
|
|
||||||
* Handle unauthorized user events gracefully (#15071) (#15074)
|
|
||||||
* Restore Access.log following migration to Chi framework (Stops access logging of /api/internal routes) (#14475)
|
|
||||||
* Migrate from Macaron to Chi framework (#14293)
|
|
||||||
* Deprecate building for mips (#14174)
|
|
||||||
* Consolidate Logos and update README header (#14136)
|
|
||||||
* Inline manifest.json (#14038)
|
|
||||||
* Store repository data in data path if not previously set (#13991)
|
|
||||||
* Rename "gitea" png to "logo" (#13974)
|
|
||||||
* Standardise logging of failed authentication attempts in internal SSH (#13962)
|
|
||||||
* Add markdown support in organization description (#13549)
|
|
||||||
* Improve users management through the CLI (#6001) (#10492)
|
|
||||||
* FEATURES
|
|
||||||
* Create a new issue with reference to lines of code from file view (#14863)
|
|
||||||
* Repository transfer has to be confirmed, if user can not create repo for new owner (#14792)
|
|
||||||
* Allow blocking some email domains from registering an account (#14667)
|
|
||||||
* Create a new issue based on reference to an issue comment (#14366)
|
|
||||||
* Add support to migrate from gogs (#14342)
|
|
||||||
* Add pager to the branches page (#14202)
|
|
||||||
* Minimal OpenID Connect implementation (#14139)
|
|
||||||
* Display current stopwatch in navbar (#14122)
|
|
||||||
* Display SVG files as images instead of text (#14101)
|
|
||||||
* Disable SSH key deletion of externally managed Keys (#13985)
|
|
||||||
* Add support for ed25519_sk and ecdsa_sk SSH keys (#13462)
|
|
||||||
* Add support for Mastodon OAuth2 provider (#13293)
|
|
||||||
* Add gitea sendmail command (#13079)
|
|
||||||
* Create DB session provider(based on xorm) (#13031)
|
|
||||||
* Add dismiss review feature (#12674)
|
|
||||||
* Make manual merge autodetection optional and add manual merge as merge method (#12543)
|
|
||||||
* Dump github/gitlab/gitea repository data to a local directory and restore to gitea (#12244)
|
|
||||||
* Create Rootless Docker image (#10154)
|
|
||||||
* API
|
|
||||||
* Speedup issue search (#15179) (#15192)
|
|
||||||
* Get pull, return head branch sha, even if deleted (#14931)
|
|
||||||
* Export LFS & TimeTracking function status (#14753)
|
|
||||||
* Show Gitea version in swagger (#14654)
|
|
||||||
* Fix PATCH /repos/{owner}/{repo} panic (#14637)
|
|
||||||
* Add Restricted Field to User (#14630)
|
|
||||||
* Add support for ref parameter to get raw file API (#14602)
|
|
||||||
* Add affected files of commits to commit struct (#14579)
|
|
||||||
* Fix CJK fonts again and misc. font issues (#14575)
|
|
||||||
* Add delete release by tag & delete tag (#14563) & (#13358)
|
|
||||||
* Add pagination to ListBranches (#14524)
|
|
||||||
* Add signoff option in commit form (#14516)
|
|
||||||
* GetRelease by tag only return release (#14397)
|
|
||||||
* Add MirrorInterval to the API (#14163)
|
|
||||||
* Make BasicAuth Prefix case insensitive (#14106)
|
|
||||||
* Add user filter to issueTrackedTimes, enable usage for issue managers (#14081)
|
|
||||||
* Add ref to create/edit issue options & deprecated assignee (#13992)
|
|
||||||
* Add Ref to Issue (#13946)
|
|
||||||
* Expose default theme in meta and API (#13809)
|
|
||||||
* Send error message when CSRF token is missing (#13676)
|
|
||||||
* List, Check, Add & delete endpoints for repository teams (#13630)
|
|
||||||
* Admin EditUser: Make FullName, Email, Website & Location optional (#13562)
|
|
||||||
* Add more filters to issues search (#13514)
|
|
||||||
* Add review request api (#11355)
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix delete nonexist oauth application 500 and prevent deadlock (#15384) (#15396)
|
|
||||||
* Always set the merge base used to merge the commit (#15352) (#15385)
|
|
||||||
* Upgrade to bluemonday 1.0.7 (#15379) (#15380)
|
|
||||||
* Turn RepoRef and RepoAssignment back into func(*Context) (#15372) (#15377)
|
|
||||||
* Move FCGI req.URL.Path fix-up to the FCGI listener (#15292) (#15361)
|
|
||||||
* Show diff on rename with diff changes (#15338) (#15339)
|
|
||||||
* Fix handling of logout event (#15323) (#15337)
|
|
||||||
* Fix CanCreateRepo check (#15311) (#15321)
|
|
||||||
* Fix xorm log stack level (#15285) (#15316)
|
|
||||||
* Fix bug in Wrap (#15302) (#15309)
|
|
||||||
* Drop the event source if we are unauthorized (#15275) (#15280)
|
|
||||||
* Backport Fix graph pagination (#15225) (#15249)
|
|
||||||
* Prevent NPE in CommentMustAsDiff if no hunk header (#15199) (#15200)
|
|
||||||
* should run RetrieveRepoMetas() for empty pr (#15187) (#15190)
|
|
||||||
* Move setting to enable closing issue via commit in non default branch to repo settings (#14965)
|
|
||||||
* Show correct issues for team dashboard (#14952)
|
|
||||||
* Ensure that new pull request button works on forked forks owned by owner of the root and reduce ambiguity (#14932)
|
|
||||||
* Only allow issue labels from owner repository or organization (#14928)
|
|
||||||
* Fix alignment of People and Teams right arrow on org homepage (#14924)
|
|
||||||
* Fix overdue marking of closed issues and milestones (#14923)
|
|
||||||
* Prevent panic when empty MilestoneID in repo/issue/list (#14911)
|
|
||||||
* Fix migration context data (#14910)
|
|
||||||
* Handle URLs with trailing slash (#14852)
|
|
||||||
* Add CORS config on to /login/oauth/access_token endpoint (#14850)
|
|
||||||
* Make searching issues by keyword case insensitive on DB (#14848)
|
|
||||||
* Prevent use of double sub-path and incorrect asset path in manifest (#14827)
|
|
||||||
* Fix link account ui (#14763)
|
|
||||||
* Fix preview status switch button on wiki editor (#14742)
|
|
||||||
* Fix github download on migration (#14703)
|
|
||||||
* Fix svg spacing (#14638)
|
|
||||||
* Prevent adding nil label to .AddedLabels or .RemovedLabels (#14623)
|
|
||||||
* Truncated organizations name (#14615)
|
|
||||||
* Exclude the current dump file from the dump (#14606)
|
|
||||||
* Use OldRef instead of CommitSHA for DeleteBranch comments (#14604)
|
|
||||||
* Ensure memcache caching works when TTL greater than 30 days (#14592)
|
|
||||||
* Remove NULs byte arrays passed to PostProcess (#14587)
|
|
||||||
* Restore detection of branches are equal on compare page (#14586)
|
|
||||||
* Fix incorrect key name so registerManualConfirm works (#14455)
|
|
||||||
* Fix close/reopen with comment (#14436)
|
|
||||||
* Allow passcode invalid error to appear (#14371)
|
|
||||||
* Escape branch names in compare url (#14364)
|
|
||||||
* Label and milestone webhooks on issue/pull creation (#14363)
|
|
||||||
* Handle NotifyCreateRef as create branch in feeds (#14245)
|
|
||||||
* Prevent clipping input text in Chrome + Segoe UI Font (#14179)
|
|
||||||
* Fix UI on edit auth source page (#14137)
|
|
||||||
* Fix git.parseTagData (#14105)
|
|
||||||
* Refactor get tag to remove unnecessary steps (#14058)
|
|
||||||
* Fix integrations test error with space in CURDIR path (#14056)
|
|
||||||
* Dropdown triangle fixes (#14028)
|
|
||||||
* Fix label of --id in admin delete user (#14005)
|
|
||||||
* Cause NotifyMigrateRepository to emit a repo create webhook (#14004)
|
|
||||||
* Update HEAD to match defaultBranch in template generation (#13948)
|
|
||||||
* Fix action avatar loading (#13909)
|
|
||||||
* Fix issue participants (#13893)
|
|
||||||
* Fix avatar template error (#13833)
|
|
||||||
* Fix review request notification email links when external issue tracker is enabled (#13723)
|
|
||||||
* Fix blame line alignment (#13542)
|
|
||||||
* Include OriginalAuthor in Reaction constraint (#13505)
|
|
||||||
* Comments on review should have the same sha (#13448)
|
|
||||||
* Fix whitespace rendering in diff (#13415)
|
|
||||||
* Fixed git args duplication (#13411)
|
|
||||||
* Fix bug on release publisherid migrations (#13410)
|
|
||||||
* Fix --port setting (#13288)
|
|
||||||
* Keep database transactions not too big (#13254)
|
|
||||||
* Git version check, ignore pre-releases constraints (#13234)
|
|
||||||
* Handle and propagate errors when checking if paths are Dirs, Files or Exist (#13186)
|
|
||||||
* Update Mirror IsEmpty status on synchronize (#13185)
|
|
||||||
* Use GO variable in go-check target (#13146) (#13147)
|
|
||||||
* ENHANCEMENTS
|
|
||||||
* UI style improvements
|
|
||||||
* Dropzone styling improvements (#15291) (#15374)
|
|
||||||
* Add size to Save function (#15264) (#15270)
|
|
||||||
* Monaco improvements (#15333) (#15345)
|
|
||||||
* Support .mailmap in code activity stats (#15009)
|
|
||||||
* Sort release attachments by name (#15008)
|
|
||||||
* Add ui.explore settings to control view of explore pages (#14094)
|
|
||||||
* Make internal SSH server host key path configurable (#14918)
|
|
||||||
* Hide resync all ssh principals when using internal ssh server (#14904)
|
|
||||||
* Add SameSite setting for cookies (#14900)
|
|
||||||
* Move Bleve and Elastic code indexers to use a common cat-file --batch (#14781)
|
|
||||||
* Add environment-to-ini to docker image (#14762)
|
|
||||||
* Add preview support for wiki editor when disable simpleMDE (#14757)
|
|
||||||
* Add easyMDE(simpleMDE) support for release content editor (#14744)
|
|
||||||
* Organization removal confirmation using name not password (#14738)
|
|
||||||
* Make branch names in PR description clickable (#14716)
|
|
||||||
* Add Password Algorithm option to install page (#14701)
|
|
||||||
* Add fullTextSearch to dropdowns by default (#14694)
|
|
||||||
* Fix truncated organization names (#14655)
|
|
||||||
* Whitespace in commits (#14650)
|
|
||||||
* Sort / move project boards (#14634)
|
|
||||||
* Make fileheader sticky in diffs (#14616)
|
|
||||||
* Add helper descriptions on new repo page (#14591)
|
|
||||||
* Move the stopwatches to the eventsource stream (#14588)
|
|
||||||
* Add Content-Length header to HEAD requests (#14542)
|
|
||||||
* Add Image Diff options in Diff view (#14450)
|
|
||||||
* Improve Description in new/ edit Project template (#14429)
|
|
||||||
* Allow ssh-keygen on Windows to detect ssh key type (#14413)
|
|
||||||
* Display error if twofaSecret cannot be retrieved (#14372)
|
|
||||||
* Sort issue search results by revelance (#14353)
|
|
||||||
* Implement ghost comment mitigation (#14349)
|
|
||||||
* Upgrade blevesearch dependency to v2.0.1 (#14346)
|
|
||||||
* Add edit, delete and reaction support to code review comments on issue page (#14339)
|
|
||||||
* Merge default and system webhooks under one menu (#14244)
|
|
||||||
* Add option for administrator to reset user 2FA (#14243)
|
|
||||||
* Add option to change username to the admin panel (#14229)
|
|
||||||
* Check for 'main' as potential default branch name (#14193)
|
|
||||||
* Project: show referenced PRs in issue cards (#14183)
|
|
||||||
* Use caddy's certmagic library for extensible/robust ACME handling (#14177)
|
|
||||||
* CLI support for OAuth sources custom icons (#14166)
|
|
||||||
* Custom icons for OAuth sources (#14161)
|
|
||||||
* Team dashboards (#14159)
|
|
||||||
* KanBan: be able to set default board (#14147)
|
|
||||||
* Disable Fomantic's custom scrollbars (#14109)
|
|
||||||
* Add UI to delete tracked times (#14100)
|
|
||||||
* Rework heatmap permissions (#14080)
|
|
||||||
* Issue and pull request filters on organization dashboard (#14072)
|
|
||||||
* Fix webhook list styling (#14001)
|
|
||||||
* Show dropdown with all statuses for commit (#13977)
|
|
||||||
* Show status check for merged PRs (#13975)
|
|
||||||
* Diff stat improvements (#13954)
|
|
||||||
* Report permissions denied in internal SSH (#13953)
|
|
||||||
* Markdown task list improvements (#13952)
|
|
||||||
* Heatmap days clickable (#13935)
|
|
||||||
* chore: use octicon-mirror for feeds display (#13928)
|
|
||||||
* Move diff split code into own template file (#13919)
|
|
||||||
* Markdown: Enable wrapping in code blocks and a color tweak (#13894)
|
|
||||||
* Do not reload page after adding comments in Pull Request reviews (#13877)
|
|
||||||
* Add pull request manually merge instruction (#13840)
|
|
||||||
* add thumbnail preview section to issue attachments (#13826)
|
|
||||||
* Move Repo APIFormat to convert package (#13787)
|
|
||||||
* Move notification APIFormat (#13783)
|
|
||||||
* Swap swagger-ui with swagger-ui-dist (#13777)
|
|
||||||
* User Settings: Ignore empty language codes & validate (#13755)
|
|
||||||
* Improve migrate page and add card CSS (#13751)
|
|
||||||
* Add block on official review requests branch protection (#13705)
|
|
||||||
* Add review requested filter on pull request overview (#13701)
|
|
||||||
* Use chronological commit order in default squash message (#13696)
|
|
||||||
* Clickable links in pull request (and issue) titles (#13695)
|
|
||||||
* Support shortened commit SHAs in URLs (#13686)
|
|
||||||
* Use native git variants by default with go-git variants as build tag (#13673)
|
|
||||||
* Don't render dropdown when only 1 merge style is available (#13670)
|
|
||||||
* Move webhook type from int to string (#13664)
|
|
||||||
* Direct avatar rendering (#13649)
|
|
||||||
* Verify password for local-account activation (#13631)
|
|
||||||
* Prevent clone protocol button flash on page load (#13626)
|
|
||||||
* Remove fetch request from heatmap (#13623)
|
|
||||||
* Refactor combine label comments with tests (#13619)
|
|
||||||
* Move metrics from macaron to chi (#13601)
|
|
||||||
* Issue and Pulls lists rework (#13594)
|
|
||||||
* HTTP cache rework and enable caching for storage assets (#13569)
|
|
||||||
* Use mount but not register for chi routes (#13555)
|
|
||||||
* Use monaco for the git hook editor (#13552)
|
|
||||||
* Make heatmap colors more distinct (#13533)
|
|
||||||
* Lazy-load issue reviewers and assignees avatars (#13526)
|
|
||||||
* Change search and filter icons to SVG (#13473)
|
|
||||||
* Create tag on ui (#13467)
|
|
||||||
* updateSize when create a repo with init commit (#13441)
|
|
||||||
* Added title and action buttons to Project view page (#13437)
|
|
||||||
* Override fomantic monospace fonts and set size (#13435)
|
|
||||||
* Rework focused comment styling (#13434)
|
|
||||||
* Tags cleanup (#13428)
|
|
||||||
* Various style tweaks (#13418)
|
|
||||||
* Refactor push update (#13381)
|
|
||||||
* Comment box tweaks and SVG dropdown triangles (#13376)
|
|
||||||
* Various style fixes (#13372)
|
|
||||||
* Change repo home page icons to SVG (#13364)
|
|
||||||
* Use CSS Vars for primary color (#13361)
|
|
||||||
* Refactor image paste code (#13354)
|
|
||||||
* Switch from SimpleMDE to EasyMDE (#13333)
|
|
||||||
* Group Label Changed Comments in timeline (#13304)
|
|
||||||
* Make the logger an interface (#13294)
|
|
||||||
* Fix PR/Issue titles on mobile (#13292)
|
|
||||||
* Rearrange the order of the merged by etc. in locale (#13284)
|
|
||||||
* Replace footer and modal icons with SVG (#13245)
|
|
||||||
* Issues overview should not show issues from archived repos (#13220)
|
|
||||||
* Show stale label for stale code comment which is marked as resolved (#13213)
|
|
||||||
* Use CSS Variables for fonts, remove postcss-loader (#13204)
|
|
||||||
* Add mentionable teams to tributeValues and change team mention rules to gh's style (#13198)
|
|
||||||
* Move install pages out of main macaron routes (#13195)
|
|
||||||
* Update outdated label to use Fomantic UI style (#13181)
|
|
||||||
* Added option to disable webhooks (#13176)
|
|
||||||
* Change order of possible-owner organizations to alphabetical (#13160)
|
|
||||||
* Log IP on SSH authentication failure for Built-in SSH server (#13150)
|
|
||||||
* Added option to disable migrations (#13114)
|
|
||||||
* New "Add Mirror" Button in the Organization view (#13105)
|
|
||||||
* Manually approve new registration (#13083)
|
|
||||||
* Cron job to cleanup hook_task table (#13080)
|
|
||||||
* Use the headline comment of pull-request as the squash commit's message (#13071)
|
|
||||||
* Clarify the suffices and prefixes of setting.AppSubURL and setting.AppURL (#12999)
|
|
||||||
* Slightly simplify the queue settings code to help reduce the risk of problems (#12976)
|
|
||||||
* Add precise search type for Elastic Search (#12869)
|
|
||||||
* Move APIFormat functions into convert package (#12856)
|
|
||||||
* Multiple GitGraph improvements: Exclude PR heads, Add branch/PR links, Show only certain branches, (#12766)
|
|
||||||
* Add TrN for repository limit (#12492)
|
|
||||||
* Refactor doctor (#12264)
|
|
||||||
* Add the tag list page to the release page (#12096)
|
|
||||||
* Redirect on changed user and org name (#11649)
|
|
||||||
* load U2F js only on pages which need it (#11585)
|
|
||||||
* Make archival asynchronous (#11296)
|
|
||||||
* Introduce go chi web framework as frontend of macaron, so that we can move routes from macaron to chi step by step (#7420)
|
|
||||||
* Improve vfsgen to not unzip bindata files but send to browser directly (#7109)
|
|
||||||
* Enhance release list (#6025)
|
|
||||||
* DOCS
|
|
||||||
* Swagger show models by default (#14880)
|
|
||||||
* Add missing repo.projects unit into swagger (#14876)
|
|
||||||
* Update docs and comments to remove macaron (#14491)
|
|
||||||
* Issue template addition: Are you using Gitea behind CloudFlare? (#14098)
|
|
||||||
* Generate man pages (#13901)
|
|
||||||
* Reformat/fine-tune docs (#13897)
|
|
||||||
* Added Table of Contents to long documentation pages (#13890)
|
|
||||||
* Add docs command (#13429)
|
|
||||||
* Update external-renderers.en-us.md (#13165)
|
|
||||||
* MISC
|
|
||||||
* Add builds for apple M1 (darwin arm64) (#14951)
|
|
||||||
* Migrate to use jsoniter instead of encoding/json (#14841)
|
|
||||||
* Reduce make verbosity (#13803)
|
|
||||||
* Add git command error directory on log (#13194)
|
|
||||||
|
|
||||||
## [1.13.7](https://github.com/go-gitea/gitea/releases/tag/v1.13.7) - 2021-04-07
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Update to bluemonday-1.0.6 (#15294) (#15298)
|
|
||||||
* Clusterfuzz found another way (#15160) (#15169)
|
|
||||||
* API
|
|
||||||
* Fix wrong user returned in API (#15139) (#15150)
|
|
||||||
* BUGFIXES
|
|
||||||
* Add 'fonts' into 'KnownPublicEntries' (#15188) (#15317)
|
|
||||||
* Speed up `enry.IsVendor` (#15213) (#15246)
|
|
||||||
* Response 404 for diff/patch of a commit that not exist (#15221) (#15238)
|
|
||||||
* Prevent NPE in CommentMustAsDiff if no hunk header (#15199) (#15201)
|
|
||||||
* MISC
|
|
||||||
* Add size to Save function (#15264) (#15271)
|
|
||||||
|
|
||||||
## [1.13.6](https://github.com/go-gitea/gitea/releases/tag/v1.13.6) - 2021-03-23
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Fix bug on avatar middleware (#15124) (#15125)
|
|
||||||
* Fix another clusterfuzz identified issue (#15096) (#15114)
|
|
||||||
* API
|
|
||||||
* Fix nil exeption for get pull reviews API #15104 (#15106)
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix markdown rendering in milestone content (#15056) (#15092)
|
|
||||||
|
|
||||||
## [1.13.5](https://github.com/go-gitea/gitea/releases/tag/v1.13.5) - 2021-03-21
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Update to goldmark 1.3.3 (#15059) (#15061)
|
|
||||||
* Another clusterfuzz spotted issue (#15032) (#15034)
|
|
||||||
* API
|
|
||||||
* Fix set milestone on PR creation (#14981) (#15001)
|
|
||||||
* Prevent panic when editing forked repos by API (#14960) (#14963)
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix bug when upload on web (#15042) (#15055)
|
|
||||||
* Delete Labels & IssueLabels on Repo Delete too (#15039) (#15051)
|
|
||||||
* Fix postgres ID sequences broken by recreate-table (#15015) (#15029)
|
|
||||||
* Fix several render issues (#14986) (#15013)
|
|
||||||
* Make sure sibling images get a link too (#14979) (#14995)
|
|
||||||
* Fix Anchor jumping with escaped query components (#14969) (#14977)
|
|
||||||
* Fix release mail html template (#14976)
|
|
||||||
* Fix excluding more than two labels on issues list (#14962) (#14973)
|
|
||||||
* Don't mark each comment poster as OP (#14971) (#14972)
|
|
||||||
* Add "captcha" to list of reserved usernames (#14930)
|
|
||||||
* Re-enable import local paths after reversion from #13610 (#14925) (#14927)
|
|
||||||
|
|
||||||
## [1.13.4](https://github.com/go-gitea/gitea/releases/tag/v1.13.4) - 2021-03-07
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Fix issue popups (#14898) (#14899)
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix race in LFS ContentStore.Put(...) (#14895) (#14913)
|
|
||||||
* Fix a couple of issues with a feeds (#14897) (#14903)
|
|
||||||
* When transfering repository and database transaction failed, rollback the renames (#14864) (#14902)
|
|
||||||
* Fix race in local storage (#14888) (#14901)
|
|
||||||
* Fix 500 on pull view page if user is not loged in (#14885) (#14886)
|
|
||||||
* DOCS
|
|
||||||
* Fix how lfs data path is set (#14855) (#14884)
|
|
||||||
|
|
||||||
## [1.13.3](https://github.com/go-gitea/gitea/releases/tag/v1.13.3) - 2021-03-04
|
|
||||||
|
|
||||||
* BREAKING
|
|
||||||
* Turn default hash password algorithm back to pbkdf2 from argon2 until we find a better one (#14673) (#14675)
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix paging of file commit logs (#14831) (#14879)
|
|
||||||
* Print useful error if SQLite is used in settings but not supported (#14476) (#14874)
|
|
||||||
* Fix display since time round (#14226) (#14873)
|
|
||||||
* When Deleting Repository only explicitly close PRs whose base is not this repository (#14823) (#14842)
|
|
||||||
* Set HCaptchaSiteKey on Link Account pages (#14834) (#14839)
|
|
||||||
* Fix a couple of CommentAsPatch issues. (#14804) (#14820)
|
|
||||||
* Disable broken OAuth2 providers at startup (#14802) (#14811)
|
|
||||||
* Repo Transfer permission checks (#14792) (#14794)
|
|
||||||
* Fix double alert in oauth2 application edit view (#14764) (#14768)
|
|
||||||
* Fix broken spans in diffs (#14678) (#14683)
|
|
||||||
* Prevent race in PersistableChannelUniqueQueue.Has (#14651) (#14676)
|
|
||||||
* HasPreviousCommit causes recursive load of commits unnecessarily (#14598) (#14649)
|
|
||||||
* Do not assume all 40 char strings are SHA1s (#14624) (#14648)
|
|
||||||
* Allow org labels to be set with issue templates (#14593) (#14647)
|
|
||||||
* Accept multiple SSH keys in single LDAP SSHPublicKey attribute (#13989) (#14607)
|
|
||||||
* Fix bug about ListOptions and stars/watchers pagnation (#14556) (#14573)
|
|
||||||
* Fix GPG key deletion during account deletion (#14561) (#14569)
|
|
||||||
|
|
||||||
## [1.13.2](https://github.com/go-gitea/gitea/releases/tag/v1.13.2) - 2021-01-31
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Prevent panic on fuzzer provided string (#14405) (#14409)
|
|
||||||
* Add secure/httpOnly attributes to the lang cookie (#14279) (#14280)
|
|
||||||
* API
|
|
||||||
* If release publisher is deleted use ghost user (#14375)
|
|
||||||
* BUGFIXES
|
|
||||||
* Internal ssh server respect Ciphers, MACs and KeyExchanges settings (#14523) (#14530)
|
|
||||||
* Set the name Mapper in migrations (#14526) (#14529)
|
|
||||||
* Fix wiki preview (#14515)
|
|
||||||
* Update code.gitea.io/sdk/gitea v0.13.1 -> v0.13.2 (#14497)
|
|
||||||
* ChangeUserName: rename user files back on DB issue (#14447)
|
|
||||||
* Fix lfs preview bug (#14428) (#14433)
|
|
||||||
* Ensure timeout error is shown on u2f timeout (#14417) (#14431)
|
|
||||||
* Fix Deadlock & Delete affected reactions on comment deletion (#14392) (#14425)
|
|
||||||
* Use path not filepath in routers/editor (#14390) (#14396)
|
|
||||||
* Check if label template exist first (#14384) (#14389)
|
|
||||||
* Fix migration v141 (#14387) (#14388)
|
|
||||||
* Use Request.URL.RequestURI() for fcgi (#14347)
|
|
||||||
* Use ServerError provided by Context (#14333) (#14345)
|
|
||||||
* Fix edit-label form init (#14337)
|
|
||||||
* Fix mailIssueCommentBatch for pull request (#14252) (#14296)
|
|
||||||
* Render links for commit hashes followed by comma (#14224) (#14227)
|
|
||||||
* Send notifications for mentions in pulls, issues, (code-)comments (#14218) (#14221)
|
|
||||||
* Fix avatar bugs (#14217) (#14220)
|
|
||||||
* Ensure that schema search path is set with every connection on postgres (#14131) (#14216)
|
|
||||||
* Fix dashboard issues labels filter bug (#14210) (#14214)
|
|
||||||
* When visit /favicon.ico but the static file is not exist return 404 but not continue to handle the route (#14211) (#14213)
|
|
||||||
* Fix branch selector on new issue page (#14194) (#14207)
|
|
||||||
* Check for notExist on profile repository page (#14197) (#14203)
|
|
||||||
|
|
||||||
## [1.13.1](https://github.com/go-gitea/gitea/releases/tag/v1.13.1) - 2020-12-29
|
## [1.13.1](https://github.com/go-gitea/gitea/releases/tag/v1.13.1) - 2020-12-29
|
||||||
|
|
||||||
* SECURITY
|
* SECURITY
|
||||||
|
|
|
@ -3,14 +3,12 @@
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
- [Contribution Guidelines](#contribution-guidelines)
|
- [Contribution Guidelines](#contribution-guidelines)
|
||||||
- [Table of Contents](#table-of-contents)
|
|
||||||
- [Introduction](#introduction)
|
- [Introduction](#introduction)
|
||||||
- [Bug reports](#bug-reports)
|
- [Bug reports](#bug-reports)
|
||||||
- [Discuss your design](#discuss-your-design)
|
- [Discuss your design](#discuss-your-design)
|
||||||
- [Testing redux](#testing-redux)
|
- [Testing redux](#testing-redux)
|
||||||
- [Vendoring](#vendoring)
|
- [Vendoring](#vendoring)
|
||||||
- [Translation](#translation)
|
- [Translation](#translation)
|
||||||
- [Building Gitea](#building-gitea)
|
|
||||||
- [Code review](#code-review)
|
- [Code review](#code-review)
|
||||||
- [Styleguide](#styleguide)
|
- [Styleguide](#styleguide)
|
||||||
- [Design guideline](#design-guideline)
|
- [Design guideline](#design-guideline)
|
||||||
|
@ -207,10 +205,6 @@ In general, HTTP methods are chosen as follows:
|
||||||
|
|
||||||
An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required).
|
An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required).
|
||||||
|
|
||||||
### Endpoints returning lists should
|
|
||||||
* support pagination (`page` & `limit` options in query)
|
|
||||||
* set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
|
|
||||||
|
|
||||||
|
|
||||||
## Developer Certificate of Origin (DCO)
|
## Developer Certificate of Origin (DCO)
|
||||||
|
|
||||||
|
@ -232,18 +226,18 @@ We assume in good faith that the information you provide is legally binding.
|
||||||
|
|
||||||
We adopted a release schedule to streamline the process of working
|
We adopted a release schedule to streamline the process of working
|
||||||
on, finishing, and issuing releases. The overall goal is to make a
|
on, finishing, and issuing releases. The overall goal is to make a
|
||||||
minor release every three or four months, which breaks down into two or three months of
|
minor release every two months, which breaks down into one month of
|
||||||
general development followed by one month of testing and polishing
|
general development followed by one month of testing and polishing
|
||||||
known as the release freeze. All the feature pull requests should be
|
known as the release freeze. All the feature pull requests should be
|
||||||
merged before feature freeze. And, during the frozen period, a corresponding
|
merged in the first month of one release period. And, during the frozen
|
||||||
release branch is open for fixes backported from main branch. Release candidates
|
period, a corresponding release branch is open for fixes backported from
|
||||||
are made during this period for user testing to
|
master. Release candidates are made during this period for user testing to
|
||||||
obtain a final version that is maintained in this branch. A release is
|
obtain a final version that is maintained in this branch. A release is
|
||||||
maintained by issuing patch releases to only correct critical problems
|
maintained by issuing patch releases to only correct critical problems
|
||||||
such as crashes or security issues.
|
such as crashes or security issues.
|
||||||
|
|
||||||
Major release cycles are seasonal. They always begin on the 25th and end on
|
Major release cycles are bimonthly. They always begin on the 25th and end on
|
||||||
the 24th (i.e., the 25th of December to March 24th).
|
the 24th (i.e., the 25th of December to February 24th).
|
||||||
|
|
||||||
During a development cycle, we may also publish any necessary minor releases
|
During a development cycle, we may also publish any necessary minor releases
|
||||||
for the previous version. For example, if the latest, published release is
|
for the previous version. For example, if the latest, published release is
|
||||||
|
|
10
Dockerfile
10
Dockerfile
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
#Build stage
|
#Build stage
|
||||||
FROM golang:1.17-alpine3.13 AS build-env
|
FROM golang:1.15-alpine3.12 AS build-env
|
||||||
|
|
||||||
ARG GOPROXY
|
ARG GOPROXY
|
||||||
ENV GOPROXY ${GOPROXY:-direct}
|
ENV GOPROXY ${GOPROXY:-direct}
|
||||||
|
@ -22,10 +22,7 @@ WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
||||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||||
&& make clean-all build
|
&& make clean-all build
|
||||||
|
|
||||||
# Begin env-to-ini build
|
FROM alpine:3.12
|
||||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
|
||||||
|
|
||||||
FROM alpine:3.13
|
|
||||||
LABEL maintainer="maintainers@gitea.io"
|
LABEL maintainer="maintainers@gitea.io"
|
||||||
|
|
||||||
EXPOSE 22 3000
|
EXPOSE 22 3000
|
||||||
|
@ -53,7 +50,7 @@ RUN addgroup \
|
||||||
-u 1000 \
|
-u 1000 \
|
||||||
-G git \
|
-G git \
|
||||||
git && \
|
git && \
|
||||||
echo "git:*" | chpasswd -e
|
echo "git:$(dd if=/dev/urandom bs=24 count=1 status=none | base64)" | chpasswd
|
||||||
|
|
||||||
ENV USER git
|
ENV USER git
|
||||||
ENV GITEA_CUSTOM /data/gitea
|
ENV GITEA_CUSTOM /data/gitea
|
||||||
|
@ -65,5 +62,4 @@ CMD ["/bin/s6-svscan", "/etc/s6"]
|
||||||
|
|
||||||
COPY docker/root /
|
COPY docker/root /
|
||||||
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
|
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
|
||||||
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
|
|
||||||
RUN ln -s /app/gitea/gitea /usr/local/bin/gitea
|
RUN ln -s /app/gitea/gitea /usr/local/bin/gitea
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
#Build stage
|
#Build stage
|
||||||
FROM golang:1.17-alpine3.13 AS build-env
|
FROM golang:1.15-alpine3.12 AS build-env
|
||||||
|
|
||||||
ARG GOPROXY
|
ARG GOPROXY
|
||||||
ENV GOPROXY ${GOPROXY:-direct}
|
ENV GOPROXY ${GOPROXY:-direct}
|
||||||
|
@ -22,10 +22,7 @@ WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
||||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||||
&& make clean-all build
|
&& make clean-all build
|
||||||
|
|
||||||
# Begin env-to-ini build
|
FROM alpine:3.12
|
||||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
|
||||||
|
|
||||||
FROM alpine:3.13
|
|
||||||
LABEL maintainer="maintainers@gitea.io"
|
LABEL maintainer="maintainers@gitea.io"
|
||||||
|
|
||||||
EXPOSE 2222 3000
|
EXPOSE 2222 3000
|
||||||
|
@ -35,7 +32,6 @@ RUN apk --no-cache add \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
gettext \
|
gettext \
|
||||||
git \
|
git \
|
||||||
curl \
|
|
||||||
gnupg
|
gnupg
|
||||||
|
|
||||||
RUN addgroup \
|
RUN addgroup \
|
||||||
|
@ -47,22 +43,19 @@ RUN addgroup \
|
||||||
-s /bin/bash \
|
-s /bin/bash \
|
||||||
-u 1000 \
|
-u 1000 \
|
||||||
-G git \
|
-G git \
|
||||||
git
|
git && \
|
||||||
|
echo "git:$(dd if=/dev/urandom bs=24 count=1 status=none | base64)" | chpasswd
|
||||||
|
|
||||||
RUN mkdir -p /var/lib/gitea /etc/gitea
|
RUN mkdir -p /var/lib/gitea /etc/gitea
|
||||||
RUN chown git:git /var/lib/gitea /etc/gitea
|
RUN chown git:git /var/lib/gitea /etc/gitea
|
||||||
|
|
||||||
COPY docker/rootless /
|
COPY docker/rootless /
|
||||||
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /usr/local/bin/gitea
|
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /usr/local/bin/gitea
|
||||||
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
|
|
||||||
|
|
||||||
#git:git
|
USER git:git
|
||||||
USER 1000:1000
|
|
||||||
ENV GITEA_WORK_DIR /var/lib/gitea
|
ENV GITEA_WORK_DIR /var/lib/gitea
|
||||||
ENV GITEA_CUSTOM /var/lib/gitea/custom
|
ENV GITEA_CUSTOM /var/lib/gitea/custom
|
||||||
ENV GITEA_TEMP /tmp/gitea
|
ENV GITEA_TEMP /tmp/gitea
|
||||||
ENV TMPDIR /tmp/gitea
|
|
||||||
|
|
||||||
#TODO add to docs the ability to define the ini to load (usefull to test and revert a config)
|
#TODO add to docs the ability to define the ini to load (usefull to test and revert a config)
|
||||||
ENV GITEA_APP_INI /etc/gitea/app.ini
|
ENV GITEA_APP_INI /etc/gitea/app.ini
|
||||||
ENV HOME "/var/lib/gitea/git"
|
ENV HOME "/var/lib/gitea/git"
|
||||||
|
|
|
@ -39,8 +39,3 @@ David Svantesson <davidsvantesson@gmail.com> (@davidsvantesson)
|
||||||
a1012112796 <1012112796@qq.com> (@a1012112796)
|
a1012112796 <1012112796@qq.com> (@a1012112796)
|
||||||
Karl Heinz Marbaise <kama@soebes.de> (@khmarbaise)
|
Karl Heinz Marbaise <kama@soebes.de> (@khmarbaise)
|
||||||
Norwin Roosen <git@nroo.de> (@noerw)
|
Norwin Roosen <git@nroo.de> (@noerw)
|
||||||
Kyle Dumont <kdumontnu@gmail.com> (@kdumontnu)
|
|
||||||
Patrick Schratz <patrick.schratz@gmail.com> (@pat-s)
|
|
||||||
Janis Estelmann <admin@oldschoolhack.me> (@KN4CK3R)
|
|
||||||
Steven Kriegler <sk.bunsenbrenner@gmail.com> (@justusbunsi)
|
|
||||||
Jimmy Praet <jimmy.praet@telenet.be> (@jpraet)
|
|
||||||
|
|
171
Makefile
171
Makefile
|
@ -24,9 +24,9 @@ SHASUM ?= shasum -a 256
|
||||||
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
||||||
COMMA := ,
|
COMMA := ,
|
||||||
|
|
||||||
XGO_VERSION := go-1.17.x
|
XGO_VERSION := go-1.15.x
|
||||||
MIN_GO_VERSION := 001016000
|
MIN_GO_VERSION := 001013000
|
||||||
MIN_NODE_VERSION := 012017000
|
MIN_NODE_VERSION := 010013000
|
||||||
|
|
||||||
DOCKER_IMAGE ?= gitea/gitea
|
DOCKER_IMAGE ?= gitea/gitea
|
||||||
DOCKER_TAG ?= latest
|
DOCKER_TAG ?= latest
|
||||||
|
@ -43,9 +43,6 @@ endif
|
||||||
ifeq ($(OS), Windows_NT)
|
ifeq ($(OS), Windows_NT)
|
||||||
GOFLAGS := -v -buildmode=exe
|
GOFLAGS := -v -buildmode=exe
|
||||||
EXECUTABLE ?= gitea.exe
|
EXECUTABLE ?= gitea.exe
|
||||||
else ifeq ($(OS), Windows)
|
|
||||||
GOFLAGS := -v -buildmode=exe
|
|
||||||
EXECUTABLE ?= gitea.exe
|
|
||||||
else
|
else
|
||||||
GOFLAGS := -v
|
GOFLAGS := -v
|
||||||
EXECUTABLE ?= gitea
|
EXECUTABLE ?= gitea
|
||||||
|
@ -64,9 +61,8 @@ EXTRA_GOFLAGS ?=
|
||||||
MAKE_VERSION := $(shell $(MAKE) -v | head -n 1)
|
MAKE_VERSION := $(shell $(MAKE) -v | head -n 1)
|
||||||
MAKE_EVIDENCE_DIR := .make_evidence
|
MAKE_EVIDENCE_DIR := .make_evidence
|
||||||
|
|
||||||
ifeq ($(RACE_ENABLED),true)
|
ifneq ($(RACE_ENABLED),)
|
||||||
GOFLAGS += -race
|
GOTESTFLAGS ?= -race
|
||||||
GOTESTFLAGS += -race
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
STORED_VERSION_FILE := VERSION
|
STORED_VERSION_FILE := VERSION
|
||||||
|
@ -78,7 +74,7 @@ else
|
||||||
ifneq ($(DRONE_BRANCH),)
|
ifneq ($(DRONE_BRANCH),)
|
||||||
VERSION ?= $(subst release/v,,$(DRONE_BRANCH))
|
VERSION ?= $(subst release/v,,$(DRONE_BRANCH))
|
||||||
else
|
else
|
||||||
VERSION ?= main
|
VERSION ?= master
|
||||||
endif
|
endif
|
||||||
|
|
||||||
STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null)
|
STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null)
|
||||||
|
@ -91,11 +87,11 @@ endif
|
||||||
|
|
||||||
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
||||||
|
|
||||||
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
|
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(filter-out code.gitea.io/gitea/integrations,$(shell $(GO) list -mod=vendor ./... | grep -v /vendor/)))
|
||||||
|
|
||||||
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/models/migrations code.gitea.io/gitea/integrations/migration-test code.gitea.io/gitea/integrations,$(shell $(GO) list -mod=vendor ./... | grep -v /vendor/))
|
FOMANTIC_CONFIGS := semantic.json web_src/fomantic/theme.config.less web_src/fomantic/_site/globals/site.variables
|
||||||
|
FOMANTIC_DEST := web_src/fomantic/build/semantic.js web_src/fomantic/build/semantic.css
|
||||||
FOMANTIC_WORK_DIR := web_src/fomantic
|
FOMANTIC_DEST_DIR := web_src/fomantic/build
|
||||||
|
|
||||||
WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f)
|
WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f)
|
||||||
WEBPACK_CONFIGS := webpack.config.js
|
WEBPACK_CONFIGS := webpack.config.js
|
||||||
|
@ -115,8 +111,6 @@ TAGS_EVIDENCE := $(MAKE_EVIDENCE_DIR)/tags
|
||||||
|
|
||||||
TEST_TAGS ?= sqlite sqlite_unlock_notify
|
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_DIRS := cmd integrations models modules routers build services vendor tools
|
GO_DIRS := cmd integrations models modules routers build services vendor tools
|
||||||
|
|
||||||
GO_SOURCES := $(wildcard *.go)
|
GO_SOURCES := $(wildcard *.go)
|
||||||
|
@ -131,8 +125,8 @@ GO_SOURCES_OWN := $(filter-out vendor/% %/bindata.go, $(GO_SOURCES))
|
||||||
#To update swagger use: GO111MODULE=on go get -u github.com/go-swagger/go-swagger/cmd/swagger
|
#To update swagger use: GO111MODULE=on go get -u github.com/go-swagger/go-swagger/cmd/swagger
|
||||||
SWAGGER := $(GO) run -mod=vendor github.com/go-swagger/go-swagger/cmd/swagger
|
SWAGGER := $(GO) run -mod=vendor github.com/go-swagger/go-swagger/cmd/swagger
|
||||||
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
|
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
|
||||||
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
|
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl}}/api/v1"|g
|
||||||
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
|
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl}}/api/v1"|"basePath": "/api/v1"|g
|
||||||
SWAGGER_EXCLUDE := code.gitea.io/sdk
|
SWAGGER_EXCLUDE := code.gitea.io/sdk
|
||||||
SWAGGER_NEWLINE_COMMAND := -e '$$a\'
|
SWAGGER_NEWLINE_COMMAND := -e '$$a\'
|
||||||
|
|
||||||
|
@ -175,9 +169,6 @@ help:
|
||||||
@echo " - checks run various consistency checks"
|
@echo " - checks run various consistency checks"
|
||||||
@echo " - checks-frontend check frontend files"
|
@echo " - checks-frontend check frontend files"
|
||||||
@echo " - checks-backend check backend files"
|
@echo " - checks-backend check backend files"
|
||||||
@echo " - test test everything"
|
|
||||||
@echo " - test-frontend test frontend files"
|
|
||||||
@echo " - test-backend test backend files"
|
|
||||||
@echo " - webpack build webpack files"
|
@echo " - webpack build webpack files"
|
||||||
@echo " - svg build svg files"
|
@echo " - svg build svg files"
|
||||||
@echo " - fomantic build fomantic files"
|
@echo " - fomantic build fomantic files"
|
||||||
|
@ -185,7 +176,6 @@ help:
|
||||||
@echo " - fmt format the Go code"
|
@echo " - fmt format the Go code"
|
||||||
@echo " - generate-license update license files"
|
@echo " - generate-license update license files"
|
||||||
@echo " - generate-gitignore update gitignore files"
|
@echo " - generate-gitignore update gitignore files"
|
||||||
@echo " - generate-manpage generate manpage"
|
|
||||||
@echo " - generate-swagger generate the swagger spec from code comments"
|
@echo " - generate-swagger generate the swagger spec from code comments"
|
||||||
@echo " - swagger-validate check if the swagger spec is valid"
|
@echo " - swagger-validate check if the swagger spec is valid"
|
||||||
@echo " - golangci-lint run golangci-lint linter"
|
@echo " - golangci-lint run golangci-lint linter"
|
||||||
|
@ -200,7 +190,7 @@ help:
|
||||||
go-check:
|
go-check:
|
||||||
$(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+' | tr '.' ' ');))
|
$(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+' | tr '.' ' ');))
|
||||||
@if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \
|
@if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \
|
||||||
echo "Gitea requires Go 1.16 or greater to build. You can get it at https://golang.org/dl/"; \
|
echo "Gitea requires Go 1.13 or greater to build. You can get it at https://golang.org/dl/"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -214,16 +204,15 @@ git-check:
|
||||||
.PHONY: node-check
|
.PHONY: node-check
|
||||||
node-check:
|
node-check:
|
||||||
$(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');))
|
$(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');))
|
||||||
$(eval MIN_NODE_VER_FMT := $(shell printf "%g.%g.%g" $(shell echo $(MIN_NODE_VERSION) | grep -o ...)))
|
|
||||||
$(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1))
|
$(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1))
|
||||||
@if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \
|
@if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \
|
||||||
echo "Gitea requires Node.js $(MIN_NODE_VER_FMT) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \
|
echo "Gitea requires Node.js 10 or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
.PHONY: clean-all
|
.PHONY: clean-all
|
||||||
clean-all: clean
|
clean-all: clean
|
||||||
rm -rf $(WEBPACK_DEST_ENTRIES) node_modules
|
rm -rf $(WEBPACK_DEST_ENTRIES)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
@ -232,7 +221,7 @@ clean:
|
||||||
integrations*.test \
|
integrations*.test \
|
||||||
integrations/gitea-integration-pgsql/ integrations/gitea-integration-mysql/ integrations/gitea-integration-mysql8/ integrations/gitea-integration-sqlite/ \
|
integrations/gitea-integration-pgsql/ integrations/gitea-integration-mysql/ integrations/gitea-integration-mysql8/ integrations/gitea-integration-sqlite/ \
|
||||||
integrations/gitea-integration-mssql/ integrations/indexers-mysql/ integrations/indexers-mysql8/ integrations/indexers-pgsql integrations/indexers-sqlite \
|
integrations/gitea-integration-mssql/ integrations/indexers-mysql/ integrations/indexers-mysql8/ integrations/indexers-pgsql integrations/indexers-sqlite \
|
||||||
integrations/indexers-mssql integrations/mysql.ini integrations/mysql8.ini integrations/pgsql.ini integrations/mssql.ini man/
|
integrations/indexers-mssql integrations/mysql.ini integrations/mysql8.ini integrations/pgsql.ini integrations/mssql.ini
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
|
@ -243,7 +232,7 @@ fmt:
|
||||||
vet:
|
vet:
|
||||||
@echo "Running go vet..."
|
@echo "Running go vet..."
|
||||||
@$(GO) vet $(GO_PACKAGES)
|
@$(GO) vet $(GO_PACKAGES)
|
||||||
@GOOS= GOARCH= $(GO) build -mod=vendor code.gitea.io/gitea-vet
|
@$(GO) build -mod=vendor code.gitea.io/gitea-vet
|
||||||
@$(GO) vet -vettool=gitea-vet $(GO_PACKAGES)
|
@$(GO) vet -vettool=gitea-vet $(GO_PACKAGES)
|
||||||
|
|
||||||
.PHONY: $(TAGS_EVIDENCE)
|
.PHONY: $(TAGS_EVIDENCE)
|
||||||
|
@ -286,10 +275,7 @@ errcheck:
|
||||||
|
|
||||||
.PHONY: revive
|
.PHONY: revive
|
||||||
revive:
|
revive:
|
||||||
@hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
GO111MODULE=on $(GO) run -mod=vendor build/lint.go -config .revive.toml -exclude=./vendor/... ./... || exit 1
|
||||||
GO111MODULE=off $(GO) get -u github.com/mgechev/revive; \
|
|
||||||
fi
|
|
||||||
@revive -config .revive.toml -exclude=./vendor/... ./...
|
|
||||||
|
|
||||||
.PHONY: misspell-check
|
.PHONY: misspell-check
|
||||||
misspell-check:
|
misspell-check:
|
||||||
|
@ -297,7 +283,7 @@ misspell-check:
|
||||||
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
||||||
fi
|
fi
|
||||||
@echo "Running misspell-check..."
|
@echo "Running misspell-check..."
|
||||||
@misspell -error -i unknwon $(GO_SOURCES_OWN)
|
@misspell -error -i unknwon,destory $(GO_SOURCES_OWN)
|
||||||
|
|
||||||
.PHONY: misspell
|
.PHONY: misspell
|
||||||
misspell:
|
misspell:
|
||||||
|
@ -331,9 +317,8 @@ 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 web_src/js build templates *.config.js
|
npx eslint --color --max-warnings=0 web_src/js build templates webpack.config.js
|
||||||
npx stylelint --color --max-warnings=0 web_src/less
|
npx stylelint --color --max-warnings=0 web_src/less
|
||||||
npx editorconfig-checker templates
|
|
||||||
|
|
||||||
.PHONY: lint-backend
|
.PHONY: lint-backend
|
||||||
lint-backend: golangci-lint revive vet
|
lint-backend: golangci-lint revive vet
|
||||||
|
@ -355,23 +340,16 @@ watch-backend: go-check
|
||||||
air -c .air.conf
|
air -c .air.conf
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: test-frontend test-backend
|
test:
|
||||||
|
@echo "Running go test with -tags '$(TEST_TAGS)'..."
|
||||||
.PHONY: test-backend
|
|
||||||
test-backend:
|
|
||||||
@echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..."
|
|
||||||
@$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='$(TEST_TAGS)' $(GO_PACKAGES)
|
@$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='$(TEST_TAGS)' $(GO_PACKAGES)
|
||||||
|
|
||||||
.PHONY: test-frontend
|
|
||||||
test-frontend: node_modules
|
|
||||||
@NODE_OPTIONS="--experimental-vm-modules --no-warnings" npx jest --color
|
|
||||||
|
|
||||||
.PHONY: test-check
|
.PHONY: test-check
|
||||||
test-check:
|
test-check:
|
||||||
@echo "Running test-check...";
|
@echo "Running test-check...";
|
||||||
@diff=$$(git status -s); \
|
@diff=$$(git status -s); \
|
||||||
if [ -n "$$diff" ]; then \
|
if [ -n "$$diff" ]; then \
|
||||||
echo "make test-backend has changed files in the source tree:"; \
|
echo "make test has changed files in the source tree:"; \
|
||||||
echo "$${diff}"; \
|
echo "$${diff}"; \
|
||||||
echo "You should change the tests to create these files in a temporary directory."; \
|
echo "You should change the tests to create these files in a temporary directory."; \
|
||||||
echo "Do not simply add these files to .gitignore"; \
|
echo "Do not simply add these files to .gitignore"; \
|
||||||
|
@ -381,17 +359,15 @@ test-check:
|
||||||
.PHONY: test\#%
|
.PHONY: test\#%
|
||||||
test\#%:
|
test\#%:
|
||||||
@echo "Running go test with -tags '$(TEST_TAGS)'..."
|
@echo "Running go test with -tags '$(TEST_TAGS)'..."
|
||||||
@$(GO) test -mod=vendor $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_PACKAGES)
|
@$(GO) test -mod=vendor -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_PACKAGES)
|
||||||
|
|
||||||
.PHONY: coverage
|
.PHONY: coverage
|
||||||
coverage:
|
coverage:
|
||||||
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' coverage.out > coverage-bodged.out
|
GO111MODULE=on $(GO) run -mod=vendor build/gocovmerge.go integration.coverage.out $(shell find . -type f -name "coverage.out") > coverage.all
|
||||||
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' integration.coverage.out > integration.coverage-bodged.out
|
|
||||||
GO111MODULE=on $(GO) run -mod=vendor build/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all || (echo "gocovmerge failed"; echo "integration.coverage.out"; cat integration.coverage.out; echo "coverage.out"; cat coverage.out; exit 1)
|
|
||||||
|
|
||||||
.PHONY: unit-test-coverage
|
.PHONY: unit-test-coverage
|
||||||
unit-test-coverage:
|
unit-test-coverage:
|
||||||
@echo "Running unit-test-coverage $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..."
|
@echo "Running unit-test-coverage -tags '$(TEST_TAGS)'..."
|
||||||
@$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
|
@$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
|
||||||
|
|
||||||
.PHONY: vendor
|
.PHONY: vendor
|
||||||
|
@ -420,9 +396,8 @@ test-sqlite\#%: integrations.sqlite.test generate-ini-sqlite
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*)
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*)
|
||||||
|
|
||||||
.PHONY: test-sqlite-migration
|
.PHONY: test-sqlite-migration
|
||||||
test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test generate-ini-sqlite
|
test-sqlite-migration: migrations.sqlite.test generate-ini-sqlite
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.sqlite.test
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.sqlite.test
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.individual.sqlite.test
|
|
||||||
|
|
||||||
generate-ini-mysql:
|
generate-ini-mysql:
|
||||||
sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \
|
sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \
|
||||||
|
@ -441,9 +416,8 @@ test-mysql\#%: integrations.mysql.test generate-ini-mysql
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*)
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*)
|
||||||
|
|
||||||
.PHONY: test-mysql-migration
|
.PHONY: test-mysql-migration
|
||||||
test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test generate-ini-mysql
|
test-mysql-migration: migrations.mysql.test generate-ini-mysql
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./migrations.mysql.test
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./migrations.mysql.test
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./migrations.individual.mysql.test
|
|
||||||
|
|
||||||
generate-ini-mysql8:
|
generate-ini-mysql8:
|
||||||
sed -e 's|{{TEST_MYSQL8_HOST}}|${TEST_MYSQL8_HOST}|g' \
|
sed -e 's|{{TEST_MYSQL8_HOST}}|${TEST_MYSQL8_HOST}|g' \
|
||||||
|
@ -462,9 +436,8 @@ test-mysql8\#%: integrations.mysql8.test generate-ini-mysql8
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./integrations.mysql8.test -test.run $(subst .,/,$*)
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./integrations.mysql8.test -test.run $(subst .,/,$*)
|
||||||
|
|
||||||
.PHONY: test-mysql8-migration
|
.PHONY: test-mysql8-migration
|
||||||
test-mysql8-migration: migrations.mysql8.test migrations.individual.mysql8.test generate-ini-mysql8
|
test-mysql8-migration: migrations.mysql8.test generate-ini-mysql8
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./migrations.mysql8.test
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./migrations.mysql8.test
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./migrations.individual.mysql8.test
|
|
||||||
|
|
||||||
generate-ini-pgsql:
|
generate-ini-pgsql:
|
||||||
sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \
|
sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \
|
||||||
|
@ -484,9 +457,8 @@ test-pgsql\#%: integrations.pgsql.test generate-ini-pgsql
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*)
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*)
|
||||||
|
|
||||||
.PHONY: test-pgsql-migration
|
.PHONY: test-pgsql-migration
|
||||||
test-pgsql-migration: migrations.pgsql.test migrations.individual.pgsql.test generate-ini-pgsql
|
test-pgsql-migration: migrations.pgsql.test generate-ini-pgsql
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./migrations.pgsql.test
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./migrations.pgsql.test
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./migrations.individual.pgsql.test
|
|
||||||
|
|
||||||
generate-ini-mssql:
|
generate-ini-mssql:
|
||||||
sed -e 's|{{TEST_MSSQL_HOST}}|${TEST_MSSQL_HOST}|g' \
|
sed -e 's|{{TEST_MSSQL_HOST}}|${TEST_MSSQL_HOST}|g' \
|
||||||
|
@ -505,9 +477,8 @@ test-mssql\#%: integrations.mssql.test generate-ini-mssql
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*)
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*)
|
||||||
|
|
||||||
.PHONY: test-mssql-migration
|
.PHONY: test-mssql-migration
|
||||||
test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test generate-ini-mssql
|
test-mssql-migration: migrations.mssql.test generate-ini-mssql
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./migrations.mssql.test -test.failfast
|
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./migrations.mssql.test -test.failfast
|
||||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./migrations.individual.mssql.test -test.failfast
|
|
||||||
|
|
||||||
.PHONY: bench-sqlite
|
.PHONY: bench-sqlite
|
||||||
bench-sqlite: integrations.sqlite.test generate-ini-sqlite
|
bench-sqlite: integrations.sqlite.test generate-ini-sqlite
|
||||||
|
@ -567,26 +538,6 @@ migrations.mssql.test: $(GO_SOURCES)
|
||||||
migrations.sqlite.test: $(GO_SOURCES)
|
migrations.sqlite.test: $(GO_SOURCES)
|
||||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)'
|
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)'
|
||||||
|
|
||||||
.PHONY: migrations.individual.mysql.test
|
|
||||||
migrations.individual.mysql.test: $(GO_SOURCES)
|
|
||||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.mysql.test
|
|
||||||
|
|
||||||
.PHONY: migrations.individual.mysql8.test
|
|
||||||
migrations.individual.mysql8.test: $(GO_SOURCES)
|
|
||||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.mysql8.test
|
|
||||||
|
|
||||||
.PHONY: migrations.individual.pgsql.test
|
|
||||||
migrations.individual.pgsql.test: $(GO_SOURCES)
|
|
||||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.pgsql.test
|
|
||||||
|
|
||||||
.PHONY: migrations.individual.mssql.test
|
|
||||||
migrations.individual.mssql.test: $(GO_SOURCES)
|
|
||||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.mssql.test
|
|
||||||
|
|
||||||
.PHONY: migrations.individual.sqlite.test
|
|
||||||
migrations.individual.sqlite.test: $(GO_SOURCES)
|
|
||||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.sqlite.test -tags '$(TEST_TAGS)'
|
|
||||||
|
|
||||||
.PHONY: check
|
.PHONY: check
|
||||||
check: test
|
check: test
|
||||||
|
|
||||||
|
@ -598,7 +549,7 @@ install: $(wildcard *.go)
|
||||||
build: frontend backend
|
build: frontend backend
|
||||||
|
|
||||||
.PHONY: frontend
|
.PHONY: frontend
|
||||||
frontend: $(WEBPACK_DEST)
|
frontend: node-check $(WEBPACK_DEST)
|
||||||
|
|
||||||
.PHONY: backend
|
.PHONY: backend
|
||||||
backend: go-check generate $(EXECUTABLE)
|
backend: go-check generate $(EXECUTABLE)
|
||||||
|
@ -620,12 +571,10 @@ $(DIST_DIRS):
|
||||||
.PHONY: release-windows
|
.PHONY: release-windows
|
||||||
release-windows: | $(DIST_DIRS)
|
release-windows: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) install src.techknowlogick.com/xgo@latest; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
@echo "Warning: windows version is built using golang 1.14"
|
||||||
ifeq (,$(findstring gogit,$(TAGS)))
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
|
|
||||||
endif
|
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
cp /build/* $(DIST)/binaries
|
cp /build/* $(DIST)/binaries
|
||||||
endif
|
endif
|
||||||
|
@ -633,9 +582,9 @@ endif
|
||||||
.PHONY: release-linux
|
.PHONY: release-linux
|
||||||
release-linux: | $(DIST_DIRS)
|
release-linux: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) install src.techknowlogick.com/xgo@latest; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
cp /build/* $(DIST)/binaries
|
cp /build/* $(DIST)/binaries
|
||||||
endif
|
endif
|
||||||
|
@ -643,9 +592,9 @@ endif
|
||||||
.PHONY: release-darwin
|
.PHONY: release-darwin
|
||||||
release-darwin: | $(DIST_DIRS)
|
release-darwin: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) install src.techknowlogick.com/xgo@latest; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
cp /build/* $(DIST)/binaries
|
cp /build/* $(DIST)/binaries
|
||||||
endif
|
endif
|
||||||
|
@ -666,11 +615,9 @@ release-compress: | $(DIST_DIRS)
|
||||||
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done;
|
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done;
|
||||||
|
|
||||||
.PHONY: release-sources
|
.PHONY: release-sources
|
||||||
release-sources: | $(DIST_DIRS)
|
release-sources: | $(DIST_DIRS) node_modules
|
||||||
echo $(VERSION) > $(STORED_VERSION_FILE)
|
echo $(VERSION) > $(STORED_VERSION_FILE)
|
||||||
# bsdtar needs a ^ to prevent matching subdirectories
|
tar --exclude=./$(DIST) --exclude=./.git --exclude=./$(MAKE_EVIDENCE_DIR) --exclude=./node_modules/.cache --exclude=./$(AIR_TMP_DIR) -czf $(DIST)/release/gitea-src-$(VERSION).tar.gz .
|
||||||
$(eval EXCL := --exclude=$(shell tar --help | grep -q bsdtar && echo "^")./)
|
|
||||||
tar $(addprefix $(EXCL),$(TAR_EXCLUDES)) -czf $(DIST)/release/gitea-src-$(VERSION).tar.gz .
|
|
||||||
rm -f $(STORED_VERSION_FILE)
|
rm -f $(STORED_VERSION_FILE)
|
||||||
|
|
||||||
.PHONY: release-docs
|
.PHONY: release-docs
|
||||||
|
@ -696,20 +643,22 @@ npm-update: node-check | node_modules
|
||||||
@touch node_modules
|
@touch node_modules
|
||||||
|
|
||||||
.PHONY: fomantic
|
.PHONY: fomantic
|
||||||
fomantic:
|
fomantic: $(FOMANTIC_DEST)
|
||||||
rm -rf $(FOMANTIC_WORK_DIR)/build
|
|
||||||
cd $(FOMANTIC_WORK_DIR) && npm install --no-save
|
$(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) | node_modules
|
||||||
cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config
|
@if [ ! -d node_modules/fomantic-ui ]; then \
|
||||||
cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/
|
npm install --no-save --no-package-lock fomantic-ui@2.8.7; \
|
||||||
cp -f web_src/js/vendor/dropdown.js $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/definitions/modules
|
fi
|
||||||
cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build
|
rm -rf $(FOMANTIC_DEST_DIR)
|
||||||
rm -f $(FOMANTIC_WORK_DIR)/build/*.min.*
|
cp -f web_src/fomantic/theme.config.less node_modules/fomantic-ui/src/theme.config
|
||||||
|
cp -rf web_src/fomantic/_site/* node_modules/fomantic-ui/src/_site/
|
||||||
|
npx gulp -f node_modules/fomantic-ui/gulpfile.js build
|
||||||
|
@touch $(FOMANTIC_DEST)
|
||||||
|
|
||||||
.PHONY: webpack
|
.PHONY: webpack
|
||||||
webpack: $(WEBPACK_DEST)
|
webpack: $(WEBPACK_DEST)
|
||||||
|
|
||||||
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json
|
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules
|
||||||
@$(MAKE) -s node-check node_modules
|
|
||||||
rm -rf $(WEBPACK_DEST_ENTRIES)
|
rm -rf $(WEBPACK_DEST_ENTRIES)
|
||||||
npx webpack
|
npx webpack
|
||||||
@touch $(WEBPACK_DEST)
|
@touch $(WEBPACK_DEST)
|
||||||
|
@ -748,18 +697,10 @@ generate-gitignore:
|
||||||
GO111MODULE=on $(GO) run build/generate-gitignores.go
|
GO111MODULE=on $(GO) run build/generate-gitignores.go
|
||||||
|
|
||||||
.PHONY: generate-images
|
.PHONY: generate-images
|
||||||
generate-images: | node_modules
|
generate-images:
|
||||||
npm install --no-save --no-package-lock fabric@4 imagemin-zopfli@7
|
npm install --no-save --no-package-lock fabric imagemin-zopfli
|
||||||
node build/generate-images.js $(TAGS)
|
node build/generate-images.js $(TAGS)
|
||||||
|
|
||||||
.PHONY: generate-manpage
|
|
||||||
generate-manpage:
|
|
||||||
@[ -f gitea ] || make backend
|
|
||||||
@mkdir -p man/man1/ man/man5
|
|
||||||
@./gitea docs --man > man/man1/gitea.1
|
|
||||||
@gzip -9 man/man1/gitea.1 && echo man/man1/gitea.1.gz created
|
|
||||||
@#TODO A smal script witch format config-cheat-sheet.en-us.md nicely to suit as config man page
|
|
||||||
|
|
||||||
.PHONY: pr\#%
|
.PHONY: pr\#%
|
||||||
pr\#%: clean-all
|
pr\#%: clean-all
|
||||||
$(GO) run contrib/pr/checkout.go $*
|
$(GO) run contrib/pr/checkout.go $*
|
||||||
|
@ -768,7 +709,7 @@ pr\#%: clean-all
|
||||||
golangci-lint:
|
golangci-lint:
|
||||||
@hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
export BINARY="golangci-lint"; \
|
export BINARY="golangci-lint"; \
|
||||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.37.0; \
|
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.31.0; \
|
||||||
fi
|
fi
|
||||||
golangci-lint run --timeout 10m
|
golangci-lint run --timeout 10m
|
||||||
|
|
||||||
|
|
38
README.md
38
README.md
|
@ -1,21 +1,24 @@
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://gitea.io/">
|
<a href="https://gitea.io/">
|
||||||
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/main/public/img/gitea.svg" width="220"/>
|
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea.svg" width="220"/>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<h1 align="center">Gitea - Git with a cup of tea</h1>
|
<h1 align="center">Gitea - Git with a cup of tea</h1>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://drone.gitea.io/go-gitea/gitea" title="Build Status">
|
<a href="https://drone.gitea.io/go-gitea/gitea" title="Build Status">
|
||||||
<img src="https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg?ref=refs/heads/main">
|
<img src="https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg?ref=refs/heads/master">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
|
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
|
||||||
<img src="https://img.shields.io/discord/322538954119184384.svg">
|
<img src="https://img.shields.io/discord/322538954119184384.svg">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov">
|
<a href="https://microbadger.com/images/gitea/gitea" title="Get your own image badge on microbadger.com">
|
||||||
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
|
<img src="https://images.microbadger.com/badges/image/gitea/gitea.svg">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://goreportcard.com/report/code.gitea.io/gitea" title="Go Report Card">
|
<a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov">
|
||||||
|
<img src="https://codecov.io/gh/go-gitea/gitea/branch/master/graph/badge.svg">
|
||||||
|
</a>
|
||||||
|
<a href="https://godoc.org/code.gitea.io/gitea" title="Go Report Card">
|
||||||
<img src="https://goreportcard.com/badge/code.gitea.io/gitea">
|
<img src="https://goreportcard.com/badge/code.gitea.io/gitea">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc">
|
<a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc">
|
||||||
|
@ -39,9 +42,6 @@
|
||||||
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea" title="TODOs">
|
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea" title="TODOs">
|
||||||
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea">
|
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.bountysource.com/teams/gitea" title="Bountysource">
|
|
||||||
<img src="https://img.shields.io/bountysource/team/gitea/activity">
|
|
||||||
</a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -73,12 +73,14 @@ or if sqlite support is required:
|
||||||
|
|
||||||
The `build` target is split into two sub-targets:
|
The `build` target is split into two sub-targets:
|
||||||
|
|
||||||
- `make backend` which requires [Go 1.16](https://golang.org/dl/) or greater.
|
- `make backend` which requires [Go 1.13](https://golang.org/dl/) or greater.
|
||||||
- `make frontend` which requires [Node.js 12.17](https://nodejs.org/en/download/) or greater and Internet connectivity to download npm dependencies.
|
- `make frontend` which requires [Node.js 10.13](https://nodejs.org/en/download/) or greater.
|
||||||
|
|
||||||
When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js and Internet connectivity.
|
If pre-built frontend files are present it is possible to only build the backend:
|
||||||
|
|
||||||
Parallelism (`make -j <num>`) is not supported.
|
TAGS="bindata" make backend
|
||||||
|
|
||||||
|
Parallelism is not supported for these targets, so please don't include `-j <num>`.
|
||||||
|
|
||||||
More info: https://docs.gitea.io/en-us/install-from-source/
|
More info: https://docs.gitea.io/en-us/install-from-source/
|
||||||
|
|
||||||
|
@ -98,16 +100,6 @@ NOTES:
|
||||||
1. **YOU MUST READ THE [CONTRIBUTORS GUIDE](CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST.**
|
1. **YOU MUST READ THE [CONTRIBUTORS GUIDE](CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST.**
|
||||||
2. If you have found a vulnerability in the project, please write privately to **security@gitea.io**. Thanks!
|
2. If you have found a vulnerability in the project, please write privately to **security@gitea.io**. Thanks!
|
||||||
|
|
||||||
## Translating
|
|
||||||
|
|
||||||
Translations are done through Crowdin. If you want to translate to a new language ask one of the managers in the Crowdin project to add a new language there.
|
|
||||||
|
|
||||||
You can also just create an issue for adding a language or ask on discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty but we hope fo fill it as questions pop up.
|
|
||||||
|
|
||||||
https://docs.gitea.io/en-us/translation-guidelines/
|
|
||||||
|
|
||||||
[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea)
|
|
||||||
|
|
||||||
## Further information
|
## Further information
|
||||||
|
|
||||||
For more information and instructions about how to install Gitea, please look at our [documentation](https://docs.gitea.io/en-us/).
|
For more information and instructions about how to install Gitea, please look at our [documentation](https://docs.gitea.io/en-us/).
|
||||||
|
@ -157,7 +149,7 @@ We're [working on it](https://github.com/go-gitea/gitea/issues/1029).
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the MIT License.
|
This project is licensed under the MIT License.
|
||||||
See the [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) file
|
See the [LICENSE](https://github.com/go-gitea/gitea/blob/master/LICENSE) file
|
||||||
for the full license text.
|
for the full license text.
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
23
README_ZH.md
23
README_ZH.md
|
@ -1,21 +1,24 @@
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://gitea.io/">
|
<a href="https://gitea.io/">
|
||||||
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/main/public/img/gitea.svg" width="220"/>
|
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea.svg" width="220"/>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<h1 align="center">Gitea - Git with a cup of tea</h1>
|
<h1 align="center">Gitea - Git with a cup of tea</h1>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://drone.gitea.io/go-gitea/gitea" title="Build Status">
|
<a href="https://drone.gitea.io/go-gitea/gitea" title="Build Status">
|
||||||
<img src="https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg?ref=refs/heads/main">
|
<img src="https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg?ref=refs/heads/master">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
|
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
|
||||||
<img src="https://img.shields.io/discord/322538954119184384.svg">
|
<img src="https://img.shields.io/discord/322538954119184384.svg">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov">
|
<a href="https://microbadger.com/images/gitea/gitea" title="Get your own image badge on microbadger.com">
|
||||||
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
|
<img src="https://images.microbadger.com/badges/image/gitea/gitea.svg">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://goreportcard.com/report/code.gitea.io/gitea" title="Go Report Card">
|
<a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov">
|
||||||
|
<img src="https://codecov.io/gh/go-gitea/gitea/branch/master/graph/badge.svg">
|
||||||
|
</a>
|
||||||
|
<a href="https://godoc.org/code.gitea.io/gitea" title="Go Report Card">
|
||||||
<img src="https://goreportcard.com/badge/code.gitea.io/gitea">
|
<img src="https://goreportcard.com/badge/code.gitea.io/gitea">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc">
|
<a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc">
|
||||||
|
@ -39,9 +42,6 @@
|
||||||
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea" title="TODOs">
|
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea" title="TODOs">
|
||||||
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea">
|
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://img.shields.io/bountysource/team/gitea" title="Bountysource">
|
|
||||||
<img src="https://img.shields.io/bountysource/team/gitea/activity">
|
|
||||||
</a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -68,11 +68,6 @@ Gitea 的首要目标是创建一个极易安装,运行非常快速,安装
|
||||||
|
|
||||||
Fork -> Patch -> Push -> Pull Request
|
Fork -> Patch -> Push -> Pull Request
|
||||||
|
|
||||||
## 翻译
|
|
||||||
|
|
||||||
多语言翻译是基于Crowdin进行的.
|
|
||||||
[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea)
|
|
||||||
|
|
||||||
## 作者
|
## 作者
|
||||||
|
|
||||||
* [Maintainers](https://github.com/orgs/go-gitea/people)
|
* [Maintainers](https://github.com/orgs/go-gitea/people)
|
||||||
|
@ -81,7 +76,7 @@ Fork -> Patch -> Push -> Pull Request
|
||||||
|
|
||||||
## 授权许可
|
## 授权许可
|
||||||
|
|
||||||
本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) 文件中。
|
本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/go-gitea/gitea/blob/master/LICENSE) 文件中。
|
||||||
|
|
||||||
## 截图
|
## 截图
|
||||||
|
|
||||||
|
|
11
build.go
11
build.go
|
@ -2,8 +2,7 @@
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build vendor
|
//+build vendor
|
||||||
// +build vendor
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -11,6 +10,14 @@ package main
|
||||||
// These libraries will not be included in a normal compilation.
|
// These libraries will not be included in a normal compilation.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
// for lint
|
||||||
|
_ "github.com/mgechev/dots"
|
||||||
|
_ "github.com/mgechev/revive/formatter"
|
||||||
|
_ "github.com/mgechev/revive/lint"
|
||||||
|
_ "github.com/mgechev/revive/rule"
|
||||||
|
_ "github.com/mitchellh/go-homedir"
|
||||||
|
_ "github.com/pelletier/go-toml"
|
||||||
|
|
||||||
// for embed
|
// for embed
|
||||||
_ "github.com/shurcooL/vfsgen"
|
_ "github.com/shurcooL/vfsgen"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build ignore
|
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build ignore
|
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/format"
|
"go/format"
|
||||||
|
@ -20,8 +20,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/json"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -176,7 +174,7 @@ func generate() ([]byte, error) {
|
||||||
s = append(s, k)
|
s = append(s, k)
|
||||||
} else {
|
} else {
|
||||||
// insert into slice after first element because all emoji that support skin tones
|
// insert into slice after first element because all emoji that support skin tones
|
||||||
// have that modifier placed at this spot
|
// have that modifer placed at this spot
|
||||||
s = append(s, "")
|
s = append(s, "")
|
||||||
copy(s[2:], s[1:])
|
copy(s[2:], s[1:])
|
||||||
s[1] = k
|
s[1] = k
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
//go:build ignore
|
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import imageminZopfli from 'imagemin-zopfli';
|
#!/usr/bin/env node
|
||||||
import {optimize, extendDefaultPlugins} from 'svgo';
|
'use strict';
|
||||||
import {fabric} from 'fabric';
|
|
||||||
import fs from 'fs';
|
const imageminZopfli = require('imagemin-zopfli');
|
||||||
import {resolve, dirname} from 'path';
|
const Svgo = require('svgo');
|
||||||
import {fileURLToPath} from 'url';
|
const {fabric} = require('fabric');
|
||||||
|
const {readFile, writeFile} = require('fs').promises;
|
||||||
|
const {resolve} = require('path');
|
||||||
|
|
||||||
const {readFile, writeFile} = fs.promises;
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
||||||
const logoFile = resolve(__dirname, '../assets/logo.svg');
|
const logoFile = resolve(__dirname, '../assets/logo.svg');
|
||||||
|
|
||||||
function exit(err) {
|
function exit(err) {
|
||||||
|
@ -24,15 +24,14 @@ function loadSvg(svg) {
|
||||||
|
|
||||||
async function generate(svg, outputFile, {size, bg}) {
|
async function generate(svg, outputFile, {size, bg}) {
|
||||||
if (outputFile.endsWith('.svg')) {
|
if (outputFile.endsWith('.svg')) {
|
||||||
const {data} = optimize(svg, {
|
const svgo = new Svgo({
|
||||||
plugins: extendDefaultPlugins([
|
plugins: [
|
||||||
'removeDimensions',
|
{removeDimensions: true},
|
||||||
{
|
{addAttributesToSVGElement: {attributes: [{width: size}, {height: size}]}},
|
||||||
name: 'addAttributesToSVGElement',
|
],
|
||||||
params: {attributes: [{width: size}, {height: size}]}
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const {data} = await svgo.optimize(svg);
|
||||||
await writeFile(outputFile, data);
|
await writeFile(outputFile, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
//go:build ignore
|
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import fastGlob from 'fast-glob';
|
#!/usr/bin/env node
|
||||||
import {optimize} from 'svgo';
|
'use strict';
|
||||||
import {resolve, parse, dirname} from 'path';
|
|
||||||
import fs from 'fs';
|
const fastGlob = require('fast-glob');
|
||||||
import {fileURLToPath} from 'url';
|
const Svgo = require('svgo');
|
||||||
|
const {resolve, parse} = require('path');
|
||||||
|
const {readFile, writeFile, mkdir} = require('fs').promises;
|
||||||
|
|
||||||
const {readFile, writeFile, mkdir} = fs.promises;
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
||||||
const glob = (pattern) => fastGlob.sync(pattern, {cwd: resolve(__dirname), absolute: true});
|
const glob = (pattern) => fastGlob.sync(pattern, {cwd: resolve(__dirname), absolute: true});
|
||||||
const outputDir = resolve(__dirname, '../public/img/svg');
|
const outputDir = resolve(__dirname, '../public/img/svg');
|
||||||
|
|
||||||
|
@ -25,15 +25,31 @@ async function processFile(file, {prefix, fullName} = {}) {
|
||||||
if (prefix === 'octicon') name = name.replace(/-[0-9]+$/, ''); // chop of '-16' on octicons
|
if (prefix === 'octicon') name = name.replace(/-[0-9]+$/, ''); // chop of '-16' on octicons
|
||||||
}
|
}
|
||||||
|
|
||||||
const {data} = optimize(await readFile(file, 'utf8'), {
|
const svgo = new Svgo({
|
||||||
plugins: [
|
plugins: [
|
||||||
{name: 'preset-default'},
|
{removeXMLNS: true},
|
||||||
{name: 'removeXMLNS'},
|
{removeDimensions: true},
|
||||||
{name: 'removeDimensions'},
|
{
|
||||||
{name: 'addClassesToSVGElement', params: {classNames: ['svg', name]}},
|
addClassesToSVGElement: {
|
||||||
{name: 'addAttributesToSVGElement', params: {attributes: [{'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}]}},
|
classNames: [
|
||||||
|
'svg',
|
||||||
|
name,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
addAttributesToSVGElement: {
|
||||||
|
attributes: [
|
||||||
|
{'width': '16'},
|
||||||
|
{'height': '16'},
|
||||||
|
{'aria-hidden': 'true'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const {data} = await svgo.optimize(await readFile(file, 'utf8'));
|
||||||
await writeFile(resolve(outputDir, `${name}.svg`), data);
|
await writeFile(resolve(outputDir, `${name}.svg`), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +65,7 @@ async function main() {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
...processFiles('../node_modules/@primer/octicons/build/svg/*-16.svg', {prefix: 'octicon'}),
|
...processFiles('../node_modules/@primer/octicons/build/svg/*-16.svg', {prefix: 'octicon'}),
|
||||||
...processFiles('../web_src/svg/*.svg'),
|
...processFiles('../web_src/svg/*.svg'),
|
||||||
...processFiles('../public/img/gitea.svg', {fullName: 'gitea-gitea'}),
|
...processFiles('../assets/logo.svg', {fullName: 'gitea-gitea'}),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
// gocovmerge takes the results from multiple `go test -coverprofile` runs and
|
// gocovmerge takes the results from multiple `go test -coverprofile` runs and
|
||||||
// merges them into one profile
|
// merges them into one profile
|
||||||
|
|
||||||
//go:build ignore
|
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
@ -109,7 +108,7 @@ func main() {
|
||||||
for _, file := range flag.Args() {
|
for _, file := range flag.Args() {
|
||||||
profiles, err := cover.ParseProfiles(file)
|
profiles, err := cover.ParseProfiles(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to parse profile '%s': %v", file, err)
|
log.Fatalf("failed to parse profiles: %v", err)
|
||||||
}
|
}
|
||||||
for _, p := range profiles {
|
for _, p := range profiles {
|
||||||
merged = addProfile(merged, p)
|
merged = addProfile(merged, p)
|
||||||
|
|
|
@ -0,0 +1,325 @@
|
||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Copyright (c) 2018 Minko Gechev. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mgechev/dots"
|
||||||
|
"github.com/mgechev/revive/formatter"
|
||||||
|
"github.com/mgechev/revive/lint"
|
||||||
|
"github.com/mgechev/revive/rule"
|
||||||
|
"github.com/mitchellh/go-homedir"
|
||||||
|
"github.com/pelletier/go-toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
func fail(err string) {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultRules = []lint.Rule{
|
||||||
|
&rule.VarDeclarationsRule{},
|
||||||
|
&rule.PackageCommentsRule{},
|
||||||
|
&rule.DotImportsRule{},
|
||||||
|
&rule.BlankImportsRule{},
|
||||||
|
&rule.ExportedRule{},
|
||||||
|
&rule.VarNamingRule{},
|
||||||
|
&rule.IndentErrorFlowRule{},
|
||||||
|
&rule.IfReturnRule{},
|
||||||
|
&rule.RangeRule{},
|
||||||
|
&rule.ErrorfRule{},
|
||||||
|
&rule.ErrorNamingRule{},
|
||||||
|
&rule.ErrorStringsRule{},
|
||||||
|
&rule.ReceiverNamingRule{},
|
||||||
|
&rule.IncrementDecrementRule{},
|
||||||
|
&rule.ErrorReturnRule{},
|
||||||
|
&rule.UnexportedReturnRule{},
|
||||||
|
&rule.TimeNamingRule{},
|
||||||
|
&rule.ContextKeysType{},
|
||||||
|
&rule.ContextAsArgumentRule{},
|
||||||
|
}
|
||||||
|
|
||||||
|
var allRules = append([]lint.Rule{
|
||||||
|
&rule.ArgumentsLimitRule{},
|
||||||
|
&rule.CyclomaticRule{},
|
||||||
|
&rule.FileHeaderRule{},
|
||||||
|
&rule.EmptyBlockRule{},
|
||||||
|
&rule.SuperfluousElseRule{},
|
||||||
|
&rule.ConfusingNamingRule{},
|
||||||
|
&rule.GetReturnRule{},
|
||||||
|
&rule.ModifiesParamRule{},
|
||||||
|
&rule.ConfusingResultsRule{},
|
||||||
|
&rule.DeepExitRule{},
|
||||||
|
&rule.UnusedParamRule{},
|
||||||
|
&rule.UnreachableCodeRule{},
|
||||||
|
&rule.AddConstantRule{},
|
||||||
|
&rule.FlagParamRule{},
|
||||||
|
&rule.UnnecessaryStmtRule{},
|
||||||
|
&rule.StructTagRule{},
|
||||||
|
&rule.ModifiesValRecRule{},
|
||||||
|
&rule.ConstantLogicalExprRule{},
|
||||||
|
&rule.BoolLiteralRule{},
|
||||||
|
&rule.RedefinesBuiltinIDRule{},
|
||||||
|
&rule.ImportsBlacklistRule{},
|
||||||
|
&rule.FunctionResultsLimitRule{},
|
||||||
|
&rule.MaxPublicStructsRule{},
|
||||||
|
&rule.RangeValInClosureRule{},
|
||||||
|
&rule.RangeValAddress{},
|
||||||
|
&rule.WaitGroupByValueRule{},
|
||||||
|
&rule.AtomicRule{},
|
||||||
|
&rule.EmptyLinesRule{},
|
||||||
|
&rule.LineLengthLimitRule{},
|
||||||
|
&rule.CallToGCRule{},
|
||||||
|
&rule.DuplicatedImportsRule{},
|
||||||
|
&rule.ImportShadowingRule{},
|
||||||
|
&rule.BareReturnRule{},
|
||||||
|
&rule.UnusedReceiverRule{},
|
||||||
|
&rule.UnhandledErrorRule{},
|
||||||
|
&rule.CognitiveComplexityRule{},
|
||||||
|
&rule.StringOfIntRule{},
|
||||||
|
}, defaultRules...)
|
||||||
|
|
||||||
|
var allFormatters = []lint.Formatter{
|
||||||
|
&formatter.Stylish{},
|
||||||
|
&formatter.Friendly{},
|
||||||
|
&formatter.JSON{},
|
||||||
|
&formatter.NDJSON{},
|
||||||
|
&formatter.Default{},
|
||||||
|
&formatter.Unix{},
|
||||||
|
&formatter.Checkstyle{},
|
||||||
|
&formatter.Plain{},
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFormatters() map[string]lint.Formatter {
|
||||||
|
result := map[string]lint.Formatter{}
|
||||||
|
for _, f := range allFormatters {
|
||||||
|
result[f.Name()] = f
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLintingRules(config *lint.Config) []lint.Rule {
|
||||||
|
rulesMap := map[string]lint.Rule{}
|
||||||
|
for _, r := range allRules {
|
||||||
|
rulesMap[r.Name()] = r
|
||||||
|
}
|
||||||
|
|
||||||
|
lintingRules := []lint.Rule{}
|
||||||
|
for name := range config.Rules {
|
||||||
|
rule, ok := rulesMap[name]
|
||||||
|
if !ok {
|
||||||
|
fail("cannot find rule: " + name)
|
||||||
|
}
|
||||||
|
lintingRules = append(lintingRules, rule)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lintingRules
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseConfig(path string) *lint.Config {
|
||||||
|
config := &lint.Config{}
|
||||||
|
file, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
fail("cannot read the config file")
|
||||||
|
}
|
||||||
|
err = toml.Unmarshal(file, config)
|
||||||
|
if err != nil {
|
||||||
|
fail("cannot parse the config file: " + err.Error())
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeConfig(config *lint.Config) {
|
||||||
|
if config.Confidence == 0 {
|
||||||
|
config.Confidence = 0.8
|
||||||
|
}
|
||||||
|
severity := config.Severity
|
||||||
|
if severity != "" {
|
||||||
|
for k, v := range config.Rules {
|
||||||
|
if v.Severity == "" {
|
||||||
|
v.Severity = severity
|
||||||
|
}
|
||||||
|
config.Rules[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range config.Directives {
|
||||||
|
if v.Severity == "" {
|
||||||
|
v.Severity = severity
|
||||||
|
}
|
||||||
|
config.Directives[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConfig() *lint.Config {
|
||||||
|
config := defaultConfig()
|
||||||
|
if configPath != "" {
|
||||||
|
config = parseConfig(configPath)
|
||||||
|
}
|
||||||
|
normalizeConfig(config)
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFormatter() lint.Formatter {
|
||||||
|
formatters := getFormatters()
|
||||||
|
formatter := formatters["default"]
|
||||||
|
if formatterName != "" {
|
||||||
|
f, ok := formatters[formatterName]
|
||||||
|
if !ok {
|
||||||
|
fail("unknown formatter " + formatterName)
|
||||||
|
}
|
||||||
|
formatter = f
|
||||||
|
}
|
||||||
|
return formatter
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildDefaultConfigPath() string {
|
||||||
|
var result string
|
||||||
|
if homeDir, err := homedir.Dir(); err == nil {
|
||||||
|
result = filepath.Join(homeDir, "revive.toml")
|
||||||
|
if _, err := os.Stat(result); err != nil {
|
||||||
|
result = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultConfig() *lint.Config {
|
||||||
|
defaultConfig := lint.Config{
|
||||||
|
Confidence: 0.0,
|
||||||
|
Severity: lint.SeverityWarning,
|
||||||
|
Rules: map[string]lint.RuleConfig{},
|
||||||
|
}
|
||||||
|
for _, r := range defaultRules {
|
||||||
|
defaultConfig.Rules[r.Name()] = lint.RuleConfig{}
|
||||||
|
}
|
||||||
|
return &defaultConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeSplit(strs []string) []string {
|
||||||
|
res := []string{}
|
||||||
|
for _, s := range strs {
|
||||||
|
t := strings.Trim(s, " \t")
|
||||||
|
if len(t) > 0 {
|
||||||
|
res = append(res, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPackages() [][]string {
|
||||||
|
globs := normalizeSplit(flag.Args())
|
||||||
|
if len(globs) == 0 {
|
||||||
|
globs = append(globs, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
packages, err := dots.ResolvePackages(globs, normalizeSplit(excludePaths))
|
||||||
|
if err != nil {
|
||||||
|
fail(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return packages
|
||||||
|
}
|
||||||
|
|
||||||
|
type arrayFlags []string
|
||||||
|
|
||||||
|
func (i *arrayFlags) String() string {
|
||||||
|
return strings.Join([]string(*i), " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *arrayFlags) Set(value string) error {
|
||||||
|
*i = append(*i, value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var configPath string
|
||||||
|
var excludePaths arrayFlags
|
||||||
|
var formatterName string
|
||||||
|
var help bool
|
||||||
|
|
||||||
|
var originalUsage = flag.Usage
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Usage = func() {
|
||||||
|
originalUsage()
|
||||||
|
}
|
||||||
|
// command line help strings
|
||||||
|
const (
|
||||||
|
configUsage = "path to the configuration TOML file, defaults to $HOME/revive.toml, if present (i.e. -config myconf.toml)"
|
||||||
|
excludeUsage = "list of globs which specify files to be excluded (i.e. -exclude foo/...)"
|
||||||
|
formatterUsage = "formatter to be used for the output (i.e. -formatter stylish)"
|
||||||
|
)
|
||||||
|
|
||||||
|
defaultConfigPath := buildDefaultConfigPath()
|
||||||
|
|
||||||
|
flag.StringVar(&configPath, "config", defaultConfigPath, configUsage)
|
||||||
|
flag.Var(&excludePaths, "exclude", excludeUsage)
|
||||||
|
flag.StringVar(&formatterName, "formatter", "", formatterUsage)
|
||||||
|
flag.Parse()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
config := getConfig()
|
||||||
|
formatter := getFormatter()
|
||||||
|
packages := getPackages()
|
||||||
|
|
||||||
|
revive := lint.New(func(file string) ([]byte, error) {
|
||||||
|
return ioutil.ReadFile(file)
|
||||||
|
})
|
||||||
|
|
||||||
|
lintingRules := getLintingRules(config)
|
||||||
|
|
||||||
|
failures, err := revive.Lint(packages, lintingRules, *config)
|
||||||
|
if err != nil {
|
||||||
|
fail(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
formatChan := make(chan lint.Failure)
|
||||||
|
exitChan := make(chan bool)
|
||||||
|
|
||||||
|
var output string
|
||||||
|
go (func() {
|
||||||
|
output, err = formatter.Format(formatChan, *config)
|
||||||
|
if err != nil {
|
||||||
|
fail(err.Error())
|
||||||
|
}
|
||||||
|
exitChan <- true
|
||||||
|
})()
|
||||||
|
|
||||||
|
exitCode := 0
|
||||||
|
for f := range failures {
|
||||||
|
if f.Confidence < config.Confidence {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if exitCode == 0 {
|
||||||
|
exitCode = config.WarningCode
|
||||||
|
}
|
||||||
|
if c, ok := config.Rules[f.RuleName]; ok && c.Severity == lint.SeverityError {
|
||||||
|
exitCode = config.ErrorCode
|
||||||
|
}
|
||||||
|
if c, ok := config.Directives[f.RuleName]; ok && c.Severity == lint.SeverityError {
|
||||||
|
exitCode = config.ErrorCode
|
||||||
|
}
|
||||||
|
|
||||||
|
formatChan <- f
|
||||||
|
}
|
||||||
|
|
||||||
|
close(formatChan)
|
||||||
|
<-exitChan
|
||||||
|
if output != "" {
|
||||||
|
fmt.Println(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Exit(exitCode)
|
||||||
|
}
|
23
cmd/admin.go
23
cmd/admin.go
|
@ -14,14 +14,13 @@ import (
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/auth/oauth2"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
pwd "code.gitea.io/gitea/modules/password"
|
pwd "code.gitea.io/gitea/modules/password"
|
||||||
repo_module "code.gitea.io/gitea/modules/repository"
|
repo_module "code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/storage"
|
|
||||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
@ -490,10 +489,6 @@ func runDeleteUser(c *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := storage.Init(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var user *models.User
|
var user *models.User
|
||||||
if c.IsSet("email") {
|
if c.IsSet("email") {
|
||||||
|
@ -517,7 +512,7 @@ func runDeleteUser(c *cli.Context) error {
|
||||||
return models.DeleteUser(user)
|
return models.DeleteUser(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRepoSyncReleases(_ *cli.Context) error {
|
func runRepoSyncReleases(c *cli.Context) error {
|
||||||
if err := initDB(); err != nil {
|
if err := initDB(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -583,21 +578,21 @@ func getReleaseCount(id int64) (int64, error) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRegenerateHooks(_ *cli.Context) error {
|
func runRegenerateHooks(c *cli.Context) error {
|
||||||
if err := initDB(); err != nil {
|
if err := initDB(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
|
return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRegenerateKeys(_ *cli.Context) error {
|
func runRegenerateKeys(c *cli.Context) error {
|
||||||
if err := initDB(); err != nil {
|
if err := initDB(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return models.RewriteAllPublicKeys()
|
return models.RewriteAllPublicKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
|
func parseOAuth2Config(c *cli.Context) *models.OAuth2Config {
|
||||||
var customURLMapping *oauth2.CustomURLMapping
|
var customURLMapping *oauth2.CustomURLMapping
|
||||||
if c.IsSet("use-custom-urls") {
|
if c.IsSet("use-custom-urls") {
|
||||||
customURLMapping = &oauth2.CustomURLMapping{
|
customURLMapping = &oauth2.CustomURLMapping{
|
||||||
|
@ -609,7 +604,7 @@ func parseOAuth2Config(c *cli.Context) *oauth2.Source {
|
||||||
} else {
|
} else {
|
||||||
customURLMapping = nil
|
customURLMapping = nil
|
||||||
}
|
}
|
||||||
return &oauth2.Source{
|
return &models.OAuth2Config{
|
||||||
Provider: c.String("provider"),
|
Provider: c.String("provider"),
|
||||||
ClientID: c.String("key"),
|
ClientID: c.String("key"),
|
||||||
ClientSecret: c.String("secret"),
|
ClientSecret: c.String("secret"),
|
||||||
|
@ -627,7 +622,7 @@ func runAddOauth(c *cli.Context) error {
|
||||||
return models.CreateLoginSource(&models.LoginSource{
|
return models.CreateLoginSource(&models.LoginSource{
|
||||||
Type: models.LoginOAuth2,
|
Type: models.LoginOAuth2,
|
||||||
Name: c.String("name"),
|
Name: c.String("name"),
|
||||||
IsActive: true,
|
IsActived: true,
|
||||||
Cfg: parseOAuth2Config(c),
|
Cfg: parseOAuth2Config(c),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -646,7 +641,7 @@ func runUpdateOauth(c *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
oAuth2Config := source.Cfg.(*oauth2.Source)
|
oAuth2Config := source.OAuth2()
|
||||||
|
|
||||||
if c.IsSet("name") {
|
if c.IsSet("name") {
|
||||||
source.Name = c.String("name")
|
source.Name = c.String("name")
|
||||||
|
@ -728,7 +723,7 @@ func runListAuth(c *cli.Context) error {
|
||||||
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
|
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
|
||||||
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
|
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
|
||||||
for _, source := range loginSources {
|
for _, source := range loginSources {
|
||||||
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, models.LoginNames[source.Type], source.IsActive)
|
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, models.LoginNames[source.Type], source.IsActived)
|
||||||
}
|
}
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/services/auth/source/ldap"
|
"code.gitea.io/gitea/modules/auth/ldap"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
@ -172,7 +172,7 @@ func parseLoginSource(c *cli.Context, loginSource *models.LoginSource) {
|
||||||
loginSource.Name = c.String("name")
|
loginSource.Name = c.String("name")
|
||||||
}
|
}
|
||||||
if c.IsSet("not-active") {
|
if c.IsSet("not-active") {
|
||||||
loginSource.IsActive = !c.Bool("not-active")
|
loginSource.IsActived = !c.Bool("not-active")
|
||||||
}
|
}
|
||||||
if c.IsSet("synchronize-users") {
|
if c.IsSet("synchronize-users") {
|
||||||
loginSource.IsSyncEnabled = c.Bool("synchronize-users")
|
loginSource.IsSyncEnabled = c.Bool("synchronize-users")
|
||||||
|
@ -180,70 +180,70 @@ func parseLoginSource(c *cli.Context, loginSource *models.LoginSource) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseLdapConfig assigns values on config according to command line flags.
|
// parseLdapConfig assigns values on config according to command line flags.
|
||||||
func parseLdapConfig(c *cli.Context, config *ldap.Source) error {
|
func parseLdapConfig(c *cli.Context, config *models.LDAPConfig) error {
|
||||||
if c.IsSet("name") {
|
if c.IsSet("name") {
|
||||||
config.Name = c.String("name")
|
config.Source.Name = c.String("name")
|
||||||
}
|
}
|
||||||
if c.IsSet("host") {
|
if c.IsSet("host") {
|
||||||
config.Host = c.String("host")
|
config.Source.Host = c.String("host")
|
||||||
}
|
}
|
||||||
if c.IsSet("port") {
|
if c.IsSet("port") {
|
||||||
config.Port = c.Int("port")
|
config.Source.Port = c.Int("port")
|
||||||
}
|
}
|
||||||
if c.IsSet("security-protocol") {
|
if c.IsSet("security-protocol") {
|
||||||
p, ok := findLdapSecurityProtocolByName(c.String("security-protocol"))
|
p, ok := findLdapSecurityProtocolByName(c.String("security-protocol"))
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Unknown security protocol name: %s", c.String("security-protocol"))
|
return fmt.Errorf("Unknown security protocol name: %s", c.String("security-protocol"))
|
||||||
}
|
}
|
||||||
config.SecurityProtocol = p
|
config.Source.SecurityProtocol = p
|
||||||
}
|
}
|
||||||
if c.IsSet("skip-tls-verify") {
|
if c.IsSet("skip-tls-verify") {
|
||||||
config.SkipVerify = c.Bool("skip-tls-verify")
|
config.Source.SkipVerify = c.Bool("skip-tls-verify")
|
||||||
}
|
}
|
||||||
if c.IsSet("bind-dn") {
|
if c.IsSet("bind-dn") {
|
||||||
config.BindDN = c.String("bind-dn")
|
config.Source.BindDN = c.String("bind-dn")
|
||||||
}
|
}
|
||||||
if c.IsSet("user-dn") {
|
if c.IsSet("user-dn") {
|
||||||
config.UserDN = c.String("user-dn")
|
config.Source.UserDN = c.String("user-dn")
|
||||||
}
|
}
|
||||||
if c.IsSet("bind-password") {
|
if c.IsSet("bind-password") {
|
||||||
config.BindPassword = c.String("bind-password")
|
config.Source.BindPassword = c.String("bind-password")
|
||||||
}
|
}
|
||||||
if c.IsSet("user-search-base") {
|
if c.IsSet("user-search-base") {
|
||||||
config.UserBase = c.String("user-search-base")
|
config.Source.UserBase = c.String("user-search-base")
|
||||||
}
|
}
|
||||||
if c.IsSet("username-attribute") {
|
if c.IsSet("username-attribute") {
|
||||||
config.AttributeUsername = c.String("username-attribute")
|
config.Source.AttributeUsername = c.String("username-attribute")
|
||||||
}
|
}
|
||||||
if c.IsSet("firstname-attribute") {
|
if c.IsSet("firstname-attribute") {
|
||||||
config.AttributeName = c.String("firstname-attribute")
|
config.Source.AttributeName = c.String("firstname-attribute")
|
||||||
}
|
}
|
||||||
if c.IsSet("surname-attribute") {
|
if c.IsSet("surname-attribute") {
|
||||||
config.AttributeSurname = c.String("surname-attribute")
|
config.Source.AttributeSurname = c.String("surname-attribute")
|
||||||
}
|
}
|
||||||
if c.IsSet("email-attribute") {
|
if c.IsSet("email-attribute") {
|
||||||
config.AttributeMail = c.String("email-attribute")
|
config.Source.AttributeMail = c.String("email-attribute")
|
||||||
}
|
}
|
||||||
if c.IsSet("attributes-in-bind") {
|
if c.IsSet("attributes-in-bind") {
|
||||||
config.AttributesInBind = c.Bool("attributes-in-bind")
|
config.Source.AttributesInBind = c.Bool("attributes-in-bind")
|
||||||
}
|
}
|
||||||
if c.IsSet("public-ssh-key-attribute") {
|
if c.IsSet("public-ssh-key-attribute") {
|
||||||
config.AttributeSSHPublicKey = c.String("public-ssh-key-attribute")
|
config.Source.AttributeSSHPublicKey = c.String("public-ssh-key-attribute")
|
||||||
}
|
}
|
||||||
if c.IsSet("page-size") {
|
if c.IsSet("page-size") {
|
||||||
config.SearchPageSize = uint32(c.Uint("page-size"))
|
config.Source.SearchPageSize = uint32(c.Uint("page-size"))
|
||||||
}
|
}
|
||||||
if c.IsSet("user-filter") {
|
if c.IsSet("user-filter") {
|
||||||
config.Filter = c.String("user-filter")
|
config.Source.Filter = c.String("user-filter")
|
||||||
}
|
}
|
||||||
if c.IsSet("admin-filter") {
|
if c.IsSet("admin-filter") {
|
||||||
config.AdminFilter = c.String("admin-filter")
|
config.Source.AdminFilter = c.String("admin-filter")
|
||||||
}
|
}
|
||||||
if c.IsSet("restricted-filter") {
|
if c.IsSet("restricted-filter") {
|
||||||
config.RestrictedFilter = c.String("restricted-filter")
|
config.Source.RestrictedFilter = c.String("restricted-filter")
|
||||||
}
|
}
|
||||||
if c.IsSet("allow-deactivate-all") {
|
if c.IsSet("allow-deactivate-all") {
|
||||||
config.AllowDeactivateAll = c.Bool("allow-deactivate-all")
|
config.Source.AllowDeactivateAll = c.Bool("allow-deactivate-all")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ func parseLdapConfig(c *cli.Context, config *ldap.Source) error {
|
||||||
// findLdapSecurityProtocolByName finds security protocol by its name ignoring case.
|
// findLdapSecurityProtocolByName finds security protocol by its name ignoring case.
|
||||||
// It returns the value of the security protocol and if it was found.
|
// It returns the value of the security protocol and if it was found.
|
||||||
func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
|
func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
|
||||||
for i, n := range ldap.SecurityProtocolNames {
|
for i, n := range models.SecurityProtocolNames {
|
||||||
if strings.EqualFold(name, n) {
|
if strings.EqualFold(name, n) {
|
||||||
return i, true
|
return i, true
|
||||||
}
|
}
|
||||||
|
@ -290,14 +290,16 @@ func (a *authService) addLdapBindDn(c *cli.Context) error {
|
||||||
|
|
||||||
loginSource := &models.LoginSource{
|
loginSource := &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
IsActive: true, // active by default
|
IsActived: true, // active by default
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Enabled: true, // always true
|
Enabled: true, // always true
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
parseLoginSource(c, loginSource)
|
parseLoginSource(c, loginSource)
|
||||||
if err := parseLdapConfig(c, loginSource.Cfg.(*ldap.Source)); err != nil {
|
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +318,7 @@ func (a *authService) updateLdapBindDn(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
parseLoginSource(c, loginSource)
|
parseLoginSource(c, loginSource)
|
||||||
if err := parseLdapConfig(c, loginSource.Cfg.(*ldap.Source)); err != nil {
|
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,14 +337,16 @@ func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
|
||||||
|
|
||||||
loginSource := &models.LoginSource{
|
loginSource := &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
IsActive: true, // active by default
|
IsActived: true, // active by default
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Enabled: true, // always true
|
Enabled: true, // always true
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
parseLoginSource(c, loginSource)
|
parseLoginSource(c, loginSource)
|
||||||
if err := parseLdapConfig(c, loginSource.Cfg.(*ldap.Source)); err != nil {
|
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +365,7 @@ func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
parseLoginSource(c, loginSource)
|
parseLoginSource(c, loginSource)
|
||||||
if err := parseLdapConfig(c, loginSource.Cfg.(*ldap.Source)); err != nil {
|
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/services/auth/source/ldap"
|
"code.gitea.io/gitea/modules/auth/ldap"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
@ -54,9 +54,10 @@ func TestAddLdapBindDn(t *testing.T) {
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Name: "ldap (via Bind DN) source full",
|
Name: "ldap (via Bind DN) source full",
|
||||||
IsActive: false,
|
IsActived: false,
|
||||||
IsSyncEnabled: true,
|
IsSyncEnabled: true,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Name: "ldap (via Bind DN) source full",
|
Name: "ldap (via Bind DN) source full",
|
||||||
Host: "ldap-bind-server full",
|
Host: "ldap-bind-server full",
|
||||||
Port: 9876,
|
Port: 9876,
|
||||||
|
@ -79,6 +80,7 @@ func TestAddLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 1
|
// case 1
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -94,8 +96,9 @@ func TestAddLdapBindDn(t *testing.T) {
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Name: "ldap (via Bind DN) source min",
|
Name: "ldap (via Bind DN) source min",
|
||||||
IsActive: true,
|
IsActived: true,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Name: "ldap (via Bind DN) source min",
|
Name: "ldap (via Bind DN) source min",
|
||||||
Host: "ldap-bind-server min",
|
Host: "ldap-bind-server min",
|
||||||
Port: 1234,
|
Port: 1234,
|
||||||
|
@ -107,6 +110,7 @@ func TestAddLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 2
|
// case 2
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -274,8 +278,9 @@ func TestAddLdapSimpleAuth(t *testing.T) {
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Name: "ldap (simple auth) source full",
|
Name: "ldap (simple auth) source full",
|
||||||
IsActive: false,
|
IsActived: false,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Name: "ldap (simple auth) source full",
|
Name: "ldap (simple auth) source full",
|
||||||
Host: "ldap-simple-server full",
|
Host: "ldap-simple-server full",
|
||||||
Port: 987,
|
Port: 987,
|
||||||
|
@ -295,6 +300,7 @@ func TestAddLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 1
|
// case 1
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -310,8 +316,9 @@ func TestAddLdapSimpleAuth(t *testing.T) {
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Name: "ldap (simple auth) source min",
|
Name: "ldap (simple auth) source min",
|
||||||
IsActive: true,
|
IsActived: true,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Name: "ldap (simple auth) source min",
|
Name: "ldap (simple auth) source min",
|
||||||
Host: "ldap-simple-server min",
|
Host: "ldap-simple-server min",
|
||||||
Port: 123,
|
Port: 123,
|
||||||
|
@ -323,6 +330,7 @@ func TestAddLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 2
|
// case 2
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -509,17 +517,20 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
id: 23,
|
id: 23,
|
||||||
existingLoginSource: &models.LoginSource{
|
existingLoginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
IsActive: true,
|
IsActived: true,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Name: "ldap (via Bind DN) source full",
|
Name: "ldap (via Bind DN) source full",
|
||||||
IsActive: false,
|
IsActived: false,
|
||||||
IsSyncEnabled: true,
|
IsSyncEnabled: true,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Name: "ldap (via Bind DN) source full",
|
Name: "ldap (via Bind DN) source full",
|
||||||
Host: "ldap-bind-server full",
|
Host: "ldap-bind-server full",
|
||||||
Port: 9876,
|
Port: 9876,
|
||||||
|
@ -542,6 +553,7 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 1
|
// case 1
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -550,7 +562,9 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// case 2
|
// case 2
|
||||||
|
@ -563,11 +577,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Name: "ldap (via Bind DN) source",
|
Name: "ldap (via Bind DN) source",
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Name: "ldap (via Bind DN) source",
|
Name: "ldap (via Bind DN) source",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 3
|
// case 3
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -577,13 +593,17 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
existingLoginSource: &models.LoginSource{
|
existingLoginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
IsActive: true,
|
IsActived: true,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
IsActive: false,
|
IsActived: false,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// case 4
|
// case 4
|
||||||
|
@ -595,11 +615,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
SecurityProtocol: ldap.SecurityProtocol(1),
|
SecurityProtocol: ldap.SecurityProtocol(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 5
|
// case 5
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -609,11 +631,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
SkipVerify: true,
|
SkipVerify: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 6
|
// case 6
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -623,11 +647,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Host: "ldap-server",
|
Host: "ldap-server",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 7
|
// case 7
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -637,11 +663,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Port: 389,
|
Port: 389,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 8
|
// case 8
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -651,11 +679,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
UserBase: "ou=Users,dc=domain,dc=org",
|
UserBase: "ou=Users,dc=domain,dc=org",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 9
|
// case 9
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -665,11 +695,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Filter: "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
|
Filter: "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 10
|
// case 10
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -679,11 +711,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
|
AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 11
|
// case 11
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -693,11 +727,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeUsername: "uid",
|
AttributeUsername: "uid",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 12
|
// case 12
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -707,11 +743,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeName: "givenName",
|
AttributeName: "givenName",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 13
|
// case 13
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -721,11 +759,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeSurname: "sn",
|
AttributeSurname: "sn",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 14
|
// case 14
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -735,11 +775,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeMail: "mail",
|
AttributeMail: "mail",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 15
|
// case 15
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -749,11 +791,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributesInBind: true,
|
AttributesInBind: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 16
|
// case 16
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -763,11 +807,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeSSHPublicKey: "publickey",
|
AttributeSSHPublicKey: "publickey",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 17
|
// case 17
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -777,11 +823,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
BindDN: "cn=readonly,dc=domain,dc=org",
|
BindDN: "cn=readonly,dc=domain,dc=org",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 18
|
// case 18
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -791,11 +839,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
BindPassword: "secret",
|
BindPassword: "secret",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 19
|
// case 19
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -806,7 +856,9 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
IsSyncEnabled: true,
|
IsSyncEnabled: true,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// case 20
|
// case 20
|
||||||
|
@ -818,11 +870,13 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
SearchPageSize: 12,
|
SearchPageSize: 12,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 21
|
// case 21
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -847,7 +901,9 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
},
|
},
|
||||||
existingLoginSource: &models.LoginSource{
|
existingLoginSource: &models.LoginSource{
|
||||||
Type: models.LoginOAuth2,
|
Type: models.LoginOAuth2,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
errMsg: "Invalid authentication type. expected: LDAP (via BindDN), actual: OAuth2",
|
errMsg: "Invalid authentication type. expected: LDAP (via BindDN), actual: OAuth2",
|
||||||
},
|
},
|
||||||
|
@ -877,7 +933,9 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
||||||
}
|
}
|
||||||
return &models.LoginSource{
|
return &models.LoginSource{
|
||||||
Type: models.LoginLDAP,
|
Type: models.LoginLDAP,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -938,8 +996,9 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Name: "ldap (simple auth) source full",
|
Name: "ldap (simple auth) source full",
|
||||||
IsActive: false,
|
IsActived: false,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Name: "ldap (simple auth) source full",
|
Name: "ldap (simple auth) source full",
|
||||||
Host: "ldap-simple-server full",
|
Host: "ldap-simple-server full",
|
||||||
Port: 987,
|
Port: 987,
|
||||||
|
@ -958,6 +1017,7 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 1
|
// case 1
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -966,7 +1026,9 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// case 2
|
// case 2
|
||||||
|
@ -979,11 +1041,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Name: "ldap (simple auth) source",
|
Name: "ldap (simple auth) source",
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Name: "ldap (simple auth) source",
|
Name: "ldap (simple auth) source",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 3
|
// case 3
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -993,13 +1057,17 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
existingLoginSource: &models.LoginSource{
|
existingLoginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
IsActive: true,
|
IsActived: true,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
IsActive: false,
|
IsActived: false,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// case 4
|
// case 4
|
||||||
|
@ -1011,11 +1079,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
SecurityProtocol: ldap.SecurityProtocol(2),
|
SecurityProtocol: ldap.SecurityProtocol(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 5
|
// case 5
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1025,11 +1095,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
SkipVerify: true,
|
SkipVerify: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 6
|
// case 6
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1039,11 +1111,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Host: "ldap-server",
|
Host: "ldap-server",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 7
|
// case 7
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1053,11 +1127,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Port: 987,
|
Port: 987,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 8
|
// case 8
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1067,11 +1143,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
UserBase: "ou=Users,dc=domain,dc=org",
|
UserBase: "ou=Users,dc=domain,dc=org",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 9
|
// case 9
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1081,11 +1159,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
Filter: "(&(objectClass=posixAccount)(cn=%s))",
|
Filter: "(&(objectClass=posixAccount)(cn=%s))",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 10
|
// case 10
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1095,11 +1175,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
|
AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 11
|
// case 11
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1109,11 +1191,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeUsername: "uid",
|
AttributeUsername: "uid",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 12
|
// case 12
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1123,11 +1207,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeName: "givenName",
|
AttributeName: "givenName",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 13
|
// case 13
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1137,11 +1223,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeSurname: "sn",
|
AttributeSurname: "sn",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 14
|
// case 14
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1151,12 +1239,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeMail: "mail",
|
AttributeMail: "mail",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 15
|
// case 15
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1166,11 +1255,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
AttributeSSHPublicKey: "publickey",
|
AttributeSSHPublicKey: "publickey",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 16
|
// case 16
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1180,11 +1271,13 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
loginSource: &models.LoginSource{
|
loginSource: &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{
|
||||||
UserDN: "cn=%s,ou=Users,dc=domain,dc=org",
|
UserDN: "cn=%s,ou=Users,dc=domain,dc=org",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
// case 17
|
// case 17
|
||||||
{
|
{
|
||||||
args: []string{
|
args: []string{
|
||||||
|
@ -1209,7 +1302,9 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
existingLoginSource: &models.LoginSource{
|
existingLoginSource: &models.LoginSource{
|
||||||
Type: models.LoginPAM,
|
Type: models.LoginPAM,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
errMsg: "Invalid authentication type. expected: LDAP (simple auth), actual: PAM",
|
errMsg: "Invalid authentication type. expected: LDAP (simple auth), actual: PAM",
|
||||||
},
|
},
|
||||||
|
@ -1239,7 +1334,9 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
||||||
}
|
}
|
||||||
return &models.LoginSource{
|
return &models.LoginSource{
|
||||||
Type: models.LoginDLDAP,
|
Type: models.LoginDLDAP,
|
||||||
Cfg: &ldap.Source{},
|
Cfg: &models.LDAPConfig{
|
||||||
|
Source: &ldap.Source{},
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
26
cmd/cmd.go
26
cmd/cmd.go
|
@ -7,13 +7,9 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
@ -70,25 +66,3 @@ func initDBDisableConsole(disableConsole bool) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func installSignals() (context.Context, context.CancelFunc) {
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
go func() {
|
|
||||||
// install notify
|
|
||||||
signalChannel := make(chan os.Signal, 1)
|
|
||||||
|
|
||||||
signal.Notify(
|
|
||||||
signalChannel,
|
|
||||||
syscall.SIGINT,
|
|
||||||
syscall.SIGTERM,
|
|
||||||
)
|
|
||||||
select {
|
|
||||||
case <-signalChannel:
|
|
||||||
case <-ctx.Done():
|
|
||||||
}
|
|
||||||
cancel()
|
|
||||||
signal.Reset()
|
|
||||||
}()
|
|
||||||
|
|
||||||
return ctx, cancel
|
|
||||||
}
|
|
||||||
|
|
|
@ -27,10 +27,10 @@ func runConvert(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("AppPath: %s", setting.AppPath)
|
log.Trace("AppPath: %s", setting.AppPath)
|
||||||
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
log.Trace("AppWorkPath: %s", setting.AppWorkPath)
|
||||||
log.Info("Custom path: %s", setting.CustomPath)
|
log.Trace("Custom path: %s", setting.CustomPath)
|
||||||
log.Info("Log path: %s", setting.LogRootPath)
|
log.Trace("Log path: %s", setting.LogRootPath)
|
||||||
setting.InitDBConfig()
|
setting.InitDBConfig()
|
||||||
|
|
||||||
if !setting.Database.UseMySQL {
|
if !setting.Database.UseMySQL {
|
||||||
|
|
72
cmd/dump.go
72
cmd/dump.go
|
@ -6,6 +6,7 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -15,13 +16,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/json"
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/storage"
|
"code.gitea.io/gitea/modules/storage"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"gitea.com/go-chi/session"
|
"gitea.com/macaron/session"
|
||||||
archiver "github.com/mholt/archiver/v3"
|
archiver "github.com/mholt/archiver/v3"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
@ -49,6 +49,38 @@ func addFile(w archiver.Writer, filePath string, absPath string, verbose bool) e
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addRecursive(w archiver.Writer, dirPath string, absPath string, verbose bool) error {
|
||||||
|
if verbose {
|
||||||
|
log.Info("Adding dir %s\n", dirPath)
|
||||||
|
}
|
||||||
|
dir, err := os.Open(absPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Could not open directory %s: %s", absPath, err)
|
||||||
|
}
|
||||||
|
defer dir.Close()
|
||||||
|
|
||||||
|
files, err := dir.Readdir(0)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Unable to list files in %s: %s", absPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := addFile(w, dirPath, absPath, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fileInfo := range files {
|
||||||
|
if fileInfo.IsDir() {
|
||||||
|
err = addRecursive(w, filepath.Join(dirPath, fileInfo.Name()), filepath.Join(absPath, fileInfo.Name()), verbose)
|
||||||
|
} else {
|
||||||
|
err = addFile(w, filepath.Join(dirPath, fileInfo.Name()), filepath.Join(absPath, fileInfo.Name()), verbose)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func isSubdir(upper string, lower string) (bool, error) {
|
func isSubdir(upper string, lower string) (bool, error) {
|
||||||
if relPath, err := filepath.Rel(upper, lower); err != nil {
|
if relPath, err := filepath.Rel(upper, lower); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -125,18 +157,6 @@ It can be used for backup and capture Gitea server image to send to maintainer`,
|
||||||
Name: "skip-log, L",
|
Name: "skip-log, L",
|
||||||
Usage: "Skip the log dumping",
|
Usage: "Skip the log dumping",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "skip-custom-dir",
|
|
||||||
Usage: "Skip custom directory",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "skip-lfs-data",
|
|
||||||
Usage: "Skip LFS data",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "skip-attachment-data",
|
|
||||||
Usage: "Skip attachment data",
|
|
||||||
},
|
|
||||||
cli.GenericFlag{
|
cli.GenericFlag{
|
||||||
Name: "type",
|
Name: "type",
|
||||||
Value: outputTypeEnum,
|
Value: outputTypeEnum,
|
||||||
|
@ -191,11 +211,6 @@ func runDump(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
absFileName, err := filepath.Abs(fileName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
verbose := ctx.Bool("verbose")
|
verbose := ctx.Bool("verbose")
|
||||||
outType := ctx.String("type")
|
outType := ctx.String("type")
|
||||||
var iface interface{}
|
var iface interface{}
|
||||||
|
@ -218,13 +233,11 @@ func runDump(ctx *cli.Context) error {
|
||||||
log.Info("Skip dumping local repositories")
|
log.Info("Skip dumping local repositories")
|
||||||
} else {
|
} else {
|
||||||
log.Info("Dumping local repositories... %s", setting.RepoRootPath)
|
log.Info("Dumping local repositories... %s", setting.RepoRootPath)
|
||||||
if err := addRecursiveExclude(w, "repos", setting.RepoRootPath, []string{absFileName}, verbose); err != nil {
|
if err := addRecursive(w, "repos", setting.RepoRootPath, verbose); err != nil {
|
||||||
fatal("Failed to include repositories: %v", err)
|
fatal("Failed to include repositories: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet("skip-lfs-data") && ctx.Bool("skip-lfs-data") {
|
if err := storage.LFS.IterateObjects(func(objPath string, object storage.Object) error {
|
||||||
log.Info("Skip dumping LFS data")
|
|
||||||
} else if err := storage.LFS.IterateObjects(func(objPath string, object storage.Object) error {
|
|
||||||
info, err := object.Stat()
|
info, err := object.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -279,13 +292,10 @@ func runDump(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet("skip-custom-dir") && ctx.Bool("skip-custom-dir") {
|
|
||||||
log.Info("Skipping custom directory")
|
|
||||||
} else {
|
|
||||||
customDir, err := os.Stat(setting.CustomPath)
|
customDir, err := os.Stat(setting.CustomPath)
|
||||||
if err == nil && customDir.IsDir() {
|
if err == nil && customDir.IsDir() {
|
||||||
if is, _ := isSubdir(setting.AppDataPath, setting.CustomPath); !is {
|
if is, _ := isSubdir(setting.AppDataPath, setting.CustomPath); !is {
|
||||||
if err := addRecursiveExclude(w, "custom", setting.CustomPath, []string{absFileName}, verbose); err != nil {
|
if err := addRecursive(w, "custom", setting.CustomPath, verbose); err != nil {
|
||||||
fatal("Failed to include custom: %v", err)
|
fatal("Failed to include custom: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -294,7 +304,6 @@ func runDump(ctx *cli.Context) error {
|
||||||
} else {
|
} else {
|
||||||
log.Info("Custom dir %s doesn't exist, skipped", setting.CustomPath)
|
log.Info("Custom dir %s doesn't exist, skipped", setting.CustomPath)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
isExist, err := util.IsExist(setting.AppDataPath)
|
isExist, err := util.IsExist(setting.AppDataPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -316,15 +325,12 @@ func runDump(ctx *cli.Context) error {
|
||||||
excludes = append(excludes, setting.LFS.Path)
|
excludes = append(excludes, setting.LFS.Path)
|
||||||
excludes = append(excludes, setting.Attachment.Path)
|
excludes = append(excludes, setting.Attachment.Path)
|
||||||
excludes = append(excludes, setting.LogRootPath)
|
excludes = append(excludes, setting.LogRootPath)
|
||||||
excludes = append(excludes, absFileName)
|
|
||||||
if err := addRecursiveExclude(w, "data", setting.AppDataPath, excludes, verbose); err != nil {
|
if err := addRecursiveExclude(w, "data", setting.AppDataPath, excludes, verbose); err != nil {
|
||||||
fatal("Failed to include data directory: %v", err)
|
fatal("Failed to include data directory: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet("skip-attachment-data") && ctx.Bool("skip-attachment-data") {
|
if err := storage.Attachments.IterateObjects(func(objPath string, object storage.Object) error {
|
||||||
log.Info("Skip dumping attachment data")
|
|
||||||
} else if err := storage.Attachments.IterateObjects(func(objPath string, object storage.Object) error {
|
|
||||||
info, err := object.Stat()
|
info, err := object.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -352,7 +358,7 @@ func runDump(ctx *cli.Context) error {
|
||||||
log.Error("Unable to check if %s exists. Error: %v", setting.LogRootPath, err)
|
log.Error("Unable to check if %s exists. Error: %v", setting.LogRootPath, err)
|
||||||
}
|
}
|
||||||
if isExist {
|
if isExist {
|
||||||
if err := addRecursiveExclude(w, "log", setting.LogRootPath, []string{absFileName}, verbose); err != nil {
|
if err := addRecursive(w, "log", setting.LogRootPath, verbose); err != nil {
|
||||||
fatal("Failed to include log: %v", err)
|
fatal("Failed to include log: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,10 +80,10 @@ func runDumpRepository(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("AppPath: %s", setting.AppPath)
|
log.Trace("AppPath: %s", setting.AppPath)
|
||||||
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
log.Trace("AppWorkPath: %s", setting.AppWorkPath)
|
||||||
log.Info("Custom path: %s", setting.CustomPath)
|
log.Trace("Custom path: %s", setting.CustomPath)
|
||||||
log.Info("Log path: %s", setting.LogRootPath)
|
log.Trace("Log path: %s", setting.LogRootPath)
|
||||||
setting.InitDBConfig()
|
setting.InitDBConfig()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build bindata
|
|
||||||
// +build bindata
|
// +build bindata
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
@ -20,7 +19,6 @@ import (
|
||||||
"code.gitea.io/gitea/modules/public"
|
"code.gitea.io/gitea/modules/public"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/templates"
|
"code.gitea.io/gitea/modules/templates"
|
||||||
"code.gitea.io/gitea/modules/util"
|
|
||||||
|
|
||||||
"github.com/gobwas/glob"
|
"github.com/gobwas/glob"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
@ -273,7 +271,7 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
||||||
} else if !fi.Mode().IsRegular() {
|
} else if !fi.Mode().IsRegular() {
|
||||||
return fmt.Errorf("%s already exists, but it's not a regular file", dest)
|
return fmt.Errorf("%s already exists, but it's not a regular file", dest)
|
||||||
} else if rename {
|
} else if rename {
|
||||||
if err := util.Rename(dest, dest+".bak"); err != nil {
|
if err := os.Rename(dest, dest+".bak"); err != nil {
|
||||||
return fmt.Errorf("Error creating backup for %s: %v", dest, err)
|
return fmt.Errorf("Error creating backup for %s: %v", dest, err)
|
||||||
}
|
}
|
||||||
// Attempt to respect file permissions mask (even if user:group will be set anew)
|
// Attempt to respect file permissions mask (even if user:group will be set anew)
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build !bindata
|
|
||||||
// +build !bindata
|
// +build !bindata
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|
|
@ -71,7 +71,7 @@ func runGenerateInternalToken(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runGenerateLfsJwtSecret(c *cli.Context) error {
|
func runGenerateLfsJwtSecret(c *cli.Context) error {
|
||||||
JWTSecretBase64, err := generate.NewJwtSecretBase64()
|
JWTSecretBase64, err := generate.NewJwtSecret()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
407
cmd/hook.go
407
cmd/hook.go
|
@ -38,7 +38,6 @@ var (
|
||||||
subcmdHookPreReceive,
|
subcmdHookPreReceive,
|
||||||
subcmdHookUpdate,
|
subcmdHookUpdate,
|
||||||
subcmdHookPostReceive,
|
subcmdHookPostReceive,
|
||||||
subcmdHookProcReceive,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,18 +74,6 @@ var (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// Note: new hook since git 2.29
|
|
||||||
subcmdHookProcReceive = cli.Command{
|
|
||||||
Name: "proc-receive",
|
|
||||||
Usage: "Delegate proc-receive Git hook",
|
|
||||||
Description: "This command should only be called by Git",
|
|
||||||
Action: runHookProcReceive,
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "debug",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type delayWriter struct {
|
type delayWriter struct {
|
||||||
|
@ -165,22 +152,21 @@ func runHookPreReceive(c *cli.Context) error {
|
||||||
if os.Getenv(models.EnvIsInternal) == "true" {
|
if os.Getenv(models.EnvIsInternal) == "true" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setup("hooks/pre-receive.log", c.Bool("debug"))
|
setup("hooks/pre-receive.log", c.Bool("debug"))
|
||||||
|
|
||||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||||
return fail(`Rejecting changes as Gitea environment not set.
|
fail(`Rejecting changes as Gitea environment not set.
|
||||||
If you are pushing over SSH you must push with a key managed by
|
If you are pushing over SSH you must push with a key managed by
|
||||||
Gitea or set your environment appropriately.`, "")
|
Gitea or set your environment appropriately.`, "")
|
||||||
}
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the environment is set by serv command
|
// the environment setted on serv command
|
||||||
isWiki := os.Getenv(models.EnvRepoIsWiki) == "true"
|
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
|
||||||
username := os.Getenv(models.EnvRepoUsername)
|
username := os.Getenv(models.EnvRepoUsername)
|
||||||
reponame := os.Getenv(models.EnvRepoName)
|
reponame := os.Getenv(models.EnvRepoName)
|
||||||
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
||||||
|
@ -193,7 +179,7 @@ Gitea or set your environment appropriately.`, "")
|
||||||
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
||||||
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
|
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
|
||||||
GitPushOptions: pushOptions(),
|
GitPushOptions: pushOptions(),
|
||||||
PullRequestID: prID,
|
ProtectedBranchID: prID,
|
||||||
IsDeployKey: isDeployKey,
|
IsDeployKey: isDeployKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,11 +204,6 @@ Gitea or set your environment appropriately.`, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
supportProcRecive := false
|
|
||||||
if git.CheckGitVersionAtLeast("2.29") == nil {
|
|
||||||
supportProcRecive = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
// TODO: support news feeds for wiki
|
// TODO: support news feeds for wiki
|
||||||
if isWiki {
|
if isWiki {
|
||||||
|
@ -240,10 +221,8 @@ Gitea or set your environment appropriately.`, "")
|
||||||
total++
|
total++
|
||||||
lastline++
|
lastline++
|
||||||
|
|
||||||
// If the ref is a branch or tag, check if it's protected
|
// If the ref is a branch, check if it's protected
|
||||||
// if supportProcRecive all ref should be checked because
|
if strings.HasPrefix(refFullName, git.BranchPrefix) {
|
||||||
// permission check was delayed
|
|
||||||
if supportProcRecive || strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
|
|
||||||
oldCommitIDs[count] = oldCommitID
|
oldCommitIDs[count] = oldCommitID
|
||||||
newCommitIDs[count] = newCommitID
|
newCommitIDs[count] = newCommitID
|
||||||
refFullNames[count] = refFullName
|
refFullNames[count] = refFullName
|
||||||
|
@ -251,19 +230,19 @@ Gitea or set your environment appropriately.`, "")
|
||||||
fmt.Fprintf(out, "*")
|
fmt.Fprintf(out, "*")
|
||||||
|
|
||||||
if count >= hookBatchSize {
|
if count >= hookBatchSize {
|
||||||
fmt.Fprintf(out, " Checking %d references\n", count)
|
fmt.Fprintf(out, " Checking %d branches\n", count)
|
||||||
|
|
||||||
hookOptions.OldCommitIDs = oldCommitIDs
|
hookOptions.OldCommitIDs = oldCommitIDs
|
||||||
hookOptions.NewCommitIDs = newCommitIDs
|
hookOptions.NewCommitIDs = newCommitIDs
|
||||||
hookOptions.RefFullNames = refFullNames
|
hookOptions.RefFullNames = refFullNames
|
||||||
statusCode, msg := private.HookPreReceive(ctx, username, reponame, hookOptions)
|
statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusOK:
|
case http.StatusOK:
|
||||||
// no-op
|
// no-op
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("Internal Server Error", msg)
|
fail("Internal Server Error", msg)
|
||||||
default:
|
default:
|
||||||
return fail(msg, "")
|
fail(msg, "")
|
||||||
}
|
}
|
||||||
count = 0
|
count = 0
|
||||||
lastline = 0
|
lastline = 0
|
||||||
|
@ -282,14 +261,14 @@ Gitea or set your environment appropriately.`, "")
|
||||||
hookOptions.NewCommitIDs = newCommitIDs[:count]
|
hookOptions.NewCommitIDs = newCommitIDs[:count]
|
||||||
hookOptions.RefFullNames = refFullNames[:count]
|
hookOptions.RefFullNames = refFullNames[:count]
|
||||||
|
|
||||||
fmt.Fprintf(out, " Checking %d references\n", count)
|
fmt.Fprintf(out, " Checking %d branches\n", count)
|
||||||
|
|
||||||
statusCode, msg := private.HookPreReceive(ctx, username, reponame, hookOptions)
|
statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("Internal Server Error", msg)
|
fail("Internal Server Error", msg)
|
||||||
case http.StatusForbidden:
|
case http.StatusForbidden:
|
||||||
return fail(msg, "")
|
fail(msg, "")
|
||||||
}
|
}
|
||||||
} else if lastline > 0 {
|
} else if lastline > 0 {
|
||||||
fmt.Fprintf(out, "\n")
|
fmt.Fprintf(out, "\n")
|
||||||
|
@ -306,11 +285,8 @@ func runHookUpdate(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runHookPostReceive(c *cli.Context) error {
|
func runHookPostReceive(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// First of all run update-server-info no matter what
|
// First of all run update-server-info no matter what
|
||||||
if _, err := git.NewCommand("update-server-info").SetParentContext(ctx).Run(); err != nil {
|
if _, err := git.NewCommand("update-server-info").Run(); err != nil {
|
||||||
return fmt.Errorf("Failed to call 'git update-server-info': %v", err)
|
return fmt.Errorf("Failed to call 'git update-server-info': %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,12 +299,13 @@ func runHookPostReceive(c *cli.Context) error {
|
||||||
|
|
||||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||||
return fail(`Rejecting changes as Gitea environment not set.
|
fail(`Rejecting changes as Gitea environment not set.
|
||||||
If you are pushing over SSH you must push with a key managed by
|
If you are pushing over SSH you must push with a key managed by
|
||||||
Gitea or set your environment appropriately.`, "")
|
Gitea or set your environment appropriately.`, "")
|
||||||
}
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var out io.Writer
|
var out io.Writer
|
||||||
var dWriter *delayWriter
|
var dWriter *delayWriter
|
||||||
|
@ -343,9 +320,9 @@ Gitea or set your environment appropriately.`, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the environment is set by serv command
|
// the environment setted on serv command
|
||||||
repoUser := os.Getenv(models.EnvRepoUsername)
|
repoUser := os.Getenv(models.EnvRepoUsername)
|
||||||
isWiki := os.Getenv(models.EnvRepoIsWiki) == "true"
|
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
|
||||||
repoName := os.Getenv(models.EnvRepoName)
|
repoName := os.Getenv(models.EnvRepoName)
|
||||||
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
||||||
pusherName := os.Getenv(models.EnvPusherName)
|
pusherName := os.Getenv(models.EnvPusherName)
|
||||||
|
@ -394,11 +371,11 @@ Gitea or set your environment appropriately.`, "")
|
||||||
hookOptions.OldCommitIDs = oldCommitIDs
|
hookOptions.OldCommitIDs = oldCommitIDs
|
||||||
hookOptions.NewCommitIDs = newCommitIDs
|
hookOptions.NewCommitIDs = newCommitIDs
|
||||||
hookOptions.RefFullNames = refFullNames
|
hookOptions.RefFullNames = refFullNames
|
||||||
resp, err := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
|
resp, err := private.HookPostReceive(repoUser, repoName, hookOptions)
|
||||||
if resp == nil {
|
if resp == nil {
|
||||||
_ = dWriter.Close()
|
_ = dWriter.Close()
|
||||||
hookPrintResults(results)
|
hookPrintResults(results)
|
||||||
return fail("Internal Server Error", err)
|
fail("Internal Server Error", err)
|
||||||
}
|
}
|
||||||
wasEmpty = wasEmpty || resp.RepoWasEmpty
|
wasEmpty = wasEmpty || resp.RepoWasEmpty
|
||||||
results = append(results, resp.Results...)
|
results = append(results, resp.Results...)
|
||||||
|
@ -409,9 +386,9 @@ Gitea or set your environment appropriately.`, "")
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
if wasEmpty && masterPushed {
|
if wasEmpty && masterPushed {
|
||||||
// We need to tell the repo to reset the default branch to master
|
// We need to tell the repo to reset the default branch to master
|
||||||
err := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
|
err := private.SetDefaultBranch(repoUser, repoName, "master")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
|
fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "Processed %d references in total\n", total)
|
fmt.Fprintf(out, "Processed %d references in total\n", total)
|
||||||
|
@ -427,11 +404,11 @@ Gitea or set your environment appropriately.`, "")
|
||||||
|
|
||||||
fmt.Fprintf(out, " Processing %d references\n", count)
|
fmt.Fprintf(out, " Processing %d references\n", count)
|
||||||
|
|
||||||
resp, err := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
|
resp, err := private.HookPostReceive(repoUser, repoName, hookOptions)
|
||||||
if resp == nil {
|
if resp == nil {
|
||||||
_ = dWriter.Close()
|
_ = dWriter.Close()
|
||||||
hookPrintResults(results)
|
hookPrintResults(results)
|
||||||
return fail("Internal Server Error", err)
|
fail("Internal Server Error", err)
|
||||||
}
|
}
|
||||||
wasEmpty = wasEmpty || resp.RepoWasEmpty
|
wasEmpty = wasEmpty || resp.RepoWasEmpty
|
||||||
results = append(results, resp.Results...)
|
results = append(results, resp.Results...)
|
||||||
|
@ -440,9 +417,9 @@ Gitea or set your environment appropriately.`, "")
|
||||||
|
|
||||||
if wasEmpty && masterPushed {
|
if wasEmpty && masterPushed {
|
||||||
// We need to tell the repo to reset the default branch to master
|
// We need to tell the repo to reset the default branch to master
|
||||||
err := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
|
err := private.SetDefaultBranch(repoUser, repoName, "master")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
|
fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = dWriter.Close()
|
_ = dWriter.Close()
|
||||||
|
@ -483,327 +460,3 @@ func pushOptions() map[string]string {
|
||||||
}
|
}
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
func runHookProcReceive(c *cli.Context) error {
|
|
||||||
setup("hooks/proc-receive.log", c.Bool("debug"))
|
|
||||||
|
|
||||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
|
||||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
|
||||||
return fail(`Rejecting changes as Gitea environment not set.
|
|
||||||
If you are pushing over SSH you must push with a key managed by
|
|
||||||
Gitea or set your environment appropriately.`, "")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if git.CheckGitVersionAtLeast("2.29") != nil {
|
|
||||||
return fail("Internal Server Error", "git not support proc-receive.")
|
|
||||||
}
|
|
||||||
|
|
||||||
reader := bufio.NewReader(os.Stdin)
|
|
||||||
repoUser := os.Getenv(models.EnvRepoUsername)
|
|
||||||
repoName := os.Getenv(models.EnvRepoName)
|
|
||||||
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
|
||||||
pusherName := os.Getenv(models.EnvPusherName)
|
|
||||||
|
|
||||||
// 1. Version and features negotiation.
|
|
||||||
// S: PKT-LINE(version=1\0push-options atomic...) / PKT-LINE(version=1\n)
|
|
||||||
// S: flush-pkt
|
|
||||||
// H: PKT-LINE(version=1\0push-options...)
|
|
||||||
// H: flush-pkt
|
|
||||||
|
|
||||||
rs, err := readPktLine(reader, pktLineTypeData)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
const VersionHead string = "version=1"
|
|
||||||
|
|
||||||
var (
|
|
||||||
hasPushOptions bool
|
|
||||||
response = []byte(VersionHead)
|
|
||||||
requestOptions []string
|
|
||||||
)
|
|
||||||
|
|
||||||
index := bytes.IndexByte(rs.Data, byte(0))
|
|
||||||
if index >= len(rs.Data) {
|
|
||||||
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
|
||||||
}
|
|
||||||
|
|
||||||
if index < 0 {
|
|
||||||
if len(rs.Data) == 10 && rs.Data[9] == '\n' {
|
|
||||||
index = 9
|
|
||||||
} else {
|
|
||||||
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(rs.Data[0:index]) != VersionHead {
|
|
||||||
return fail("Internal Server Error", "Received unsupported version: %s", string(rs.Data[0:index]))
|
|
||||||
}
|
|
||||||
requestOptions = strings.Split(string(rs.Data[index+1:]), " ")
|
|
||||||
|
|
||||||
for _, option := range requestOptions {
|
|
||||||
if strings.HasPrefix(option, "push-options") {
|
|
||||||
response = append(response, byte(0))
|
|
||||||
response = append(response, []byte("push-options")...)
|
|
||||||
hasPushOptions = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response = append(response, '\n')
|
|
||||||
|
|
||||||
_, err = readPktLine(reader, pktLineTypeFlush)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeDataPktLine(os.Stdout, response)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeFlushPktLine(os.Stdout)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. receive commands from server.
|
|
||||||
// S: PKT-LINE(<old-oid> <new-oid> <ref>)
|
|
||||||
// S: ... ...
|
|
||||||
// S: flush-pkt
|
|
||||||
// # [receive push-options]
|
|
||||||
// S: PKT-LINE(push-option)
|
|
||||||
// S: ... ...
|
|
||||||
// S: flush-pkt
|
|
||||||
hookOptions := private.HookOptions{
|
|
||||||
UserName: pusherName,
|
|
||||||
UserID: pusherID,
|
|
||||||
}
|
|
||||||
hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize)
|
|
||||||
hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize)
|
|
||||||
hookOptions.RefFullNames = make([]string, 0, hookBatchSize)
|
|
||||||
|
|
||||||
for {
|
|
||||||
// note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed
|
|
||||||
rs, err = readPktLine(reader, pktLineTypeUnknow)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Type == pktLineTypeFlush {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
t := strings.SplitN(string(rs.Data), " ", 3)
|
|
||||||
if len(t) != 3 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
hookOptions.OldCommitIDs = append(hookOptions.OldCommitIDs, t[0])
|
|
||||||
hookOptions.NewCommitIDs = append(hookOptions.NewCommitIDs, t[1])
|
|
||||||
hookOptions.RefFullNames = append(hookOptions.RefFullNames, t[2])
|
|
||||||
}
|
|
||||||
|
|
||||||
hookOptions.GitPushOptions = make(map[string]string)
|
|
||||||
|
|
||||||
if hasPushOptions {
|
|
||||||
for {
|
|
||||||
rs, err = readPktLine(reader, pktLineTypeUnknow)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Type == pktLineTypeFlush {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
kv := strings.SplitN(string(rs.Data), "=", 2)
|
|
||||||
if len(kv) == 2 {
|
|
||||||
hookOptions.GitPushOptions[kv[0]] = kv[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. run hook
|
|
||||||
resp, err := private.HookProcReceive(ctx, repoUser, repoName, hookOptions)
|
|
||||||
if err != nil {
|
|
||||||
return fail("Internal Server Error", "run proc-receive hook failed :%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. response result to service
|
|
||||||
// # a. OK, but has an alternate reference. The alternate reference name
|
|
||||||
// # and other status can be given in option directives.
|
|
||||||
// H: PKT-LINE(ok <ref>)
|
|
||||||
// H: PKT-LINE(option refname <refname>)
|
|
||||||
// H: PKT-LINE(option old-oid <old-oid>)
|
|
||||||
// H: PKT-LINE(option new-oid <new-oid>)
|
|
||||||
// H: PKT-LINE(option forced-update)
|
|
||||||
// H: ... ...
|
|
||||||
// H: flush-pkt
|
|
||||||
// # b. NO, I reject it.
|
|
||||||
// H: PKT-LINE(ng <ref> <reason>)
|
|
||||||
// # c. Fall through, let 'receive-pack' to execute it.
|
|
||||||
// H: PKT-LINE(ok <ref>)
|
|
||||||
// H: PKT-LINE(option fall-through)
|
|
||||||
|
|
||||||
for _, rs := range resp.Results {
|
|
||||||
if len(rs.Err) > 0 {
|
|
||||||
err = writeDataPktLine(os.Stdout, []byte("ng "+rs.OriginalRef+" "+rs.Err))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.IsNotMatched {
|
|
||||||
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = writeDataPktLine(os.Stdout, []byte("option fall-through"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = writeDataPktLine(os.Stdout, []byte("option refname "+rs.Ref))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if rs.OldOID != git.EmptySHA {
|
|
||||||
err = writeDataPktLine(os.Stdout, []byte("option old-oid "+rs.OldOID))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = writeDataPktLine(os.Stdout, []byte("option new-oid "+rs.NewOID))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if rs.IsForcePush {
|
|
||||||
err = writeDataPktLine(os.Stdout, []byte("option forced-update"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = writeFlushPktLine(os.Stdout)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// git PKT-Line api
|
|
||||||
// pktLineType message type of pkt-line
|
|
||||||
type pktLineType int64
|
|
||||||
|
|
||||||
const (
|
|
||||||
// UnKnow type
|
|
||||||
pktLineTypeUnknow pktLineType = 0
|
|
||||||
// flush-pkt "0000"
|
|
||||||
pktLineTypeFlush pktLineType = iota
|
|
||||||
// data line
|
|
||||||
pktLineTypeData
|
|
||||||
)
|
|
||||||
|
|
||||||
// gitPktLine pkt-line api
|
|
||||||
type gitPktLine struct {
|
|
||||||
Type pktLineType
|
|
||||||
Length uint64
|
|
||||||
Data []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func readPktLine(in *bufio.Reader, requestType pktLineType) (*gitPktLine, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
r *gitPktLine
|
|
||||||
)
|
|
||||||
|
|
||||||
// read prefix
|
|
||||||
lengthBytes := make([]byte, 4)
|
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
lengthBytes[i], err = in.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r = new(gitPktLine)
|
|
||||||
r.Length, err = strconv.ParseUint(string(lengthBytes), 16, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong :%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Length == 0 {
|
|
||||||
if requestType == pktLineTypeData {
|
|
||||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
|
|
||||||
}
|
|
||||||
r.Type = pktLineTypeFlush
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Length <= 4 || r.Length > 65520 || requestType == pktLineTypeFlush {
|
|
||||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Data = make([]byte, r.Length-4)
|
|
||||||
for i := range r.Data {
|
|
||||||
r.Data[i], err = in.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Type = pktLineTypeData
|
|
||||||
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeFlushPktLine(out io.Writer) error {
|
|
||||||
l, err := out.Write([]byte("0000"))
|
|
||||||
if err != nil {
|
|
||||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
|
||||||
}
|
|
||||||
if l != 4 {
|
|
||||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeDataPktLine(out io.Writer, data []byte) error {
|
|
||||||
hexchar := []byte("0123456789abcdef")
|
|
||||||
hex := func(n uint64) byte {
|
|
||||||
return hexchar[(n)&15]
|
|
||||||
}
|
|
||||||
|
|
||||||
length := uint64(len(data) + 4)
|
|
||||||
tmp := make([]byte, 4)
|
|
||||||
tmp[0] = hex(length >> 12)
|
|
||||||
tmp[1] = hex(length >> 8)
|
|
||||||
tmp[2] = hex(length >> 4)
|
|
||||||
tmp[3] = hex(length)
|
|
||||||
|
|
||||||
lr, err := out.Write(tmp)
|
|
||||||
if err != nil {
|
|
||||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
|
||||||
}
|
|
||||||
if 4 != lr {
|
|
||||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
lr, err = out.Write(data)
|
|
||||||
if err != nil {
|
|
||||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
|
||||||
}
|
|
||||||
if int(length-4) != lr {
|
|
||||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPktLine(t *testing.T) {
|
|
||||||
// test read
|
|
||||||
s := strings.NewReader("0000")
|
|
||||||
r := bufio.NewReader(s)
|
|
||||||
result, err := readPktLine(r, pktLineTypeFlush)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, pktLineTypeFlush, result.Type)
|
|
||||||
|
|
||||||
s = strings.NewReader("0006a\n")
|
|
||||||
r = bufio.NewReader(s)
|
|
||||||
result, err = readPktLine(r, pktLineTypeData)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, pktLineTypeData, result.Type)
|
|
||||||
assert.Equal(t, []byte("a\n"), result.Data)
|
|
||||||
|
|
||||||
// test write
|
|
||||||
w := bytes.NewBuffer([]byte{})
|
|
||||||
err = writeFlushPktLine(w)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, []byte("0000"), w.Bytes())
|
|
||||||
|
|
||||||
w.Reset()
|
|
||||||
err = writeDataPktLine(w, []byte("a\nb"))
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, []byte("0007a\nb"), w.Bytes())
|
|
||||||
}
|
|
|
@ -62,12 +62,9 @@ func runKeys(c *cli.Context) error {
|
||||||
return errors.New("No key type and content provided")
|
return errors.New("No key type and content provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setup("keys.log", false)
|
setup("keys.log", false)
|
||||||
|
|
||||||
authorizedString, err := private.AuthorizedPublicKeyByContent(ctx, content)
|
authorizedString, err := private.AuthorizedPublicKeyByContent(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func runSendMail(c *cli.Context) error {
|
func runSendMail(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setting.NewContext()
|
setting.NewContext()
|
||||||
|
|
||||||
if err := argsSet(c, "title"); err != nil {
|
if err := argsSet(c, "title"); err != nil {
|
||||||
|
@ -42,7 +39,7 @@ func runSendMail(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status, message := private.SendEmail(ctx, subject, body, nil)
|
status, message := private.SendEmail(subject, body, nil)
|
||||||
if status != http.StatusOK {
|
if status != http.StatusOK {
|
||||||
fmt.Printf("error: %s\n", message)
|
fmt.Printf("error: %s\n", message)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -236,13 +236,10 @@ func runRemoveLogger(c *cli.Context) error {
|
||||||
group = log.DEFAULT
|
group = log.DEFAULT
|
||||||
}
|
}
|
||||||
name := c.Args().First()
|
name := c.Args().First()
|
||||||
ctx, cancel := installSignals()
|
statusCode, msg := private.RemoveLogger(group, name)
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
statusCode, msg := private.RemoveLogger(ctx, group, name)
|
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("InternalServerError", msg)
|
fail("InternalServerError", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
@ -374,13 +371,10 @@ func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) e
|
||||||
if c.IsSet("name") {
|
if c.IsSet("name") {
|
||||||
name = c.String("name")
|
name = c.String("name")
|
||||||
}
|
}
|
||||||
ctx, cancel := installSignals()
|
statusCode, msg := private.AddLogger(group, name, mode, vals)
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
statusCode, msg := private.AddLogger(ctx, group, name, mode, vals)
|
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("InternalServerError", msg)
|
fail("InternalServerError", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
@ -388,14 +382,11 @@ func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) e
|
||||||
}
|
}
|
||||||
|
|
||||||
func runShutdown(c *cli.Context) error {
|
func runShutdown(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setup("manager", c.Bool("debug"))
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.Shutdown(ctx)
|
statusCode, msg := private.Shutdown()
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("InternalServerError", msg)
|
fail("InternalServerError", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
@ -403,14 +394,11 @@ func runShutdown(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRestart(c *cli.Context) error {
|
func runRestart(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setup("manager", c.Bool("debug"))
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.Restart(ctx)
|
statusCode, msg := private.Restart()
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("InternalServerError", msg)
|
fail("InternalServerError", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
@ -418,14 +406,11 @@ func runRestart(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runFlushQueues(c *cli.Context) error {
|
func runFlushQueues(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setup("manager", c.Bool("debug"))
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.FlushQueues(ctx, c.Duration("timeout"), c.Bool("non-blocking"))
|
statusCode, msg := private.FlushQueues(c.Duration("timeout"), c.Bool("non-blocking"))
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("InternalServerError", msg)
|
fail("InternalServerError", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
@ -433,14 +418,11 @@ func runFlushQueues(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPauseLogging(c *cli.Context) error {
|
func runPauseLogging(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setup("manager", c.Bool("debug"))
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.PauseLogging(ctx)
|
statusCode, msg := private.PauseLogging()
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("InternalServerError", msg)
|
fail("InternalServerError", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
@ -448,14 +430,11 @@ func runPauseLogging(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runResumeLogging(c *cli.Context) error {
|
func runResumeLogging(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setup("manager", c.Bool("debug"))
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.ResumeLogging(ctx)
|
statusCode, msg := private.ResumeLogging()
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("InternalServerError", msg)
|
fail("InternalServerError", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
@ -463,14 +442,11 @@ func runResumeLogging(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runReleaseReopenLogging(c *cli.Context) error {
|
func runReleaseReopenLogging(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
setup("manager", c.Bool("debug"))
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.ReleaseReopenLogging(ctx)
|
statusCode, msg := private.ReleaseReopenLogging()
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
return fail("InternalServerError", msg)
|
fail("InternalServerError", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
|
|
@ -28,10 +28,10 @@ func runMigrate(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("AppPath: %s", setting.AppPath)
|
log.Trace("AppPath: %s", setting.AppPath)
|
||||||
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
log.Trace("AppWorkPath: %s", setting.AppWorkPath)
|
||||||
log.Info("Custom path: %s", setting.CustomPath)
|
log.Trace("Custom path: %s", setting.CustomPath)
|
||||||
log.Info("Log path: %s", setting.LogRootPath)
|
log.Trace("Log path: %s", setting.LogRootPath)
|
||||||
setting.InitDBConfig()
|
setting.InitDBConfig()
|
||||||
|
|
||||||
if err := models.NewEngine(context.Background(), migrations.Migrate); err != nil {
|
if err := models.NewEngine(context.Background(), migrations.Migrate); err != nil {
|
||||||
|
|
|
@ -110,10 +110,10 @@ func runMigrateStorage(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("AppPath: %s", setting.AppPath)
|
log.Trace("AppPath: %s", setting.AppPath)
|
||||||
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
log.Trace("AppWorkPath: %s", setting.AppWorkPath)
|
||||||
log.Info("Custom path: %s", setting.CustomPath)
|
log.Trace("Custom path: %s", setting.CustomPath)
|
||||||
log.Info("Log path: %s", setting.LogRootPath)
|
log.Trace("Log path: %s", setting.LogRootPath)
|
||||||
setting.InitDBConfig()
|
setting.InitDBConfig()
|
||||||
|
|
||||||
if err := models.NewEngine(context.Background(), migrations.Migrate); err != nil {
|
if err := models.NewEngine(context.Background(), migrations.Migrate); err != nil {
|
||||||
|
@ -184,7 +184,7 @@ func runMigrateStorage(ctx *cli.Context) error {
|
||||||
return fmt.Errorf("Unsupported storage: %s", ctx.String("type"))
|
return fmt.Errorf("Unsupported storage: %s", ctx.String("type"))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Warn("All files have been copied to the new placement but old files are still on the original placement.")
|
log.Warn("All files have been copied to the new placement but old files are still on the orignial placement.")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,15 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"context"
|
||||||
"net/http"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/private"
|
"code.gitea.io/gitea/modules/migrations"
|
||||||
|
"code.gitea.io/gitea/modules/migrations/base"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/storage"
|
||||||
|
pull_service "code.gitea.io/gitea/services/pull"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
@ -46,23 +49,71 @@ wiki, issues, labels, releases, release_assets, milestones, pull_requests, comme
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRestoreRepository(c *cli.Context) error {
|
func runRestoreRepository(ctx *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
if err := initDB(); err != nil {
|
||||||
defer cancel()
|
return err
|
||||||
|
|
||||||
setting.NewContext()
|
|
||||||
|
|
||||||
statusCode, errStr := private.RestoreRepo(
|
|
||||||
ctx,
|
|
||||||
c.String("repo_dir"),
|
|
||||||
c.String("owner_name"),
|
|
||||||
c.String("repo_name"),
|
|
||||||
c.StringSlice("units"),
|
|
||||||
)
|
|
||||||
if statusCode == http.StatusOK {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Fatal("Failed to restore repository: %v", errStr)
|
log.Trace("AppPath: %s", setting.AppPath)
|
||||||
return errors.New(errStr)
|
log.Trace("AppWorkPath: %s", setting.AppWorkPath)
|
||||||
|
log.Trace("Custom path: %s", setting.CustomPath)
|
||||||
|
log.Trace("Log path: %s", setting.LogRootPath)
|
||||||
|
setting.InitDBConfig()
|
||||||
|
|
||||||
|
if err := storage.Init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pull_service.Init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts = base.MigrateOptions{
|
||||||
|
RepoName: ctx.String("repo_name"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ctx.String("units")) == 0 {
|
||||||
|
opts.Wiki = true
|
||||||
|
opts.Issues = true
|
||||||
|
opts.Milestones = true
|
||||||
|
opts.Labels = true
|
||||||
|
opts.Releases = true
|
||||||
|
opts.Comments = true
|
||||||
|
opts.PullRequests = true
|
||||||
|
opts.ReleaseAssets = true
|
||||||
|
} else {
|
||||||
|
units := strings.Split(ctx.String("units"), ",")
|
||||||
|
for _, unit := range units {
|
||||||
|
switch strings.ToLower(unit) {
|
||||||
|
case "wiki":
|
||||||
|
opts.Wiki = true
|
||||||
|
case "issues":
|
||||||
|
opts.Issues = true
|
||||||
|
case "milestones":
|
||||||
|
opts.Milestones = true
|
||||||
|
case "labels":
|
||||||
|
opts.Labels = true
|
||||||
|
case "releases":
|
||||||
|
opts.Releases = true
|
||||||
|
case "release_assets":
|
||||||
|
opts.ReleaseAssets = true
|
||||||
|
case "comments":
|
||||||
|
opts.Comments = true
|
||||||
|
case "pull_requests":
|
||||||
|
opts.PullRequests = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := migrations.RestoreRepository(
|
||||||
|
context.Background(),
|
||||||
|
ctx.String("repo_dir"),
|
||||||
|
ctx.String("owner_name"),
|
||||||
|
ctx.String("repo_name"),
|
||||||
|
); err != nil {
|
||||||
|
log.Fatal("Failed to restore repository: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
84
cmd/serv.go
84
cmd/serv.go
|
@ -6,6 +6,7 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -17,15 +18,13 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/lfs"
|
||||||
"code.gitea.io/gitea/modules/json"
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/pprof"
|
"code.gitea.io/gitea/modules/pprof"
|
||||||
"code.gitea.io/gitea/modules/private"
|
"code.gitea.io/gitea/modules/private"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/services/lfs"
|
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/dgrijalva/jwt-go"
|
||||||
"github.com/kballard/go-shellquote"
|
"github.com/kballard/go-shellquote"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
@ -59,7 +58,7 @@ func setup(logPath string, debug bool) {
|
||||||
}
|
}
|
||||||
setting.NewContext()
|
setting.NewContext()
|
||||||
if debug {
|
if debug {
|
||||||
setting.RunMode = "dev"
|
setting.ProdMode = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,30 +72,19 @@ var (
|
||||||
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
|
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func fail(userMessage, logMessage string, args ...interface{}) error {
|
func fail(userMessage, logMessage string, args ...interface{}) {
|
||||||
// There appears to be a chance to cause a zombie process and failure to read the Exit status
|
|
||||||
// if nothing is outputted on stdout.
|
|
||||||
fmt.Fprintln(os.Stdout, "")
|
|
||||||
fmt.Fprintln(os.Stderr, "Gitea:", userMessage)
|
fmt.Fprintln(os.Stderr, "Gitea:", userMessage)
|
||||||
|
|
||||||
if len(logMessage) > 0 {
|
if len(logMessage) > 0 {
|
||||||
if !setting.IsProd() {
|
if !setting.ProdMode {
|
||||||
fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
|
fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if len(logMessage) > 0 {
|
os.Exit(1)
|
||||||
_ = private.SSHLog(ctx, true, fmt.Sprintf(logMessage+": ", args...))
|
|
||||||
}
|
|
||||||
return cli.NewExitError(fmt.Sprintf("Gitea: %s", userMessage), 1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runServ(c *cli.Context) error {
|
func runServ(c *cli.Context) error {
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// FIXME: This needs to internationalised
|
// FIXME: This needs to internationalised
|
||||||
setup("serv.log", c.Bool("debug"))
|
setup("serv.log", c.Bool("debug"))
|
||||||
|
|
||||||
|
@ -114,18 +102,18 @@ func runServ(c *cli.Context) error {
|
||||||
|
|
||||||
keys := strings.Split(c.Args()[0], "-")
|
keys := strings.Split(c.Args()[0], "-")
|
||||||
if len(keys) != 2 || keys[0] != "key" {
|
if len(keys) != 2 || keys[0] != "key" {
|
||||||
return fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
|
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
|
||||||
}
|
}
|
||||||
keyID, err := strconv.ParseInt(keys[1], 10, 64)
|
keyID, err := strconv.ParseInt(keys[1], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fail("Key ID format error", "Invalid key argument: %s", c.Args()[1])
|
fail("Key ID format error", "Invalid key argument: %s", c.Args()[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
|
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
|
||||||
if len(cmd) == 0 {
|
if len(cmd) == 0 {
|
||||||
key, user, err := private.ServNoCommand(ctx, keyID)
|
key, user, err := private.ServNoCommand(keyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fail("Internal error", "Failed to check provided key: %v", err)
|
fail("Internal error", "Failed to check provided key: %v", err)
|
||||||
}
|
}
|
||||||
switch key.Type {
|
switch key.Type {
|
||||||
case models.KeyTypeDeploy:
|
case models.KeyTypeDeploy:
|
||||||
|
@ -143,18 +131,11 @@ func runServ(c *cli.Context) error {
|
||||||
|
|
||||||
words, err := shellquote.Split(cmd)
|
words, err := shellquote.Split(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fail("Error parsing arguments", "Failed to parse arguments: %v", err)
|
fail("Error parsing arguments", "Failed to parse arguments: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(words) < 2 {
|
if len(words) < 2 {
|
||||||
if git.CheckGitVersionAtLeast("2.29") == nil {
|
fail("Too few arguments", "Too few arguments in cmd: %s", cmd)
|
||||||
// for AGit Flow
|
|
||||||
if cmd == "ssh_info" {
|
|
||||||
fmt.Print(`{"type":"gitea","version":1}`)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fail("Too few arguments", "Too few arguments in cmd: %s", cmd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
verb := words[0]
|
verb := words[0]
|
||||||
|
@ -166,7 +147,7 @@ func runServ(c *cli.Context) error {
|
||||||
var lfsVerb string
|
var lfsVerb string
|
||||||
if verb == lfsAuthenticateVerb {
|
if verb == lfsAuthenticateVerb {
|
||||||
if !setting.LFS.StartServer {
|
if !setting.LFS.StartServer {
|
||||||
return fail("Unknown git command", "LFS authentication request over SSH denied, LFS support is disabled")
|
fail("Unknown git command", "LFS authentication request over SSH denied, LFS support is disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(words) > 2 {
|
if len(words) > 2 {
|
||||||
|
@ -179,37 +160,37 @@ func runServ(c *cli.Context) error {
|
||||||
|
|
||||||
rr := strings.SplitN(repoPath, "/", 2)
|
rr := strings.SplitN(repoPath, "/", 2)
|
||||||
if len(rr) != 2 {
|
if len(rr) != 2 {
|
||||||
return fail("Invalid repository path", "Invalid repository path: %v", repoPath)
|
fail("Invalid repository path", "Invalid repository path: %v", repoPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
username := strings.ToLower(rr[0])
|
username := strings.ToLower(rr[0])
|
||||||
reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git"))
|
reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git"))
|
||||||
|
|
||||||
if alphaDashDotPattern.MatchString(reponame) {
|
if alphaDashDotPattern.MatchString(reponame) {
|
||||||
return fail("Invalid repo name", "Invalid repo name: %s", reponame)
|
fail("Invalid repo name", "Invalid repo name: %s", reponame)
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.EnablePprof || c.Bool("enable-pprof") {
|
if setting.EnablePprof || c.Bool("enable-pprof") {
|
||||||
if err := os.MkdirAll(setting.PprofDataPath, os.ModePerm); err != nil {
|
if err := os.MkdirAll(setting.PprofDataPath, os.ModePerm); err != nil {
|
||||||
return fail("Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)
|
fail("Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stopCPUProfiler, err := pprof.DumpCPUProfileForUsername(setting.PprofDataPath, username)
|
stopCPUProfiler, err := pprof.DumpCPUProfileForUsername(setting.PprofDataPath, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fail("Internal Server Error", "Unable to start CPU profile: %v", err)
|
fail("Internal Server Error", "Unable to start CPU profile: %v", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
stopCPUProfiler()
|
stopCPUProfiler()
|
||||||
err := pprof.DumpMemProfileForUsername(setting.PprofDataPath, username)
|
err := pprof.DumpMemProfileForUsername(setting.PprofDataPath, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = fail("Internal Server Error", "Unable to dump Mem Profile: %v", err)
|
fail("Internal Server Error", "Unable to dump Mem Profile: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
requestedMode, has := allowedCommands[verb]
|
requestedMode, has := allowedCommands[verb]
|
||||||
if !has {
|
if !has {
|
||||||
return fail("Unknown git command", "Unknown git command %s", verb)
|
fail("Unknown git command", "Unknown git command %s", verb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if verb == lfsAuthenticateVerb {
|
if verb == lfsAuthenticateVerb {
|
||||||
|
@ -218,20 +199,21 @@ func runServ(c *cli.Context) error {
|
||||||
} else if lfsVerb == "download" {
|
} else if lfsVerb == "download" {
|
||||||
requestedMode = models.AccessModeRead
|
requestedMode = models.AccessModeRead
|
||||||
} else {
|
} else {
|
||||||
return fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb)
|
fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results, err := private.ServCommand(ctx, keyID, username, reponame, requestedMode, verb, lfsVerb)
|
results, err := private.ServCommand(keyID, username, reponame, requestedMode, verb, lfsVerb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if private.IsErrServCommand(err) {
|
if private.IsErrServCommand(err) {
|
||||||
errServCommand := err.(private.ErrServCommand)
|
errServCommand := err.(private.ErrServCommand)
|
||||||
if errServCommand.StatusCode != http.StatusInternalServerError {
|
if errServCommand.StatusCode != http.StatusInternalServerError {
|
||||||
return fail("Unauthorized", "%s", errServCommand.Error())
|
fail("Unauthorized", "%s", errServCommand.Error())
|
||||||
|
} else {
|
||||||
|
fail("Internal Server Error", "%s", errServCommand.Error())
|
||||||
}
|
}
|
||||||
return fail("Internal Server Error", "%s", errServCommand.Error())
|
|
||||||
}
|
}
|
||||||
return fail("Internal Server Error", "%s", err.Error())
|
fail("Internal Server Error", "%s", err.Error())
|
||||||
}
|
}
|
||||||
os.Setenv(models.EnvRepoIsWiki, strconv.FormatBool(results.IsWiki))
|
os.Setenv(models.EnvRepoIsWiki, strconv.FormatBool(results.IsWiki))
|
||||||
os.Setenv(models.EnvRepoName, results.RepoName)
|
os.Setenv(models.EnvRepoName, results.RepoName)
|
||||||
|
@ -264,7 +246,7 @@ func runServ(c *cli.Context) error {
|
||||||
// Sign and get the complete encoded token as a string using the secret
|
// Sign and get the complete encoded token as a string using the secret
|
||||||
tokenString, err := token.SignedString(setting.LFS.JWTSecretBytes)
|
tokenString, err := token.SignedString(setting.LFS.JWTSecretBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fail("Internal error", "Failed to sign JWT token: %v", err)
|
fail("Internal error", "Failed to sign JWT token: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenAuthentication := &models.LFSTokenResponse{
|
tokenAuthentication := &models.LFSTokenResponse{
|
||||||
|
@ -276,7 +258,7 @@ func runServ(c *cli.Context) error {
|
||||||
enc := json.NewEncoder(os.Stdout)
|
enc := json.NewEncoder(os.Stdout)
|
||||||
err = enc.Encode(tokenAuthentication)
|
err = enc.Encode(tokenAuthentication)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fail("Internal error", "Failed to encode LFS json response: %v", err)
|
fail("Internal error", "Failed to encode LFS json response: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -289,9 +271,9 @@ func runServ(c *cli.Context) error {
|
||||||
var gitcmd *exec.Cmd
|
var gitcmd *exec.Cmd
|
||||||
verbs := strings.Split(verb, " ")
|
verbs := strings.Split(verb, " ")
|
||||||
if len(verbs) == 2 {
|
if len(verbs) == 2 {
|
||||||
gitcmd = exec.CommandContext(ctx, verbs[0], verbs[1], repoPath)
|
gitcmd = exec.Command(verbs[0], verbs[1], repoPath)
|
||||||
} else {
|
} else {
|
||||||
gitcmd = exec.CommandContext(ctx, verb, repoPath)
|
gitcmd = exec.Command(verb, repoPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
gitcmd.Dir = setting.RepoRootPath
|
gitcmd.Dir = setting.RepoRootPath
|
||||||
|
@ -299,13 +281,13 @@ func runServ(c *cli.Context) error {
|
||||||
gitcmd.Stdin = os.Stdin
|
gitcmd.Stdin = os.Stdin
|
||||||
gitcmd.Stderr = os.Stderr
|
gitcmd.Stderr = os.Stderr
|
||||||
if err = gitcmd.Run(); err != nil {
|
if err = gitcmd.Run(); err != nil {
|
||||||
return fail("Internal error", "Failed to execute git command: %v", err)
|
fail("Internal error", "Failed to execute git command: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update user key activity.
|
// Update user key activity.
|
||||||
if results.KeyID > 0 {
|
if results.KeyID > 0 {
|
||||||
if err = private.UpdatePublicKeyInRepo(ctx, results.KeyID, results.RepoID); err != nil {
|
if err = private.UpdatePublicKeyInRepo(results.KeyID, results.RepoID); err != nil {
|
||||||
return fail("Internal error", "UpdatePublicKeyInRepo: %v", err)
|
fail("Internal error", "UpdatePublicKeyInRepo: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
91
cmd/web.go
91
cmd/web.go
|
@ -16,11 +16,13 @@ import (
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/routers"
|
"code.gitea.io/gitea/routers"
|
||||||
"code.gitea.io/gitea/routers/install"
|
"code.gitea.io/gitea/routers/routes"
|
||||||
|
|
||||||
context2 "github.com/gorilla/context"
|
context2 "github.com/gorilla/context"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
"golang.org/x/crypto/acme/autocert"
|
||||||
ini "gopkg.in/ini.v1"
|
ini "gopkg.in/ini.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,14 +49,6 @@ and it takes care of all the other things for you`,
|
||||||
Value: setting.PIDFile,
|
Value: setting.PIDFile,
|
||||||
Usage: "Custom pid file path",
|
Usage: "Custom pid file path",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "quiet, q",
|
|
||||||
Usage: "Only display Fatal logging errors until logging is set-up",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "verbose",
|
|
||||||
Usage: "Set initial logging to TRACE level until logging is properly set-up",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,27 +65,44 @@ func runHTTPRedirector() {
|
||||||
http.Redirect(w, r, target, http.StatusTemporaryRedirect)
|
http.Redirect(w, r, target, http.StatusTemporaryRedirect)
|
||||||
})
|
})
|
||||||
|
|
||||||
var err = runHTTP("tcp", source, "HTTP Redirector", context2.ClearHandler(handler))
|
var err = runHTTP("tcp", source, context2.ClearHandler(handler))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to start port redirection: %v", err)
|
log.Fatal("Failed to start port redirection: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runWeb(ctx *cli.Context) error {
|
func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error {
|
||||||
if ctx.Bool("verbose") {
|
certManager := autocert.Manager{
|
||||||
_ = log.DelLogger("console")
|
Prompt: autocert.AcceptTOS,
|
||||||
log.NewLogger(0, "console", "console", fmt.Sprintf(`{"level": "trace", "colorize": %t, "stacktraceLevel": "none"}`, log.CanColorStdout))
|
HostPolicy: autocert.HostWhitelist(domain),
|
||||||
} else if ctx.Bool("quiet") {
|
Cache: autocert.DirCache(directory),
|
||||||
_ = log.DelLogger("console")
|
Email: email,
|
||||||
log.NewLogger(0, "console", "console", fmt.Sprintf(`{"level": "fatal", "colorize": %t, "stacktraceLevel": "none"}`, log.CanColorStdout))
|
|
||||||
}
|
}
|
||||||
defer func() {
|
go func() {
|
||||||
if panicked := recover(); panicked != nil {
|
log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
|
||||||
log.Fatal("PANIC: %v\n%s", panicked, string(log.Stack(2)))
|
// all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here)
|
||||||
|
var err = runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
return runHTTPSWithTLSConfig("tcp", listenAddr, certManager.TLSConfig(), context2.ClearHandler(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "GET" && r.Method != "HEAD" {
|
||||||
|
http.Error(w, "Use HTTPS", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Remove the trailing slash at the end of setting.AppURL, the request
|
||||||
|
// URI always contains a leading slash, which would result in a double
|
||||||
|
// slash
|
||||||
|
target := strings.TrimSuffix(setting.AppURL, "/") + r.URL.RequestURI()
|
||||||
|
http.Redirect(w, r, target, http.StatusFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runWeb(ctx *cli.Context) error {
|
||||||
managerCtx, cancel := context.WithCancel(context.Background())
|
managerCtx, cancel := context.WithCancel(context.Background())
|
||||||
graceful.InitManager(managerCtx)
|
graceful.InitManager(managerCtx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -109,7 +120,7 @@ func runWeb(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform pre-initialization
|
// Perform pre-initialization
|
||||||
needsInstall := install.PreloadSettings(graceful.GetManager().HammerContext())
|
needsInstall := routers.PreInstallInit(graceful.GetManager().HammerContext())
|
||||||
if needsInstall {
|
if needsInstall {
|
||||||
// Flag for port number in case first time run conflict
|
// Flag for port number in case first time run conflict
|
||||||
if ctx.IsSet("port") {
|
if ctx.IsSet("port") {
|
||||||
|
@ -122,7 +133,8 @@ func runWeb(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c := install.Routes()
|
c := routes.NewChi()
|
||||||
|
routes.RegisterInstallRoute(c)
|
||||||
err := listen(c, false)
|
err := listen(c, false)
|
||||||
select {
|
select {
|
||||||
case <-graceful.GetManager().IsShutdown():
|
case <-graceful.GetManager().IsShutdown():
|
||||||
|
@ -153,9 +165,11 @@ func runWeb(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up Chi routes
|
// Set up Chi routes
|
||||||
c := routers.NormalRoutes()
|
c := routes.NewChi()
|
||||||
|
c.Mount("/", routes.NormalRoutes())
|
||||||
|
routes.DelegateToMacaron(c)
|
||||||
|
|
||||||
err := listen(c, true)
|
err := listen(c, true)
|
||||||
<-graceful.GetManager().Done()
|
<-graceful.GetManager().Done()
|
||||||
log.Info("PID: %d Gitea Web Finished", os.Getpid())
|
log.Info("PID: %d Gitea Web Finished", os.Getpid())
|
||||||
|
@ -172,6 +186,19 @@ func setPort(port string) error {
|
||||||
case setting.FCGI:
|
case setting.FCGI:
|
||||||
case setting.FCGIUnix:
|
case setting.FCGIUnix:
|
||||||
default:
|
default:
|
||||||
|
// Save LOCAL_ROOT_URL if port changed
|
||||||
|
cfg := ini.Empty()
|
||||||
|
isFile, err := util.IsFile(setting.CustomConf)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Unable to check if %s is a file", err)
|
||||||
|
}
|
||||||
|
if isFile {
|
||||||
|
// Keeps custom settings if there is already something.
|
||||||
|
if err := cfg.Append(setting.CustomConf); err != nil {
|
||||||
|
return fmt.Errorf("Failed to load custom conf '%s': %v", setting.CustomConf, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defaultLocalURL := string(setting.Protocol) + "://"
|
defaultLocalURL := string(setting.Protocol) + "://"
|
||||||
if setting.HTTPAddr == "0.0.0.0" {
|
if setting.HTTPAddr == "0.0.0.0" {
|
||||||
defaultLocalURL += "localhost"
|
defaultLocalURL += "localhost"
|
||||||
|
@ -180,10 +207,10 @@ func setPort(port string) error {
|
||||||
}
|
}
|
||||||
defaultLocalURL += ":" + setting.HTTPPort + "/"
|
defaultLocalURL += ":" + setting.HTTPPort + "/"
|
||||||
|
|
||||||
// Save LOCAL_ROOT_URL if port changed
|
|
||||||
setting.CreateOrAppendToCustomConf(func(cfg *ini.File) {
|
|
||||||
cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
|
cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
|
||||||
})
|
if err := cfg.SaveTo(setting.CustomConf); err != nil {
|
||||||
|
return fmt.Errorf("Error saving generated JWT Secret to custom config: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -205,7 +232,7 @@ func listen(m http.Handler, handleRedirector bool) error {
|
||||||
if handleRedirector {
|
if handleRedirector {
|
||||||
NoHTTPRedirector()
|
NoHTTPRedirector()
|
||||||
}
|
}
|
||||||
err = runHTTP("tcp", listenAddr, "Web", context2.ClearHandler(m))
|
err = runHTTP("tcp", listenAddr, context2.ClearHandler(m))
|
||||||
case setting.HTTPS:
|
case setting.HTTPS:
|
||||||
if setting.EnableLetsEncrypt {
|
if setting.EnableLetsEncrypt {
|
||||||
err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m))
|
err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m))
|
||||||
|
@ -218,22 +245,22 @@ func listen(m http.Handler, handleRedirector bool) error {
|
||||||
NoHTTPRedirector()
|
NoHTTPRedirector()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
|
err = runHTTPS("tcp", listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
|
||||||
case setting.FCGI:
|
case setting.FCGI:
|
||||||
if handleRedirector {
|
if handleRedirector {
|
||||||
NoHTTPRedirector()
|
NoHTTPRedirector()
|
||||||
}
|
}
|
||||||
err = runFCGI("tcp", listenAddr, "FCGI Web", context2.ClearHandler(m))
|
err = runFCGI("tcp", listenAddr, context2.ClearHandler(m))
|
||||||
case setting.UnixSocket:
|
case setting.UnixSocket:
|
||||||
if handleRedirector {
|
if handleRedirector {
|
||||||
NoHTTPRedirector()
|
NoHTTPRedirector()
|
||||||
}
|
}
|
||||||
err = runHTTP("unix", listenAddr, "Web", context2.ClearHandler(m))
|
err = runHTTP("unix", listenAddr, context2.ClearHandler(m))
|
||||||
case setting.FCGIUnix:
|
case setting.FCGIUnix:
|
||||||
if handleRedirector {
|
if handleRedirector {
|
||||||
NoHTTPRedirector()
|
NoHTTPRedirector()
|
||||||
}
|
}
|
||||||
err = runFCGI("unix", listenAddr, "Web", context2.ClearHandler(m))
|
err = runFCGI("unix", listenAddr, context2.ClearHandler(m))
|
||||||
default:
|
default:
|
||||||
log.Fatal("Invalid protocol: %s", setting.Protocol)
|
log.Fatal("Invalid protocol: %s", setting.Protocol)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,23 +9,21 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/fcgi"
|
"net/http/fcgi"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func runHTTP(network, listenAddr, name string, m http.Handler) error {
|
func runHTTP(network, listenAddr string, m http.Handler) error {
|
||||||
return graceful.HTTPListenAndServe(network, listenAddr, name, m)
|
return graceful.HTTPListenAndServe(network, listenAddr, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler) error {
|
func runHTTPS(network, listenAddr, certFile, keyFile string, m http.Handler) error {
|
||||||
return graceful.HTTPListenAndServeTLS(network, listenAddr, name, certFile, keyFile, m)
|
return graceful.HTTPListenAndServeTLS(network, listenAddr, certFile, keyFile, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler) error {
|
func runHTTPSWithTLSConfig(network, listenAddr string, tlsConfig *tls.Config, m http.Handler) error {
|
||||||
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
|
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, tlsConfig, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector
|
// NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector
|
||||||
|
@ -45,17 +43,12 @@ func NoInstallListener() {
|
||||||
graceful.GetManager().InformCleanup()
|
graceful.GetManager().InformCleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
func runFCGI(network, listenAddr, name string, m http.Handler) error {
|
func runFCGI(network, listenAddr string, m http.Handler) error {
|
||||||
// This needs to handle stdin as fcgi point
|
// This needs to handle stdin as fcgi point
|
||||||
fcgiServer := graceful.NewServer(network, listenAddr, name)
|
fcgiServer := graceful.NewServer(network, listenAddr)
|
||||||
|
|
||||||
err := fcgiServer.ListenAndServe(func(listener net.Listener) error {
|
err := fcgiServer.ListenAndServe(func(listener net.Listener) error {
|
||||||
return fcgi.Serve(listener, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
return fcgi.Serve(listener, m)
|
||||||
if setting.AppSubURL != "" {
|
|
||||||
req.URL.Path = strings.TrimPrefix(req.URL.Path, setting.AppSubURL)
|
|
||||||
}
|
|
||||||
m.ServeHTTP(resp, req)
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to start FCGI main server: %v", err)
|
log.Fatal("Failed to start FCGI main server: %v", err)
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
|
||||||
|
|
||||||
"github.com/caddyserver/certmagic"
|
|
||||||
context2 "github.com/gorilla/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error {
|
|
||||||
|
|
||||||
// If HTTP Challenge enabled, needs to be serving on port 80. For TLSALPN needs 443.
|
|
||||||
// Due to docker port mapping this can't be checked programmatically
|
|
||||||
// TODO: these are placeholders until we add options for each in settings with appropriate warning
|
|
||||||
enableHTTPChallenge := true
|
|
||||||
enableTLSALPNChallenge := true
|
|
||||||
altHTTPPort := 0
|
|
||||||
altTLSALPNPort := 0
|
|
||||||
|
|
||||||
if p, err := strconv.Atoi(setting.PortToRedirect); err == nil {
|
|
||||||
altHTTPPort = p
|
|
||||||
}
|
|
||||||
if p, err := strconv.Atoi(setting.HTTPPort); err == nil {
|
|
||||||
altTLSALPNPort = p
|
|
||||||
}
|
|
||||||
|
|
||||||
magic := certmagic.NewDefault()
|
|
||||||
magic.Storage = &certmagic.FileStorage{Path: directory}
|
|
||||||
myACME := certmagic.NewACMEManager(magic, certmagic.ACMEManager{
|
|
||||||
Email: email,
|
|
||||||
Agreed: setting.LetsEncryptTOS,
|
|
||||||
DisableHTTPChallenge: !enableHTTPChallenge,
|
|
||||||
DisableTLSALPNChallenge: !enableTLSALPNChallenge,
|
|
||||||
ListenHost: setting.HTTPAddr,
|
|
||||||
AltTLSALPNPort: altTLSALPNPort,
|
|
||||||
AltHTTPPort: altHTTPPort,
|
|
||||||
})
|
|
||||||
|
|
||||||
magic.Issuers = []certmagic.Issuer{myACME}
|
|
||||||
|
|
||||||
// this obtains certificates or renews them if necessary
|
|
||||||
err := magic.ManageSync([]string{domain})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsConfig := magic.TLSConfig()
|
|
||||||
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2")
|
|
||||||
|
|
||||||
if enableHTTPChallenge {
|
|
||||||
go func() {
|
|
||||||
log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
|
|
||||||
// all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here)
|
|
||||||
var err = runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, "Let's Encrypt HTTP Challenge", myACME.HTTPChallengeHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
return runHTTPSWithTLSConfig("tcp", listenAddr, "Web", tlsConfig, context2.ClearHandler(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "GET" && r.Method != "HEAD" {
|
|
||||||
http.Error(w, "Use HTTPS", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Remove the trailing slash at the end of setting.AppURL, the request
|
|
||||||
// URI always contains a leading slash, which would result in a double
|
|
||||||
// slash
|
|
||||||
target := strings.TrimSuffix(setting.AppURL, "/") + r.URL.RequestURI()
|
|
||||||
http.Redirect(w, r, target, http.StatusFound)
|
|
||||||
}
|
|
|
@ -22,13 +22,11 @@ The environment variables should be of the form:
|
||||||
|
|
||||||
GITEA__SECTION_NAME__KEY_NAME
|
GITEA__SECTION_NAME__KEY_NAME
|
||||||
|
|
||||||
Note, SECTION_NAME in the notation above is case-insensitive.
|
|
||||||
|
|
||||||
Environment variables are usually restricted to a reduced character
|
Environment variables are usually restricted to a reduced character
|
||||||
set "0-9A-Z_" - in order to allow the setting of sections with
|
set "0-9A-Z_" - in order to allow the setting of sections with
|
||||||
characters outside of that set, they should be escaped as following:
|
characters outside of that set, they should be escaped as following:
|
||||||
"_0X2E_" for "." and "_0X2D_" for "-". The entire section and key names
|
"_0X2E_" for ".". The entire section and key names can be escaped as
|
||||||
can be escaped as a UTF8 byte string if necessary. E.g. to configure:
|
a UTF8 byte string if necessary. E.g. to configure:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
@ -42,6 +40,27 @@ You would set the environment variables: "GITEA__LOG_0x2E_CONSOLE__COLORIZE=fals
|
||||||
and "GITEA__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
|
and "GITEA__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
|
||||||
on the configuration cheat sheet.
|
on the configuration cheat sheet.
|
||||||
|
|
||||||
To build locally, run:
|
To plug this command in to the docker, you simply compile the provided go file using:
|
||||||
|
|
||||||
|
go build environment-to-ini.go
|
||||||
|
|
||||||
|
And copy the resulting `environment-to-ini` command to /app/gitea in the docker.
|
||||||
|
|
||||||
|
Apply the below patch to /etc/s6/gitea.setup to wire this in.
|
||||||
|
|
||||||
|
If you find this useful please comment on #7287
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/docker/root/etc/s6/gitea/setup b/docker/root/etc/s6/gitea/setup
|
||||||
|
index f87ce9115..565bfcba9 100755
|
||||||
|
--- a/docker/root/etc/s6/gitea/setup
|
||||||
|
+++ b/docker/root/etc/s6/gitea/setup
|
||||||
|
@@ -44,6 +44,8 @@ if [ ! -f ${GITEA_CUSTOM}/conf/app.ini ]; then
|
||||||
|
SECRET_KEY=${SECRET_KEY:-""} \
|
||||||
|
envsubst < /etc/templates/app.ini > ${GITEA_CUSTOM}/conf/app.ini
|
||||||
|
|
||||||
|
+ /app/gitea/environment-to-ini -c ${GITEA_CUSTOM}/conf/app.ini
|
||||||
|
+
|
||||||
|
chown ${USER}:git ${GITEA_CUSTOM}/conf/app.ini
|
||||||
|
fi
|
||||||
|
|
||||||
go build contrib/environment-to-ini/environment-to-ini.go
|
|
||||||
|
|
|
@ -110,8 +110,6 @@ func runEnvironmentToIni(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
cfg.NameMapper = ini.SnackCase
|
cfg.NameMapper = ini.SnackCase
|
||||||
|
|
||||||
changed := false
|
|
||||||
|
|
||||||
prefix := c.String("prefix") + "__"
|
prefix := c.String("prefix") + "__"
|
||||||
|
|
||||||
for _, kv := range os.Environ() {
|
for _, kv := range os.Environ() {
|
||||||
|
@ -145,22 +143,16 @@ func runEnvironmentToIni(c *cli.Context) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
oldValue := key.Value()
|
|
||||||
if !changed && oldValue != value {
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
key.SetValue(value)
|
key.SetValue(value)
|
||||||
}
|
}
|
||||||
destination := c.String("out")
|
destination := c.String("out")
|
||||||
if len(destination) == 0 {
|
if len(destination) == 0 {
|
||||||
destination = setting.CustomConf
|
destination = setting.CustomConf
|
||||||
}
|
}
|
||||||
if destination != setting.CustomConf || changed {
|
|
||||||
err = cfg.SaveTo(destination)
|
err = cfg.SaveTo(destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if c.Bool("clear") {
|
if c.Bool("clear") {
|
||||||
for _, kv := range os.Environ() {
|
for _, kv := range os.Environ() {
|
||||||
idx := strings.IndexByte(kv, '=')
|
idx := strings.IndexByte(kv, '=')
|
||||||
|
@ -232,6 +224,5 @@ func DecodeSectionKey(encoded string) (string, string) {
|
||||||
} else {
|
} else {
|
||||||
key += remaining
|
key += remaining
|
||||||
}
|
}
|
||||||
section = strings.ToLower(section)
|
|
||||||
return section, key
|
return section, key
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
gitea_git "code.gitea.io/gitea/modules/git"
|
|
||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
"code.gitea.io/gitea/modules/markup/external"
|
"code.gitea.io/gitea/modules/markup/external"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/routers"
|
"code.gitea.io/gitea/routers"
|
||||||
|
"code.gitea.io/gitea/routers/routes"
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/config"
|
"github.com/go-git/go-git/v5/config"
|
||||||
|
@ -80,7 +80,7 @@ func runPR() {
|
||||||
setting.RunUser = curUser.Username
|
setting.RunUser = curUser.Username
|
||||||
|
|
||||||
log.Printf("[PR] Loading fixtures data ...\n")
|
log.Printf("[PR] Loading fixtures data ...\n")
|
||||||
gitea_git.CheckLFSVersion()
|
setting.CheckLFSVersion()
|
||||||
//models.LoadConfigs()
|
//models.LoadConfigs()
|
||||||
/*
|
/*
|
||||||
setting.Database.Type = "sqlite3"
|
setting.Database.Type = "sqlite3"
|
||||||
|
@ -114,9 +114,11 @@ func runPR() {
|
||||||
|
|
||||||
log.Printf("[PR] Setting up router\n")
|
log.Printf("[PR] Setting up router\n")
|
||||||
//routers.GlobalInit()
|
//routers.GlobalInit()
|
||||||
external.RegisterRenderers()
|
external.RegisterParsers()
|
||||||
markup.Init()
|
markup.Init()
|
||||||
c := routers.NormalRoutes()
|
c := routes.NewChi()
|
||||||
|
c.Mount("/", routes.NormalRoutes())
|
||||||
|
routes.DelegateToMacaron(c)
|
||||||
|
|
||||||
log.Printf("[PR] Ready for testing !\n")
|
log.Printf("[PR] Ready for testing !\n")
|
||||||
log.Printf("[PR] Login with user1, user2, user3, ... with pass: password\n")
|
log.Printf("[PR] Login with user1, user2, user3, ... with pass: password\n")
|
||||||
|
|
|
@ -3,23 +3,14 @@ Description=Gitea (Git with a cup of tea)
|
||||||
After=syslog.target
|
After=syslog.target
|
||||||
After=network.target
|
After=network.target
|
||||||
###
|
###
|
||||||
# Don't forget to add the database service dependencies
|
# Don't forget to add the database service requirements
|
||||||
###
|
###
|
||||||
#
|
#
|
||||||
#Wants=mysql.service
|
#Requires=mysql.service
|
||||||
#After=mysql.service
|
#Requires=mariadb.service
|
||||||
#
|
#Requires=postgresql.service
|
||||||
#Wants=mariadb.service
|
#Requires=memcached.service
|
||||||
#After=mariadb.service
|
#Requires=redis.service
|
||||||
#
|
|
||||||
#Wants=postgresql.service
|
|
||||||
#After=postgresql.service
|
|
||||||
#
|
|
||||||
#Wants=memcached.service
|
|
||||||
#After=memcached.service
|
|
||||||
#
|
|
||||||
#Wants=redis.service
|
|
||||||
#After=redis.service
|
|
||||||
#
|
#
|
||||||
###
|
###
|
||||||
# If using socket activation for main http/s
|
# If using socket activation for main http/s
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
grep 'git' go.mod | grep '\.com' | grep -v indirect | grep -v replace | cut -f 2 | cut -d ' ' -f 1 | while read line; do
|
|
||||||
go get -u "$line"
|
|
||||||
make vendor
|
|
||||||
git add .
|
|
||||||
git commit -S -m "update $line"
|
|
||||||
done
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +1,18 @@
|
||||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-rootless
|
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}-rootless
|
||||||
{{#if build.tags}}
|
{{#if build.tags}}
|
||||||
tags:
|
tags:
|
||||||
{{#each build.tags}}
|
{{#each build.tags}}
|
||||||
- {{this}}-rootless
|
- {{this}}-rootless
|
||||||
{{/each}}
|
{{/each}}
|
||||||
- "latest-rootless"
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
manifests:
|
manifests:
|
||||||
-
|
-
|
||||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-amd64-rootless
|
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64-rootless
|
||||||
platform:
|
platform:
|
||||||
architecture: amd64
|
architecture: amd64
|
||||||
os: linux
|
os: linux
|
||||||
-
|
-
|
||||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-arm64-rootless
|
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64-rootless
|
||||||
platform:
|
platform:
|
||||||
architecture: arm64
|
architecture: arm64
|
||||||
os: linux
|
os: linux
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}
|
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
|
||||||
{{#if build.tags}}
|
{{#if build.tags}}
|
||||||
tags:
|
tags:
|
||||||
{{#each build.tags}}
|
{{#each build.tags}}
|
||||||
- {{this}}
|
- {{this}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
- "latest"
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
manifests:
|
manifests:
|
||||||
-
|
-
|
||||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-amd64
|
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64
|
||||||
platform:
|
platform:
|
||||||
architecture: amd64
|
architecture: amd64
|
||||||
os: linux
|
os: linux
|
||||||
-
|
-
|
||||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-arm64
|
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64
|
||||||
platform:
|
platform:
|
||||||
architecture: arm64
|
architecture: arm64
|
||||||
os: linux
|
os: linux
|
||||||
|
|
|
@ -23,7 +23,7 @@ if [ ! -f ${GITEA_CUSTOM}/conf/app.ini ]; then
|
||||||
INSTALL_LOCK=true
|
INSTALL_LOCK=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Substitute the environment variables in the template
|
# Substitude the environment variables in the template
|
||||||
APP_NAME=${APP_NAME:-"Gitea: Git with a cup of tea"} \
|
APP_NAME=${APP_NAME:-"Gitea: Git with a cup of tea"} \
|
||||||
RUN_MODE=${RUN_MODE:-"prod"} \
|
RUN_MODE=${RUN_MODE:-"prod"} \
|
||||||
DOMAIN=${DOMAIN:-"localhost"} \
|
DOMAIN=${DOMAIN:-"localhost"} \
|
||||||
|
@ -48,9 +48,6 @@ if [ ! -f ${GITEA_CUSTOM}/conf/app.ini ]; then
|
||||||
chown ${USER}:git ${GITEA_CUSTOM}/conf/app.ini
|
chown ${USER}:git ${GITEA_CUSTOM}/conf/app.ini
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Replace app.ini settings with env variables in the form GITEA__SECTION_NAME__KEY_NAME
|
|
||||||
environment-to-ini --config ${GITEA_CUSTOM}/conf/app.ini
|
|
||||||
|
|
||||||
# only chown if current owner is not already the gitea ${USER}. No recursive check to save time
|
# only chown if current owner is not already the gitea ${USER}. No recursive check to save time
|
||||||
if ! [[ $(ls -ld /data/gitea | awk '{print $3}') = ${USER} ]]; then chown -R ${USER}:git /data/gitea; fi
|
if ! [[ $(ls -ld /data/gitea | awk '{print $3}') = ${USER} ]]; then chown -R ${USER}:git /data/gitea; fi
|
||||||
if ! [[ $(ls -ld /app/gitea | awk '{print $3}') = ${USER} ]]; then chown -R ${USER}:git /app/gitea; fi
|
if ! [[ $(ls -ld /app/gitea | awk '{print $3}') = ${USER} ]]; then chown -R ${USER}:git /app/gitea; fi
|
||||||
|
|
|
@ -24,31 +24,9 @@ if [ ! -f /data/ssh/ssh_host_ecdsa_key ]; then
|
||||||
ssh-keygen -t ecdsa -b 256 -f /data/ssh/ssh_host_ecdsa_key -N "" > /dev/null
|
ssh-keygen -t ecdsa -b 256 -f /data/ssh/ssh_host_ecdsa_key -N "" > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -e /data/ssh/ssh_host_ed25519_cert ]; then
|
|
||||||
SSH_ED25519_CERT=${SSH_ED25519_CERT:-"/data/ssh/ssh_host_ed25519_cert"}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e /data/ssh/ssh_host_rsa_cert ]; then
|
|
||||||
SSH_RSA_CERT=${SSH_RSA_CERT:-"/data/ssh/ssh_host_rsa_cert"}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e /data/ssh/ssh_host_ecdsa_cert ]; then
|
|
||||||
SSH_ECDSA_CERT=${SSH_ECDSA_CERT:-"/data/ssh/ssh_host_ecdsa_cert"}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e /data/ssh/ssh_host_dsa_cert ]; then
|
|
||||||
SSH_DSA_CERT=${SSH_DSA_CERT:-"/data/ssh/ssh_host_dsa_cert"}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d /etc/ssh ]; then
|
if [ -d /etc/ssh ]; then
|
||||||
SSH_PORT=${SSH_PORT:-"22"} \
|
SSH_PORT=${SSH_PORT:-"22"} \
|
||||||
SSH_LISTEN_PORT=${SSH_LISTEN_PORT:-"${SSH_PORT}"} \
|
SSH_LISTEN_PORT=${SSH_LISTEN_PORT:-"${SSH_PORT}"} \
|
||||||
SSH_ED25519_CERT="${SSH_ED25519_CERT:+"HostCertificate "}${SSH_ED25519_CERT}" \
|
|
||||||
SSH_RSA_CERT="${SSH_RSA_CERT:+"HostCertificate "}${SSH_RSA_CERT}" \
|
|
||||||
SSH_ECDSA_CERT="${SSH_ECDSA_CERT:+"HostCertificate "}${SSH_ECDSA_CERT}" \
|
|
||||||
SSH_DSA_CERT="${SSH_DSA_CERT:+"HostCertificate "}${SSH_DSA_CERT}" \
|
|
||||||
SSH_MAX_STARTUPS="${SSH_MAX_STARTUPS:+"MaxStartups "}${SSH_MAX_STARTUPS}" \
|
|
||||||
SSH_MAX_SESSIONS="${SSH_MAX_SESSIONS:+"MaxSessions "}${SSH_MAX_SESSIONS}" \
|
|
||||||
envsubst < /etc/templates/sshd_config > /etc/ssh/sshd_config
|
envsubst < /etc/templates/sshd_config > /etc/ssh/sshd_config
|
||||||
|
|
||||||
chmod 0644 /etc/ssh/sshd_config
|
chmod 0644 /etc/ssh/sshd_config
|
||||||
|
|
|
@ -47,14 +47,14 @@ PATH = /data/gitea/attachments
|
||||||
[log]
|
[log]
|
||||||
MODE = console
|
MODE = console
|
||||||
LEVEL = info
|
LEVEL = info
|
||||||
|
REDIRECT_MACARON_LOG = true
|
||||||
|
MACARON = console
|
||||||
ROUTER = console
|
ROUTER = console
|
||||||
ROOT_PATH = /data/gitea/log
|
ROOT_PATH = /data/gitea/log
|
||||||
|
|
||||||
[security]
|
[security]
|
||||||
INSTALL_LOCK = $INSTALL_LOCK
|
INSTALL_LOCK = $INSTALL_LOCK
|
||||||
SECRET_KEY = $SECRET_KEY
|
SECRET_KEY = $SECRET_KEY
|
||||||
REVERSE_PROXY_LIMIT = 1
|
|
||||||
REVERSE_PROXY_TRUSTED_PROXIES = *
|
|
||||||
|
|
||||||
[service]
|
[service]
|
||||||
DISABLE_REGISTRATION = $DISABLE_REGISTRATION
|
DISABLE_REGISTRATION = $DISABLE_REGISTRATION
|
||||||
|
|
|
@ -5,19 +5,16 @@ AddressFamily any
|
||||||
ListenAddress 0.0.0.0
|
ListenAddress 0.0.0.0
|
||||||
ListenAddress ::
|
ListenAddress ::
|
||||||
|
|
||||||
${SSH_MAX_STARTUPS}
|
|
||||||
${SSH_MAX_SESSIONS}
|
|
||||||
|
|
||||||
LogLevel INFO
|
LogLevel INFO
|
||||||
|
|
||||||
HostKey /data/ssh/ssh_host_ed25519_key
|
HostKey /data/ssh/ssh_host_ed25519_key
|
||||||
${SSH_ED25519_CERT}
|
HostCertificate /data/ssh/ssh_host_ed25519_cert
|
||||||
HostKey /data/ssh/ssh_host_rsa_key
|
HostKey /data/ssh/ssh_host_rsa_key
|
||||||
${SSH_RSA_CERT}
|
HostCertificate /data/ssh/ssh_host_rsa_cert
|
||||||
HostKey /data/ssh/ssh_host_ecdsa_key
|
HostKey /data/ssh/ssh_host_ecdsa_key
|
||||||
${SSH_ECDSA_CERT}
|
HostCertificate /data/ssh/ssh_host_ecdsa_cert
|
||||||
HostKey /data/ssh/ssh_host_dsa_key
|
HostKey /data/ssh/ssh_host_dsa_key
|
||||||
${SSH_DSA_CERT}
|
HostCertificate /data/ssh/ssh_host_dsa_cert
|
||||||
|
|
||||||
AuthorizedKeysFile .ssh/authorized_keys
|
AuthorizedKeysFile .ssh/authorized_keys
|
||||||
AuthorizedPrincipalsFile .ssh/authorized_principals
|
AuthorizedPrincipalsFile .ssh/authorized_principals
|
||||||
|
|
|
@ -49,8 +49,6 @@ ROOT_PATH = $GITEA_WORK_DIR/data/log
|
||||||
[security]
|
[security]
|
||||||
INSTALL_LOCK = $INSTALL_LOCK
|
INSTALL_LOCK = $INSTALL_LOCK
|
||||||
SECRET_KEY = $SECRET_KEY
|
SECRET_KEY = $SECRET_KEY
|
||||||
REVERSE_PROXY_LIMIT = 1
|
|
||||||
REVERSE_PROXY_TRUSTED_PROXIES = *
|
|
||||||
|
|
||||||
[service]
|
[service]
|
||||||
DISABLE_REGISTRATION = $DISABLE_REGISTRATION
|
DISABLE_REGISTRATION = $DISABLE_REGISTRATION
|
||||||
|
|
|
@ -25,7 +25,7 @@ if [ ! -f ${GITEA_APP_INI} ]; then
|
||||||
INSTALL_LOCK=true
|
INSTALL_LOCK=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Substitute the environment variables in the template
|
# Substitude the environment variables in the template
|
||||||
APP_NAME=${APP_NAME:-"Gitea: Git with a cup of tea"} \
|
APP_NAME=${APP_NAME:-"Gitea: Git with a cup of tea"} \
|
||||||
RUN_MODE=${RUN_MODE:-"prod"} \
|
RUN_MODE=${RUN_MODE:-"prod"} \
|
||||||
RUN_USER=${USER:-"git"} \
|
RUN_USER=${USER:-"git"} \
|
||||||
|
@ -46,6 +46,3 @@ if [ ! -f ${GITEA_APP_INI} ]; then
|
||||||
SECRET_KEY=${SECRET_KEY:-""} \
|
SECRET_KEY=${SECRET_KEY:-""} \
|
||||||
envsubst < /etc/templates/app.ini > ${GITEA_APP_INI}
|
envsubst < /etc/templates/app.ini > ${GITEA_APP_INI}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Replace app.ini settings with env variables in the form GITEA__SECTION_NAME__KEY_NAME
|
|
||||||
environment-to-ini --config ${GITEA_APP_INI}
|
|
||||||
|
|
|
@ -31,4 +31,4 @@ update: $(THEME)
|
||||||
$(THEME): $(THEME)/theme.toml
|
$(THEME): $(THEME)/theme.toml
|
||||||
$(THEME)/theme.toml:
|
$(THEME)/theme.toml:
|
||||||
mkdir -p $$(dirname $@)
|
mkdir -p $$(dirname $@)
|
||||||
curl -L -s $(ARCHIVE) | tar xz -C $$(dirname $@)
|
curl -s $(ARCHIVE) | tar xz -C $$(dirname $@)
|
||||||
|
|
|
@ -18,10 +18,10 @@ params:
|
||||||
description: Git with a cup of tea
|
description: Git with a cup of tea
|
||||||
author: The Gitea Authors
|
author: The Gitea Authors
|
||||||
website: https://docs.gitea.io
|
website: https://docs.gitea.io
|
||||||
version: 1.15.0
|
version: 1.13.1
|
||||||
minGoVersion: 1.16
|
minGoVersion: 1.13
|
||||||
goVersion: 1.17
|
goVersion: 1.15
|
||||||
minNodeVersion: 12.17
|
minNodeVersion: 10.13
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
home:
|
home:
|
||||||
|
@ -147,15 +147,15 @@ languages:
|
||||||
url: https://blog.gitea.io/
|
url: https://blog.gitea.io/
|
||||||
weight: 30
|
weight: 30
|
||||||
pre: rss
|
pre: rss
|
||||||
- name: 商店
|
- name: 程式碼
|
||||||
url: https://shop.gitea.io/
|
url: https://code.gitea.io/
|
||||||
weight: 40
|
weight: 40
|
||||||
pre: shopping-cart
|
pre: code
|
||||||
- name: 翻譯
|
- name: 翻译
|
||||||
url: https://crowdin.com/project/gitea
|
url: https://crowdin.com/project/gitea
|
||||||
weight: 41
|
weight: 41
|
||||||
pre: language
|
pre: language
|
||||||
- name: 下載
|
- name: 下载
|
||||||
url: https://dl.gitea.io/
|
url: https://dl.gitea.io/
|
||||||
weight: 50
|
weight: 50
|
||||||
pre: download
|
pre: download
|
||||||
|
@ -163,11 +163,11 @@ languages:
|
||||||
url: https://github.com/go-gitea/
|
url: https://github.com/go-gitea/
|
||||||
weight: 60
|
weight: 60
|
||||||
pre: github
|
pre: github
|
||||||
- name: Discord 聊天室
|
- name: Discord Chat
|
||||||
url: https://discord.gg/Gitea
|
url: https://discord.gg/Gitea
|
||||||
weight: 70
|
weight: 70
|
||||||
pre: comment
|
pre: comment
|
||||||
- name: 討論區
|
- name: Forum
|
||||||
url: https://discourse.gitea.io/
|
url: https://discourse.gitea.io/
|
||||||
weight: 80
|
weight: 80
|
||||||
pre: group
|
pre: group
|
||||||
|
@ -313,20 +313,20 @@ languages:
|
||||||
weight: 80
|
weight: 80
|
||||||
pre: group
|
pre: group
|
||||||
|
|
||||||
de-de:
|
pt-pt:
|
||||||
weight: 6
|
weight: 6
|
||||||
languageName: Deutsch
|
languageName: Português de Portugal
|
||||||
menu:
|
menu:
|
||||||
page:
|
page:
|
||||||
- name: Webseite
|
- name: Página inicial
|
||||||
url: https://gitea.io/en-us/
|
url: https://gitea.io/pt-pt/
|
||||||
weight: 10
|
weight: 10
|
||||||
pre: home
|
pre: home
|
||||||
post: active
|
- name: Documentação
|
||||||
- name: Dokumentation
|
url: /pt-pt/
|
||||||
url: /de-de/
|
|
||||||
weight: 20
|
weight: 20
|
||||||
pre: question
|
pre: question
|
||||||
|
post: active
|
||||||
- name: API
|
- name: API
|
||||||
url: https://try.gitea.io/api/swagger
|
url: https://try.gitea.io/api/swagger
|
||||||
weight: 45
|
weight: 45
|
||||||
|
@ -335,15 +335,15 @@ languages:
|
||||||
url: https://blog.gitea.io/
|
url: https://blog.gitea.io/
|
||||||
weight: 30
|
weight: 30
|
||||||
pre: rss
|
pre: rss
|
||||||
- name: Code
|
- name: Código-fonte
|
||||||
url: https://code.gitea.io/
|
url: https://code.gitea.io/
|
||||||
weight: 40
|
weight: 40
|
||||||
pre: code
|
pre: code
|
||||||
- name: Übersetzung
|
- name: Tradução
|
||||||
url: https://crowdin.com/project/gitea
|
url: https://crowdin.com/project/gitea
|
||||||
weight: 41
|
weight: 41
|
||||||
pre: language
|
pre: language
|
||||||
- name: Downloads
|
- name: Descarregamentos
|
||||||
url: https://dl.gitea.io/
|
url: https://dl.gitea.io/
|
||||||
weight: 50
|
weight: 50
|
||||||
pre: download
|
pre: download
|
||||||
|
@ -351,11 +351,11 @@ languages:
|
||||||
url: https://github.com/go-gitea/
|
url: https://github.com/go-gitea/
|
||||||
weight: 60
|
weight: 60
|
||||||
pre: github
|
pre: github
|
||||||
- name: Discord Chat
|
- name: Discussão no Discord
|
||||||
url: https://discord.gg/Gitea
|
url: https://discord.gg/Gitea
|
||||||
weight: 70
|
weight: 70
|
||||||
pre: comment
|
pre: comment
|
||||||
- name: Forum
|
- name: Fórum
|
||||||
url: https://discourse.gitea.io/
|
url: https://discourse.gitea.io/
|
||||||
weight: 80
|
weight: 80
|
||||||
pre: group
|
pre: group
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
---
|
|
||||||
date: "2016-12-01T16:00:00+02:00"
|
|
||||||
title: "進階"
|
|
||||||
slug: "advanced"
|
|
||||||
weight: 30
|
|
||||||
toc: false
|
|
||||||
draft: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
name: "進階"
|
|
||||||
weight: 40
|
|
||||||
identifier: "advanced"
|
|
||||||
---
|
|
|
@ -32,7 +32,7 @@ You absolutely must not place a general ToS or privacy statement that implies th
|
||||||
Create or append to `/path/to/custom/templates/custom/extra_links_footer.tmpl`:
|
Create or append to `/path/to/custom/templates/custom/extra_links_footer.tmpl`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
<a class="item" href="{{AppSubUrl}}/assets/privacy.html">Privacy Policy</a>
|
<a class="item" href="{{AppSubUrl}}/privacy.html">Privacy Policy</a>
|
||||||
```
|
```
|
||||||
|
|
||||||
Restart Gitea to see the changes.
|
Restart Gitea to see the changes.
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
---
|
|
||||||
date: "2021-02-02"
|
|
||||||
title: "Clone filters (partial clone)"
|
|
||||||
slug: "clone-filters"
|
|
||||||
weight: 25
|
|
||||||
draft: false
|
|
||||||
toc: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
parent: "advanced"
|
|
||||||
name: "Clone filters"
|
|
||||||
weight: 25
|
|
||||||
identifier: "clone-filters"
|
|
||||||
---
|
|
||||||
|
|
||||||
# Clone filters (partial clone)
|
|
||||||
|
|
||||||
Git introduces `--filter` option to `git clone` command, which filters out
|
|
||||||
large files and objects (such as blobs) to create partial clone of a repo.
|
|
||||||
Clone filters are especially useful for large repo and/or metered connection,
|
|
||||||
where full clone (without `--filter`) can be expensive (as all history data
|
|
||||||
must be downloaded).
|
|
||||||
|
|
||||||
This requires Git version 2.22 or later, both on the Gitea server and on the
|
|
||||||
client. For clone filters to work properly, make sure that Git version
|
|
||||||
on the client is at least the same as on the server (or later). Login to
|
|
||||||
Gitea server as admin and head to Site Administration -> Configuration to
|
|
||||||
see Git version of the server.
|
|
||||||
|
|
||||||
By default, clone filters are disabled, which cause the server to ignore
|
|
||||||
`--filter` option.
|
|
||||||
|
|
||||||
To enable clone filters on per-repo basis, edit the repo's `config` on
|
|
||||||
repository location. Consult `ROOT` option on `repository` section of
|
|
||||||
Gitea configuration (`app.ini`) for the exact location. For example, to
|
|
||||||
enable clone filters for `some-repo`, edit
|
|
||||||
`/var/gitea/data/gitea-repositories/some-user/some-repo.git/config` and add:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[uploadpack]
|
|
||||||
allowfilter = true
|
|
||||||
```
|
|
||||||
|
|
||||||
To enable clone filters globally, add that config above to `~/.gitconfig`
|
|
||||||
of user that run Gitea (for example `git`).
|
|
||||||
|
|
||||||
Alternatively, you can use `git config` to set the option.
|
|
||||||
|
|
||||||
To enable for a specific repo:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /var/gitea/data/gitea-repositories/some-user/some-repo.git
|
|
||||||
git config --local uploadpack.allowfilter true
|
|
||||||
```
|
|
||||||
To enable globally, login as user that run Gitea and:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git config --global uploadpack.allowfilter true
|
|
||||||
```
|
|
||||||
|
|
||||||
See [GitHub blog post: Get up to speed with partial clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/)
|
|
||||||
for common use cases of clone filters (blobless and treeless clones), and
|
|
||||||
[Gitlab docs for partial clone](https://docs.gitlab.com/ee/topics/git/partial_clone.html)
|
|
||||||
for more advanced use cases (such as filter by file size and remove
|
|
||||||
filters to turn partial clone into full clone).
|
|
|
@ -59,7 +59,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- `MIRROR_QUEUE_LENGTH`: **1000**: Patch test queue length, increase if pull request patch
|
- `MIRROR_QUEUE_LENGTH`: **1000**: Patch test queue length, increase if pull request patch
|
||||||
testing starts hanging.
|
testing starts hanging.
|
||||||
- `PREFERRED_LICENSES`: **Apache License 2.0,MIT License**: Preferred Licenses to place at
|
- `PREFERRED_LICENSES`: **Apache License 2.0,MIT License**: Preferred Licenses to place at
|
||||||
the top of the list. Name must match file name in options/license or custom/options/license.
|
the top of the list. Name must match file name in conf/license or custom/conf/license.
|
||||||
- `DISABLE_HTTP_GIT`: **false**: Disable the ability to interact with repositories over the
|
- `DISABLE_HTTP_GIT`: **false**: Disable the ability to interact with repositories over the
|
||||||
HTTP protocol.
|
HTTP protocol.
|
||||||
- `USE_COMPAT_SSH_URI`: **false**: Force ssh:// clone url instead of scp-style uri when
|
- `USE_COMPAT_SSH_URI`: **false**: Force ssh:// clone url instead of scp-style uri when
|
||||||
|
@ -75,7 +75,6 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
||||||
- `DISABLE_MIRRORS`: **false**: Disable the creation of **new** mirrors. Pre-existing mirrors remain valid.
|
- `DISABLE_MIRRORS`: **false**: Disable the creation of **new** mirrors. Pre-existing mirrors remain valid.
|
||||||
- `DISABLE_MIGRATIONS`: **false**: Disable migrating feature.
|
- `DISABLE_MIGRATIONS`: **false**: Disable migrating feature.
|
||||||
- `DISABLE_STARS`: **false**: Disable stars feature.
|
|
||||||
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
|
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
|
||||||
- `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to adopt unadopted repositories
|
- `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to adopt unadopted repositories
|
||||||
- `ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to delete unadopted repositories
|
- `ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to delete unadopted repositories
|
||||||
|
@ -94,11 +93,10 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- `REOPEN_KEYWORDS`: **reopen**, **reopens**, **reopened**: List of keywords used in Pull Request comments to automatically reopen
|
- `REOPEN_KEYWORDS`: **reopen**, **reopens**, **reopened**: List of keywords used in Pull Request comments to automatically reopen
|
||||||
a related issue
|
a related issue
|
||||||
- `DEFAULT_MERGE_MESSAGE_COMMITS_LIMIT`: **50**: In the default merge message for squash commits include at most this many commits. Set to `-1` to include all commits
|
- `DEFAULT_MERGE_MESSAGE_COMMITS_LIMIT`: **50**: In the default merge message for squash commits include at most this many commits. Set to `-1` to include all commits
|
||||||
- `DEFAULT_MERGE_MESSAGE_SIZE`: **5120**: In the default merge message for squash commits limit the size of the commit messages. Set to `-1` to have no limit. Only used if `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES` is `true`.
|
- `DEFAULT_MERGE_MESSAGE_SIZE`: **5120**: In the default merge message for squash commits limit the size of the commit messages. Set to `-1` to have no limit.
|
||||||
- `DEFAULT_MERGE_MESSAGE_ALL_AUTHORS`: **false**: In the default merge message for squash commits walk all commits to include all authors in the Co-authored-by otherwise just use those in the limited list
|
- `DEFAULT_MERGE_MESSAGE_ALL_AUTHORS`: **false**: In the default merge message for squash commits walk all commits to include all authors in the Co-authored-by otherwise just use those in the limited list
|
||||||
- `DEFAULT_MERGE_MESSAGE_MAX_APPROVERS`: **10**: In default merge messages limit the number of approvers listed as `Reviewed-by:`. Set to `-1` to include all.
|
- `DEFAULT_MERGE_MESSAGE_MAX_APPROVERS`: **10**: In default merge messages limit the number of approvers listed as `Reviewed-by:`. Set to `-1` to include all.
|
||||||
- `DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY`: **true**: In default merge messages only include approvers who are officially allowed to review.
|
- `DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY`: **true**: In default merge messages only include approvers who are officially allowed to review.
|
||||||
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: In default squash-merge messages include the commit message of all commits comprising the pull request.
|
|
||||||
|
|
||||||
### Repository - Issue (`repository.issue`)
|
### Repository - Issue (`repository.issue`)
|
||||||
|
|
||||||
|
@ -115,7 +113,6 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
### Repository - Release (`repository.release`)
|
### Repository - Release (`repository.release`)
|
||||||
|
|
||||||
- `ALLOWED_TYPES`: **\<empty\>**: 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`: **\<empty\>**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||||
- `DEFAULT_PAGING_NUM`: **10**: The default paging number of releases user interface
|
|
||||||
|
|
||||||
### Repository - Signing (`repository.signing`)
|
### Repository - Signing (`repository.signing`)
|
||||||
|
|
||||||
|
@ -129,8 +126,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- Options other than `never` and `always` can be combined as a comma separated list.
|
- Options other than `never` and `always` can be combined as a comma separated list.
|
||||||
- `DEFAULT_TRUST_MODEL`: **collaborator**: \[collaborator, committer, collaboratorcommitter\]: The default trust model used for verifying commits.
|
- `DEFAULT_TRUST_MODEL`: **collaborator**: \[collaborator, committer, collaboratorcommitter\]: The default trust model used for verifying commits.
|
||||||
- `collaborator`: Trust signatures signed by keys of collaborators.
|
- `collaborator`: Trust signatures signed by keys of collaborators.
|
||||||
- `committer`: Trust signatures that match committers (This matches GitHub and will force Gitea signed commits to have Gitea as the committer).
|
- `committer`: Trust signatures that match committers (This matches GitHub and will force Gitea signed commits to have Gitea as the commmitter).
|
||||||
- `collaboratorcommitter`: Trust signatures signed by keys of collaborators which match the committer.
|
- `collaboratorcommitter`: Trust signatures signed by keys of collaborators which match the commiter.
|
||||||
- `WIKI`: **never**: \[never, pubkey, twofa, always, parentsigned\]: Sign commits to wiki.
|
- `WIKI`: **never**: \[never, pubkey, twofa, always, parentsigned\]: Sign commits to wiki.
|
||||||
- `CRUD_ACTIONS`: **pubkey, twofa, parentsigned**: \[never, pubkey, twofa, parentsigned, always\]: Sign CRUD actions.
|
- `CRUD_ACTIONS`: **pubkey, twofa, parentsigned**: \[never, pubkey, twofa, parentsigned, always\]: Sign CRUD actions.
|
||||||
- Options as above, with the addition of:
|
- Options as above, with the addition of:
|
||||||
|
@ -145,15 +142,6 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
|
|
||||||
- `LOCAL_COPY_PATH`: **tmp/local-repo**: Path for temporary local repository copies. Defaults to `tmp/local-repo`
|
- `LOCAL_COPY_PATH`: **tmp/local-repo**: Path for temporary local repository copies. Defaults to `tmp/local-repo`
|
||||||
|
|
||||||
## Repository - MIME type mapping (`repository.mimetype_mapping`)
|
|
||||||
|
|
||||||
Configuration for set the expected MIME type based on file extensions of downloadable files. Configuration presents in key-value pairs and file extensions starts with leading `.`.
|
|
||||||
|
|
||||||
The following configuration set `Content-Type: application/vnd.android.package-archive` header when downloading files with `.apk` file extension.
|
|
||||||
```ini
|
|
||||||
.apk=application/vnd.android.package-archive
|
|
||||||
```
|
|
||||||
|
|
||||||
## CORS (`cors`)
|
## CORS (`cors`)
|
||||||
|
|
||||||
- `ENABLED`: **false**: enable cors headers (disabled by default)
|
- `ENABLED`: **false**: enable cors headers (disabled by default)
|
||||||
|
@ -163,7 +151,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
- `METHODS`: **GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS**: list of methods allowed to request
|
- `METHODS`: **GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS**: list of methods allowed to request
|
||||||
- `MAX_AGE`: **10m**: max time to cache response
|
- `MAX_AGE`: **10m**: max time to cache response
|
||||||
- `ALLOW_CREDENTIALS`: **false**: allow request with credentials
|
- `ALLOW_CREDENTIALS`: **false**: allow request with credentials
|
||||||
- `X_FRAME_OPTIONS`: **SAMEORIGIN**: Set the `X-Frame-Options` header value.
|
|
||||||
|
|
||||||
## UI (`ui`)
|
## UI (`ui`)
|
||||||
|
|
||||||
|
@ -182,10 +169,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
- `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB)
|
- `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB)
|
||||||
- `REACTIONS`: All available reactions users can choose on issues/prs and comments
|
- `REACTIONS`: All available reactions users can choose on issues/prs and comments
|
||||||
Values can be emoji alias (:smile:) or a unicode emoji.
|
Values can be emoji alias (:smile:) or a unicode emoji.
|
||||||
For custom reactions, add a tightly cropped square image to public/img/emoji/reaction_name.png
|
For custom reactions, add a tightly cropped square image to public/emoji/img/reaction_name.png
|
||||||
- `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: Additional Emojis not defined in the utf8 standard.
|
|
||||||
By default we support gitea (:gitea:), to add more copy them to public/img/emoji/emoji_name.png and
|
|
||||||
add it to this config.
|
|
||||||
- `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used.
|
- `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used.
|
||||||
- `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page.
|
- `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page.
|
||||||
- `USE_SERVICE_WORKER`: **true**: Whether to enable a Service Worker to cache frontend assets.
|
- `USE_SERVICE_WORKER`: **true**: Whether to enable a Service Worker to cache frontend assets.
|
||||||
|
@ -214,10 +198,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
|
|
||||||
- `ENABLE_RENDER`: **true**: Whether to render SVG files as images. If SVG rendering is disabled, SVG files are displayed as text and cannot be embedded in markdown files as images.
|
- `ENABLE_RENDER`: **true**: Whether to render SVG files as images. If SVG rendering is disabled, SVG files are displayed as text and cannot be embedded in markdown files as images.
|
||||||
|
|
||||||
### UI - CSV Files (`ui.csv`)
|
|
||||||
|
|
||||||
- `MAX_FILE_SIZE`: **524288** (512kb): Maximum allowed file size in bytes to render CSV files as table. (Set to 0 for no limit).
|
|
||||||
|
|
||||||
## Markdown (`markdown`)
|
## Markdown (`markdown`)
|
||||||
|
|
||||||
- `ENABLE_HARD_LINE_BREAK_IN_COMMENTS`: **true**: Render soft line breaks as hard line breaks in comments, which
|
- `ENABLE_HARD_LINE_BREAK_IN_COMMENTS`: **true**: Render soft line breaks as hard line breaks in comments, which
|
||||||
|
@ -257,9 +237,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
most cases you do not need to change the default value. Alter it only if
|
most cases you do not need to change the default value. Alter it only if
|
||||||
your SSH server node is not the same as HTTP node. Do not set this variable
|
your SSH server node is not the same as HTTP node. Do not set this variable
|
||||||
if `PROTOCOL` is set to `unix`.
|
if `PROTOCOL` is set to `unix`.
|
||||||
- `PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the connection. (Set to 0 to
|
|
||||||
disable all timeouts.)
|
|
||||||
- `PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to connections.
|
|
||||||
|
|
||||||
- `DISABLE_SSH`: **false**: Disable SSH feature when it's not available.
|
- `DISABLE_SSH`: **false**: Disable SSH feature when it's not available.
|
||||||
- `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server.
|
- `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server.
|
||||||
|
@ -276,17 +253,12 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set.
|
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set.
|
||||||
- `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
|
- `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
|
||||||
- `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
|
- `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
|
||||||
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models.PublicKey` and the others are strings which are shellquoted.
|
|
||||||
- `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect.
|
- `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect.
|
||||||
- `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect.
|
- `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect.
|
||||||
- `SSH_SERVER_MACS`: **hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect
|
- `SSH_SERVER_MACS`: **hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect
|
||||||
- `SSH_SERVER_HOST_KEYS`: **ssh/gitea.rsa, ssh/gogs.rsa**: For the built-in SSH server, choose the keypairs to offer as the host key. The private key should be at `SSH_SERVER_HOST_KEY` and the public `SSH_SERVER_HOST_KEY.pub`. Relative paths are made absolute relative to the `APP_DATA_PATH`. If no key exists a 4096 bit RSA key will be created for you.
|
|
||||||
- `SSH_KEY_TEST_PATH`: **/tmp**: Directory to create temporary files in when testing public keys using ssh-keygen, default is the system temporary directory.
|
- `SSH_KEY_TEST_PATH`: **/tmp**: Directory to create temporary files in when testing public keys using ssh-keygen, default is the system temporary directory.
|
||||||
- `SSH_KEYGEN_PATH`: **ssh-keygen**: Path to ssh-keygen, default is 'ssh-keygen' which means the shell is responsible for finding out which one to call.
|
- `SSH_KEYGEN_PATH`: **ssh-keygen**: Path to ssh-keygen, default is 'ssh-keygen' which means the shell is responsible for finding out which one to call.
|
||||||
- `SSH_EXPOSE_ANONYMOUS`: **false**: Enable exposure of SSH clone URL to anonymous visitors, default is false.
|
- `SSH_EXPOSE_ANONYMOUS`: **false**: Enable exposure of SSH clone URL to anonymous visitors, default is false.
|
||||||
- `SSH_PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the SSH connections. (Set to
|
|
||||||
0 to disable all timeouts.)
|
|
||||||
- `SSH_PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to SSH connections.
|
|
||||||
- `MINIMUM_KEY_SIZE_CHECK`: **true**: Indicate whether to check minimum key size with corresponding type.
|
- `MINIMUM_KEY_SIZE_CHECK`: **true**: Indicate whether to check minimum key size with corresponding type.
|
||||||
|
|
||||||
- `OFFLINE_MODE`: **false**: Disables use of CDN for static files and Gravatar for profile pictures.
|
- `OFFLINE_MODE`: **false**: Disables use of CDN for static files and Gravatar for profile pictures.
|
||||||
|
@ -302,7 +274,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
- `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore, organizations, login\].
|
- `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore, organizations, login\].
|
||||||
|
|
||||||
- `LFS_START_SERVER`: **false**: Enables git-lfs support.
|
- `LFS_START_SERVER`: **false**: Enables git-lfs support.
|
||||||
- `LFS_CONTENT_PATH`: **%(APP_DATA_PATH)/lfs**: Default LFS content path. (if it is on local storage.) **DEPRECATED** use settings in `[lfs]`.
|
- `LFS_CONTENT_PATH`: **%(APP_DATA_PATH)/lfs**: Default LFS content path. (if it is on local storage.)
|
||||||
- `LFS_JWT_SECRET`: **\<empty\>**: LFS authentication secret, change this a unique string.
|
- `LFS_JWT_SECRET`: **\<empty\>**: LFS authentication secret, change this a unique string.
|
||||||
- `LFS_HTTP_AUTH_EXPIRY`: **20m**: LFS authentication validity period in time.Duration, pushes taking longer than this may fail.
|
- `LFS_HTTP_AUTH_EXPIRY`: **20m**: LFS authentication validity period in time.Duration, pushes taking longer than this may fail.
|
||||||
- `LFS_MAX_FILE_SIZE`: **0**: Maximum allowed LFS file size in bytes (Set to 0 for no limit).
|
- `LFS_MAX_FILE_SIZE`: **0**: Maximum allowed LFS file size in bytes (Set to 0 for no limit).
|
||||||
|
@ -347,9 +319,9 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
|
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
|
||||||
- `LOG_SQL`: **true**: Log the executed SQL.
|
- `LOG_SQL`: **true**: Log the executed SQL.
|
||||||
- `DB_RETRIES`: **10**: How many ORM init / DB connect attempts allowed.
|
- `DB_RETRIES`: **10**: How many ORM init / DB connect attempts allowed.
|
||||||
- `DB_RETRY_BACKOFF`: **3s**: time.Duration to wait before trying another ORM init / DB connect attempt, if failure occurred.
|
- `DB_RETRY_BACKOFF`: **3s**: time.Duration to wait before trying another ORM init / DB connect attempt, if failure occured.
|
||||||
- `MAX_OPEN_CONNS` **0**: Database maximum open connections - default is 0, meaning there is no limit.
|
- `MAX_OPEN_CONNS` **0**: Database maximum open connections - default is 0, meaning there is no limit.
|
||||||
- `MAX_IDLE_CONNS` **2**: Max idle database connections on connection pool, default is 2 - this will be capped to `MAX_OPEN_CONNS`.
|
- `MAX_IDLE_CONNS` **2**: Max idle database connections on connnection pool, default is 2 - this will be capped to `MAX_OPEN_CONNS`.
|
||||||
- `CONN_MAX_LIFETIME` **0 or 3s**: Sets the maximum amount of time a DB connection may be reused - default is 0, meaning there is no limit (except on MySQL where it is 3s - see #6804 & #7071).
|
- `CONN_MAX_LIFETIME` **0 or 3s**: Sets the maximum amount of time a DB connection may be reused - default is 0, meaning there is no limit (except on MySQL where it is 3s - see #6804 & #7071).
|
||||||
|
|
||||||
Please see #8540 & #8273 for further discussion of the appropriate values for `MAX_OPEN_CONNS`, `MAX_IDLE_CONNS` & `CONN_MAX_LIFETIME` and their
|
Please see #8540 & #8273 for further discussion of the appropriate values for `MAX_OPEN_CONNS`, `MAX_IDLE_CONNS` & `CONN_MAX_LIFETIME` and their
|
||||||
|
@ -362,10 +334,10 @@ relation to port exhaustion.
|
||||||
- `ISSUE_INDEXER_NAME`: **gitea_issues**: Issue indexer name, available when ISSUE_INDEXER_TYPE is elasticsearch
|
- `ISSUE_INDEXER_NAME`: **gitea_issues**: Issue indexer name, available when ISSUE_INDEXER_TYPE is elasticsearch
|
||||||
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search; available when ISSUE_INDEXER_TYPE is bleve and elasticsearch.
|
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search; available when ISSUE_INDEXER_TYPE is bleve and elasticsearch.
|
||||||
- The next 4 configuration values are deprecated and should be set in `queue.issue_indexer` however are kept for backwards compatibility:
|
- The next 4 configuration values are deprecated and should be set in `queue.issue_indexer` however are kept for backwards compatibility:
|
||||||
- `ISSUE_INDEXER_QUEUE_TYPE`: **levelqueue**: Issue indexer queue, currently supports:`channel`, `levelqueue`, `redis`. **DEPRECATED** use settings in `[queue.issue_indexer]`.
|
- `ISSUE_INDEXER_QUEUE_TYPE`: **levelqueue**: Issue indexer queue, currently supports:`channel`, `levelqueue`, `redis`.
|
||||||
- `ISSUE_INDEXER_QUEUE_DIR`: **queues/common**: When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this will be the path where the queue will be saved. **DEPRECATED** use settings in `[queue.issue_indexer]`.
|
- `ISSUE_INDEXER_QUEUE_DIR`: **indexers/issues.queue**: When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this will be the path where the queue will be saved.
|
||||||
- `ISSUE_INDEXER_QUEUE_CONN_STR`: **addrs=127.0.0.1:6379 db=0**: When `ISSUE_INDEXER_QUEUE_TYPE` is `redis`, this will store the redis connection string. When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this is a directory or additional options of the form `leveldb://path/to/db?option=value&....`, and overrides `ISSUE_INDEXER_QUEUE_DIR`. **DEPRECATED** use settings in `[queue.issue_indexer]`.
|
- `ISSUE_INDEXER_QUEUE_CONN_STR`: **addrs=127.0.0.1:6379 db=0**: When `ISSUE_INDEXER_QUEUE_TYPE` is `redis`, this will store the redis connection string. When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this is a directory or additional options of the form `leveldb://path/to/db?option=value&....`, and overrides `ISSUE_INDEXER_QUEUE_DIR`.
|
||||||
- `ISSUE_INDEXER_QUEUE_BATCH_NUMBER`: **20**: Batch queue number. **DEPRECATED** use settings in `[queue.issue_indexer]`.
|
- `ISSUE_INDEXER_QUEUE_BATCH_NUMBER`: **20**: Batch queue number.
|
||||||
|
|
||||||
- `REPO_INDEXER_ENABLED`: **false**: Enables code search (uses a lot of disk space, about 6 times more than the repository size).
|
- `REPO_INDEXER_ENABLED`: **false**: Enables code search (uses a lot of disk space, about 6 times more than the repository size).
|
||||||
- `REPO_INDEXER_TYPE`: **bleve**: Code search engine type, could be `bleve` or `elasticsearch`.
|
- `REPO_INDEXER_TYPE`: **bleve**: Code search engine type, could be `bleve` or `elasticsearch`.
|
||||||
|
@ -376,29 +348,29 @@ relation to port exhaustion.
|
||||||
- `REPO_INDEXER_INCLUDE`: **empty**: A comma separated list of glob patterns (see https://github.com/gobwas/glob) to **include** in the index. Use `**.txt` to match any files with .txt extension. An empty list means include all files.
|
- `REPO_INDEXER_INCLUDE`: **empty**: A comma separated list of glob patterns (see https://github.com/gobwas/glob) to **include** in the index. Use `**.txt` to match any files with .txt extension. An empty list means include all files.
|
||||||
- `REPO_INDEXER_EXCLUDE`: **empty**: A comma separated list of glob patterns (see https://github.com/gobwas/glob) to **exclude** from the index. Files that match this list will not be indexed, even if they match in `REPO_INDEXER_INCLUDE`.
|
- `REPO_INDEXER_EXCLUDE`: **empty**: A comma separated list of glob patterns (see https://github.com/gobwas/glob) to **exclude** from the index. Files that match this list will not be indexed, even if they match in `REPO_INDEXER_INCLUDE`.
|
||||||
- `REPO_INDEXER_EXCLUDE_VENDORED`: **true**: Exclude vendored files from index.
|
- `REPO_INDEXER_EXCLUDE_VENDORED`: **true**: Exclude vendored files from index.
|
||||||
- `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request. **DEPRECATED** use settings in `[queue.issue_indexer]`.
|
- `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request.
|
||||||
- `MAX_FILE_SIZE`: **1048576**: Maximum size in bytes of files to be indexed.
|
- `MAX_FILE_SIZE`: **1048576**: Maximum size in bytes of files to be indexed.
|
||||||
- `STARTUP_TIMEOUT`: **30s**: If the indexer takes longer than this timeout to start - fail. (This timeout will be added to the hammer time above for child processes - as bleve will not start until the previous parent is shutdown.) Set to zero to never timeout.
|
- `STARTUP_TIMEOUT`: **30s**: If the indexer takes longer than this timeout to start - fail. (This timeout will be added to the hammer time above for child processes - as bleve will not start until the previous parent is shutdown.) Set to zero to never timeout.
|
||||||
|
|
||||||
## Queue (`queue` and `queue.*`)
|
## Queue (`queue` and `queue.*`)
|
||||||
|
|
||||||
- `TYPE`: **persistable-channel**: General queue type, currently support: `persistable-channel` (uses a LevelDB internally), `channel`, `level`, `redis`, `dummy`
|
- `TYPE`: **persistable-channel**: General queue type, currently support: `persistable-channel` (uses a LevelDB internally), `channel`, `level`, `redis`, `dummy`
|
||||||
- `DATADIR`: **queues/**: Base DataDir for storing persistent and level queues. `DATADIR` for individual queues can be set in `queue.name` sections but will default to `DATADIR/`**`common`**. (Previously each queue would default to `DATADIR/`**`name`**.)
|
- `DATADIR`: **queues/**: Base DataDir for storing persistent and level queues. `DATADIR` for individual queues can be set in `queue.name` sections but will default to `DATADIR/`**`name`**.
|
||||||
- `LENGTH`: **20**: Maximal queue size before channel queues block
|
- `LENGTH`: **20**: Maximal queue size before channel queues block
|
||||||
- `BATCH_LENGTH`: **20**: Batch data before passing to the handler
|
- `BATCH_LENGTH`: **20**: Batch data before passing to the handler
|
||||||
- `CONN_STR`: **redis://127.0.0.1:6379/0**: Connection string for the redis queue type. Options can be set using query params. Similarly LevelDB options can also be set using: **leveldb://relative/path?option=value** or **leveldb:///absolute/path?option=value**, and will override `DATADIR`
|
- `CONN_STR`: **redis://127.0.0.1:6379/0**: Connection string for the redis queue type. Options can be set using query params. Similarly LevelDB options can also be set using: **leveldb://relative/path?option=value** or **leveldb:///absolute/path?option=value**, and will override `DATADIR`
|
||||||
- `QUEUE_NAME`: **_queue**: The suffix for default redis and disk queue name. Individual queues will default to **`name`**`QUEUE_NAME` but can be overridden in the specific `queue.name` section.
|
- `QUEUE_NAME`: **_queue**: The suffix for default redis and disk queue name. Individual queues will default to **`name`**`QUEUE_NAME` but can be overriden in the specific `queue.name` section.
|
||||||
- `SET_NAME`: **_unique**: The suffix that will be added to the default redis and disk queue `set` name for unique queues. Individual queues will default to
|
- `SET_NAME`: **_unique**: The suffix that will be added to the default redis and disk queue `set` name for unique queues. Individual queues will default to
|
||||||
**`name`**`QUEUE_NAME`_`SET_NAME`_ but can be overridden in the specific `queue.name` section.
|
**`name`**`QUEUE_NAME`_`SET_NAME`_ but can be overridden in the specific `queue.name` section.
|
||||||
- `WRAP_IF_NECESSARY`: **true**: Will wrap queues with a timeoutable queue if the selected queue is not ready to be created - (Only relevant for the level queue.)
|
- `WRAP_IF_NECESSARY`: **true**: Will wrap queues with a timeoutable queue if the selected queue is not ready to be created - (Only relevant for the level queue.)
|
||||||
- `MAX_ATTEMPTS`: **10**: Maximum number of attempts to create the wrapped queue
|
- `MAX_ATTEMPTS`: **10**: Maximum number of attempts to create the wrapped queue
|
||||||
- `TIMEOUT`: **GRACEFUL_HAMMER_TIME + 30s**: Timeout the creation of the wrapped queue if it takes longer than this to create.
|
- `TIMEOUT`: **GRACEFUL_HAMMER_TIME + 30s**: Timeout the creation of the wrapped queue if it takes longer than this to create.
|
||||||
- Queues by default come with a dynamically scaling worker pool. The following settings configure this:
|
- Queues by default come with a dynamically scaling worker pool. The following settings configure this:
|
||||||
- `WORKERS`: **0** (v1.14 and before: **1**): Number of initial workers for the queue.
|
- `WORKERS`: **1**: Number of initial workers for the queue.
|
||||||
- `MAX_WORKERS`: **10**: Maximum number of worker go-routines for the queue.
|
- `MAX_WORKERS`: **10**: Maximum number of worker go-routines for the queue.
|
||||||
- `BLOCK_TIMEOUT`: **1s**: If the queue blocks for this time, boost the number of workers - the `BLOCK_TIMEOUT` will then be doubled before boosting again whilst the boost is ongoing.
|
- `BLOCK_TIMEOUT`: **1s**: If the queue blocks for this time, boost the number of workers - the `BLOCK_TIMEOUT` will then be doubled before boosting again whilst the boost is ongoing.
|
||||||
- `BOOST_TIMEOUT`: **5m**: Boost workers will timeout after this long.
|
- `BOOST_TIMEOUT`: **5m**: Boost workers will timeout after this long.
|
||||||
- `BOOST_WORKERS`: **1** (v1.14 and before: **5**): This many workers will be added to the worker pool if there is a boost.
|
- `BOOST_WORKERS`: **5**: This many workers will be added to the worker pool if there is a boost.
|
||||||
|
|
||||||
## Admin (`admin`)
|
## Admin (`admin`)
|
||||||
|
|
||||||
|
@ -417,9 +389,6 @@ relation to port exhaustion.
|
||||||
authentication.
|
authentication.
|
||||||
- `REVERSE_PROXY_AUTHENTICATION_EMAIL`: **X-WEBAUTH-EMAIL**: Header name for reverse proxy
|
- `REVERSE_PROXY_AUTHENTICATION_EMAIL`: **X-WEBAUTH-EMAIL**: Header name for reverse proxy
|
||||||
authentication provided email.
|
authentication provided email.
|
||||||
- `REVERSE_PROXY_LIMIT`: **1**: Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request.
|
|
||||||
Number of trusted proxy count. Set to zero to not use these headers.
|
|
||||||
- `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: List of IP addresses and networks separated by comma of trusted proxy servers. Use `*` to trust all.
|
|
||||||
- `DISABLE_GIT_HOOKS`: **true**: Set to `false` to enable users with git hook privilege to create custom git hooks.
|
- `DISABLE_GIT_HOOKS`: **true**: Set to `false` to enable users with git hook privilege to create custom git hooks.
|
||||||
WARNING: Custom git hooks can be used to perform arbitrary code execution on the host operating system.
|
WARNING: Custom git hooks can be used to perform arbitrary code execution on the host operating system.
|
||||||
This enables the users to access and modify this config file and the Gitea database and interrupt the Gitea service.
|
This enables the users to access and modify this config file and the Gitea database and interrupt the Gitea service.
|
||||||
|
@ -427,12 +396,11 @@ relation to port exhaustion.
|
||||||
It also enables them to access other resources available to the user on the operating system that is running the
|
It also enables them to access other resources available to the user on the operating system that is running the
|
||||||
Gitea instance and perform arbitrary actions in the name of the Gitea OS user.
|
Gitea instance and perform arbitrary actions in the name of the Gitea OS user.
|
||||||
This maybe harmful to you website or your operating system.
|
This maybe harmful to you website or your operating system.
|
||||||
- `DISABLE_WEBHOOKS`: **false**: Set to `true` to disable webhooks feature.
|
|
||||||
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to gitea repositories you should set the environment appropriately.
|
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to gitea repositories you should set the environment appropriately.
|
||||||
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
|
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
|
||||||
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
|
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
|
||||||
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
||||||
- `PASSWORD_HASH_ALGO`: **pbkdf2**: The hash algorithm to use \[argon2, pbkdf2, scrypt, bcrypt\], argon2 will spend more memory than others.
|
- `PASSWORD_HASH_ALGO`: **argon2**: The hash algorithm to use \[argon2, pbkdf2, scrypt, bcrypt\].
|
||||||
- `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie.
|
- `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie.
|
||||||
- `MIN_PASSWORD_LENGTH`: **6**: Minimum password length for new users.
|
- `MIN_PASSWORD_LENGTH`: **6**: Minimum password length for new users.
|
||||||
- `PASSWORD_COMPLEXITY`: **off**: Comma separated list of character classes required to pass minimum complexity. If left empty or no valid values are specified, checking is disabled (off):
|
- `PASSWORD_COMPLEXITY`: **off**: Comma separated list of character classes required to pass minimum complexity. If left empty or no valid values are specified, checking is disabled (off):
|
||||||
|
@ -442,7 +410,6 @@ relation to port exhaustion.
|
||||||
- spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~``
|
- spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~``
|
||||||
- off - do not check password complexity
|
- off - do not check password complexity
|
||||||
- `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed.
|
- `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed.
|
||||||
- `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**: Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security.
|
|
||||||
|
|
||||||
## OpenID (`openid`)
|
## OpenID (`openid`)
|
||||||
|
|
||||||
|
@ -453,21 +420,6 @@ relation to port exhaustion.
|
||||||
- `BLACKLISTED_URIS`: **\<empty\>**: If non-empty, list of POSIX regex patterns matching
|
- `BLACKLISTED_URIS`: **\<empty\>**: If non-empty, list of POSIX regex patterns matching
|
||||||
OpenID URI's to block.
|
OpenID URI's to block.
|
||||||
|
|
||||||
## OAuth2 Client (`oauth2_client`)
|
|
||||||
|
|
||||||
- `REGISTER_EMAIL_CONFIRM`: *[service]* **REGISTER\_EMAIL\_CONFIRM**: Set this to enable or disable email confirmation of OAuth2 auto-registration. (Overwrites the REGISTER\_EMAIL\_CONFIRM setting of the `[service]` section)
|
|
||||||
- `OPENID_CONNECT_SCOPES`: **\<empty\>**: List of additional openid connect scopes. (`openid` is implicitly added)
|
|
||||||
- `ENABLE_AUTO_REGISTRATION`: **false**: Automatically create user accounts for new oauth2 users.
|
|
||||||
- `USERNAME`: **nickname**: The source of the username for new oauth2 accounts:
|
|
||||||
- userid - use the userid / sub attribute
|
|
||||||
- nickname - use the nickname attribute
|
|
||||||
- email - use the username part of the email attribute
|
|
||||||
- `UPDATE_AVATAR`: **false**: Update avatar if available from oauth2 provider. Update will be performed on each login.
|
|
||||||
- `ACCOUNT_LINKING`: **login**: How to handle if an account / email already exists:
|
|
||||||
- disabled - show an error
|
|
||||||
- login - show an account linking login
|
|
||||||
- auto - automatically link with the account (Please be aware that this will grant access to an existing account just because the same username or email is provided. You must make sure that this does not cause issues with your authentication providers.)
|
|
||||||
|
|
||||||
## Service (`service`)
|
## Service (`service`)
|
||||||
|
|
||||||
- `ACTIVE_CODE_LIVE_MINUTES`: **180**: Time limit (min) to confirm account/email registration.
|
- `ACTIVE_CODE_LIVE_MINUTES`: **180**: Time limit (min) to confirm account/email registration.
|
||||||
|
@ -505,35 +457,23 @@ relation to port exhaustion.
|
||||||
- `HCAPTCHA_SITEKEY`: **""**: Sign up at https://www.hcaptcha.com/ to get a sitekey for hcaptcha.
|
- `HCAPTCHA_SITEKEY`: **""**: Sign up at https://www.hcaptcha.com/ to get a sitekey for hcaptcha.
|
||||||
- `DEFAULT_KEEP_EMAIL_PRIVATE`: **false**: By default set users to keep their email address private.
|
- `DEFAULT_KEEP_EMAIL_PRIVATE`: **false**: By default set users to keep their email address private.
|
||||||
- `DEFAULT_ALLOW_CREATE_ORGANIZATION`: **true**: Allow new users to create organizations by default.
|
- `DEFAULT_ALLOW_CREATE_ORGANIZATION`: **true**: Allow new users to create organizations by default.
|
||||||
- `DEFAULT_USER_IS_RESTRICTED`: **false**: Give new users restricted permissions by default
|
|
||||||
- `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default.
|
- `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default.
|
||||||
- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access.
|
- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access.
|
||||||
- `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles.
|
- `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles.
|
||||||
- `ENABLE_TIMETRACKING`: **true**: Enable Timetracking feature.
|
- `ENABLE_TIMETRACKING`: **true**: Enable Timetracking feature.
|
||||||
- `DEFAULT_ENABLE_TIMETRACKING`: **true**: Allow repositories to use timetracking by default.
|
- `DEFAULT_ENABLE_TIMETRACKING`: **true**: Allow repositories to use timetracking by deault.
|
||||||
- `DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME`: **true**: Only allow users with write permissions to track time.
|
- `DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME`: **true**: Only allow users with write permissions to track time.
|
||||||
- `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register
|
- `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register
|
||||||
on this instance.
|
on this instance.
|
||||||
- `EMAIL_DOMAIN_BLOCKLIST`: **\<empty\>**: If non-empty, list of domain names that cannot be used to register on this instance
|
|
||||||
- `SHOW_REGISTRATION_BUTTON`: **! DISABLE\_REGISTRATION**: Show Registration Button
|
- `SHOW_REGISTRATION_BUTTON`: **! DISABLE\_REGISTRATION**: Show Registration Button
|
||||||
- `SHOW_MILESTONES_DASHBOARD_PAGE`: **true** Enable this to show the milestones dashboard page - a view of all the user's milestones
|
- `SHOW_MILESTONES_DASHBOARD_PAGE`: **true** Enable this to show the milestones dashboard page - a view of all the user's milestones
|
||||||
- `AUTO_WATCH_NEW_REPOS`: **true**: Enable this to let all organisation users watch new repos when they are created
|
- `AUTO_WATCH_NEW_REPOS`: **true**: Enable this to let all organisation users watch new repos when they are created
|
||||||
- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch a repository after their first commit to it
|
- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch a repository after their first commit to it
|
||||||
- `DEFAULT_USER_VISIBILITY`: **public**: Set default visibility mode for users, either "public", "limited" or "private".
|
|
||||||
- `ALLOWED_USER_VISIBILITY_MODES`: **public,limited,private**: Set which visibility modes a user can have
|
|
||||||
- `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private".
|
- `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private".
|
||||||
- `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation.
|
- `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation.
|
||||||
- `ALLOW_ONLY_INTERNAL_REGISTRATION`: **false** Set to true to force registration only via gitea.
|
|
||||||
- `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services.
|
- `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services.
|
||||||
- `NO_REPLY_ADDRESS`: **noreply.DOMAIN** Value for the domain part of the user's email address in the git log if user has set KeepEmailPrivate to true. DOMAIN resolves to the value in server.DOMAIN.
|
- `NO_REPLY_ADDRESS`: **DOMAIN** Default value for the domain part of the user's email address in the git log if he has set KeepEmailPrivate to true.
|
||||||
The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
|
The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
|
||||||
- `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted.
|
|
||||||
- `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles
|
|
||||||
|
|
||||||
### Service - Explore (`service.explore`)
|
|
||||||
|
|
||||||
- `REQUIRE_SIGNIN_VIEW`: **false**: Only allow signed in users to view the explore pages.
|
|
||||||
- `DISABLE_USERS_PAGE`: **false**: Disable the users explore page.
|
|
||||||
|
|
||||||
## SSH Minimum Key Sizes (`ssh.minimum_key_sizes`)
|
## SSH Minimum Key Sizes (`ssh.minimum_key_sizes`)
|
||||||
|
|
||||||
|
@ -550,8 +490,8 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||||
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
|
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
|
||||||
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
|
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
|
||||||
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
|
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
|
||||||
- `PROXY_URL`: **\<empty\>**: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy. If not given, will use global proxy setting.
|
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
||||||
- `PROXY_HOSTS`: **\<empty\>`**: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts. If not given, will use global proxy setting.
|
- `PROXY_HOSTS`: ****: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
||||||
|
|
||||||
## Mailer (`mailer`)
|
## Mailer (`mailer`)
|
||||||
|
|
||||||
|
@ -559,9 +499,9 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||||
- `DISABLE_HELO`: **\<empty\>**: Disable HELO operation.
|
- `DISABLE_HELO`: **\<empty\>**: Disable HELO operation.
|
||||||
- `HELO_HOSTNAME`: **\<empty\>**: Custom hostname for HELO operation.
|
- `HELO_HOSTNAME`: **\<empty\>**: Custom hostname for HELO operation.
|
||||||
- `HOST`: **\<empty\>**: SMTP mail host address and port (example: smtp.gitea.io:587).
|
- `HOST`: **\<empty\>**: SMTP mail host address and port (example: smtp.gitea.io:587).
|
||||||
- As per RFC 8314, if supported, Implicit TLS/SMTPS on port 465 is recommended, otherwise opportunistic TLS via STARTTLS on port 587 should be used.
|
- Using opportunistic TLS via STARTTLS on port 587 is recommended per RFC 6409.
|
||||||
- `IS_TLS_ENABLED` : **false** : Forcibly use TLS to connect even if not on a default SMTPS port.
|
- `IS_TLS_ENABLED` : **false** : Forcibly use TLS to connect even if not on a default SMTPS port.
|
||||||
- Note, if the port ends with `465` Implicit TLS/SMTPS/SMTP over TLS will be used despite this setting.
|
- Note, if the port ends with `465` SMTPS/SMTP over TLS will be used despite this setting.
|
||||||
- Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`.
|
- Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`.
|
||||||
- `FROM`: **\<empty\>**: Mail from address, RFC 5322. This can be just an email address, or
|
- `FROM`: **\<empty\>**: Mail from address, RFC 5322. This can be just an email address, or
|
||||||
the "Name" \<email@example.com\> format.
|
the "Name" \<email@example.com\> format.
|
||||||
|
@ -593,12 +533,11 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||||
## Cache (`cache`)
|
## Cache (`cache`)
|
||||||
|
|
||||||
- `ENABLED`: **true**: Enable the cache.
|
- `ENABLED`: **true**: Enable the cache.
|
||||||
- `ADAPTER`: **memory**: Cache engine adapter, either `memory`, `redis`, `twoqueue` or `memcache`. (`twoqueue` represents a size limited LRU cache.)
|
- `ADAPTER`: **memory**: Cache engine adapter, either `memory`, `redis`, or `memcache`.
|
||||||
- `INTERVAL`: **60**: Garbage Collection interval (sec), for memory and twoqueue cache only.
|
- `INTERVAL`: **60**: Garbage Collection interval (sec), for memory cache only.
|
||||||
- `HOST`: **\<empty\>**: Connection string for `redis` and `memcache`. For `twoqueue` sets configuration for the queue.
|
- `HOST`: **\<empty\>**: Connection string for `redis` and `memcache`.
|
||||||
- Redis: `redis://:macaron@127.0.0.1:6379/0?pool_size=100&idle_timeout=180s`
|
- Redis: `redis://:macaron@127.0.0.1:6379/0?pool_size=100&idle_timeout=180s`
|
||||||
- Memcache: `127.0.0.1:9090;127.0.0.1:9091`
|
- Memcache: `127.0.0.1:9090;127.0.0.1:9091`
|
||||||
- TwoQueue LRU cache: `{"size":50000,"recent_ratio":0.25,"ghost_ratio":0.5}` or `50000` representing the maximum number of objects stored in the cache.
|
|
||||||
- `ITEM_TTL`: **16h**: Time to keep items in cache if not used, Setting it to 0 disables caching.
|
- `ITEM_TTL`: **16h**: Time to keep items in cache if not used, Setting it to 0 disables caching.
|
||||||
|
|
||||||
## Cache - LastCommitCache settings (`cache.last_commit`)
|
## Cache - LastCommitCache settings (`cache.last_commit`)
|
||||||
|
@ -609,14 +548,12 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||||
|
|
||||||
## Session (`session`)
|
## Session (`session`)
|
||||||
|
|
||||||
- `PROVIDER`: **memory**: Session engine provider \[memory, file, redis, db, mysql, couchbase, memcache, postgres\].
|
- `PROVIDER`: **memory**: Session engine provider \[memory, file, redis, mysql, couchbase, memcache, nodb, postgres\].
|
||||||
- `PROVIDER_CONFIG`: **data/sessions**: For file, the root path; for db, empty (database config will be used); for others, the connection string.
|
- `PROVIDER_CONFIG`: **data/sessions**: For file, the root path; for others, the connection string.
|
||||||
- `COOKIE_SECURE`: **false**: Enable this to force using HTTPS for all session access.
|
- `COOKIE_SECURE`: **false**: Enable this to force using HTTPS for all session access.
|
||||||
- `COOKIE_NAME`: **i\_like\_gitea**: The name of the cookie used for the session ID.
|
- `COOKIE_NAME`: **i\_like\_gitea**: The name of the cookie used for the session ID.
|
||||||
- `GC_INTERVAL_TIME`: **86400**: GC interval in seconds.
|
- `GC_INTERVAL_TIME`: **86400**: GC interval in seconds.
|
||||||
- `SESSION_LIFE_TIME`: **86400**: Session life time in seconds, default is 86400 (1 day)
|
- `SESSION_LIFE_TIME`: **86400**: Session life time in seconds, default is 86400 (1 day)
|
||||||
- `DOMAIN`: **\<empty\>**: Sets the cookie Domain
|
|
||||||
- `SAME_SITE`: **lax** \[strict, lax, none\]: Set the SameSite setting for the cookie.
|
|
||||||
|
|
||||||
## Picture (`picture`)
|
## Picture (`picture`)
|
||||||
|
|
||||||
|
@ -671,15 +608,16 @@ Default templates for project boards:
|
||||||
- `MODE`: **console**: Logging mode. For multiple modes, use a comma to separate values. You can configure each mode in per mode log subsections `\[log.modename\]`. By default the file mode will log to `$ROOT_PATH/gitea.log`.
|
- `MODE`: **console**: Logging mode. For multiple modes, use a comma to separate values. You can configure each mode in per mode log subsections `\[log.modename\]`. By default the file mode will log to `$ROOT_PATH/gitea.log`.
|
||||||
- `LEVEL`: **Info**: General log level. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
|
- `LEVEL`: **Info**: General log level. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
|
||||||
- `STACKTRACE_LEVEL`: **None**: Default log level at which to log create stack traces. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
|
- `STACKTRACE_LEVEL`: **None**: Default log level at which to log create stack traces. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
|
||||||
|
- `REDIRECT_MACARON_LOG`: **false**: Redirects the Macaron log to its own logger or the default logger.
|
||||||
|
- `MACARON`: **file**: Logging mode for the macaron logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.macaron\]`. By default the file mode will log to `$ROOT_PATH/macaron.log`. (If you set this to `,` it will log to default gitea logger.)
|
||||||
- `ROUTER_LOG_LEVEL`: **Info**: The log level that the router should log at. (If you are setting the access log, its recommended to place this at Debug.)
|
- `ROUTER_LOG_LEVEL`: **Info**: The log level that the router should log at. (If you are setting the access log, its recommended to place this at Debug.)
|
||||||
- `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default gitea logger.)
|
- `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default gitea logger.)
|
||||||
NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`.
|
NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`.
|
||||||
- `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template
|
- `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template
|
||||||
- `ENABLE_SSH_LOG`: **false**: save ssh log to log file
|
|
||||||
- `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default gitea logger.)
|
- `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default gitea logger.)
|
||||||
- `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log.
|
- `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log.
|
||||||
- The following variables are available:
|
- The following variables are available:
|
||||||
- `Ctx`: the `context.Context` of the request.
|
- `Ctx`: the `macaron.Context` of the request.
|
||||||
- `Identity`: the SignedUserName or `"-"` if not logged in.
|
- `Identity`: the SignedUserName or `"-"` if not logged in.
|
||||||
- `Start`: the start time of the request.
|
- `Start`: the start time of the request.
|
||||||
- `ResponseWriter`: the responseWriter from the request.
|
- `ResponseWriter`: the responseWriter from the request.
|
||||||
|
@ -732,18 +670,13 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||||
- `RUN_AT_START`: **false**: Run cron tasks at application start-up.
|
- `RUN_AT_START`: **false**: Run cron tasks at application start-up.
|
||||||
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
|
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
|
||||||
|
|
||||||
- `SCHEDULE` accept formats
|
|
||||||
- Full crontab specs, e.g. `* * * * * ?`
|
|
||||||
- Descriptors, e.g. `@midnight`, `@every 1h30m` ...
|
|
||||||
- See more: [cron decument](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14)
|
|
||||||
|
|
||||||
### Basic cron tasks - enabled by default
|
### Basic cron tasks - enabled by default
|
||||||
|
|
||||||
#### Cron - Cleanup old repository archives (`cron.archive_cleanup`)
|
#### Cron - Cleanup old repository archives (`cron.archive_cleanup`)
|
||||||
|
|
||||||
- `ENABLED`: **true**: Enable service.
|
- `ENABLED`: **true**: Enable service.
|
||||||
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
|
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
|
||||||
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
|
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
|
||||||
- `OLDER_THAN`: **24h**: Archives created more than `OLDER_THAN` ago are subject to deletion, e.g. `12h`.
|
- `OLDER_THAN`: **24h**: Archives created more than `OLDER_THAN` ago are subject to deletion, e.g. `12h`.
|
||||||
|
|
||||||
#### Cron - Update Mirrors (`cron.update_mirrors`)
|
#### Cron - Update Mirrors (`cron.update_mirrors`)
|
||||||
|
@ -753,31 +686,22 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||||
|
|
||||||
#### Cron - Repository Health Check (`cron.repo_health_check`)
|
#### Cron - Repository Health Check (`cron.repo_health_check`)
|
||||||
|
|
||||||
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
|
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository health check.
|
||||||
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
|
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
|
||||||
- `ARGS`: **\<empty\>**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
|
- `ARGS`: **\<empty\>**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
|
||||||
|
|
||||||
#### Cron - Repository Statistics Check (`cron.check_repo_stats`)
|
#### Cron - Repository Statistics Check (`cron.check_repo_stats`)
|
||||||
|
|
||||||
- `RUN_AT_START`: **true**: Run repository statistics check at start time.
|
- `RUN_AT_START`: **true**: Run repository statistics check at start time.
|
||||||
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
|
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository statistics check.
|
||||||
|
|
||||||
### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
|
|
||||||
|
|
||||||
- `ENABLED`: **true**: Enable cleanup hook_task job.
|
|
||||||
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
|
|
||||||
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
|
|
||||||
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
|
|
||||||
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
|
|
||||||
- `NUMBER_TO_KEEP`: **10**: If CLEANUP_TYPE is set to PerWebhook, this is number of hook_task records to keep for a webhook (i.e. keep the most recent x deliveries).
|
|
||||||
|
|
||||||
#### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
|
#### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
|
||||||
|
|
||||||
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
|
- `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
|
||||||
|
|
||||||
#### Cron - Sync External Users (`cron.sync_external_users`)
|
#### Cron - Sync External Users (`cron.sync_external_users`)
|
||||||
|
|
||||||
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
|
- `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
|
||||||
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
|
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
|
||||||
|
|
||||||
### Extended cron tasks (not enabled by default)
|
### Extended cron tasks (not enabled by default)
|
||||||
|
@ -820,28 +744,19 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||||
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
|
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
|
||||||
- `SCHEDULE`: **@every 72h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
|
- `SCHEDULE`: **@every 72h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
|
||||||
|
|
||||||
#### Cron - Delete all old actions from database ('cron.delete_old_actions')
|
|
||||||
- `ENABLED`: **false**: Enable service.
|
|
||||||
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
|
|
||||||
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
|
|
||||||
- `SCHEDULE`: **@every 128h**: Cron syntax for scheduling a work, e.g. `@every 128h`.
|
|
||||||
- `OLDER_THAN`: **@every 8760h**: any action older than this expression will be deleted from database, suggest using `8760h` (1 year) because that's the max length of heatmap.
|
|
||||||
|
|
||||||
## Git (`git`)
|
## Git (`git`)
|
||||||
|
|
||||||
- `PATH`: **""**: The path of git executable. If empty, Gitea searches through the PATH environment.
|
- `PATH`: **""**: The path of git executable. If empty, Gitea searches through the PATH environment.
|
||||||
- `DISABLE_DIFF_HIGHLIGHT`: **false**: Disables highlight of added and removed changes.
|
- `DISABLE_DIFF_HIGHLIGHT`: **false**: Disables highlight of added and removed changes.
|
||||||
- `MAX_GIT_DIFF_LINES`: **1000**: Max number of lines allowed of a single file in diff view.
|
- `MAX_GIT_DIFF_LINES`: **100**: Max number of lines allowed of a single file in diff view.
|
||||||
- `MAX_GIT_DIFF_LINE_CHARACTERS`: **5000**: Max character count per line highlighted in diff view.
|
- `MAX_GIT_DIFF_LINE_CHARACTERS`: **5000**: Max character count per line highlighted in diff view.
|
||||||
- `MAX_GIT_DIFF_FILES`: **100**: Max number of files shown in diff view.
|
- `MAX_GIT_DIFF_FILES`: **100**: Max number of files shown in diff view.
|
||||||
- `COMMITS_RANGE_SIZE`: **50**: Set the default commits range size
|
|
||||||
- `BRANCHES_RANGE_SIZE`: **20**: Set the default branches range size
|
|
||||||
- `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`. See more on http://git-scm.com/docs/git-gc/
|
- `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`. See more on http://git-scm.com/docs/git-gc/
|
||||||
- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use git wire protocol version 2 when git version >= 2.18, default is true, set to false when you always want git wire protocol version 1
|
- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use git wire protocol version 2 when git version >= 2.18, default is true, set to false when you always want git wire protocol version 1
|
||||||
- `PULL_REQUEST_PUSH_MESSAGE`: **true**: Respond to pushes to a non-default branch with a URL for creating a Pull Request (if the repository has them enabled)
|
- `PULL_REQUEST_PUSH_MESSAGE`: **true**: Respond to pushes to a non-default branch with a URL for creating a Pull Request (if the repository has them enabled)
|
||||||
- `VERBOSE_PUSH`: **true**: Print status information about pushes as they are being processed.
|
- `VERBOSE_PUSH`: **true**: Print status information about pushes as they are being processed.
|
||||||
- `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay.
|
- `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay.
|
||||||
- `LARGE_OBJECT_THRESHOLD`: **1048576**: (Go-Git only), don't cache objects greater than this in memory. (Set to 0 to disable.)
|
|
||||||
## Git - Timeout settings (`git.timeout`)
|
## Git - Timeout settings (`git.timeout`)
|
||||||
- `DEFAUlT`: **360**: Git operations default timeout seconds.
|
- `DEFAUlT`: **360**: Git operations default timeout seconds.
|
||||||
- `MIGRATE`: **600**: Migrate external repositories timeout seconds.
|
- `MIGRATE`: **600**: Migrate external repositories timeout seconds.
|
||||||
|
@ -869,9 +784,7 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||||
- `ACCESS_TOKEN_EXPIRATION_TIME`: **3600**: Lifetime of an OAuth2 access token in seconds
|
- `ACCESS_TOKEN_EXPIRATION_TIME`: **3600**: Lifetime of an OAuth2 access token in seconds
|
||||||
- `REFRESH_TOKEN_EXPIRATION_TIME`: **730**: Lifetime of an OAuth2 refresh token in hours
|
- `REFRESH_TOKEN_EXPIRATION_TIME`: **730**: Lifetime of an OAuth2 refresh token in hours
|
||||||
- `INVALIDATE_REFRESH_TOKENS`: **false**: Check if refresh token has already been used
|
- `INVALIDATE_REFRESH_TOKENS`: **false**: Check if refresh token has already been used
|
||||||
- `JWT_SIGNING_ALGORITHM`: **RS256**: Algorithm used to sign OAuth2 tokens. Valid values: \[`HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`\]
|
- `JWT_SECRET`: **\<empty\>**: OAuth2 authentication secret for access and refresh tokens, change this a unique string.
|
||||||
- `JWT_SECRET`: **\<empty\>**: OAuth2 authentication secret for access and refresh tokens, change this to a unique string. This setting is only needed if `JWT_SIGNING_ALGORITHM` is set to `HS256`, `HS384` or `HS512`.
|
|
||||||
- `JWT_SIGNING_PRIVATE_KEY_FILE`: **jwt/private.pem**: Private key file path used to sign OAuth2 tokens. The path is relative to `APP_DATA_PATH`. This setting is only needed if `JWT_SIGNING_ALGORITHM` is set to `RS256`, `RS384`, `RS512`, `ES256`, `ES384` or `ES512`. The file must contain a RSA or ECDSA private key in the PKCS8 format. If no key exists a 4096 bit key will be created for you.
|
|
||||||
- `MAX_TOKEN_LENGTH`: **32767**: Maximum length of token/cookie to accept from OAuth2 provider
|
- `MAX_TOKEN_LENGTH`: **32767**: Maximum length of token/cookie to accept from OAuth2 provider
|
||||||
|
|
||||||
## i18n (`i18n`)
|
## i18n (`i18n`)
|
||||||
|
@ -885,23 +798,19 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||||
|
|
||||||
## Markup (`markup`)
|
## Markup (`markup`)
|
||||||
|
|
||||||
- `MERMAID_MAX_SOURCE_CHARACTERS`: **5000**: Set the maximum size of a Mermaid source. (Set to -1 to disable)
|
|
||||||
|
|
||||||
Gitea can support Markup using external tools. The example below will add a markup named `asciidoc`.
|
Gitea can support Markup using external tools. The example below will add a markup named `asciidoc`.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[markup.asciidoc]
|
[markup.asciidoc]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
NEED_POSTPROCESS = true
|
|
||||||
FILE_EXTENSIONS = .adoc,.asciidoc
|
FILE_EXTENSIONS = .adoc,.asciidoc
|
||||||
RENDER_COMMAND = "asciidoc --out-file=- -"
|
RENDER_COMMAND = "asciidoc --out-file=- -"
|
||||||
IS_INPUT_FILE = false
|
IS_INPUT_FILE = false
|
||||||
```
|
```
|
||||||
|
|
||||||
- ENABLED: **false** Enable markup support; set to **true** to enable this renderer.
|
- ENABLED: **false** Enable markup support; set to **true** to enable this renderer.
|
||||||
- NEED\_POSTPROCESS: **true** set to **true** to replace links / sha1 and etc.
|
|
||||||
- FILE\_EXTENSIONS: **\<empty\>** List of file extensions that should be rendered by an external
|
- FILE\_EXTENSIONS: **\<empty\>** List of file extensions that should be rendered by an external
|
||||||
command. Multiple extensions needs a comma as splitter.
|
command. Multiple extentions needs a comma as splitter.
|
||||||
- RENDER\_COMMAND: External command to render all matching extensions.
|
- RENDER\_COMMAND: External command to render all matching extensions.
|
||||||
- IS\_INPUT\_FILE: **false** Input is not a standard input but a file param followed `RENDER_COMMAND`.
|
- IS\_INPUT\_FILE: **false** Input is not a standard input but a file param followed `RENDER_COMMAND`.
|
||||||
|
|
||||||
|
@ -919,21 +828,17 @@ Gitea supports customizing the sanitization policy for rendered HTML. The exampl
|
||||||
ELEMENT = span
|
ELEMENT = span
|
||||||
ALLOW_ATTR = class
|
ALLOW_ATTR = class
|
||||||
REGEXP = ^\s*((math(\s+|$)|inline(\s+|$)|display(\s+|$)))+
|
REGEXP = ^\s*((math(\s+|$)|inline(\s+|$)|display(\s+|$)))+
|
||||||
ALLOW_DATA_URI_IMAGES = true
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- `ELEMENT`: The element this policy applies to. Must be non-empty.
|
- `ELEMENT`: The element this policy applies to. Must be non-empty.
|
||||||
- `ALLOW_ATTR`: The attribute this policy allows. Must be non-empty.
|
- `ALLOW_ATTR`: The attribute this policy allows. Must be non-empty.
|
||||||
- `REGEXP`: A regex to match the contents of the attribute against. Must be present but may be empty for unconditional whitelisting of this attribute.
|
- `REGEXP`: A regex to match the contents of the attribute against. Must be present but may be empty for unconditional whitelisting of this attribute.
|
||||||
- `ALLOW_DATA_URI_IMAGES`: **false** Allow data uri images (`<img src="data:image/png;base64,..."/>`).
|
|
||||||
|
|
||||||
Multiple sanitisation rules can be defined by adding unique subsections, e.g. `[markup.sanitizer.TeX-2]`.
|
Multiple sanitisation rules can be defined by adding unique subsections, e.g. `[markup.sanitizer.TeX-2]`.
|
||||||
To apply a sanitisation rules only for a specify external renderer they must use the renderer name, e.g. `[markup.sanitizer.asciidoc.rule-1]`.
|
|
||||||
If the rule is defined above the renderer ini section or the name does not match a renderer it is applied to every renderer.
|
|
||||||
|
|
||||||
## Time (`time`)
|
## Time (`time`)
|
||||||
|
|
||||||
- `FORMAT`: Time format to display on UI. i.e. RFC1123 or 2006-01-02 15:04:05
|
- `FORMAT`: Time format to diplay on UI. i.e. RFC1123 or 2006-01-02 15:04:05
|
||||||
- `DEFAULT_UI_LOCATION`: Default location of time on the UI, so that we can display correct user's time on UI. i.e. Shanghai/Asia
|
- `DEFAULT_UI_LOCATION`: Default location of time on the UI, so that we can display correct user's time on UI. i.e. Shanghai/Asia
|
||||||
|
|
||||||
## Task (`task`)
|
## Task (`task`)
|
||||||
|
@ -951,7 +856,6 @@ Task queue configuration has been moved to `queue.task`. However, the below conf
|
||||||
- `ALLOWED_DOMAINS`: **\<empty\>**: Domains allowlist for migrating repositories, default is blank. It means everything will be allowed. Multiple domains could be separated by commas.
|
- `ALLOWED_DOMAINS`: **\<empty\>**: Domains allowlist for migrating repositories, default is blank. It means everything will be allowed. Multiple domains could be separated by commas.
|
||||||
- `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option will be ignored.
|
- `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option will be ignored.
|
||||||
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291
|
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291
|
||||||
- `SKIP_TLS_VERIFY`: **false**: Allow skip tls verify
|
|
||||||
|
|
||||||
## Mirror (`mirror`)
|
## Mirror (`mirror`)
|
||||||
|
|
||||||
|
@ -966,7 +870,7 @@ is `data/lfs` and the default of `MINIO_BASE_PATH` is `lfs/`.
|
||||||
|
|
||||||
- `STORAGE_TYPE`: **local**: Storage type for lfs, `local` for local disk or `minio` for s3 compatible object storage service or other name defined with `[storage.xxx]`
|
- `STORAGE_TYPE`: **local**: Storage type for lfs, `local` for local disk or `minio` for s3 compatible object storage service or other name defined with `[storage.xxx]`
|
||||||
- `SERVE_DIRECT`: **false**: Allows the storage driver to redirect to authenticated URLs to serve files directly. Currently, only Minio/S3 is supported via signed URLs, local does nothing.
|
- `SERVE_DIRECT`: **false**: Allows the storage driver to redirect to authenticated URLs to serve files directly. Currently, only Minio/S3 is supported via signed URLs, local does nothing.
|
||||||
- `PATH`: **./data/lfs**: Where to store LFS files, only available when `STORAGE_TYPE` is `local`. If not set it fall back to deprecated LFS_CONTENT_PATH value in [server] section.
|
- `CONTENT_PATH`: **./data/lfs**: Where to store LFS files, only available when `STORAGE_TYPE` is `local`.
|
||||||
- `MINIO_ENDPOINT`: **localhost:9000**: Minio endpoint to connect only available when `STORAGE_TYPE` is `minio`
|
- `MINIO_ENDPOINT`: **localhost:9000**: Minio endpoint to connect only available when `STORAGE_TYPE` is `minio`
|
||||||
- `MINIO_ACCESS_KEY_ID`: Minio accessKeyID to connect only available when `STORAGE_TYPE` is `minio`
|
- `MINIO_ACCESS_KEY_ID`: Minio accessKeyID to connect only available when `STORAGE_TYPE` is `minio`
|
||||||
- `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey to connect only available when `STORAGE_TYPE is` `minio`
|
- `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey to connect only available when `STORAGE_TYPE is` `minio`
|
||||||
|
@ -1008,36 +912,6 @@ MINIO_USE_SSL = false
|
||||||
|
|
||||||
And used by `[attachment]`, `[lfs]` and etc. as `STORAGE_TYPE`.
|
And used by `[attachment]`, `[lfs]` and etc. as `STORAGE_TYPE`.
|
||||||
|
|
||||||
## Repository Archive Storage (`storage.repo-archive`)
|
|
||||||
|
|
||||||
Configuration for repository archive storage. It will inherit from default `[storage]` or
|
|
||||||
`[storage.xxx]` when set `STORAGE_TYPE` to `xxx`. The default of `PATH`
|
|
||||||
is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`.
|
|
||||||
|
|
||||||
- `STORAGE_TYPE`: **local**: Storage type for repo archive, `local` for local disk or `minio` for s3 compatible object storage service or other name defined with `[storage.xxx]`
|
|
||||||
- `SERVE_DIRECT`: **false**: Allows the storage driver to redirect to authenticated URLs to serve files directly. Currently, only Minio/S3 is supported via signed URLs, local does nothing.
|
|
||||||
- `PATH`: **./data/repo-archive**: Where to store archive files, only available when `STORAGE_TYPE` is `local`.
|
|
||||||
- `MINIO_ENDPOINT`: **localhost:9000**: Minio endpoint to connect only available when `STORAGE_TYPE` is `minio`
|
|
||||||
- `MINIO_ACCESS_KEY_ID`: Minio accessKeyID to connect only available when `STORAGE_TYPE` is `minio`
|
|
||||||
- `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey to connect only available when `STORAGE_TYPE is` `minio`
|
|
||||||
- `MINIO_BUCKET`: **gitea**: Minio bucket to store the lfs 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_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
|
|
||||||
|
|
||||||
## Proxy (`proxy`)
|
|
||||||
|
|
||||||
- `PROXY_ENABLED`: **false**: Enable the proxy if true, all requests to external via HTTP will be affected, if false, no proxy will be used even environment http_proxy/https_proxy
|
|
||||||
- `PROXY_URL`: **\<empty\>**: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
|
||||||
- `PROXY_HOSTS`: **\<empty\>**: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
|
||||||
|
|
||||||
i.e.
|
|
||||||
```ini
|
|
||||||
PROXY_ENABLED = true
|
|
||||||
PROXY_URL = socks://127.0.0.1:1080
|
|
||||||
PROXY_HOSTS = *.github.com
|
|
||||||
```
|
|
||||||
|
|
||||||
## Other (`other`)
|
## Other (`other`)
|
||||||
|
|
||||||
- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.
|
- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.
|
||||||
|
|
|
@ -36,11 +36,6 @@ menu:
|
||||||
- `MAX_CREATION_LIMIT`: 全局最大每个用户创建的git工程数目, `-1` 表示没限制。
|
- `MAX_CREATION_LIMIT`: 全局最大每个用户创建的git工程数目, `-1` 表示没限制。
|
||||||
- `PULL_REQUEST_QUEUE_LENGTH`: 小心:合并请求测试队列的长度,尽量放大。
|
- `PULL_REQUEST_QUEUE_LENGTH`: 小心:合并请求测试队列的长度,尽量放大。
|
||||||
|
|
||||||
### Repository - Release (`repository.release`)
|
|
||||||
|
|
||||||
- `ALLOWED_TYPES`: **\<empty\>**: 允许扩展名的列表,用逗号分隔 (`.zip`), mime 类型 (`text/plain`) 或者匹配符号 (`image/*`, `audio/*`, `video/*`). 空值或者 `*/*` 允许所有类型。
|
|
||||||
- `DEFAULT_PAGING_NUM`: **10**: 默认的发布版本页面分页。
|
|
||||||
|
|
||||||
## UI (`ui`)
|
## UI (`ui`)
|
||||||
|
|
||||||
- `EXPLORE_PAGING_NUM`: 探索页面每页显示的仓库数量。
|
- `EXPLORE_PAGING_NUM`: 探索页面每页显示的仓库数量。
|
||||||
|
@ -80,7 +75,6 @@ menu:
|
||||||
|
|
||||||
- `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true` 或 `false`, 默认是 `false`。
|
- `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true` 或 `false`, 默认是 `false`。
|
||||||
- `LFS_JWT_SECRET`: LFS 认证密钥,改成自己的。
|
- `LFS_JWT_SECRET`: LFS 认证密钥,改成自己的。
|
||||||
- `LFS_CONTENT_PATH`: **已废弃**, 存放 lfs 命令上传的文件的地方,默认是 `data/lfs`。
|
|
||||||
|
|
||||||
## Database (`database`)
|
## Database (`database`)
|
||||||
|
|
||||||
|
@ -140,11 +134,6 @@ menu:
|
||||||
- `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: 允许通过反向认证做自动注册。
|
- `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: 允许通过反向认证做自动注册。
|
||||||
- `ENABLE_CAPTCHA`: 注册时使用图片验证码。
|
- `ENABLE_CAPTCHA`: 注册时使用图片验证码。
|
||||||
|
|
||||||
### Service - Expore (`service.explore`)
|
|
||||||
|
|
||||||
- `REQUIRE_SIGNIN_VIEW`: **false**: 仅允许已登录的用户查看探索页面。
|
|
||||||
- `DISABLE_USERS_PAGE`: **false**: 不显示用户探索页面。
|
|
||||||
|
|
||||||
## Webhook (`webhook`)
|
## Webhook (`webhook`)
|
||||||
|
|
||||||
- `QUEUE_LENGTH`: 说明: Hook 任务队列长度。
|
- `QUEUE_LENGTH`: 说明: Hook 任务队列长度。
|
||||||
|
@ -250,11 +239,6 @@ test01.xls: application/vnd.ms-excel; charset=binary
|
||||||
|
|
||||||
- `ENABLED`: 是否在后台运行定期任务。
|
- `ENABLED`: 是否在后台运行定期任务。
|
||||||
- `RUN_AT_START`: 是否启动时自动运行。
|
- `RUN_AT_START`: 是否启动时自动运行。
|
||||||
- `SCHEDULE` 所接受的格式
|
|
||||||
- 完整 crontab 控制, 例如 `* * * * * ?`
|
|
||||||
- 描述符, 例如 `@midnight`, `@every 1h30m` ...
|
|
||||||
- 更多细节参见 [cron api文档](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14)
|
|
||||||
|
|
||||||
|
|
||||||
### Cron - Update Mirrors (`cron.update_mirrors`)
|
### Cron - Update Mirrors (`cron.update_mirrors`)
|
||||||
|
|
||||||
|
@ -262,18 +246,18 @@ test01.xls: application/vnd.ms-excel; charset=binary
|
||||||
|
|
||||||
### Cron - Repository Health Check (`cron.repo_health_check`)
|
### Cron - Repository Health Check (`cron.repo_health_check`)
|
||||||
|
|
||||||
- `SCHEDULE`: 仓库健康监测的Cron语法,比如:`@midnight`。
|
- `SCHEDULE`: 仓库健康监测的Cron语法,比如:`@every 24h`。
|
||||||
- `TIMEOUT`: 仓库健康监测的超时时间,比如:`60s`.
|
- `TIMEOUT`: 仓库健康监测的超时时间,比如:`60s`.
|
||||||
- `ARGS`: 执行 `git fsck` 命令的参数,比如:`--unreachable --tags`。
|
- `ARGS`: 执行 `git fsck` 命令的参数,比如:`--unreachable --tags`。
|
||||||
|
|
||||||
### Cron - Repository Statistics Check (`cron.check_repo_stats`)
|
### Cron - Repository Statistics Check (`cron.check_repo_stats`)
|
||||||
|
|
||||||
- `RUN_AT_START`: 是否启动时自动运行仓库统计。
|
- `RUN_AT_START`: 是否启动时自动运行仓库统计。
|
||||||
- `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@midnight`.
|
- `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@every 24h`.
|
||||||
|
|
||||||
### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
|
### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
|
||||||
|
|
||||||
- `SCHEDULE`: **@midnight** : 每次同步的间隔时间。此任务总是在启动时自动进行。
|
- `SCHEDULE`: **@every 24h** : 每次同步的间隔时间。此任务总是在启动时自动进行。
|
||||||
|
|
||||||
## Git (`git`)
|
## Git (`git`)
|
||||||
|
|
||||||
|
@ -307,14 +291,12 @@ test01.xls: application/vnd.ms-excel; charset=binary
|
||||||
```ini
|
```ini
|
||||||
[markup.asciidoc]
|
[markup.asciidoc]
|
||||||
ENABLED = false
|
ENABLED = false
|
||||||
NEED_POSTPROCESS = true
|
|
||||||
FILE_EXTENSIONS = .adoc,.asciidoc
|
FILE_EXTENSIONS = .adoc,.asciidoc
|
||||||
RENDER_COMMAND = "asciidoc --out-file=- -"
|
RENDER_COMMAND = "asciidoc --out-file=- -"
|
||||||
IS_INPUT_FILE = false
|
IS_INPUT_FILE = false
|
||||||
```
|
```
|
||||||
|
|
||||||
- ENABLED: 是否启用,默认为false。
|
- ENABLED: 是否启用,默认为false。
|
||||||
- NEED\_POSTPROCESS: **true** 设置为 true 则会替换渲染文件中的内部链接和Commit ID 等。
|
|
||||||
- FILE_EXTENSIONS: 关联的文档的扩展名,多个扩展名用都好分隔。
|
- FILE_EXTENSIONS: 关联的文档的扩展名,多个扩展名用都好分隔。
|
||||||
- RENDER_COMMAND: 工具的命令行命令及参数。
|
- RENDER_COMMAND: 工具的命令行命令及参数。
|
||||||
- IS_INPUT_FILE: 输入方式是最后一个参数为文件路径还是从标准输入读取。
|
- IS_INPUT_FILE: 输入方式是最后一个参数为文件路径还是从标准输入读取。
|
||||||
|
@ -337,7 +319,6 @@ IS_INPUT_FILE = false
|
||||||
- `ALLOWED_DOMAINS`: **\<empty\>**: 迁移仓库的域名白名单,默认为空,表示允许从任意域名迁移仓库,多个域名用逗号分隔。
|
- `ALLOWED_DOMAINS`: **\<empty\>**: 迁移仓库的域名白名单,默认为空,表示允许从任意域名迁移仓库,多个域名用逗号分隔。
|
||||||
- `BLOCKED_DOMAINS`: **\<empty\>**: 迁移仓库的域名黑名单,默认为空,多个域名用逗号分隔。如果 `ALLOWED_DOMAINS` 不为空,此选项将会被忽略。
|
- `BLOCKED_DOMAINS`: **\<empty\>**: 迁移仓库的域名黑名单,默认为空,多个域名用逗号分隔。如果 `ALLOWED_DOMAINS` 不为空,此选项将会被忽略。
|
||||||
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918
|
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918
|
||||||
- `SKIP_TLS_VERIFY`: **false**: 允许忽略 TLS 认证
|
|
||||||
|
|
||||||
## LFS (`lfs`)
|
## LFS (`lfs`)
|
||||||
|
|
||||||
|
@ -345,7 +326,7 @@ LFS 的存储配置。 如果 `STORAGE_TYPE` 为空,则此配置将从 `[stora
|
||||||
|
|
||||||
- `STORAGE_TYPE`: **local**: LFS 的存储类型,`local` 将存储到磁盘,`minio` 将存储到 s3 兼容的对象服务。
|
- `STORAGE_TYPE`: **local**: LFS 的存储类型,`local` 将存储到磁盘,`minio` 将存储到 s3 兼容的对象服务。
|
||||||
- `SERVE_DIRECT`: **false**: 允许直接重定向到存储系统。当前,仅 Minio/S3 是支持的。
|
- `SERVE_DIRECT`: **false**: 允许直接重定向到存储系统。当前,仅 Minio/S3 是支持的。
|
||||||
- `PATH`: 存放 lfs 命令上传的文件的地方,默认是 `data/lfs`。
|
- `CONTENT_PATH`: 存放 lfs 命令上传的文件的地方,默认是 `data/lfs`。
|
||||||
- `MINIO_ENDPOINT`: **localhost:9000**: Minio 地址,仅当 `LFS_STORAGE_TYPE` 为 `minio` 时有效。
|
- `MINIO_ENDPOINT`: **localhost:9000**: Minio 地址,仅当 `LFS_STORAGE_TYPE` 为 `minio` 时有效。
|
||||||
- `MINIO_ACCESS_KEY_ID`: Minio accessKeyID,仅当 `LFS_STORAGE_TYPE` 为 `minio` 时有效。
|
- `MINIO_ACCESS_KEY_ID`: Minio accessKeyID,仅当 `LFS_STORAGE_TYPE` 为 `minio` 时有效。
|
||||||
- `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey,仅当 `LFS_STORAGE_TYPE` 为 `minio` 时有效。
|
- `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey,仅当 `LFS_STORAGE_TYPE` 为 `minio` 时有效。
|
||||||
|
@ -388,34 +369,6 @@ MINIO_USE_SSL = false
|
||||||
|
|
||||||
然后你在 `[attachment]`, `[lfs]` 等中可以把这个名字用作 `STORAGE_TYPE` 的值。
|
然后你在 `[attachment]`, `[lfs]` 等中可以把这个名字用作 `STORAGE_TYPE` 的值。
|
||||||
|
|
||||||
## Repository Archive Storage (`storage.repo-archive`)
|
|
||||||
|
|
||||||
Repository archive 的存储配置。 如果 `STORAGE_TYPE` 为空,则此配置将从 `[storage]` 继承。如果不为 `local` 或者 `minio` 而为 `xxx`, 则从 `[storage.xxx]` 继承。当继承时, `PATH` 默认为 `data/repo-archive`,`MINIO_BASE_PATH` 默认为 `repo-archive/`。
|
|
||||||
|
|
||||||
- `STORAGE_TYPE`: **local**: Repository archive 的存储类型,`local` 将存储到磁盘,`minio` 将存储到 s3 兼容的对象服务。
|
|
||||||
- `SERVE_DIRECT`: **false**: 允许直接重定向到存储系统。当前,仅 Minio/S3 是支持的。
|
|
||||||
- `PATH`: 存放 Repository archive 上传的文件的地方,默认是 `data/repo-archive`。
|
|
||||||
- `MINIO_ENDPOINT`: **localhost:9000**: Minio 地址,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
|
||||||
- `MINIO_ACCESS_KEY_ID`: Minio accessKeyID,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
|
||||||
- `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
|
||||||
- `MINIO_BUCKET`: **gitea**: Minio bucket,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
|
||||||
- `MINIO_LOCATION`: **us-east-1**: Minio location ,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
|
||||||
- `MINIO_BASE_PATH`: **repo-archive/**: Minio base path ,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
|
||||||
- `MINIO_USE_SSL`: **false**: Minio 是否启用 ssl ,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
|
||||||
|
|
||||||
## Proxy (`proxy`)
|
|
||||||
|
|
||||||
- `PROXY_ENABLED`: **false**: 是否启用全局代理。如果为否,则不使用代理,环境变量中的代理也不使用
|
|
||||||
- `PROXY_URL`: **\<empty\>**: 代理服务器地址,支持 http://, https//, socks://,为空则不启用代理而使用环境变量中的 http_proxy/https_proxy
|
|
||||||
- `PROXY_HOSTS`: **\<empty\>**: 逗号分隔的多个需要代理的网址,支持 * 号匹配符号, ** 表示匹配所有网站
|
|
||||||
|
|
||||||
i.e.
|
|
||||||
```ini
|
|
||||||
PROXY_ENABLED = true
|
|
||||||
PROXY_URL = socks://127.0.0.1:1080
|
|
||||||
PROXY_HOSTS = *.github.com
|
|
||||||
```
|
|
||||||
|
|
||||||
## Other (`other`)
|
## Other (`other`)
|
||||||
|
|
||||||
- `SHOW_FOOTER_BRANDING`: 为真则在页面底部显示Gitea的字样。
|
- `SHOW_FOOTER_BRANDING`: 为真则在页面底部显示Gitea的字样。
|
||||||
|
|
|
@ -30,19 +30,18 @@ the Linux Filesystem Standard. Gitea will attempt to create required folders, in
|
||||||
`custom/`. Distributions may provide a symlink for `custom` using `/etc/gitea/`.
|
`custom/`. Distributions may provide a symlink for `custom` using `/etc/gitea/`.
|
||||||
|
|
||||||
Application settings can be found in file `CustomConf` which is by default,
|
Application settings can be found in file `CustomConf` which is by default,
|
||||||
`$GITEA_CUSTOM/conf/app.ini` but may be different if your build has set this differently.
|
`CustomPath/conf/app.ini` but may be different if your build has set this differently.
|
||||||
Again `gitea help` will allow you review this variable and you can override it using the
|
Again `gitea help` will allow you review this variable and you can override it using the
|
||||||
`--config` option on the `gitea` binary.
|
`--config` option on the `gitea` binary.
|
||||||
|
|
||||||
- [Quick Cheat Sheet](https://docs.gitea.io/en-us/config-cheat-sheet/)
|
- [Quick Cheat Sheet](https://docs.gitea.io/en-us/config-cheat-sheet/)
|
||||||
- [Complete List](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini)
|
- [Complete List](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
|
||||||
|
|
||||||
If the `CustomPath` folder can't be found despite checking `gitea help`, check the `GITEA_CUSTOM`
|
If the `CustomPath` folder can't be found despite checking `gitea help`, check the `GITEA_CUSTOM`
|
||||||
environment variable; this can be used to override the default path to something else.
|
environment variable; this can be used to override the default path to something else.
|
||||||
`GITEA_CUSTOM` might, for example, be set by an init script. You can check whether the value
|
`GITEA_CUSTOM` might, for example, be set by an init script.
|
||||||
is set under the "Configuration" tab on the site administration page.
|
|
||||||
|
|
||||||
- [List of Environment Variables](https://docs.gitea.io/en-us/environment-variables/)
|
- [List of Environment Variables](https://docs.gitea.io/en-us/specific-variables/)
|
||||||
|
|
||||||
**Note:** Gitea must perform a full restart to see configuration changes.
|
**Note:** Gitea must perform a full restart to see configuration changes.
|
||||||
|
|
||||||
|
@ -53,23 +52,27 @@ is set under the "Configuration" tab on the site administration page.
|
||||||
## Serving custom public files
|
## Serving custom public files
|
||||||
|
|
||||||
To make Gitea serve custom public files (like pages and images), use the folder
|
To make Gitea serve custom public files (like pages and images), use the folder
|
||||||
`$GITEA_CUSTOM/public/` as the webroot. Symbolic links will be followed.
|
`custom/public/` as the webroot. Symbolic links will be followed.
|
||||||
|
|
||||||
For example, a file `image.png` stored in `$GITEA_CUSTOM/public/`, can be accessed with
|
For example, a file `image.png` stored in `custom/public/`, can be accessed with
|
||||||
the url `http://gitea.domain.tld/assets/image.png`.
|
the url `http://gitea.domain.tld/image.png`.
|
||||||
|
|
||||||
## Changing the logo
|
## Changing the default logo
|
||||||
|
|
||||||
To build a custom logo clone the Gitea source repository, replace `assets/logo.svg` and run
|
To build a custom logo replace `assets/logo.svg` and run `make generate-images`. This will update
|
||||||
`make generate-images`. This will update below output files which you can then place in `$GITEA_CUSTOM/public/img` on your server:
|
these customizable logo files which you can then place in `custom/public/img` on your server:
|
||||||
|
|
||||||
- `public/img/logo.svg` - Used for favicon, site icon, app icon
|
- `public/img/logo.svg`
|
||||||
- `public/img/logo.png` - Used for Open Graph
|
- `public/img/logo.png`
|
||||||
- `public/img/favicon.png` - Used as fallback for browsers that don't support SVG favicons
|
- `public/img/favicon.png`
|
||||||
- `public/img/avatar_default.png` - Used as the default avatar image
|
- `public/img/avatar_default.png`
|
||||||
- `public/img/apple-touch-icon.png` - Used on iOS devices for bookmarks
|
- `public/img/apple-touch-icon.png`
|
||||||
|
|
||||||
In case the source image is not in vector format, you can attempt to convert a raster image using tools like [this](https://www.aconvert.com/image/png-to-svg/).
|
## Changing the default avatar
|
||||||
|
|
||||||
|
Either generate it via above method or place the png image at the following path:
|
||||||
|
|
||||||
|
- `custom/public/img/avatar_default.png`
|
||||||
|
|
||||||
## Customizing Gitea pages and resources
|
## Customizing Gitea pages and resources
|
||||||
|
|
||||||
|
@ -77,43 +80,43 @@ Gitea's executable contains all the resources required to run: templates, images
|
||||||
and translations. Any of them can be overridden by placing a replacement in a matching path
|
and translations. Any of them can be overridden by placing a replacement in a matching path
|
||||||
inside the `custom` directory. For example, to replace the default `.gitignore` provided
|
inside the `custom` directory. For example, to replace the default `.gitignore` provided
|
||||||
for C++ repositories, we want to replace `options/gitignore/C++`. To do this, a replacement
|
for C++ repositories, we want to replace `options/gitignore/C++`. To do this, a replacement
|
||||||
must be placed in `$GITEA_CUSTOM/options/gitignore/C++` (see about the location of the `CustomPath`
|
must be placed in `custom/options/gitignore/C++` (see about the location of the `custom`
|
||||||
directory at the top of this document).
|
directory at the top of this document).
|
||||||
|
|
||||||
Every single page of Gitea can be changed. Dynamic content is generated using [go templates](https://golang.org/pkg/html/template/),
|
Every single page of Gitea can be changed. Dynamic content is generated using [go templates](https://golang.org/pkg/html/template/),
|
||||||
which can be modified by placing replacements below the `$GITEA_CUSTOM/templates` directory.
|
which can be modified by placing replacements below the `custom/templates` directory.
|
||||||
|
|
||||||
To obtain any embedded file (including templates), the [`gitea embedded` tool]({{< relref "doc/advanced/cmd-embedded.en-us.md" >}}) can be used. Alternatively, they can be found in the [`templates`](https://github.com/go-gitea/gitea/tree/main/templates) directory of Gitea source (Note: the example link is from the `main` branch. Make sure to use templates compatible with the release you are using).
|
To obtain any embedded file (including templates), the [`gitea embedded` tool]({{< relref "doc/advanced/cmd-embedded.en-us.md" >}}) can be used. Alternatively, they can be found in the [`templates`](https://github.com/go-gitea/gitea/tree/master/templates) directory of Gitea source (Note: the example link is from the `master` branch. Make sure to use templates compatible with the release you are using).
|
||||||
|
|
||||||
Be aware that any statement contained inside `{{` and `}}` are Gitea's template syntax and
|
Be aware that any statement contained inside `{{` and `}}` are Gitea's template syntax and
|
||||||
shouldn't be touched without fully understanding these components.
|
shouldn't be touched without fully understanding these components.
|
||||||
|
|
||||||
### Customizing startpage / homepage
|
### Customizing startpage / homepage
|
||||||
|
|
||||||
Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/main/templates/home.tmpl) for your version of Gitea from `templates` to `$GITEA_CUSTOM/templates`.
|
Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/master/templates/home.tmpl) for your version of Gitea from `templates` to `custom/templates`.
|
||||||
Edit as you wish.
|
Edit as you wish.
|
||||||
Dont forget to restart your gitea to apply the changes.
|
Dont forget to restart your gitea to apply the changes.
|
||||||
|
|
||||||
### Adding links and tabs
|
### Adding links and tabs
|
||||||
|
|
||||||
If all you want is to add extra links to the top navigation bar or footer, or extra tabs to the repository view, you can put them in `extra_links.tmpl` (links added to the navbar), `extra_links_footer.tmpl` (links added to the left side of footer), and `extra_tabs.tmpl` inside your `$GITEA_CUSTOM/templates/custom/` directory.
|
If all you want is to add extra links to the top navigation bar or footer, or extra tabs to the repository view, you can put them in `extra_links.tmpl` (links added to the navbar), `extra_links_footer.tmpl` (links added to the left side of footer), and `extra_tabs.tmpl` inside your `custom/templates/custom/` directory.
|
||||||
|
|
||||||
For instance, let's say you are in Germany and must add the famously legally-required "Impressum"/about page, listing who is responsible for the site's content:
|
For instance, let's say you are in Germany and must add the famously legally-required "Impressum"/about page, listing who is responsible for the site's content:
|
||||||
just place it under your "$GITEA_CUSTOM/public/" directory (for instance `$GITEA_CUSTOM/public/impressum.html`) and put a link to it in either `$GITEA_CUSTOM/templates/custom/extra_links.tmpl` or `$GITEA_CUSTOM/templates/custom/extra_links_footer.tmpl`.
|
just place it under your "custom/public/" directory (for instance `custom/public/impressum.html`) and put a link to it in either `custom/templates/custom/extra_links.tmpl` or `custom/templates/custom/extra_links_footer.tmpl`.
|
||||||
|
|
||||||
To match the current style, the link should have the class name "item", and you can use `{{AppSubUrl}}` to get the base URL:
|
To match the current style, the link should have the class name "item", and you can use `{{AppSubUrl}}` to get the base URL:
|
||||||
`<a class="item" href="{{AppSubUrl}}/assets/impressum.html">Impressum</a>`
|
`<a class="item" href="{{AppSubUrl}}/impressum.html">Impressum</a>`
|
||||||
|
|
||||||
For more information, see [Adding Legal Pages](https://docs.gitea.io/en-us/adding-legal-pages).
|
For more information, see [Adding Legal Pages](https://docs.gitea.io/en-us/adding-legal-pages).
|
||||||
|
|
||||||
You can add new tabs in the same way, putting them in `extra_tabs.tmpl`.
|
You can add new tabs in the same way, putting them in `extra_tabs.tmpl`.
|
||||||
The exact HTML needed to match the style of other tabs is in the file
|
The exact HTML needed to match the style of other tabs is in the file
|
||||||
`templates/repo/header.tmpl`
|
`templates/repo/header.tmpl`
|
||||||
([source in GitHub](https://github.com/go-gitea/gitea/blob/main/templates/repo/header.tmpl))
|
([source in GitHub](https://github.com/go-gitea/gitea/blob/master/templates/repo/header.tmpl))
|
||||||
|
|
||||||
### Other additions to the page
|
### Other additions to the page
|
||||||
|
|
||||||
Apart from `extra_links.tmpl` and `extra_tabs.tmpl`, there are other useful templates you can put in your `$GITEA_CUSTOM/templates/custom/` directory:
|
Apart from `extra_links.tmpl` and `extra_tabs.tmpl`, there are other useful templates you can put in your `custom/templates/custom/` directory:
|
||||||
|
|
||||||
- `header.tmpl`, just before the end of the `<head>` tag where you can add custom CSS files for instance.
|
- `header.tmpl`, just before the end of the `<head>` tag where you can add custom CSS files for instance.
|
||||||
- `body_outer_pre.tmpl`, right after the start of `<body>`.
|
- `body_outer_pre.tmpl`, right after the start of `<body>`.
|
||||||
|
@ -129,7 +132,7 @@ The data is encoded and sent to the PlantUML server which generates the picture.
|
||||||
demo server at http://www.plantuml.com/plantuml, but if you (or your users) have sensitive data you
|
demo server at http://www.plantuml.com/plantuml, but if you (or your users) have sensitive data you
|
||||||
can set up your own [PlantUML server](https://plantuml.com/server) instead. To set up PlantUML rendering,
|
can set up your own [PlantUML server](https://plantuml.com/server) instead. To set up PlantUML rendering,
|
||||||
copy javascript files from https://gitea.com/davidsvantesson/plantuml-code-highlight and put them in your
|
copy javascript files from https://gitea.com/davidsvantesson/plantuml-code-highlight and put them in your
|
||||||
`$GITEA_CUSTOM/public` folder. Then add the following to `custom/footer.tmpl`:
|
`custom/public` folder. Then add the following to `custom/footer.tmpl`:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
{{if .RequireHighlightJS}}
|
{{if .RequireHighlightJS}}
|
||||||
|
@ -138,7 +141,7 @@ copy javascript files from https://gitea.com/davidsvantesson/plantuml-code-highl
|
||||||
<script src="https://your-server.com/plantuml_codeblock_parse.js"></script>
|
<script src="https://your-server.com/plantuml_codeblock_parse.js"></script>
|
||||||
<script>
|
<script>
|
||||||
<!-- Replace call with address to your plantuml server-->
|
<!-- Replace call with address to your plantuml server-->
|
||||||
parsePlantumlCodeBlocks("http://www.plantuml.com/plantuml");
|
parsePlantumlCodeBlocks("http://www.plantuml..com/plantuml");
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
```
|
```
|
||||||
|
@ -174,13 +177,13 @@ You can display STL file directly in Gitea by adding:
|
||||||
|
|
||||||
if ($('.view-raw>a[href$=".stl" i]').length) {
|
if ($('.view-raw>a[href$=".stl" i]').length) {
|
||||||
$("body").append(
|
$("body").append(
|
||||||
'<link href="/assets/Madeleine.js/src/css/Madeleine.css" rel="stylesheet">'
|
'<link href="/Madeleine.js/src/css/Madeleine.css" rel="stylesheet">'
|
||||||
);
|
);
|
||||||
Promise.all([
|
Promise.all([
|
||||||
lS("/assets/Madeleine.js/src/lib/stats.js"),
|
lS("/Madeleine.js/src/lib/stats.js"),
|
||||||
lS("/assets/Madeleine.js/src/lib/detector.js"),
|
lS("/Madeleine.js/src/lib/detector.js"),
|
||||||
lS("/assets/Madeleine.js/src/lib/three.min.js"),
|
lS("/Madeleine.js/src/lib/three.min.js"),
|
||||||
lS("/assets/Madeleine.js/src/Madeleine.js"),
|
lS("/Madeleine.js/src/Madeleine.js"),
|
||||||
]).then(function () {
|
]).then(function () {
|
||||||
$(".view-raw")
|
$(".view-raw")
|
||||||
.attr("id", "view-raw")
|
.attr("id", "view-raw")
|
||||||
|
@ -188,7 +191,7 @@ You can display STL file directly in Gitea by adding:
|
||||||
new Madeleine({
|
new Madeleine({
|
||||||
target: "view-raw",
|
target: "view-raw",
|
||||||
data: $('.view-raw>a[href$=".stl" i]').attr("href"),
|
data: $('.view-raw>a[href$=".stl" i]').attr("href"),
|
||||||
path: "/assets/Madeleine.js/src",
|
path: "/Madeleine.js/src",
|
||||||
});
|
});
|
||||||
$('.view-raw>a[href$=".stl"]').remove();
|
$('.view-raw>a[href$=".stl"]').remove();
|
||||||
});
|
});
|
||||||
|
@ -198,15 +201,15 @@ You can display STL file directly in Gitea by adding:
|
||||||
|
|
||||||
to the file `templates/custom/footer.tmpl`
|
to the file `templates/custom/footer.tmpl`
|
||||||
|
|
||||||
You also need to download the content of the library [Madeleine.js](https://jinjunho.github.io/Madeleine.js/) and place it under `$GITEA_CUSTOM/public/` folder.
|
You also need to download the content of the library [Madeleine.js](https://jinjunho.github.io/Madeleine.js/) and place it under `custom/public/` folder.
|
||||||
|
|
||||||
You should end-up with a folder structure similar to:
|
You should end-up with a folder structucture similar to:
|
||||||
|
|
||||||
```
|
```
|
||||||
$GITEA_CUSTOM/templates
|
custom/templates
|
||||||
-- custom
|
-- custom
|
||||||
`-- footer.tmpl
|
`-- footer.tmpl
|
||||||
$GITEA_CUSTOM/public
|
custom/public
|
||||||
-- Madeleine.js
|
-- Madeleine.js
|
||||||
|-- LICENSE
|
|-- LICENSE
|
||||||
|-- README.md
|
|-- README.md
|
||||||
|
@ -252,11 +255,11 @@ Then restart gitea and open a STL file on your gitea instance.
|
||||||
|
|
||||||
## Customizing Gitea mails
|
## Customizing Gitea mails
|
||||||
|
|
||||||
The `$GITEA_CUSTOM/templates/mail` folder allows changing the body of every mail of Gitea.
|
The `custom/templates/mail` folder allows changing the body of every mail of Gitea.
|
||||||
Templates to override can be found in the
|
Templates to override can be found in the
|
||||||
[`templates/mail`](https://github.com/go-gitea/gitea/tree/main/templates/mail)
|
[`templates/mail`](https://github.com/go-gitea/gitea/tree/master/templates/mail)
|
||||||
directory of Gitea source.
|
directory of Gitea source.
|
||||||
Override by making a copy of the file under `$GITEA_CUSTOM/templates/mail` using a
|
Override by making a copy of the file under `custom/templates/mail` using a
|
||||||
full path structure matching source.
|
full path structure matching source.
|
||||||
|
|
||||||
Any statement contained inside `{{` and `}}` are Gitea's template
|
Any statement contained inside `{{` and `}}` are Gitea's template
|
||||||
|
@ -264,7 +267,7 @@ syntax and shouldn't be touched without fully understanding these components.
|
||||||
|
|
||||||
## Adding Analytics to Gitea
|
## Adding Analytics to Gitea
|
||||||
|
|
||||||
Google Analytics, Matomo (previously Piwik), and other analytics services can be added to Gitea. To add the tracking code, refer to the `Other additions to the page` section of this document, and add the JavaScript to the `$GITEA_CUSTOM/templates/custom/header.tmpl` file.
|
Google Analytics, Matomo (previously Piwik), and other analytics services can be added to Gitea. To add the tracking code, refer to the `Other additions to the page` section of this document, and add the JavaScript to the `custom/templates/custom/header.tmpl` file.
|
||||||
|
|
||||||
## Customizing gitignores, labels, licenses, locales, and readmes.
|
## Customizing gitignores, labels, licenses, locales, and readmes.
|
||||||
|
|
||||||
|
@ -274,22 +277,22 @@ Place custom files in corresponding sub-folder under `custom/options`.
|
||||||
|
|
||||||
### gitignores
|
### gitignores
|
||||||
|
|
||||||
To add custom .gitignore, add a file with existing [.gitignore rules](https://git-scm.com/docs/gitignore) in it to `$GITEA_CUSTOM/options/gitignore`
|
To add custom .gitignore, add a file with existing [.gitignore rules](https://git-scm.com/docs/gitignore) in it to `custom/options/gitignore`
|
||||||
|
|
||||||
### 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`
|
To add a custom label set, add a file that follows the [label format](https://github.com/go-gitea/gitea/blob/master/options/label/Default) to `custom/options/label`
|
||||||
`#hex-color label name ; label description`
|
`#hex-color label name ; label description`
|
||||||
|
|
||||||
### 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 `custom/options/license`
|
||||||
|
|
||||||
### Locales
|
### Locales
|
||||||
|
|
||||||
Locales are managed via our [crowdin](https://crowdin.com/project/gitea).
|
Locales are managed via our [crowdin](https://crowdin.com/project/gitea).
|
||||||
You can override a locale by placing an altered locale file in `$GITEA_CUSTOM/options/locale`.
|
You can override a locale by placing an altered locale file in `custom/options/locale`.
|
||||||
Gitea's default locale files can be found in the [`options/locale`](https://github.com/go-gitea/gitea/tree/main/options/locale) source folder and these should be used as examples for your changes.
|
Gitea's default locale files can be found in the [`options/locale`](https://github.com/go-gitea/gitea/tree/master/options/locale) source folder and these should be used as examples for your changes.
|
||||||
|
|
||||||
To add a completely new locale, as well as placing the file in the above location, you will need to add the new lang and name to the `[i18n]` section in your `app.ini`. Keep in mind that Gitea will use those settings as **overrides**, so if you want to keep the other languages as well you will need to copy/paste the default values and add your own to them.
|
To add a completely new locale, as well as placing the file in the above location, you will need to add the new lang and name to the `[i18n]` section in your `app.ini`. Keep in mind that Gitea will use those settings as **overrides**, so if you want to keep the other languages as well you will need to copy/paste the default values and add your own to them.
|
||||||
|
|
||||||
|
@ -303,7 +306,7 @@ Locales may change between versions, so keeping track of your customized locales
|
||||||
|
|
||||||
### Readmes
|
### Readmes
|
||||||
|
|
||||||
To add a custom Readme, add a markdown formatted file (without an `.md` extension) to `$GITEA_CUSTOM/options/readme`
|
To add a custom Readme, add a markdown formatted file (without an `.md` extension) to `custom/options/readme`
|
||||||
|
|
||||||
**NOTE:** readme templates support **variable expansion**.
|
**NOTE:** readme templates support **variable expansion**.
|
||||||
currently there are `{Name}` (name of repository), `{Description}`, `{CloneURL.SSH}`, `{CloneURL.HTTPS}` and `{OwnerName}`
|
currently there are `{Name}` (name of repository), `{Description}`, `{CloneURL.SSH}`, `{CloneURL.HTTPS}` and `{OwnerName}`
|
||||||
|
@ -321,21 +324,8 @@ A full list of supported emoji's is at [emoji list](https://gitea.com/gitea/gite
|
||||||
|
|
||||||
## Customizing the look of Gitea
|
## Customizing the look of Gitea
|
||||||
|
|
||||||
The default built-in themes are `gitea` (light) and `arc-green` (dark).
|
As of version 1.6.0 Gitea has built-in themes. The two built-in themes are, the default theme `gitea`, and a dark theme `arc-green`. To change the look of your Gitea install change the value of `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` to another one of the available options.
|
||||||
The default theme can be changed via `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini`.
|
As of version 1.8.0 Gitea also has per-user themes. The list of themes a user can choose from can be configured with the `THEMES` value in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` (defaults to `gitea` and `arc-green`, light and dark respectively)
|
||||||
|
|
||||||
Gitea also has support for user themes, which means every user can select which theme should be used.
|
|
||||||
The list of themes a user can choose from can be configured with the `THEMES` value in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini`.
|
|
||||||
|
|
||||||
To make a custom theme available to all users:
|
|
||||||
|
|
||||||
1. Add a CSS file to `$GITEA_PUBLIC/public/css/theme-<theme-name>.css`.
|
|
||||||
The value of `$GITEA_PUBLIC` of your instance can be queried by calling `gitea help` and looking up the value of "CustomPath".
|
|
||||||
2. Add `<theme-name>` to the comma-separated list of setting `THEMES` in `app.ini`
|
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
## Customizing fonts
|
## Customizing fonts
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ Gitea 引用 `custom` 目录中的自定义配置文件来覆盖配置、模板
|
||||||
|
|
||||||
将自定义的公共文件(比如页面和图片)作为 webroot 放在 `custom/public/` 中来让 Gitea 提供这些自定义内容(符号链接将被追踪)。
|
将自定义的公共文件(比如页面和图片)作为 webroot 放在 `custom/public/` 中来让 Gitea 提供这些自定义内容(符号链接将被追踪)。
|
||||||
|
|
||||||
举例说明:`image.png` 存放在 `custom/public/`中,那么它可以通过链接 http://gitea.domain.tld/assets/image.png 访问。
|
举例说明:`image.png` 存放在 `custom/public/`中,那么它可以通过链接 http://gitea.domain.tld/image.png 访问。
|
||||||
|
|
||||||
## 修改默认头像
|
## 修改默认头像
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ Gitea 引用 `custom` 目录中的自定义配置文件来覆盖配置、模板
|
||||||
"custom/public/"目录下(比如 `custom/public/impressum.html`)并且将它与 `custom/templates/custom/extra_links.tmpl` 链接起来即可。
|
"custom/public/"目录下(比如 `custom/public/impressum.html`)并且将它与 `custom/templates/custom/extra_links.tmpl` 链接起来即可。
|
||||||
|
|
||||||
这个链接应当使用一个名为“item”的 class 来匹配当前样式,您可以使用 `{{AppSubUrl}}` 来获取 base URL:
|
这个链接应当使用一个名为“item”的 class 来匹配当前样式,您可以使用 `{{AppSubUrl}}` 来获取 base URL:
|
||||||
`<a class="item" href="{{AppSubUrl}}/assets/impressum.html">Impressum</a>`
|
`<a class="item" href="{{AppSubUrl}}/impressum.html">Impressum</a>`
|
||||||
|
|
||||||
同理,您可以将页签添加到 `extra_tabs.tmpl` 中,使用同样的方式来添加页签。它的具体样式需要与
|
同理,您可以将页签添加到 `extra_tabs.tmpl` 中,使用同样的方式来添加页签。它的具体样式需要与
|
||||||
`templates/repo/header.tmpl` 中已有的其他选项卡的样式匹配
|
`templates/repo/header.tmpl` 中已有的其他选项卡的样式匹配
|
||||||
|
|
|
@ -58,6 +58,15 @@ For documentation about each of the variables available, refer to the
|
||||||
- `HOMEDRIVE`: Main drive path used to access the home directory (C:)
|
- `HOMEDRIVE`: Main drive path used to access the home directory (C:)
|
||||||
- `HOMEPATH`: Home relative path in the given home drive path
|
- `HOMEPATH`: Home relative path in the given home drive path
|
||||||
|
|
||||||
|
## Macaron (framework used by Gitea)
|
||||||
|
|
||||||
|
- `HOST`: Host Macaron will listen on
|
||||||
|
- `PORT`: Port Macaron will listen on
|
||||||
|
- `MACARON_ENV`: global variable to provide special functionality for development environments
|
||||||
|
vs. production environments. If MACARON_ENV is set to "" or "development", then templates will
|
||||||
|
be recompiled on every request. For more performance, set the MACARON_ENV environment variable
|
||||||
|
to "production".
|
||||||
|
|
||||||
## Miscellaneous
|
## Miscellaneous
|
||||||
|
|
||||||
- `SKIP_MINWINSVC`: If set to 1, do not run as a service on Windows.
|
- `SKIP_MINWINSVC`: If set to 1, do not run as a service on Windows.
|
||||||
|
|
|
@ -50,6 +50,13 @@ GITEA_CUSTOM=/home/gitea/custom ./gitea web
|
||||||
* `HOMEDRIVE`: 用于访问 home 目录的主驱动器路径(C盘)
|
* `HOMEDRIVE`: 用于访问 home 目录的主驱动器路径(C盘)
|
||||||
* `HOMEPATH`:在指定主驱动器下的 home 目录相对路径
|
* `HOMEPATH`:在指定主驱动器下的 home 目录相对路径
|
||||||
|
|
||||||
|
## Macaron(Gitea 使用的 web 框架)
|
||||||
|
|
||||||
|
* `HOST`:Macaron 监听的主机地址
|
||||||
|
* `PORT`:Macaron 监听的端口地址
|
||||||
|
* `MACARON_ENV`:为开发环境和生产环境提供特殊功能性配置的全局变量,当 MACARON_ENV 设置为 "" 或 "development"
|
||||||
|
时,每次请求都会重编译页面模板。为了提高性能表现,可将它设置为 "production"。
|
||||||
|
|
||||||
## Miscellaneous
|
## Miscellaneous
|
||||||
|
|
||||||
* `SKIP_MINWINSVC`:如果设置为 1,在 Windows 上不会以 service 的形式运行。
|
* `SKIP_MINWINSVC`:如果设置为 1,在 Windows 上不会以 service 的形式运行。
|
||||||
|
|
|
@ -64,13 +64,13 @@ IS_INPUT_FILE = false
|
||||||
[markup.jupyter]
|
[markup.jupyter]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
FILE_EXTENSIONS = .ipynb
|
FILE_EXTENSIONS = .ipynb
|
||||||
RENDER_COMMAND = "jupyter nbconvert --stdin --stdout --to html --template basic"
|
RENDER_COMMAND = "jupyter nbconvert --stdout --to html --template basic "
|
||||||
IS_INPUT_FILE = false
|
IS_INPUT_FILE = true
|
||||||
|
|
||||||
[markup.restructuredtext]
|
[markup.restructuredtext]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
FILE_EXTENSIONS = .rst
|
FILE_EXTENSIONS = .rst
|
||||||
RENDER_COMMAND = "timeout 30s pandoc +RTS -M512M -RTS -f rst"
|
RENDER_COMMAND = rst2html.py
|
||||||
IS_INPUT_FILE = false
|
IS_INPUT_FILE = false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -90,79 +90,11 @@ FILE_EXTENSIONS = .md,.markdown
|
||||||
RENDER_COMMAND = pandoc -f markdown -t html --katex
|
RENDER_COMMAND = pandoc -f markdown -t html --katex
|
||||||
```
|
```
|
||||||
|
|
||||||
You must define `ELEMENT` and `ALLOW_ATTR` in each section.
|
You must define `ELEMENT`, `ALLOW_ATTR`, and `REGEXP` in each section.
|
||||||
|
|
||||||
To define multiple entries, add a unique alphanumeric suffix (e.g., `[markup.sanitizer.1]` and `[markup.sanitizer.something]`).
|
To define multiple entries, add a unique alphanumeric suffix (e.g., `[markup.sanitizer.1]` and `[markup.sanitizer.something]`).
|
||||||
|
|
||||||
To apply a sanitisation rules only for a specify external renderer they must use the renderer name, e.g. `[markup.sanitizer.asciidoc.rule-1]`, `[markup.sanitizer.<renderer>.rule-1]`.
|
|
||||||
|
|
||||||
**Note**: If the rule is defined above the renderer ini section or the name does not match a renderer it is applied to every renderer.
|
|
||||||
|
|
||||||
Once your configuration changes have been made, restart Gitea to have changes take effect.
|
Once your configuration changes have been made, restart Gitea to have changes take effect.
|
||||||
|
|
||||||
**Note**: Prior to Gitea 1.12 there was a single `markup.sanitiser` section with keys that were redefined for multiple rules, however,
|
**Note**: Prior to Gitea 1.12 there was a single `markup.sanitiser` section with keys that were redefined for multiple rules, however,
|
||||||
there were significant problems with this method of configuration necessitating configuration through multiple sections.
|
there were significant problems with this method of configuration necessitating configuration through multiple sections.
|
||||||
|
|
||||||
### Example: Office DOCX
|
|
||||||
|
|
||||||
Display Office DOCX files with [`pandoc`](https://pandoc.org/):
|
|
||||||
```ini
|
|
||||||
[markup.docx]
|
|
||||||
ENABLED = true
|
|
||||||
FILE_EXTENSIONS = .docx
|
|
||||||
RENDER_COMMAND = "pandoc --from docx --to html --self-contained --template /path/to/basic.html"
|
|
||||||
|
|
||||||
[markup.sanitizer.docx.img]
|
|
||||||
ALLOW_DATA_URI_IMAGES = true
|
|
||||||
```
|
|
||||||
|
|
||||||
The template file has the following content:
|
|
||||||
```
|
|
||||||
$body$
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example: Jupyter Notebook
|
|
||||||
|
|
||||||
Display Jupyter Notebook files with [`nbconvert`](https://github.com/jupyter/nbconvert):
|
|
||||||
```ini
|
|
||||||
[markup.jupyter]
|
|
||||||
ENABLED = true
|
|
||||||
FILE_EXTENSIONS = .ipynb
|
|
||||||
RENDER_COMMAND = "jupyter-nbconvert --stdin --stdout --to html --template basic"
|
|
||||||
|
|
||||||
[markup.sanitizer.jupyter.img]
|
|
||||||
ALLOW_DATA_URI_IMAGES = true
|
|
||||||
```
|
|
||||||
|
|
||||||
## Customizing CSS
|
|
||||||
The external renderer is specified in the .ini in the format `[markup.XXXXX]` and the HTML supplied by your external renderer will be wrapped in a `<div>` with classes `markup` and `XXXXX`. The `markup` class provides out of the box styling (as does `markdown` if `XXXXX` is `markdown`). Otherwise you can use these classes to specifically target the contents of your rendered HTML.
|
|
||||||
|
|
||||||
And so you could write some CSS:
|
|
||||||
```css
|
|
||||||
.markup.XXXXX html {
|
|
||||||
font-size: 100%;
|
|
||||||
overflow-y: scroll;
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
-ms-text-size-adjust: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markup.XXXXX body {
|
|
||||||
color: #444;
|
|
||||||
font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.7;
|
|
||||||
padding: 1em;
|
|
||||||
margin: auto;
|
|
||||||
max-width: 42em;
|
|
||||||
background: #fefefe;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markup.XXXXX p {
|
|
||||||
color: orangered;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Add your stylesheet to your custom directory e.g `custom/public/css/my-style-XXXXX.css` and import it using a custom header file `custom/templates/custom/header.tmpl`:
|
|
||||||
```html
|
|
||||||
<link type="text/css" href="{{AppSubUrl}}/assets/css/my-style-XXXXX.css" />
|
|
||||||
```
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ The fundamental thing to be aware of in Gitea is that there are several
|
||||||
log groups:
|
log groups:
|
||||||
|
|
||||||
- The "Default" logger
|
- The "Default" logger
|
||||||
|
- The Macaron logger
|
||||||
- The Router logger
|
- The Router logger
|
||||||
- The Access logger
|
- The Access logger
|
||||||
- The XORM logger
|
- The XORM logger
|
||||||
|
@ -66,14 +67,44 @@ The provider type of the sublogger can be set using the `MODE` value in
|
||||||
its subsection, but will default to the name. This allows you to have
|
its subsection, but will default to the name. This allows you to have
|
||||||
multiple subloggers that will log to files.
|
multiple subloggers that will log to files.
|
||||||
|
|
||||||
|
### The "Macaron" logger
|
||||||
|
|
||||||
|
By default Macaron will log to its own go `log` instance. This writes
|
||||||
|
to `os.Stdout`. You can redirect this log to a Gitea configurable logger
|
||||||
|
through setting the `REDIRECT_MACARON_LOG` setting in the `[log]`
|
||||||
|
section which you can configure the outputs of by setting the `MACARON`
|
||||||
|
value in the `[log]` section of the configuration. `MACARON` defaults
|
||||||
|
to `file` if unset.
|
||||||
|
|
||||||
|
Please note, the macaron logger will log at `INFO` level, setting the
|
||||||
|
`LEVEL` of this logger to `WARN` or above will result in no macaron logs.
|
||||||
|
|
||||||
|
Each output sublogger for this logger is configured in
|
||||||
|
`[log.sublogger.macaron]` sections. There are certain default values
|
||||||
|
which will not be inherited from the `[log]` or relevant
|
||||||
|
`[log.sublogger]` sections:
|
||||||
|
|
||||||
|
- `FLAGS` is `stdflags` (Equal to
|
||||||
|
`date,time,medfile,shortfuncname,levelinitial`)
|
||||||
|
- `FILE_NAME` will default to `%(ROOT_PATH)/macaron.log`
|
||||||
|
- `EXPRESSION` will default to `""`
|
||||||
|
- `PREFIX` will default to `""`
|
||||||
|
|
||||||
|
NB: You can redirect the macaron logger to send its events to the gitea
|
||||||
|
log using the value: `MACARON = ,`
|
||||||
|
|
||||||
### The "Router" logger
|
### The "Router" logger
|
||||||
|
|
||||||
You can disable Router log by setting `DISABLE_ROUTER_LOG`.
|
There are two types of Router log. By default Macaron send its own
|
||||||
|
router log which will be directed to Macaron's go `log`, however if you
|
||||||
|
`REDIRECT_MACARON_LOG` you will enable Gitea's router log. You can
|
||||||
|
disable both types of Router log by setting `DISABLE_ROUTER_LOG`.
|
||||||
|
|
||||||
You can configure the outputs of this
|
If you enable the redirect, you can configure the outputs of this
|
||||||
router log by setting the `ROUTER` value in the `[log]` section of the
|
router log by setting the `ROUTER` value in the `[log]` section of the
|
||||||
configuration. `ROUTER` will default to `console` if unset. The Gitea
|
configuration. `ROUTER` will default to `console` if unset. The Gitea
|
||||||
Router logs at the `Info` level by default, but this can be
|
Router logs the same data as the Macaron log but has slightly different
|
||||||
|
coloring. It logs at the `Info` level by default, but this can be
|
||||||
changed if desired by setting the `ROUTER_LOG_LEVEL` value.
|
changed if desired by setting the `ROUTER_LOG_LEVEL` value.
|
||||||
|
|
||||||
Please note, setting the `LEVEL` of this logger to a level above
|
Please note, setting the `LEVEL` of this logger to a level above
|
||||||
|
@ -131,11 +162,11 @@ This value represent a go template. It's default value is:
|
||||||
|
|
||||||
The template is passed following options:
|
The template is passed following options:
|
||||||
|
|
||||||
- `Ctx` is the `context.Context`
|
- `Ctx` is the `macaron.Context`
|
||||||
- `Identity` is the `SignedUserName` or `"-"` if the user is not logged
|
- `Identity` is the `SignedUserName` or `"-"` if the user is not logged
|
||||||
in
|
in
|
||||||
- `Start` is the start time of the request
|
- `Start` is the start time of the request
|
||||||
- `ResponseWriter` is the `http.ResponseWriter`
|
- `ResponseWriter` is the `macaron.ResponseWriter`
|
||||||
|
|
||||||
Caution must be taken when changing this template as it runs outside of
|
Caution must be taken when changing this template as it runs outside of
|
||||||
the standard panic recovery trap. The template should also be as simple
|
the standard panic recovery trap. The template should also be as simple
|
||||||
|
@ -180,7 +211,7 @@ Certain configuration is common to all modes of log output:
|
||||||
- `STACKTRACE_LEVEL` is the lowest level that this output will print
|
- `STACKTRACE_LEVEL` is the lowest level that this output will print
|
||||||
a stacktrace. This value is inherited.
|
a stacktrace. This value is inherited.
|
||||||
- `MODE` is the mode of the log output. It will default to the sublogger
|
- `MODE` is the mode of the log output. It will default to the sublogger
|
||||||
name. Thus `[log.console.router]` will default to `MODE = console`.
|
name. Thus `[log.console.macaron]` will default to `MODE = console`.
|
||||||
- `COLORIZE` will default to `true` for `console` as
|
- `COLORIZE` will default to `true` for `console` as
|
||||||
described, otherwise it will default to `false`.
|
described, otherwise it will default to `false`.
|
||||||
|
|
||||||
|
@ -278,11 +309,13 @@ LOG_SQL = false ; SQL logs are rarely helpful unless we specifically ask for the
|
||||||
[log]
|
[log]
|
||||||
MODE = console
|
MODE = console
|
||||||
LEVEL = debug ; please set the level to debug when we are debugging a problem
|
LEVEL = debug ; please set the level to debug when we are debugging a problem
|
||||||
|
REDIRECT_MACARON_LOG = true
|
||||||
|
MACARON = console
|
||||||
ROUTER = console
|
ROUTER = console
|
||||||
COLORIZE = false ; this can be true if you can strip out the ansi coloring
|
COLORIZE = false ; this can be true if you can strip out the ansi coloring
|
||||||
```
|
```
|
||||||
|
|
||||||
Sometimes it will be helpful get some specific `TRACE` level logging restricted
|
Sometimes it will be helpful get some specific `TRACE` level logging retricted
|
||||||
to messages that match a specific `EXPRESSION`. Adjusting the `MODE` in the
|
to messages that match a specific `EXPRESSION`. Adjusting the `MODE` in the
|
||||||
`[log]` section to `MODE = console,traceconsole` to add a new logger output
|
`[log]` section to `MODE = console,traceconsole` to add a new logger output
|
||||||
`traceconsole` and then adding its corresponding section would be helpful:
|
`traceconsole` and then adding its corresponding section would be helpful:
|
||||||
|
@ -310,6 +343,7 @@ ROOT_PATH = %(GITEA_WORK_DIR)/log
|
||||||
MODE = console
|
MODE = console
|
||||||
LEVEL = Info
|
LEVEL = Info
|
||||||
STACKTRACE_LEVEL = None
|
STACKTRACE_LEVEL = None
|
||||||
|
REDIRECT_MACARON_LOG = false
|
||||||
ENABLE_ACCESS_LOG = false
|
ENABLE_ACCESS_LOG = false
|
||||||
ENABLE_XORM_LOG = true
|
ENABLE_XORM_LOG = true
|
||||||
XORM = ,
|
XORM = ,
|
||||||
|
@ -340,7 +374,7 @@ recommended that pausing only done for a very short period of time.
|
||||||
## Adding and removing logging whilst Gitea is running
|
## Adding and removing logging whilst Gitea is running
|
||||||
|
|
||||||
It is possible to add and remove logging whilst Gitea is running using the `gitea manager logging add` and `remove` subcommands.
|
It is possible to add and remove logging whilst Gitea is running using the `gitea manager logging add` and `remove` subcommands.
|
||||||
This functionality can only adjust running log systems and cannot be used to start the access or router loggers if they
|
This functionality can only adjust running log systems and cannot be used to start the access, macaron or router loggers if they
|
||||||
were not already initialised. If you wish to start these systems you are advised to adjust the app.ini and (gracefully) restart
|
were not already initialised. If you wish to start these systems you are advised to adjust the app.ini and (gracefully) restart
|
||||||
the Gitea service.
|
the Gitea service.
|
||||||
|
|
||||||
|
@ -437,8 +471,7 @@ Gitea includes built-in log rotation, which should be enough for most deployment
|
||||||
|
|
||||||
- Disable built-in log rotation by setting `LOG_ROTATE` to `false` in your `app.ini`.
|
- Disable built-in log rotation by setting `LOG_ROTATE` to `false` in your `app.ini`.
|
||||||
- Install `logrotate`.
|
- Install `logrotate`.
|
||||||
- Configure `logrotate` to match your deployment requirements, see `man 8 logrotate` for configuration syntax details. In the `postrotate/endscript` block send Gitea a `USR1` signal via `kill -USR1` or `kill -10` to the `gitea` process itself, or run `gitea manager logging release-and-reopen` (with the appropriate environment). Ensure that your configurations apply to all files emitted by Gitea loggers as described in the above sections.
|
- Configure `logrotate` to match your deployment requirements, see `man 8 logrotate` for configuration syntax details. In the `postrotate/endscript` block send Gitea a `USR1` signal via `kill -USR1` or `kill -10`, or run `gitea manager logging release-and-reopen` (with the appropriate environment). Ensure that your configurations apply to all files emitted by Gitea loggers as described in the above sections.
|
||||||
- Always do `logrotate /etc/logrotate.conf --debug` to test your configurations.
|
- Always do `logrotate /etc/logrotate.conf --debug` to test your configurations.
|
||||||
- If you are using docker and are running from outside of the container you can use `docker exec -u $OS_USER $CONTAINER_NAME sh -c 'gitea manager logging release-and-reopen'` or `docker exec $CONTAINER_NAME sh -c '/bin/s6-svc -1 /etc/s6/gitea/'` or send `USR1` directly to the gitea process itself.
|
|
||||||
|
|
||||||
The next `logrotate` jobs will include your configurations, so no restart is needed. You can also immediately reload `logrotate` with `logrotate /etc/logrotate.conf --force`.
|
The next `logrotate` jobs will include your configurations, so no restart is needed. You can also immediately reload `logrotate` with `logrotate /etc/logrotate.conf --force`.
|
||||||
|
|
|
@ -130,7 +130,7 @@ did not include a subject part), Gitea's **internal default** will be used.
|
||||||
The internal default (fallback) subject is the equivalent of:
|
The internal default (fallback) subject is the equivalent of:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
{{.SubjectPrefix}}[{{.Repo}}] {{.Issue.Title}} (#{{.Issue.Index}})
|
{{.SubjectPrefix}}[{{.Repo}}] {{.Issue.Title}} (#.Issue.Index)
|
||||||
```
|
```
|
||||||
|
|
||||||
For example: `Re: [mike/stuff] New color palette (#38)`
|
For example: `Re: [mike/stuff] New color palette (#38)`
|
||||||
|
|
|
@ -37,8 +37,8 @@ sudo yum install make
|
||||||
|
|
||||||
Si vous utilisez Windows, vous pouvez télécharger une des versions suivantes de Make:
|
Si vous utilisez Windows, vous pouvez télécharger une des versions suivantes de Make:
|
||||||
|
|
||||||
- [Simple binaire](http://www.equation.com/servlet/equation.cmd?fa=make). Copiez-le quelque part et mettez à jour `PATH`.
|
- [Simple binaire](http://www.equation.com/servlet/equation.cmd?fa=make). Copiez le quelque part et mettez à jour `PATH`.
|
||||||
- [32-bits version](ftp://ftp.equation.com/make/32/make.exe)
|
- [32-bits version](ftp://ftp.equation.com/make/32/make.exe)
|
||||||
- [64-bits version](ftp://ftp.equation.com/make/64/make.exe)
|
- [64-bits version](ftp://ftp.equation.com/make/64/make.exe)
|
||||||
- [MinGW](http://www.mingw.org/) inclut un _build_. Le fichier binaire est nommé `mingw32-make.exe` plutôt que `make.exe`. Ajoutez le dossier `bin` à votre `PATH`.
|
- [MinGW](http://www.mingw.org/) includes a build. The binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to your `PATH`.
|
||||||
- [Chocolatey package](https://chocolatey.org/packages/make). Exécutez `choco install make`.
|
- [Chocolatey package](https://chocolatey.org/packages/make). Run `choco install make`
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
---
|
|
||||||
date: "2021-05-14T00:00:00-00:00"
|
|
||||||
title: "Protected tags"
|
|
||||||
slug: "protected-tags"
|
|
||||||
weight: 45
|
|
||||||
toc: false
|
|
||||||
draft: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
parent: "advanced"
|
|
||||||
name: "Protected tags"
|
|
||||||
weight: 45
|
|
||||||
identifier: "protected-tags"
|
|
||||||
---
|
|
||||||
|
|
||||||
# Protected tags
|
|
||||||
|
|
||||||
Protected tags allow control over who has permission to create or update git tags. Each rule allows you to match either an individual tag name, or use an appropriate pattern to control multiple tags at once.
|
|
||||||
|
|
||||||
**Table of Contents**
|
|
||||||
|
|
||||||
{{< toc >}}
|
|
||||||
|
|
||||||
## Setting up protected tags
|
|
||||||
|
|
||||||
To protect a tag, you need to follow these steps:
|
|
||||||
|
|
||||||
1. Go to the repository’s **Settings** > **Tags** page.
|
|
||||||
1. Type a pattern to match a name. You can use a single name, a [glob pattern](https://pkg.go.dev/github.com/gobwas/glob#Compile) or a regular expression.
|
|
||||||
1. Choose the allowed users and/or teams. If you leave these fields empty no one is allowed to create or modify this tag.
|
|
||||||
1. Select **Save** to save the configuration.
|
|
||||||
|
|
||||||
## Pattern protected tags
|
|
||||||
|
|
||||||
The pattern uses [glob](https://pkg.go.dev/github.com/gobwas/glob#Compile) or regular expressions to match a tag name. For regular expressions you need to enclose the pattern in slashes.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
| Type | Pattern Protected Tag | Possible Matching Tags |
|
|
||||||
| ----- | ------------------------ | --------------------------------------- |
|
|
||||||
| Glob | `v*` | `v`, `v-1`, `version2` |
|
|
||||||
| Glob | `v[0-9]` | `v0`, `v1` up to `v9` |
|
|
||||||
| Glob | `*-release` | `2.1-release`, `final-release` |
|
|
||||||
| Glob | `gitea` | only `gitea` |
|
|
||||||
| Glob | `*gitea*` | `gitea`, `2.1-gitea`, `1_gitea-release` |
|
|
||||||
| Glob | `{v,rel}-*` | `v-`, `v-1`, `v-final`, `rel-`, `rel-x` |
|
|
||||||
| Glob | `*` | matches all possible tag names |
|
|
||||||
| Regex | `/\Av/` | `v`, `v-1`, `version2` |
|
|
||||||
| Regex | `/\Av[0-9]\z/` | `v0`, `v1` up to `v9` |
|
|
||||||
| Regex | `/\Av\d+\.\d+\.\d+\z/` | `v1.0.17`, `v2.1.0` |
|
|
||||||
| Regex | `/\Av\d+(\.\d+){0,2}\z/` | `v1`, `v2.1`, `v1.2.34` |
|
|
||||||
| Regex | `/-release\z/` | `2.1-release`, `final-release` |
|
|
||||||
| Regex | `/gitea/` | `gitea`, `2.1-gitea`, `1_gitea-release` |
|
|
||||||
| Regex | `/\Agitea\z/` | only `gitea` |
|
|
||||||
| Regex | `/^gitea$/` | only `gitea` |
|
|
||||||
| Regex | `/\A(v\|rel)-/` | `v-`, `v-1`, `v-final`, `rel-`, `rel-x` |
|
|
||||||
| Regex | `/.+/` | matches all possible tag names |
|
|
|
@ -1,88 +0,0 @@
|
||||||
---
|
|
||||||
date: "2021-05-13T00:00:00-00:00"
|
|
||||||
title: "Repository Mirror"
|
|
||||||
slug: "repo-mirror"
|
|
||||||
weight: 45
|
|
||||||
toc: false
|
|
||||||
draft: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
parent: "advanced"
|
|
||||||
name: "Repository Mirror"
|
|
||||||
weight: 45
|
|
||||||
identifier: "repo-mirror"
|
|
||||||
---
|
|
||||||
|
|
||||||
# Repository Mirror
|
|
||||||
|
|
||||||
Repository mirroring allows for the mirroring of repositories to and from external sources. You can use it to mirror branches, tags, and commits between repositories.
|
|
||||||
|
|
||||||
**Table of Contents**
|
|
||||||
|
|
||||||
{{< toc >}}
|
|
||||||
|
|
||||||
## Use cases
|
|
||||||
|
|
||||||
The following are some possible use cases for repository mirroring:
|
|
||||||
|
|
||||||
- You migrated to Gitea but still need to keep your project in another source. In that case, you can simply set it up to mirror to Gitea (pull) and all the essential history of commits, tags, and branches are available in your Gitea instance.
|
|
||||||
- You have old projects in another source that you don’t use actively anymore, but don’t want to remove for archiving purposes. In that case, you can create a push mirror so that your active Gitea repository can push its changes to the old location.
|
|
||||||
|
|
||||||
## Pulling from a remote repository
|
|
||||||
|
|
||||||
For an existing remote repository, you can set up pull mirroring as follows:
|
|
||||||
|
|
||||||
1. Select **New Migration** in the **Create...** menu on the top right.
|
|
||||||
2. Select the remote repository service.
|
|
||||||
3. Enter a repository URL.
|
|
||||||
4. If the repository needs authentication fill in your authentication information.
|
|
||||||
5. Check the box **This repository will be a mirror**.
|
|
||||||
5. Select **Migrate repository** to save the configuration.
|
|
||||||
|
|
||||||
The repository now gets mirrored periodically from the remote repository. You can force a sync by selecting **Synchronize Now** in the repository settings.
|
|
||||||
|
|
||||||
## Pushing to a remote repository
|
|
||||||
|
|
||||||
For an existing repository, you can set up push mirroring as follows:
|
|
||||||
|
|
||||||
1. In your repository, go to **Settings** > **Repository**, and then the **Mirror Settings** section.
|
|
||||||
2. Enter a repository URL.
|
|
||||||
3. If the repository needs authentication expand the **Authorization** section and fill in your authentication information.
|
|
||||||
4. Select **Add Push Mirror** to save the configuration.
|
|
||||||
|
|
||||||
The repository now gets mirrored periodically to the remote repository. You can force a sync by selecting **Synchronize Now**. In case of an error a message displayed to help you resolve it.
|
|
||||||
|
|
||||||
:exclamation::exclamation: **NOTE:** This will force push to the remote repository. This will overwrite any changes in the remote repository! :exclamation::exclamation:
|
|
||||||
|
|
||||||
### Setting up a push mirror from Gitea to GitHub
|
|
||||||
|
|
||||||
To set up a mirror from Gitea to GitHub, you need to follow these steps:
|
|
||||||
|
|
||||||
1. Create a [GitHub personal access token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) with the *public_repo* box checked.
|
|
||||||
2. Fill in the **Git Remote Repository URL**: `https://github.com/<your_github_group>/<your_github_project>.git`.
|
|
||||||
3. Fill in the **Authorization** fields with your GitHub username and the personal access token.
|
|
||||||
4. Select **Add Push Mirror** to save the configuration.
|
|
||||||
|
|
||||||
The repository pushes shortly thereafter. To force a push, select the **Synchronize Now** button.
|
|
||||||
|
|
||||||
### Setting up a push mirror from Gitea to GitLab
|
|
||||||
|
|
||||||
To set up a mirror from Gitea to GitLab, you need to follow these steps:
|
|
||||||
|
|
||||||
1. Create a [GitLab personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with *write_repository* scope.
|
|
||||||
2. Fill in the **Git Remote Repository URL**: `https://<destination host>/<your_gitlab_group_or_name>/<your_gitlab_project>.git`.
|
|
||||||
3. Fill in the **Authorization** fields with `oauth2` as **Username** and your GitLab personal access token as **Password**.
|
|
||||||
4. Select **Add Push Mirror** to save the configuration.
|
|
||||||
|
|
||||||
The repository pushes shortly thereafter. To force a push, select the **Synchronize Now** button.
|
|
||||||
|
|
||||||
### Setting up a push mirror from Gitea to Bitbucket
|
|
||||||
|
|
||||||
To set up a mirror from Gitea to Bitbucket, you need to follow these steps:
|
|
||||||
|
|
||||||
1. Create a [Bitbucket app password](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/) with the *Repository Write* box checked.
|
|
||||||
2. Fill in the **Git Remote Repository URL**: `https://bitbucket.org/<your_bitbucket_group_or_name>/<your_bitbucket_project>.git`.
|
|
||||||
3. Fill in the **Authorization** fields with your Bitbucket username and the app password as **Password**.
|
|
||||||
4. Select **Add Push Mirror** to save the configuration.
|
|
||||||
|
|
||||||
The repository pushes shortly thereafter. To force a push, select the **Synchronize Now** button.
|
|
|
@ -109,7 +109,7 @@ when creating a repository. The possible values are:
|
||||||
- `always`: Always sign
|
- `always`: Always sign
|
||||||
|
|
||||||
Options other than `never` and `always` can be combined as a comma
|
Options other than `never` and `always` can be combined as a comma
|
||||||
separated list. The commit will be signed if all selected options are true.
|
separated list.
|
||||||
|
|
||||||
### `WIKI`
|
### `WIKI`
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ The possible values are:
|
||||||
- `always`: Always sign
|
- `always`: Always sign
|
||||||
|
|
||||||
Options other than `never` and `always` can be combined as a comma
|
Options other than `never` and `always` can be combined as a comma
|
||||||
separated list. The commit will be signed if all selected options are true.
|
separated list.
|
||||||
|
|
||||||
### `CRUD_ACTIONS`
|
### `CRUD_ACTIONS`
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ editor or API CRUD actions. The possible values are:
|
||||||
- `always`: Always sign
|
- `always`: Always sign
|
||||||
|
|
||||||
Options other than `never` and `always` can be combined as a comma
|
Options other than `never` and `always` can be combined as a comma
|
||||||
separated list. The change will be signed if all selected options are true.
|
separated list.
|
||||||
|
|
||||||
### `MERGES`
|
### `MERGES`
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ The possible options are:
|
||||||
- `always`: Always sign
|
- `always`: Always sign
|
||||||
|
|
||||||
Options other than `never` and `always` can be combined as a comma
|
Options other than `never` and `always` can be combined as a comma
|
||||||
separated list. The merge will be signed if all selected options are true.
|
separated list.
|
||||||
|
|
||||||
## Obtaining the Public Key of the Signing Key
|
## Obtaining the Public Key of the Signing Key
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
---
|
|
||||||
date: "2016-12-01T16:00:00+02:00"
|
|
||||||
title: "開發人員"
|
|
||||||
slug: "developers"
|
|
||||||
weight: 40
|
|
||||||
toc: false
|
|
||||||
draft: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
name: "開發人員"
|
|
||||||
weight: 50
|
|
||||||
identifier: "developers"
|
|
||||||
---
|
|
|
@ -40,42 +40,8 @@ better understand this by looking at the code -- as of this writing,
|
||||||
Gitea parses queries and headers to find the token in
|
Gitea parses queries and headers to find the token in
|
||||||
[modules/auth/auth.go](https://github.com/go-gitea/gitea/blob/6efdcaed86565c91a3dc77631372a9cc45a58e89/modules/auth/auth.go#L47).
|
[modules/auth/auth.go](https://github.com/go-gitea/gitea/blob/6efdcaed86565c91a3dc77631372a9cc45a58e89/modules/auth/auth.go#L47).
|
||||||
|
|
||||||
## Generating and listing API tokens
|
You can create an API key token via your Gitea installation's web interface:
|
||||||
|
`Settings | Applications | Generate New Token`.
|
||||||
A new token can be generated with a `POST` request to
|
|
||||||
`/users/:name/tokens`.
|
|
||||||
|
|
||||||
Note that `/users/:name/tokens` is a special endpoint and requires you
|
|
||||||
to authenticate using `BasicAuth` and a password, as follows:
|
|
||||||
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ curl -XPOST -H "Content-Type: application/json" -k -d '{"name":"test"}' -u username:password https://gitea.your.host/api/v1/users/<username>/tokens
|
|
||||||
{"id":1,"name":"test","sha1":"9fcb1158165773dd010fca5f0cf7174316c3e37d","token_last_eight":"16c3e37d"}
|
|
||||||
```
|
|
||||||
|
|
||||||
The ``sha1`` (the token) is only returned once and is not stored in
|
|
||||||
plain-text. It will not be displayed when listing tokens with a `GET`
|
|
||||||
request; e.g.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ curl --request GET --url https://yourusername:password@gitea.your.host/api/v1/users/<username>/tokens
|
|
||||||
[{"name":"test","sha1":"","token_last_eight:"........":},{"name":"dev","sha1":"","token_last_eight":"........"}]
|
|
||||||
```
|
|
||||||
|
|
||||||
To use the API with basic authentication with two factor authentication
|
|
||||||
enabled, you'll need to send an additional header that contains the one
|
|
||||||
time password (6 digitrotating token).
|
|
||||||
An example of the header is `X-Gitea-OTP: 123456` where `123456`
|
|
||||||
is where you'd place the code from your authenticator.
|
|
||||||
Here is how the request would look like in curl:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ curl -H "X-Gitea-OTP: 123456" --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also create an API key token via your Gitea installation's web
|
|
||||||
interface: `Settings | Applications | Generate New Token`.
|
|
||||||
|
|
||||||
## OAuth2 Provider
|
## OAuth2 Provider
|
||||||
|
|
||||||
|
@ -113,8 +79,25 @@ API Reference guide is auto-generated by swagger and available on:
|
||||||
or on
|
or on
|
||||||
[gitea demo instance](https://try.gitea.io/api/swagger)
|
[gitea demo instance](https://try.gitea.io/api/swagger)
|
||||||
|
|
||||||
The OpenAPI document is at:
|
## Listing your issued tokens via the API
|
||||||
`https://gitea.your.host/swagger.v1.json`
|
|
||||||
|
As mentioned in
|
||||||
|
[#3842](https://github.com/go-gitea/gitea/issues/3842#issuecomment-397743346),
|
||||||
|
`/users/:name/tokens` is special and requires you to authenticate
|
||||||
|
using BasicAuth, as follows:
|
||||||
|
|
||||||
|
### Using basic authentication:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ curl --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens
|
||||||
|
[{"name":"test","sha1":"..."},{"name":"dev","sha1":"..."}]
|
||||||
|
```
|
||||||
|
|
||||||
|
As of v1.8.0 of Gitea, if using basic authentication with the API and your user has two factor authentication enabled, you'll need to send an additional header that contains the one time password (6 digit rotating token). An example of the header is `X-Gitea-OTP: 123456` where `123456` is where you'd place the code from your authenticator. Here is how the request would look like in curl:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ curl -H "X-Gitea-OTP: 123456" --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens
|
||||||
|
```
|
||||||
|
|
||||||
## Sudo
|
## Sudo
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,6 @@ One of these three distributions of Make will run on Windows:
|
||||||
- The binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to `PATH`.
|
- The binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to `PATH`.
|
||||||
- [Chocolatey package](https://chocolatey.org/packages/make). Run `choco install make`
|
- [Chocolatey package](https://chocolatey.org/packages/make). Run `choco install make`
|
||||||
|
|
||||||
**Note**: If you are attempting to build using make with Windows Command Prompt, you may run into issues. The above prompts (git bash, or mingw) are recommended, however if you only have command prompt (or potentially powershell) you can set environment variables using the [set](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/set_1) command, e.g. `set TAGS=bindata`.
|
|
||||||
|
|
||||||
## Downloading and cloning the Gitea source code
|
## Downloading and cloning the Gitea source code
|
||||||
|
|
||||||
The recommended method of obtaining the source code is by using `git clone`.
|
The recommended method of obtaining the source code is by using `git clone`.
|
||||||
|
@ -88,7 +86,7 @@ from within the `$GOPATH`, hence the `go get` approach is no longer recommended.
|
||||||
|
|
||||||
## Forking Gitea
|
## Forking Gitea
|
||||||
|
|
||||||
Download the main Gitea source code as above. Then, fork the
|
Download the master Gitea source code as above. Then, fork the
|
||||||
[Gitea repository](https://github.com/go-gitea/gitea) on GitHub,
|
[Gitea repository](https://github.com/go-gitea/gitea) on GitHub,
|
||||||
and either switch the git remote origin for your fork or add your fork as another remote:
|
and either switch the git remote origin for your fork or add your fork as another remote:
|
||||||
|
|
||||||
|
@ -125,11 +123,11 @@ TAGS="bindata sqlite sqlite_unlock_notify" make build
|
||||||
|
|
||||||
The `build` target will execute both `frontend` and `backend` sub-targets. If the `bindata` tag is present, the frontend files will be compiled into the binary. It is recommended to leave out the tag when doing frontend development so that changes will be reflected.
|
The `build` target will execute both `frontend` and `backend` sub-targets. If the `bindata` tag is present, the frontend files will be compiled into the binary. It is recommended to leave out the tag when doing frontend development so that changes will be reflected.
|
||||||
|
|
||||||
See `make help` for all available `make` targets. Also see [`.drone.yml`](https://github.com/go-gitea/gitea/blob/main/.drone.yml) to see how our continuous integration works.
|
See `make help` for all available `make` targets. Also see [`.drone.yml`](https://github.com/go-gitea/gitea/blob/master/.drone.yml) to see how our continuous integration works.
|
||||||
|
|
||||||
## Building continuously
|
## Building continuously
|
||||||
|
|
||||||
To run and continuously rebuild when source files change:
|
To run and continously rebuild when source files change:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make watch
|
make watch
|
||||||
|
@ -218,7 +216,7 @@ You should validate your generated Swagger file and spell-check it with:
|
||||||
make swagger-validate misspell-check
|
make swagger-validate misspell-check
|
||||||
```
|
```
|
||||||
|
|
||||||
You should commit the changed swagger JSON file. The continuous integration
|
You should commit the changed swagger JSON file. The continous integration
|
||||||
server will check that this has been done using:
|
server will check that this has been done using:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -278,7 +276,7 @@ require `git lfs` to be installed. Other database tests are available but
|
||||||
may need adjustment to the local environment.
|
may need adjustment to the local environment.
|
||||||
|
|
||||||
Look at
|
Look at
|
||||||
[`integrations/README.md`](https://github.com/go-gitea/gitea/blob/main/integrations/README.md)
|
[`integrations/README.md`](https://github.com/go-gitea/gitea/blob/master/integrations/README.md)
|
||||||
for more information and how to run a single test.
|
for more information and how to run a single test.
|
||||||
|
|
||||||
Our continuous integration will test the code passes its unit tests and that
|
Our continuous integration will test the code passes its unit tests and that
|
||||||
|
@ -306,32 +304,19 @@ be cleaned up.
|
||||||
|
|
||||||
A `launch.json` and `tasks.json` are provided within `contrib/ide/vscode` for
|
A `launch.json` and `tasks.json` are provided within `contrib/ide/vscode` for
|
||||||
Visual Studio Code. Look at
|
Visual Studio Code. Look at
|
||||||
[`contrib/ide/README.md`](https://github.com/go-gitea/gitea/blob/main/contrib/ide/README.md)
|
[`contrib/ide/README.md`](https://github.com/go-gitea/gitea/blob/master/contrib/ide/README.md)
|
||||||
for more information.
|
for more information.
|
||||||
|
|
||||||
## GoLand
|
|
||||||
|
|
||||||
Clicking the `Run Application` arrow on the function `func main()` in `/main.go`
|
|
||||||
can quickly start a debuggable gitea instance.
|
|
||||||
|
|
||||||
The `Output Directory` in `Run/Debug Configuration` MUST be set to the
|
|
||||||
gitea project directory (which contains `main.go` and `go.mod`),
|
|
||||||
otherwise, the started instance's working directory is a GoLand's temporary directory
|
|
||||||
and prevents gitea from loading dynamic resources (eg: templates) in a development environment.
|
|
||||||
|
|
||||||
To run unit tests with SQLite in GoLand, set `-tags sqlite,sqlite_unlock_notify`
|
|
||||||
in `Go tool arguments` of `Run/Debug Configuration`.
|
|
||||||
|
|
||||||
## Submitting PRs
|
## Submitting PRs
|
||||||
|
|
||||||
Once you're happy with your changes, push them up and open a pull request. It
|
Once you're happy with your changes, push them up and open a pull request. It
|
||||||
is recommended that you allow Gitea Managers and Owners to modify your PR
|
is recommended that you allow Gitea Managers and Owners to modify your PR
|
||||||
branches as we will need to update it to main before merging and/or may be
|
branches as we will need to update it to master before merging and/or may be
|
||||||
able to help fix issues directly.
|
able to help fix issues directly.
|
||||||
|
|
||||||
Any PR requires two approvals from the Gitea maintainers and needs to pass the
|
Any PR requires two approvals from the Gitea maintainers and needs to pass the
|
||||||
continuous integration. Take a look at our
|
continous integration. Take a look at our
|
||||||
[`CONTRIBUTING.md`](https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md)
|
[`CONTRIBUTING.md`](https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md)
|
||||||
document.
|
document.
|
||||||
|
|
||||||
If you need more help pop on to [Discord](https://discord.gg/gitea) #Develop
|
If you need more help pop on to [Discord](https://discord.gg/gitea) #Develop
|
||||||
|
|
|
@ -20,26 +20,7 @@ projects.
|
||||||
|
|
||||||
We are curating a list over at [awesome-gitea](https://gitea.com/gitea/awesome-gitea) to track these!
|
We are curating a list over at [awesome-gitea](https://gitea.com/gitea/awesome-gitea) to track these!
|
||||||
|
|
||||||
If you are looking for [CI/CD](https://gitea.com/gitea/awesome-gitea#user-content-devops),
|
If you are looking for [CI/CD](https://gitea.com/gitea/awesome-gitea#devops),
|
||||||
an [SDK](https://gitea.com/gitea/awesome-gitea#user-content-sdk),
|
an [SDK](https://gitea.com/gitea/awesome-gitea#sdk),
|
||||||
or even some extra [themes](https://gitea.com/gitea/awesome-gitea#user-content-themes),
|
or even some extra [themes](https://gitea.com/gitea/awesome-gitea#themes),
|
||||||
you can find them listed in the [awesome-gitea](https://gitea.com/gitea/awesome-gitea) repository!
|
you can find them listed in the [awesome-gitea](https://gitea.com/gitea/awesome-gitea) repository!
|
||||||
|
|
||||||
## Pre-Fill New File name and contents
|
|
||||||
|
|
||||||
If you'd like to open a new file with a given name and contents,
|
|
||||||
you can do so with query parameters:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
GET /{{org}}/{{repo}}/_new/{{filepath}}
|
|
||||||
?filename={{filename}}
|
|
||||||
&value={{content}}
|
|
||||||
```
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
GET https://git.example.com/johndoe/bliss/_new/articles/
|
|
||||||
?filename=hello-world.md
|
|
||||||
&value=Hello%2C%20World!
|
|
||||||
```
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
date: "2019-04-15T17:29:00+08:00"
|
|
||||||
title: "整合"
|
|
||||||
slug: "integrations"
|
|
||||||
weight: 40
|
|
||||||
toc: false
|
|
||||||
draft: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
parent: "developers"
|
|
||||||
name: "整合"
|
|
||||||
weight: 65
|
|
||||||
identifier: "integrations"
|
|
||||||
---
|
|
||||||
|
|
||||||
# 整合
|
|
||||||
|
|
||||||
Gitea 有著很棒的第三方整合社群, 以及其它有著一流支援的專案。
|
|
||||||
|
|
||||||
我們持續的整理一份清單以追蹤他們!請到 [awesome-gitea](https://gitea.com/gitea/awesome-gitea) 查看。
|
|
||||||
|
|
||||||
如果您正在找尋有關 [CI/CD](https://gitea.com/gitea/awesome-gitea#user-content-devops)、[SDK](https://gitea.com/gitea/awesome-gitea#user-content-sdk) 或是其它佈景主題,您可以在存儲庫 [awesome-gitea](https://gitea.com/gitea/awesome-gitea) 找到他們。
|
|
|
@ -20,7 +20,7 @@ repository data from other git host platforms to Gitea or, in the future, migrat
|
||||||
git host platforms.
|
git host platforms.
|
||||||
Currently, migrations from Github, Gitlab, and other Gitea instances are implemented.
|
Currently, migrations from Github, Gitlab, and other Gitea instances are implemented.
|
||||||
|
|
||||||
First of all, Gitea defines some standard objects in packages [modules/migrations/base](https://github.com/go-gitea/gitea/tree/main/modules/migrations/base).
|
First of all, Gitea defines some standard objects in packages [modules/migrations/base](https://github.com/go-gitea/gitea/tree/master/modules/migrations/base).
|
||||||
They are `Repository`, `Milestone`, `Release`, `ReleaseAsset`, `Label`, `Issue`, `Comment`, `PullRequest`, `Reaction`, `Review`, `ReviewComment`.
|
They are `Repository`, `Milestone`, `Release`, `ReleaseAsset`, `Label`, `Issue`, `Comment`, `PullRequest`, `Reaction`, `Review`, `ReviewComment`.
|
||||||
|
|
||||||
## Downloader Interfaces
|
## Downloader Interfaces
|
||||||
|
@ -31,11 +31,11 @@ To migrate from a new git host platform, there are two steps to be updated.
|
||||||
- You should implement a `DownloaderFactory` which will be used to detect if the URL matches and create the above `Downloader`.
|
- You should implement a `DownloaderFactory` which will be used to detect if the URL matches and create the above `Downloader`.
|
||||||
- You'll need to register the `DownloaderFactory` via `RegisterDownloaderFactory` on `init()`.
|
- You'll need to register the `DownloaderFactory` via `RegisterDownloaderFactory` on `init()`.
|
||||||
|
|
||||||
You can find these interfaces in [downloader.go](https://github.com/go-gitea/gitea/blob/main/modules/migrations/base/downloader.go).
|
You can find these interfaces in [downloader.go](https://github.com/go-gitea/gitea/blob/master/modules/migrations/base/downloader.go).
|
||||||
|
|
||||||
## Uploader Interface
|
## Uploader Interface
|
||||||
|
|
||||||
Currently, only a `GiteaLocalUploader` is implemented, so we only save downloaded
|
Currently, only a `GiteaLocalUploader` is implemented, so we only save downloaded
|
||||||
data via this `Uploader` to the local Gitea instance. Other uploaders are not supported at this time.
|
data via this `Uploader` to the local Gitea instance. Other uploaders are not supported at this time.
|
||||||
|
|
||||||
You can find these interfaces in [uploader.go](https://github.com/go-gitea/gitea/blob/main/modules/migrations/base/uploader.go).
|
You can find these interfaces in [uploader.go](https://github.com/go-gitea/gitea/blob/master/modules/migrations/base/uploader.go).
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
---
|
|
||||||
date: "2019-04-15T17:29:00+08:00"
|
|
||||||
title: "遷移介面"
|
|
||||||
slug: "migrations-interfaces"
|
|
||||||
weight: 30
|
|
||||||
toc: false
|
|
||||||
draft: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
parent: "developers"
|
|
||||||
name: "遷移介面"
|
|
||||||
weight: 55
|
|
||||||
identifier: "migrations-interfaces"
|
|
||||||
---
|
|
||||||
|
|
||||||
# 遷移功能
|
|
||||||
|
|
||||||
完整的遷移從 Gitea 1.9.0 開始提供。它定義了兩個介面用來從其它 Git 託管平臺遷移儲存庫資料到 Gitea,未來或許會提供遷移到其它 git 託管平臺。
|
|
||||||
目前已實作了從 Github, Gitlab 和其它 Gitea 遷移資料。
|
|
||||||
|
|
||||||
Gitea 定義了一些基本物件於套件 [modules/migrations/base](https://github.com/go-gitea/gitea/tree/master/modules/migrations/base)。
|
|
||||||
分別是 `Repository`, `Milestone`, `Release`, `ReleaseAsset`, `Label`, `Issue`, `Comment`, `PullRequest`, `Reaction`, `Review`, `ReviewComment`。
|
|
||||||
|
|
||||||
## Downloader 介面
|
|
||||||
|
|
||||||
從新的 Git 託管平臺遷移,有兩個新的步驟。
|
|
||||||
|
|
||||||
- 您必須實作一個 `Downloader`,它用來取得儲存庫資訊。
|
|
||||||
- 您必須實作一個 `DownloaderFactory`,它用來偵測 URL 是否符合並建立上述的 `Downloader`。
|
|
||||||
- 您需要在 `init()` 透過 `RegisterDownloaderFactory` 來註冊 `DownloaderFactory`。
|
|
||||||
|
|
||||||
您可以在 [downloader.go](https://github.com/go-gitea/gitea/blob/master/modules/migrations/base/downloader.go) 中找到這些介面。
|
|
||||||
|
|
||||||
## Uploader 介面
|
|
||||||
|
|
||||||
目前只有 `GiteaLocalUploader` 被實作出來,所以我們只能通過 `Uploader` 儲存已下載的資料到本地的 Gitea 實例。
|
|
||||||
目前尚未支援其它 Uploader。
|
|
||||||
|
|
||||||
您可以在 [uploader.go](https://github.com/go-gitea/gitea/blob/master/modules/migrations/base/uploader.go) 中找到這些介面。
|
|
|
@ -24,12 +24,9 @@ Gitea supports acting as an OAuth2 provider to allow third party applications to
|
||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
||||||
| Endpoint | URL |
|
| Endpoint | URL |
|
||||||
| ------------------------ | ----------------------------------- |
|
| ---------------------- | --------------------------- |
|
||||||
| OpenID Connect Discovery | `/.well-known/openid-configuration` |
|
|
||||||
| Authorization Endpoint | `/login/oauth/authorize` |
|
| Authorization Endpoint | `/login/oauth/authorize` |
|
||||||
| Access Token Endpoint | `/login/oauth/access_token` |
|
| Access Token Endpoint | `/login/oauth/access_token` |
|
||||||
| OpenID Connect UserInfo | `/login/oauth/userinfo` |
|
|
||||||
| JSON Web Key Set | `/login/oauth/keys` |
|
|
||||||
|
|
||||||
## Supported OAuth2 Grants
|
## Supported OAuth2 Grants
|
||||||
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
---
|
|
||||||
date: "2019-04-19:44:00+01:00"
|
|
||||||
title: "OAuth2 提供者"
|
|
||||||
slug: "oauth2-provider"
|
|
||||||
weight: 41
|
|
||||||
toc: false
|
|
||||||
draft: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
parent: "developers"
|
|
||||||
name: "OAuth2 提供者"
|
|
||||||
weight: 41
|
|
||||||
identifier: "oauth2-provider"
|
|
||||||
---
|
|
||||||
|
|
||||||
# OAuth2 提供者
|
|
||||||
|
|
||||||
**目錄**
|
|
||||||
|
|
||||||
{{< toc >}}
|
|
||||||
|
|
||||||
Gitea 支援作為 OAuth2 提供者,能讓第三方程式能在使用者同意下存取 Gitea 的資源。此功能自 1.8.0 版開始提供。
|
|
||||||
|
|
||||||
## Endpoint
|
|
||||||
|
|
||||||
| Endpoint | URL |
|
|
||||||
| ---------------------- | --------------------------- |
|
|
||||||
| Authorization Endpoint | `/login/oauth/authorize` |
|
|
||||||
| Access Token Endpoint | `/login/oauth/access_token` |
|
|
||||||
|
|
||||||
## 支援的 OAuth2 Grant
|
|
||||||
|
|
||||||
目前 Gitea 只支援 [**Authorization Code Grant**](https://tools.ietf.org/html/rfc6749#section-1.3.1) 標準並額外支援下列擴充標準:
|
|
||||||
|
|
||||||
- [Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636)
|
|
||||||
- [OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
|
|
||||||
|
|
||||||
若想要讓第三方程式使用 Authorization Code Grant,需先在「設定」(`/user/settings/applications`)中註冊一個新的應用程式。
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
目前 Gitea 尚未支援 scope (參見 [#4300](https://github.com/go-gitea/gitea/issues/4300)),所有的第三方程式都可獲得該使用者及他所屬的組織中所有資源的存取權。
|
|
||||||
|
|
||||||
## 範例
|
|
||||||
|
|
||||||
**備註:** 此範例未使用 PKCE。
|
|
||||||
|
|
||||||
1. 重新導向使用者到 authorization endpoint 以獲得他同意授權存取資源:
|
|
||||||
<!-- 1. Redirect to user to the authorization endpoint in order to get his/her consent for accessing the resources: -->
|
|
||||||
|
|
||||||
```curl
|
|
||||||
https://[YOUR-GITEA-URL]/login/oauth/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI& response_type=code&state=STATE
|
|
||||||
```
|
|
||||||
|
|
||||||
在設定中註冊應用程式以獲得 `CLIENT_ID`。`STATE` 是一個隨機的字串,它將在使用者授權後發送回您的應用程式。`state` 參數是選用的,但應該要用它來防止 CSRF 攻擊。
|
|
||||||
|
|
||||||
![Authorization Page](/authorize.png)
|
|
||||||
|
|
||||||
使用者將會被詢問是否授權給您的應用程式。如果它們同意了,使用者將被重新導向到 `REDIRECT_URL`,例如:
|
|
||||||
|
|
||||||
```curl
|
|
||||||
https://[REDIRECT_URI]?code=RETURNED_CODE&state=STATE
|
|
||||||
```
|
|
||||||
|
|
||||||
1. 使用重新導向提供的 `code`,您可以要求一個新的應用程式和 Refresh Token。Access Token Endpoint 接受 POST 請求使用 `application/json` 或 `application/x-www-form-urlencoded` 類型的請求內容,例如:
|
|
||||||
|
|
||||||
```curl
|
|
||||||
POST https://[YOUR-GITEA-URL]/login/oauth/access_token
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"client_id": "YOUR_CLIENT_ID",
|
|
||||||
"client_secret": "YOUR_CLIENT_SECRET",
|
|
||||||
"code": "RETURNED_CODE",
|
|
||||||
"grant_type": "authorization_code",
|
|
||||||
"redirect_uri": "REDIRECT_URI"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
回應:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"access_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJnbnQiOjIsInR0IjowLCJleHAiOjE1NTUxNzk5MTIsImlhdCI6MTU1NTE3NjMxMn0.0-iFsAwBtxuckA0sNZ6QpBQmywVPz129u75vOM7wPJecw5wqGyBkmstfJHAjEOqrAf_V5Z-1QYeCh_Cz4RiKug",
|
|
||||||
"token_type": "bearer",
|
|
||||||
"expires_in": 3600,
|
|
||||||
"refresh_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJnbnQiOjIsInR0IjoxLCJjbnQiOjEsImV4cCI6MTU1NzgwNDMxMiwiaWF0IjoxNTU1MTc2MzEyfQ.S_HZQBy4q9r5SEzNGNIoFClT43HPNDbUdHH-GYNYYdkRfft6XptJBkUQscZsGxOW975Yk6RbgtGvq1nkEcklOw"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`CLIENT_SECRET` 是產生給此應用程式的唯一密鑰。請記住該密鑰只會在您於 Gitea 建立/註冊應用程式時出現一次。若您遺失密鑰,您必須在該應用程式的設定中重新產生密鑰。
|
|
||||||
|
|
||||||
`access_token` 請求中的 `REDIRECT_URI` 必須符合 `authorize` 請求中的 `REDIRECT_URI`。
|
|
||||||
|
|
||||||
1. 發送 [API requests](https://docs.gitea.io/en-us/api-usage#oauth2) 時使用 `access_token` 以存取使用者的資源。
|
|
|
@ -88,8 +88,8 @@ Adds the following fields:
|
||||||
- Bind Password (optional)
|
- Bind Password (optional)
|
||||||
|
|
||||||
- The password for the Bind DN specified above, if any. _Note: The password
|
- The password for the Bind DN specified above, if any. _Note: The password
|
||||||
is stored encrypted with the SECRET_KEY on the server. It is still recommended
|
is stored in plaintext at the server. As such, ensure that the Bind DN
|
||||||
to ensure that the Bind DN has as few privileges as possible._
|
has as few privileges as possible._
|
||||||
|
|
||||||
- User Search Base **(required)**
|
- User Search Base **(required)**
|
||||||
|
|
||||||
|
@ -170,8 +170,6 @@ To configure PAM, set the 'PAM Service Name' to a filename in `/etc/pam.d/`. To
|
||||||
work with normal Linux passwords, the user running Gitea must have read access
|
work with normal Linux passwords, the user running Gitea must have read access
|
||||||
to `/etc/shadow`.
|
to `/etc/shadow`.
|
||||||
|
|
||||||
**Note**: PAM support is added via [build-time flags](https://docs.gitea.io/en-us/install-from-source/#build), and the official binaries provided do not have this enabled.
|
|
||||||
|
|
||||||
## SMTP (Simple Mail Transfer Protocol)
|
## SMTP (Simple Mail Transfer Protocol)
|
||||||
|
|
||||||
This option allows Gitea to log in to an SMTP host as a Gitea user. To
|
This option allows Gitea to log in to an SMTP host as a Gitea user. To
|
||||||
|
@ -201,18 +199,16 @@ configure this, set the fields below:
|
||||||
with multiple domains.
|
with multiple domains.
|
||||||
- Example: `gitea.io,mydomain.com,mydomain2.com`
|
- Example: `gitea.io,mydomain.com,mydomain2.com`
|
||||||
|
|
||||||
- Force SMTPS
|
- Enable TLS Encryption
|
||||||
|
|
||||||
- SMTPS will be used by default for connections to port 465, if you wish to use SMTPS
|
- Enable TLS encryption on authentication.
|
||||||
for other ports. Set this value.
|
|
||||||
- Otherwise if the server provides the `STARTTLS` extension this will be used.
|
|
||||||
|
|
||||||
- Skip TLS Verify
|
- Skip TLS Verify
|
||||||
|
|
||||||
- Disable TLS verify on authentication.
|
- Disable TLS verify on authentication.
|
||||||
|
|
||||||
- This Authentication Source is Activated
|
- This authentication is activate
|
||||||
- Enable or disable this authentication source.
|
- Enable or disable this auth.
|
||||||
|
|
||||||
## FreeIPA
|
## FreeIPA
|
||||||
|
|
||||||
|
@ -263,7 +259,7 @@ Before activating SSPI single sign-on authentication (SSO) you have to prepare y
|
||||||
|
|
||||||
- Create a service principal name for the host where `gitea.exe` is running with class `HTTP`:
|
- Create a service principal name for the host where `gitea.exe` is running with class `HTTP`:
|
||||||
|
|
||||||
- Start `Command Prompt` or `PowerShell` as a privileged domain user (eg. Domain Administrator)
|
- Start `Command Prompt` or `PowerShell` as a priviledged domain user (eg. Domain Administrator)
|
||||||
- Run the command below, replacing `host.domain.local` with the fully qualified domain name (FQDN) of the server where the web application will be running, and `domain\user` with the name of the account created in the previous step:
|
- Run the command below, replacing `host.domain.local` with the fully qualified domain name (FQDN) of the server where the web application will be running, and `domain\user` with the name of the account created in the previous step:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -287,7 +283,7 @@ Before activating SSPI single sign-on authentication (SSO) you have to prepare y
|
||||||
- Click the `Sign In` button on the dashboard and choose SSPI to be automatically logged in with the same user that is currently logged on to the computer
|
- Click the `Sign In` button on the dashboard and choose SSPI to be automatically logged in with the same user that is currently logged on to the computer
|
||||||
|
|
||||||
- If it does not work, make sure that:
|
- If it does not work, make sure that:
|
||||||
- You are not running the web browser on the same server where gitea is running. You should be running the web browser on a domain joined computer (client) that is different from the server. If both the client and server are running on the same computer NTLM will be preferred over Kerberos.
|
- You are not running the web browser on the same server where gitea is running. You should be running the web browser on a domain joined computer (client) that is different from the server. If both the client and server are runnning on the same computer NTLM will be prefered over Kerberos.
|
||||||
- There is only one `HTTP/...` SPN for the host
|
- There is only one `HTTP/...` SPN for the host
|
||||||
- The SPN contains only the hostname, without the port
|
- The SPN contains only the hostname, without the port
|
||||||
- You have added the URL of the web app to the `Local intranet zone`
|
- You have added the URL of the web app to the `Local intranet zone`
|
||||||
|
|
|
@ -34,7 +34,7 @@ _Symbols used in table:_
|
||||||
## General Features
|
## General Features
|
||||||
|
|
||||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
| ----------------------------------- | -------------------------------------------------- | ---- | --------- | --------- | --------- | -------------- | ------------ |
|
| ----------------------------------- | -------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||||
| Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
| Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
||||||
| Low resource usage (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
| Low resource usage (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||||
| Multiple database support | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
| Multiple database support | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
||||||
|
@ -45,9 +45,9 @@ _Symbols used in table:_
|
||||||
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||||
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
||||||
| Static Git-powered pages | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Static Git-powered pages | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
| Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||||
| Built-in Container Registry | [✘](https://github.com/go-gitea/gitea/issues/2316) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Built-in Container Registry | [✘](https://github.com/go-gitea/gitea/issues/2316) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
| External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||||
| FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
| FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
|
@ -61,12 +61,12 @@ _Symbols used in table:_
|
||||||
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
| Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
||||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ |
|
||||||
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Verified Committer | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
| Verified Committer | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||||
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Reject unsigned commits | [✓](https://github.com/go-gitea/gitea/pull/9708) | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Reject unsigned commits | [✓](https://github.com/go-gitea/gitea/pull/9708) | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||||
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
|
@ -77,8 +77,8 @@ _Symbols used in table:_
|
||||||
## Issue Tracker
|
## Issue Tracker
|
||||||
|
|
||||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
| ------------------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | ----------------------------------------------------------------------- | --------- | -------------- | ------------ |
|
| ------------------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | ----------------------------------------------------------------------- | --------- | --------- | ------------ |
|
||||||
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
---
|
|
||||||
date: "2018-05-07T13:00:00+02:00"
|
|
||||||
title: "比較 Gitea 和其它自託管 Git 服務"
|
|
||||||
slug: "comparison"
|
|
||||||
weight: 5
|
|
||||||
toc: false
|
|
||||||
draft: false
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
parent: "features"
|
|
||||||
name: "比較"
|
|
||||||
weight: 5
|
|
||||||
identifier: "comparison"
|
|
||||||
---
|
|
||||||
|
|
||||||
# 比較 Gitea 和其它自託管 Git 服務
|
|
||||||
|
|
||||||
**目錄**
|
|
||||||
|
|
||||||
{{< toc >}}
|
|
||||||
|
|
||||||
為了幫助您判斷 Gitea 是否適合您的需求,這裡列出了它和其它自託管 Git 服務的比較。
|
|
||||||
|
|
||||||
請注意我們不會經常檢查其它產品的功能異動,所以這份清單可能過期,如果您在下方表格中找到需要更新的資料,請在 [GitHub 的 Issue](https://github.com/go-gitea/gitea/issues) 回報。
|
|
||||||
|
|
||||||
表格中使用的符號:
|
|
||||||
|
|
||||||
- ✓ - 支援
|
|
||||||
|
|
||||||
- ⁄ - 有限度的支援
|
|
||||||
|
|
||||||
- ✘ - 不支援
|
|
||||||
|
|
||||||
## 一般功能
|
|
||||||
|
|
||||||
| 功能 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
|
||||||
| ------------------------ | -------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
|
||||||
| 免費及開放原始碼 | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
|
||||||
| 低資源使用 (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
|
||||||
| 支援多種資料庫 | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
|
||||||
| 支援多種作業系統 | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ |
|
|
||||||
| 簡單的升級程序 | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
|
||||||
| 支援 Markdown | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 支援 Orgmode | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? |
|
|
||||||
| 支援 CSV | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
|
||||||
| 支援第三方渲染工具 | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
|
||||||
| Git 驅動的靜態頁面 | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| Git 驅動的整合 wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 部署 Token | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 有寫入權限的儲存庫 Token | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
|
||||||
| 內建 Container Registry | [✘](https://github.com/go-gitea/gitea/issues/2316) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 對外部 Git 鏡像 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
|
||||||
| FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 內建 CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 子群組: 群組中的群組 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
|
||||||
|
|
||||||
## 程式碼管理
|
|
||||||
|
|
||||||
| 功能 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
|
||||||
| ----------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
|
||||||
| 儲存庫主題描述 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 儲存庫程式碼搜尋 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 全域程式碼搜尋 | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
|
||||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ |
|
|
||||||
| 群組里程碑 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 精細的使用者權限(程式碼, 問題, Wiki 等) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 驗證提交者 | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| GPG 簽署提交 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 拒絕未經簽署的提交 | [✓](https://github.com/go-gitea/gitea/pull/9708) | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
|
||||||
| 儲存庫動態頁 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 分支管理 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 建立新分支 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 網頁程式碼編輯器 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 提交線圖 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 儲存庫範本 | [✓](https://github.com/go-gitea/gitea/pull/8768) | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
|
||||||
|
|
||||||
## 問題追蹤器
|
|
||||||
|
|
||||||
| 功能 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
|
||||||
| -------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | ----------------------------------------------------------------------- | --------- | --------- | ------------ |
|
|
||||||
| 問題追蹤器 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 問題範本 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 標籤 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 時間追蹤 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 指派問題給多個成員 | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
|
|
||||||
| 相關問題 | ✘ | ✘ | ⁄ | [✓](https://docs.gitlab.com/ce/user/project/issues/related_issues.html) | ✓ | ✘ | ✘ |
|
|
||||||
| 機密問題 | [✘](https://github.com/go-gitea/gitea/issues/3217) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 對留言的反應 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 鎖定對話 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 批次處理問題 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 問題看板(看板方法) | [✓](https://github.com/go-gitea/gitea/pull/8346) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 從問題建立新分支 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 問題搜尋 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 全域問題搜尋 | [✘](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 問題相依 | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
|
||||||
| 從電子郵件建立問題 | [✘](https://github.com/go-gitea/gitea/issues/6226) | [✘](https://github.com/gogs/gogs/issues/2602) | ✘ | ✘ | ✓ | ✓ | ✘ |
|
|
||||||
| 服務台 | [✘](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | [✓](https://gitlab.com/groups/gitlab-org/-/epics/3103) | ✓ | ✘ | ✘ |
|
|
||||||
|
|
||||||
## 拉取/合併請求
|
|
||||||
|
|
||||||
| 功能 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
|
||||||
| -------------------------- | -------------------------------------------------- | ---- | --------- | --------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------ | ------------ |
|
|
||||||
| 拉取/合併請求 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| Squash 合併 | ✓ | ✘ | ✓ | [✓](https://docs.gitlab.com/ce/user/project/merge_requests/squash_and_merge.html) | ✓ | ✓ | ✓ |
|
|
||||||
| Rebase 合併 | ✓ | ✓ | ✓ | ✘ | ⁄ | ✘ | ✓ |
|
|
||||||
| 拉取/合併請求的行內留言 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 拉取/合併請求的核可 | ✓ | ✘ | ⁄ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 解決合併衝突 | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 限制某些使用者的推送及合併 | ✓ | ✘ | ✓ | ⁄ | ✓ | ✓ | ✓ |
|
|
||||||
| 還原指定的提交或合併請求 | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 拉取/合併請求範本 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| Cherry-picking 變更 | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 下載 Patch | ✓ | ✘ | ✓ | ✓ | ✓ | [/](https://jira.atlassian.com/plugins/servlet/mobile#issue/BCLOUD-8323) | ✘ |
|
|
||||||
|
|
||||||
## 第三方整合
|
|
||||||
|
|
||||||
| 功能 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
|
||||||
| ------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
|
||||||
| 支援 Webhook | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 自訂 Git Hook | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 整合 AD / LDAP | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 支援多重 LDAP / AD 伺服器 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
|
||||||
| 同步 LDAP 使用者 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
| 支援 OpenId Connect | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
|
|
||||||
| 整合 OAuth 2.0 (外部驗證) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ |
|
|
||||||
| 成為 OAuth 2.0 提供者 | [✓](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 兩步驟驗證 (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 整合 Mattermost/Slack | ✓ | ✓ | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
|
||||||
| 整合 Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
|
||||||
| 整合 Microsoft Teams | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| 顯示外部 CI/CD 狀態 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
|
@ -13,18 +13,6 @@ menu:
|
||||||
identifier: "localization"
|
identifier: "localization"
|
||||||
---
|
---
|
||||||
|
|
||||||
# 在地化
|
# Localization
|
||||||
|
|
||||||
我們在 [Crowdin 專案](https://crowdin.com/project/gitea)上進行在地化工作。
|
## TBD
|
||||||
|
|
||||||
**英語系**的翻譯,可在修改[英文語言檔](https://github.com/go-gitea/gitea/blob/master/options/locale/locale_en-US.ini)後提出合併請求。
|
|
||||||
|
|
||||||
**非英語系**的翻譯,請前往上述的 Crowdin 專案。
|
|
||||||
|
|
||||||
## 已支援的語言
|
|
||||||
|
|
||||||
上述 Crowdin 專案中列出的語言在翻譯超過 25% 後將被支援。
|
|
||||||
|
|
||||||
翻譯被認可後將在下次 Crowdin 同步後進入到主儲存庫,通常是在任何合併請求被合併之後。
|
|
||||||
這表示更改的翻譯要到下次 Gitea 發佈後才會出現。
|
|
||||||
如果您使用的是最新建置,它將會在同步完成、您更新後出現。
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ All event pushes are POST requests. The methods currently supported are:
|
||||||
- Telegram
|
- Telegram
|
||||||
- Microsoft Teams
|
- Microsoft Teams
|
||||||
- Feishu
|
- Feishu
|
||||||
- Wechatwork
|
|
||||||
|
|
||||||
### Event information
|
### Event information
|
||||||
|
|
||||||
|
|
|
@ -15,17 +15,4 @@ menu:
|
||||||
|
|
||||||
# Webhooks
|
# Webhooks
|
||||||
|
|
||||||
Gitea 的存储 webhook。这可以有存储库管路设定页 `/:username/:reponame/settings/hooks` 中的。Webhook 也可以按照组织调整或全系统调整,所有时间的推送都是POST请求
|
|
||||||
。此方法目前被下列服务支援:
|
|
||||||
|
|
||||||
- Gitea (也可以是 GET 請求)
|
|
||||||
- Gogs
|
|
||||||
- Slack
|
|
||||||
- Discord
|
|
||||||
- Dingtalk
|
|
||||||
- Telegram
|
|
||||||
- Microsoft Teams
|
|
||||||
- Feishu
|
|
||||||
- Wechatwork
|
|
||||||
|
|
||||||
## TBD
|
## TBD
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
date: "2016-12-01T16:00:00+02:00"
|
date: "2016-12-01T16:00:00+02:00"
|
||||||
title: "Webhook"
|
title: "Webhooks"
|
||||||
slug: "webhooks"
|
slug: "webhooks"
|
||||||
weight: 10
|
weight: 10
|
||||||
toc: false
|
toc: false
|
||||||
|
@ -8,180 +8,11 @@ draft: false
|
||||||
menu:
|
menu:
|
||||||
sidebar:
|
sidebar:
|
||||||
parent: "features"
|
parent: "features"
|
||||||
name: "Webhook"
|
name: "Webhooks"
|
||||||
weight: 30
|
weight: 30
|
||||||
identifier: "webhooks"
|
identifier: "webhooks"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Webhook
|
# Webhooks
|
||||||
|
|
||||||
Gitea 的儲存庫事件支援 web hook。這可以有儲存庫管理員在設定頁 `/:username/:reponame/settings/hooks` 中調整。Webhook 也可以按照組織調整或按照全系統調整。
|
## TBD
|
||||||
所有的事件推送都是 POST 請求。此方法目前被下列服務支援:
|
|
||||||
|
|
||||||
- Gitea (也可以是 GET 請求)
|
|
||||||
- Gogs
|
|
||||||
- Slack
|
|
||||||
- Discord
|
|
||||||
- Dingtalk
|
|
||||||
- Telegram
|
|
||||||
- Microsoft Teams
|
|
||||||
- Feishu
|
|
||||||
- Wechatwork
|
|
||||||
|
|
||||||
### 事件資訊
|
|
||||||
|
|
||||||
**警告**: Payload 中的 `secret` 欄位已經在 Gitea 1.13.0 棄用,並且將在 1.14.0 移除: https://github.com/go-gitea/gitea/issues/11755
|
|
||||||
|
|
||||||
下面是一個將由 Gitea 發送到 Payload URL 的事件資訊的範例:
|
|
||||||
|
|
||||||
```
|
|
||||||
X-GitHub-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
|
|
||||||
X-GitHub-Event: push
|
|
||||||
X-Gogs-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
|
|
||||||
X-Gogs-Event: push
|
|
||||||
X-Gitea-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
|
|
||||||
X-Gitea-Event: push
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"secret": "3gEsCfjlV2ugRwgpU#w1*WaW*wa4NXgGmpCfkbG3",
|
|
||||||
"ref": "refs/heads/develop",
|
|
||||||
"before": "28e1879d029cb852e4844d9c718537df08844e03",
|
|
||||||
"after": "bffeb74224043ba2feb48d137756c8a9331c449a",
|
|
||||||
"compare_url": "http://localhost:3000/gitea/webhooks/compare/28e1879d029cb852e4844d9c718537df08844e03...bffeb74224043ba2feb48d137756c8a9331c449a",
|
|
||||||
"commits": [
|
|
||||||
{
|
|
||||||
"id": "bffeb74224043ba2feb48d137756c8a9331c449a",
|
|
||||||
"message": "Webhooks Yay!",
|
|
||||||
"url": "http://localhost:3000/gitea/webhooks/commit/bffeb74224043ba2feb48d137756c8a9331c449a",
|
|
||||||
"author": {
|
|
||||||
"name": "Gitea",
|
|
||||||
"email": "someone@gitea.io",
|
|
||||||
"username": "gitea"
|
|
||||||
},
|
|
||||||
"committer": {
|
|
||||||
"name": "Gitea",
|
|
||||||
"email": "someone@gitea.io",
|
|
||||||
"username": "gitea"
|
|
||||||
},
|
|
||||||
"timestamp": "2017-03-13T13:52:11-04:00"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"repository": {
|
|
||||||
"id": 140,
|
|
||||||
"owner": {
|
|
||||||
"id": 1,
|
|
||||||
"login": "gitea",
|
|
||||||
"full_name": "Gitea",
|
|
||||||
"email": "someone@gitea.io",
|
|
||||||
"avatar_url": "https://localhost:3000/avatars/1",
|
|
||||||
"username": "gitea"
|
|
||||||
},
|
|
||||||
"name": "webhooks",
|
|
||||||
"full_name": "gitea/webhooks",
|
|
||||||
"description": "",
|
|
||||||
"private": false,
|
|
||||||
"fork": false,
|
|
||||||
"html_url": "http://localhost:3000/gitea/webhooks",
|
|
||||||
"ssh_url": "ssh://gitea@localhost:2222/gitea/webhooks.git",
|
|
||||||
"clone_url": "http://localhost:3000/gitea/webhooks.git",
|
|
||||||
"website": "",
|
|
||||||
"stars_count": 0,
|
|
||||||
"forks_count": 1,
|
|
||||||
"watchers_count": 1,
|
|
||||||
"open_issues_count": 7,
|
|
||||||
"default_branch": "master",
|
|
||||||
"created_at": "2017-02-26T04:29:06-05:00",
|
|
||||||
"updated_at": "2017-03-13T13:51:58-04:00"
|
|
||||||
},
|
|
||||||
"pusher": {
|
|
||||||
"id": 1,
|
|
||||||
"login": "gitea",
|
|
||||||
"full_name": "Gitea",
|
|
||||||
"email": "someone@gitea.io",
|
|
||||||
"avatar_url": "https://localhost:3000/avatars/1",
|
|
||||||
"username": "gitea"
|
|
||||||
},
|
|
||||||
"sender": {
|
|
||||||
"id": 1,
|
|
||||||
"login": "gitea",
|
|
||||||
"full_name": "Gitea",
|
|
||||||
"email": "someone@gitea.io",
|
|
||||||
"avatar_url": "https://localhost:3000/avatars/1",
|
|
||||||
"username": "gitea"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 範例
|
|
||||||
|
|
||||||
此範例示範在發生推送事件時,如何使用 webhook 觸發 php 程式。
|
|
||||||
使用下列參數在您的儲存庫設定 Webhook 中建立一個 Gitea webhook:
|
|
||||||
|
|
||||||
- 目標 URL: http://mydomain.com/webhook.php
|
|
||||||
- HTTP 請求方法:POST
|
|
||||||
- POST Content Type:application/json
|
|
||||||
- Secret:123
|
|
||||||
- 觸發條件:推送事件
|
|
||||||
- 啟用:勾選
|
|
||||||
|
|
||||||
現在請到您的伺服器上建立 webhook.php 檔案
|
|
||||||
|
|
||||||
```
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$secret_key = '123';
|
|
||||||
|
|
||||||
// check for POST request
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
|
||||||
error_log('FAILED - not POST - '. $_SERVER['REQUEST_METHOD']);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get content type
|
|
||||||
$content_type = isset($_SERVER['CONTENT_TYPE']) ? strtolower(trim($_SERVER['CONTENT_TYPE'])) : '';
|
|
||||||
|
|
||||||
if ($content_type != 'application/json') {
|
|
||||||
error_log('FAILED - not application/json - '. $content_type);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get payload
|
|
||||||
$payload = trim(file_get_contents("php://input"));
|
|
||||||
|
|
||||||
if (empty($payload)) {
|
|
||||||
error_log('FAILED - no payload');
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get header signature
|
|
||||||
$header_signature = isset($_SERVER['HTTP_X_GITEA_SIGNATURE']) ? $_SERVER['HTTP_X_GITEA_SIGNATURE'] : '';
|
|
||||||
|
|
||||||
if (empty($header_signature)) {
|
|
||||||
error_log('FAILED - header signature missing');
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate payload signature
|
|
||||||
$payload_signature = hash_hmac('sha256', $payload, $secret_key, false);
|
|
||||||
|
|
||||||
// check payload signature against header signature
|
|
||||||
if ($header_signature !== $payload_signature) {
|
|
||||||
error_log('FAILED - payload signature');
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert json to array
|
|
||||||
$decoded = json_decode($payload, true);
|
|
||||||
|
|
||||||
// check for json decode errors
|
|
||||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
||||||
error_log('FAILED - json decode - '. json_last_error());
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// success, do something
|
|
||||||
```
|
|
||||||
|
|
||||||
Webhook 設定中有一個傳送測試資料按鈕,它可讓你測試您的設定並將結果顯示於最近傳送記錄。
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
---
|
---
|
||||||
date: "2017-01-20T15:00:00+08:00"
|
date: "2017-01-20T15:00:00+08:00"
|
||||||
title: "幫助"
|
title: "救命"
|
||||||
slug: "help"
|
slug: "help"
|
||||||
weight: 5
|
weight: 5
|
||||||
toc: false
|
toc: false
|
||||||
draft: false
|
draft: false
|
||||||
menu:
|
menu:
|
||||||
sidebar:
|
sidebar:
|
||||||
name: "幫助"
|
name: "救命"
|
||||||
weight: 5
|
weight: 5
|
||||||
identifier: "help"
|
identifier: "help"
|
||||||
---
|
---
|
||||||
|
|
|
@ -85,12 +85,6 @@ If certain clone options aren't showing up (HTTP/S or SSH), the following option
|
||||||
`DISABLE_SSH`: if set to true, there will be no SSH link
|
`DISABLE_SSH`: if set to true, there will be no SSH link
|
||||||
`SSH_EXPOSE_ANONYMOUS`: if set to false, SSH links will be hidden for anonymous users
|
`SSH_EXPOSE_ANONYMOUS`: if set to false, SSH links will be hidden for anonymous users
|
||||||
|
|
||||||
## File upload fails with: 413 Request Entity Too Large
|
|
||||||
|
|
||||||
This error occurs when the reverse proxy limits the file upload size.
|
|
||||||
|
|
||||||
See the [reverse proxy guide]({{< relref "doc/usage/reverse-proxies.en-us.md" >}}) for a solution with nginx.
|
|
||||||
|
|
||||||
## Custom Templates not loading or working incorrectly
|
## Custom Templates not loading or working incorrectly
|
||||||
|
|
||||||
Gitea's custom templates must be added to the correct location or Gitea will not find and use them.
|
Gitea's custom templates must be added to the correct location or Gitea will not find and use them.
|
||||||
|
@ -126,14 +120,13 @@ For more information, refer to Gitea's [API docs]({{< relref "doc/developers/api
|
||||||
|
|
||||||
There are multiple things you can combine to prevent spammers.
|
There are multiple things you can combine to prevent spammers.
|
||||||
|
|
||||||
1. By whitelisting or blocklisting certain email domains
|
1. By only whitelisting certain domains with OpenID (see below)
|
||||||
2. By only whitelisting certain domains with OpenID (see below)
|
2. Setting `ENABLE_CAPTCHA` to `true` in your `app.ini` and properly configuring `RECAPTCHA_SECRET` and `RECAPTCHA_SITEKEY`
|
||||||
3. Setting `ENABLE_CAPTCHA` to `true` in your `app.ini` and properly configuring `RECAPTCHA_SECRET` and `RECAPTCHA_SITEKEY`
|
3. Settings `DISABLE_REGISTRATION` to `true` and creating new users via the [CLI]({{< relref "doc/usage/command-line.en-us.md" >}}), [API]({{< relref "doc/developers/api-usage.en-us.md" >}}), or Gitea's Admin UI
|
||||||
4. Settings `DISABLE_REGISTRATION` to `true` and creating new users via the [CLI]({{< relref "doc/usage/command-line.en-us.md" >}}), [API]({{< relref "doc/developers/api-usage.en-us.md" >}}), or Gitea's Admin UI
|
|
||||||
|
|
||||||
### Only allow/block certain email domains
|
### Only allow certain email domains
|
||||||
|
|
||||||
You can configure `EMAIL_DOMAIN_WHITELIST` or `EMAIL_DOMAIN_BLOCKLIST` in your app.ini under `[service]`
|
You can configure `EMAIL_DOMAIN_WHITELIST` in your app.ini under `[service]`
|
||||||
|
|
||||||
### Only allow/block certain OpenID providers
|
### Only allow/block certain OpenID providers
|
||||||
|
|
||||||
|
@ -148,7 +141,7 @@ The current way to achieve this is to create/modify a user with a max repo creat
|
||||||
|
|
||||||
Restricted users are limited to a subset of the content based on their organization/team memberships and collaborations, ignoring the public flag on organizations/repos etc.\_\_
|
Restricted users are limited to a subset of the content based on their organization/team memberships and collaborations, ignoring the public flag on organizations/repos etc.\_\_
|
||||||
|
|
||||||
Example use case: A company runs a Gitea instance that requires login. Most repos are public (accessible/browsable by all co-workers).
|
Example use case: A company runs a Gitea instance that requires login. Most repos are public (accessible/browseable by all co-workers).
|
||||||
|
|
||||||
At some point, a customer or third party needs access to a specific repo and only that repo. Making such a customer account restricted and granting any needed access using team membership(s) and/or collaboration(s) is a simple way to achieve that without the need to make everything private.
|
At some point, a customer or third party needs access to a specific repo and only that repo. Making such a customer account restricted and granting any needed access using team membership(s) and/or collaboration(s) is a simple way to achieve that without the need to make everything private.
|
||||||
|
|
||||||
|
@ -331,12 +324,6 @@ is too small. Gitea requires that the `ROWFORMAT` for its tables is `DYNAMIC`.
|
||||||
If you are receiving an error line containing `Error 1071: Specified key was too long; max key length is 1000 bytes...`
|
If you are receiving an error line containing `Error 1071: Specified key was too long; max key length is 1000 bytes...`
|
||||||
then you are attempting to run Gitea on tables which use the ISAM engine. While this may have worked by chance in previous versions of Gitea, it has never been officially supported and
|
then you are attempting to run Gitea on tables which use the ISAM engine. While this may have worked by chance in previous versions of Gitea, it has never been officially supported and
|
||||||
you must use InnoDB. You should run `ALTER TABLE table_name ENGINE=InnoDB;` for each table in the database.
|
you must use InnoDB. You should run `ALTER TABLE table_name ENGINE=InnoDB;` for each table in the database.
|
||||||
If you are using MySQL 5, another possible fix is
|
|
||||||
```mysql
|
|
||||||
SET GLOBAL innodb_file_format=Barracuda;
|
|
||||||
SET GLOBAL innodb_file_per_table=1;
|
|
||||||
SET GLOBAL innodb_large_prefix=1;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Why Are Emoji Broken On MySQL
|
## Why Are Emoji Broken On MySQL
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue