Merge branch 'gitea-master' into dev

# Conflicts:
#	Makefile
#	README.md
#	package-lock.json
#	routers/user/home.go
master
ByteList 2019-11-06 11:58:17 +01:00
commit a7751f01d5
5025 changed files with 689911 additions and 148894 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,4 @@
# http://editorconfig.org # http://editorconfig.org
root = true root = true
[*] [*]
@ -15,11 +14,11 @@ indent_size = 8
indent_style = tab indent_style = tab
indent_size = 4 indent_size = 4
[*.{less}] [*.less]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
[*.{yml}] [*.{yml,json}]
indent_style = space indent_style = space
indent_size = 2 indent_size = 2

27
.eslintrc 100644
View File

@ -0,0 +1,27 @@
root: true
extends:
- eslint:recommended
parserOptions:
ecmaVersion: 2015
env:
browser: true
jquery: true
es6: true
globals:
Clipboard: false
CodeMirror: false
emojify: false
SimpleMDE: false
Vue: false
Dropzone: false
u2fApi: false
hljs: false
rules:
no-unused-vars: [error, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}]
prefer-const: [2, {destructuring: all}]
no-var: [2]

1
.github/FUNDING.yml vendored 100644
View File

@ -0,0 +1 @@
open_collective: gitea

View File

@ -1,7 +1,9 @@
<!-- NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue -->
<!-- <!--
1. Please speak English, this is the language all of us can speak and write. 1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord 2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/NsatcWJ) or forum (https://discourse.gitea.io). server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Please take a moment to check that your issue doesn't already exist. 3. Please take a moment to check that your issue doesn't already exist.
4. Please give all relevant information below for bug reports, because 4. Please give all relevant information below for bug reports, because
incomplete details will be handled as an invalid report. incomplete details will be handled as an invalid report.

9
.gitignore vendored
View File

@ -12,6 +12,7 @@ _test
# MS VSCode # MS VSCode
.vscode .vscode
__debug_bin
# Architecture specific extensions/prefixes # Architecture specific extensions/prefixes
*.[568vq] *.[568vq]
@ -51,18 +52,23 @@ coverage.all
/log /log
/public/img/avatar /public/img/avatar
/integrations/gitea-integration-mysql /integrations/gitea-integration-mysql
/integrations/gitea-integration-mysql8
/integrations/gitea-integration-pgsql /integrations/gitea-integration-pgsql
/integrations/gitea-integration-sqlite /integrations/gitea-integration-sqlite
/integrations/gitea-integration-mssql /integrations/gitea-integration-mssql
/integrations/indexers-mysql /integrations/indexers-mysql
/integrations/indexers-mysql8
/integrations/indexers-pgsql /integrations/indexers-pgsql
/integrations/indexers-sqlite /integrations/indexers-sqlite
/integrations/indexers-mssql /integrations/indexers-mssql
/integrations/mysql.ini /integrations/mysql.ini
/integrations/mysql8.ini
/integrations/pgsql.ini /integrations/pgsql.ini
/integrations/mssql.ini /integrations/mssql.ini
/node_modules /node_modules
/modules/indexer/issues/indexers
routers/repo/authorized_keys
/yarn.lock
# Snapcraft # Snapcraft
snap/.snapcraft/ snap/.snapcraft/
@ -72,3 +78,4 @@ prime/
*.snap *.snap
*.snap-build *.snap-build
*_source.tar.bz2 *_source.tar.bz2
.DS_Store

97
.golangci.yml 100644
View File

@ -0,0 +1,97 @@
linters:
enable:
- gosimple
- deadcode
- typecheck
- govet
- errcheck
- staticcheck
- unused
- structcheck
- varcheck
- golint
- dupl
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
- gofmt
- misspell
- gocritic
enable-all: false
disable-all: true
fast: false
run:
timeout: 3m
linters-settings:
gocritic:
disabled-checks:
- ifElseChain
- singleCaseSwitch # Every time this occured in the code, there was no other way.
issues:
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- unparam
- staticcheck
- path: models/migrations/v
linters:
- gocyclo
- errcheck
- dupl
- gosec
- linters:
- dupl
text: "webhook"
- linters:
- gocritic
text: "`ID' should not be capitalized"
- path: modules/templates/helper.go
linters:
- gocritic
- linters:
- unused
- deadcode
text: "swagger"
- path: contrib/pr/checkout.go
linters:
- errcheck
- path: models/issue.go
linters:
- errcheck
- path: models/migrations/
linters:
- errcheck
- path: modules/log/
linters:
- errcheck
- path: routers/routes/routes.go
linters:
- dupl
- path: routers/api/v1/repo/issue_subscription.go
linters:
- dupl
- path: routers/repo/view.go
linters:
- dupl
- path: models/migrations/
linters:
- unused
- linters:
- staticcheck
text: "argument x is overwritten before first use"
- path: modules/httplib/httplib.go
linters:
- staticcheck
# Enabling this would require refactoring the methods and how they are called.
- path: models/issue_comment_list.go
linters:
- dupl
- linters:
- misspell
text: '`Unknwon` is a misspelling of `Unknown`'

1
.npmrc 100644
View File

@ -0,0 +1 @@
save-exact=true

11
.stylelintrc 100644
View File

@ -0,0 +1,11 @@
extends: stylelint-config-standard
rules:
block-closing-brace-empty-line-before: null
color-hex-length: null
comment-empty-line-before: null
declaration-empty-line-before: null
indentation: 4
no-descending-specificity: null
rule-empty-line-before: null
selector-pseudo-element-colon-notation: null

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,8 @@
- [Translation](#translation) - [Translation](#translation)
- [Code review](#code-review) - [Code review](#code-review)
- [Styleguide](#styleguide) - [Styleguide](#styleguide)
- [Sign-off your work](#sign-off-your-work) - [Design guideline](#design-guideline)
- [Developer Certificate of Origin (DCO)](#developer-certificate-of-origin-dco)
- [Release Cycle](#release-cycle) - [Release Cycle](#release-cycle)
- [Maintainers](#maintainers) - [Maintainers](#maintainers)
- [Owners](#owners) - [Owners](#owners)
@ -64,20 +65,33 @@ high-level discussions.
## Testing redux ## Testing redux
Before sending code out for review, run all the tests for the Before submitting a pull request, run all the tests for the whole tree
whole tree to make sure the changes don't break other usage to make sure your changes don't cause regression elsewhere.
and keep the compatibility on upgrade. To make sure you are
running the test suite exactly like we do, you should install Here's how to run the test suite:
the CLI for [Drone CI](https://github.com/drone/drone), as
we are using the server for continuous testing, following [these - Install the correct version of the drone-cli package. As of this
instructions](http://docs.drone.io/cli-installation/). After that, writing, the correct drone-cli version is
you can simply call `drone exec --local --build-event "pull_request"` within [1.2.0](https://docs.drone.io/cli/install/).
your working directory and it will try to run the test suite locally. - Ensure you have enough free disk space. You will need at least
15-20 Gb of free disk space to hold all of the containers drone
creates (a default AWS or GCE disk size won't work -- see
[#6243](https://github.com/go-gitea/gitea/issues/6243)).
- Change into the base directory of your copy of the gitea repository,
and run `drone exec --event pull_request`.
- At the moment `drone exec` doesn't support the Docker Toolbox on Windows 10
(see [drone-cli#135](https://github.com/drone/drone-cli/issues/135))
The drone version, command line, and disk requirements do change over
time (see [#4053](https://github.com/go-gitea/gitea/issues/4053) and
[#6243](https://github.com/go-gitea/gitea/issues/6243)); if you
discover any issues, please feel free to send us a pull request to
update these instructions.
## Vendoring ## Vendoring
We keep a cached copy of dependencies within the `vendor/` directory, We keep a cached copy of dependencies within the `vendor/` directory,
managing updates via [dep](https://github.com/golang/dep). managing updates via [Modules](https://golang.org/cmd/go/#hdr-Module_maintenance).
Pull requests should only include `vendor/` updates if they are part of Pull requests should only include `vendor/` updates if they are part of
the same change, be it a bugfix or a feature addition. the same change, be it a bugfix or a feature addition.
@ -86,7 +100,7 @@ The `vendor/` update needs to be justified as part of the PR description,
and must be verified by the reviewers and/or merger to always reference and must be verified by the reviewers and/or merger to always reference
an existing upstream commit. an existing upstream commit.
You can find more information on how to get started with it on the [dep project website](https://golang.github.io/dep/docs/introduction.html). You can find more information on how to get started with it on the [Modules Wiki](https://github.com/golang/go/wiki/Modules).
## Translation ## Translation
@ -102,11 +116,13 @@ included in the next released version.
Generally, the go build tools are installed as-needed in the `Makefile`. Generally, the go build tools are installed as-needed in the `Makefile`.
An exception are the tools to build the CSS and images. An exception are the tools to build the CSS and images.
- To build CSS: Install [Node.js](https://nodejs.org/en/download/package-manager) - To build CSS: Install [Node.js](https://nodejs.org/en/download/package-manager) at version 8.0 or above
with `npm` and then run `npm install` and `make generate-stylesheets`. with `npm` and then run `npm install` and `make css`.
- To build Images: ImageMagick, inkscape and zopflipng binaries must be - To build Images: ImageMagick, inkscape and zopflipng binaries must be
available in your `PATH` to run `make generate-images`. available in your `PATH` to run `make generate-images`.
For more details on how to generate files, build and test Gitea, see the [hacking instructions](https://docs.gitea.io/en-us/hacking-on-gitea/)
## Code review ## Code review
Changes to Gitea must be reviewed before they are accepted—no matter who Changes to Gitea must be reviewed before they are accepted—no matter who
@ -146,22 +162,37 @@ import (
) )
``` ```
## Sign-off your work ## Design guideline
The sign-off is a simple line at the end of the explanation for the To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The gitea code is divided into the following parts:
patch. Your signature certifies that you wrote the patch or otherwise
have the right to pass it on as an open-source patch. The rules are - **integration:** Integrations tests
pretty simple: If you can certify [DCO](DCO), then you just add a line - **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependecies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
to every git commit message: - **models/fixtures:** Sample model data used in integration tests.
- **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step.
- **modules:** Different modules to handle specific functionality in Gitea.
- **public:** Frontend files (javascript, images, css, etc.)
- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers
- **services:** Support functions for common routing operations. Uses models and modules to handle the request.
- **templates:** Golang templates for generating the html output.
- **vendor:** External code that Gitea depends on.
## Developer Certificate of Origin (DCO)
We consider the act of contributing to the code by submitting a Pull
Request as the "Sign off" or agreement to the certifications and terms
of the [DCO](DCO) and [MIT license](LICENSE). No further action is required.
Additionally you could add a line at the end of your commit message.
``` ```
Signed-off-by: Joe Smith <joe.smith@email.com> Signed-off-by: Joe Smith <joe.smith@email.com>
``` ```
Please use your real name; we really dislike pseudonyms or anonymous If you set your `user.name` and `user.email` git configs, you can add the
contributions. We are in the open-source world without secrets. If you line to the end of your commit automatically with `git commit -s`.
set your `user.name` and `user.email` git configs, you can sign-off your
commit automatically with `git commit -s`. We assume in good faith that the information you provide is legally binding.
## Release Cycle ## Release Cycle
@ -273,7 +304,7 @@ be reviewed by two maintainers and must pass the automatic tests.
* Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`. * Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`.
* And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically created a release and upload all the compiled binary. (But currently it didn't add the release notes automatically. Maybe we should fix that.) * And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically created a release and upload all the compiled binary. (But currently it didn't add the release notes automatically. Maybe we should fix that.)
* If needed send PR for changelog on branch `master`. * If needed send PR for changelog on branch `master`.
* Send PR to [blog repository](https://github.com/go-gitea/blog) announcing the release. * Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release.
## Copyright ## Copyright

View File

@ -1,7 +1,10 @@
################################### ###################################
#Build stage #Build stage
FROM golang:1.11-alpine3.8 AS build-env FROM golang:1.13-alpine3.10 AS build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
ARG GITEA_VERSION ARG GITEA_VERSION
ARG TAGS="sqlite sqlite_unlock_notify" ARG TAGS="sqlite sqlite_unlock_notify"
@ -18,7 +21,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 generate build && make clean generate build
FROM alpine:3.8 FROM alpine:3.10
LABEL maintainer="maintainers@gitea.io" LABEL maintainer="maintainers@gitea.io"
EXPOSE 22 3000 EXPOSE 22 3000
@ -56,6 +59,6 @@ VOLUME ["/data"]
ENTRYPOINT ["/usr/bin/entrypoint"] ENTRYPOINT ["/usr/bin/entrypoint"]
CMD ["/bin/s6-svscan", "/etc/s6"] CMD ["/bin/s6-svscan", "/etc/s6"]
COPY docker / 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
RUN ln -s /app/gitea/gitea /usr/local/bin/gitea RUN ln -s /app/gitea/gitea /usr/local/bin/gitea

1226
Gopkg.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
ignored = ["google.golang.org/appengine*"]
[prune]
go-tests = true
unused-packages = true
non-go = true
[[constraint]]
branch = "master"
name = "code.gitea.io/git"
[[constraint]]
branch = "master"
name = "code.gitea.io/sdk"
[[constraint]]
# branch = "master"
revision = "c74e08f039e56cef576e4336382b2a2d12d9e026"
name = "github.com/blevesearch/bleve"
#Not targetting v0.7.0 since standard where use only just after this tag
[[constraint]]
revision = "12dd70caea0268ac0d6c2707d0611ef601e7c64e"
name = "golang.org/x/crypto"
[[constraint]]
branch = "master"
name = "golang.org/x/sys"
[[constraint]]
revision = "2bf8f2a19ec09c670e931282edfe6567f6be21c9"
name = "golang.org/x/text"
[[constraint]]
branch = "master"
name = "golang.org/x/net"
[[override]]
name = "github.com/go-xorm/xorm"
revision = "a6300f2a45e05a8f75f00a1d6188049fe7851915"
[[override]]
name = "github.com/go-xorm/builder"
version = "0.3.3"
[[override]]
name = "github.com/go-sql-driver/mysql"
revision = "c45f530f8e7fe40f4687eaa50d0c8c5f1b66f9e0"
[[override]]
name = "github.com/mattn/go-sqlite3"
revision = "c7c4067b79cc51e6dfdcef5c702e74b1e0fa7c75"
[[override]]
name = "github.com/gorilla/mux"
revision = "757bef944d0f21880861c2dd9c871ca543023cba"
[[constraint]]
name = "github.com/gorilla/context"
version = "1.1.1"
[[constraint]]
name = "github.com/lafriks/xormstore"
version = "1.0.0"
[[constraint]]
branch = "master"
name = "github.com/lunny/dingtalk_webhook"
[[constraint]]
name = "github.com/markbates/goth"
version = "1.47.2"
[[constraint]]
branch = "master"
name = "github.com/mcuadros/go-version"
[[constraint]]
branch = "master"
name = "github.com/russross/blackfriday"
[[constraint]]
branch = "master"
name = "github.com/tstranex/u2f"
[[constraint]]
name = "gopkg.in/editorconfig/editorconfig-core-go.v1"
version = "1.2.0"
[[constraint]]
branch = "v2"
name = "gopkg.in/gomail.v2"
[[constraint]]
name = "gopkg.in/ini.v1"
version = "1.31.1"
[[constraint]]
name = "gopkg.in/ldap.v2"
version = "2.4.1"
[[constraint]]
name = "gopkg.in/macaron.v1"
version = "1.2.4"
[[constraint]]
name = "gopkg.in/testfixtures.v2"
version = "2.0.0"
[[override]]
name = "github.com/boltdb/bolt"
revision = "ccd680d8c1a0179ac3d68f692b01e1a1589cbfc7"
source = "github.com/go-gitea/bolt"
[[override]]
branch = "master"
name = "golang.org/x/oauth2"
[[constraint]]
name = "github.com/prometheus/client_golang"
version = "0.9.0"

View File

@ -26,3 +26,12 @@ Lanre Adelowo <yo@lanre.wtf> (@adelowo)
Konrad Langenberg <k@knt.li> (@kolaente) Konrad Langenberg <k@knt.li> (@kolaente)
He-Long Zhang <outman99@hotmail.com> (@BetaCat0) He-Long Zhang <outman99@hotmail.com> (@BetaCat0)
Andrew Thornton <art27@cantab.net> (@zeripath) Andrew Thornton <art27@cantab.net> (@zeripath)
John Olheiser <john.olheiser@gmail.com> (@jolheiser)
Richard Mahn <rich.mahn@unfoldingword.org> (@richmahn)
Mrsdizzie <info@mrsdizzie.com> (@mrsdizzie)
silverwind <me@silverwind.io> (@silverwind)
Gary Kim <gary@garykim.dev> (@gary-kim)
Guillermo Prandi <gitea.maint@mailfilter.com.ar> (@guillep2k)
Mura Li <typeless@ctli.io> (@typeless)
6543 <6543@obermui.de> (@6543)
jaqra <jaqra@hotmail.com> (@jaqra)

312
Makefile
View File

@ -1,13 +1,17 @@
DIST := dist DIST := dist
IMPORT := code.gitea.io/gitea IMPORT := code.gitea.io/gitea
export GO111MODULE=off
GO ?= go GO ?= go
SED_INPLACE := sed -i SED_INPLACE := sed -i
SHASUM ?= shasum -a 256
export PATH := $($(GO) env GOPATH)/bin:$(PATH)
ifeq ($(OS), Windows_NT) ifeq ($(OS), Windows_NT)
EXECUTABLE := gitea.exe EXECUTABLE ?= gitea.exe
else else
EXECUTABLE := gitea EXECUTABLE ?= gitea
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin) ifeq ($(UNAME_S),Darwin)
SED_INPLACE := sed -i '' SED_INPLACE := sed -i ''
@ -18,12 +22,14 @@ BINDATA := modules/{options,public,templates}/bindata.go
GOFILES := $(shell find . -name "*.go" -type f ! -path "./vendor/*" ! -path "*/bindata.go") GOFILES := $(shell find . -name "*.go" -type f ! -path "./vendor/*" ! -path "*/bindata.go")
GOFMT ?= gofmt -s GOFMT ?= gofmt -s
GOFLAGS := -i -v GOFLAGS := -v
EXTRA_GOFLAGS ?= EXTRA_GOFLAGS ?=
MAKE_VERSION := $(shell make -v | head -n 1)
ifneq ($(DRONE_TAG),) ifneq ($(DRONE_TAG),)
VERSION ?= $(subst v,,$(DRONE_TAG)) VERSION ?= $(subst v,,$(DRONE_TAG))
GITEA_VERSION := $(VERSION) GITEA_VERSION ?= $(VERSION)
else else
ifneq ($(DRONE_BRANCH),) ifneq ($(DRONE_BRANCH),)
VERSION ?= $(subst release/v,,$(DRONE_BRANCH)) VERSION ?= $(subst release/v,,$(DRONE_BRANCH))
@ -34,23 +40,30 @@ else
GITEA_VERSION := wse:$(shell git describe --tags --always | sed 's/^v//' | cut -d"-" -f4) GITEA_VERSION := wse:$(shell git describe --tags --always | sed 's/^v//' | cut -d"-" -f4)
endif endif
LDFLAGS := -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)"
PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(filter-out code.gitea.io/gitea/integrations,$(shell $(GO) list ./... | grep -v /vendor/))) PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(filter-out code.gitea.io/gitea/integrations,$(shell GO111MODULE=on $(GO) list -mod=vendor ./... | grep -v /vendor/)))
SOURCES ?= $(shell find . -name "*.go" -type f) SOURCES ?= $(shell find . -name "*.go" -type f)
TAGS ?= TAGS ?=
TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'gitea-temp') TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'gitea-temp')
#To update swagger use: GO111MODULE=on go get -u github.com/go-swagger/go-swagger/cmd/swagger@v0.20.1
SWAGGER := GO111MODULE=on $(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":\s*"/api/v1"|"basePath": "{{AppSubUrl}}/api/v1"|g SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl}}/api/v1"|g
SWAGGER_SPEC_S_JSON := s|"basePath":\s*"{{AppSubUrl}}/api/v1"|"basePath": "/api/v1"|g SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl}}/api/v1"|"basePath": "/api/v1"|g
SWAGGER_NEWLINE_COMMAND := -e '$$a\'
TEST_MYSQL_HOST ?= mysql:3306 TEST_MYSQL_HOST ?= mysql:3306
TEST_MYSQL_DBNAME ?= testgitea TEST_MYSQL_DBNAME ?= testgitea
TEST_MYSQL_USERNAME ?= root TEST_MYSQL_USERNAME ?= root
TEST_MYSQL_PASSWORD ?= TEST_MYSQL_PASSWORD ?=
TEST_MYSQL8_HOST ?= mysql8:3306
TEST_MYSQL8_DBNAME ?= testgitea
TEST_MYSQL8_USERNAME ?= root
TEST_MYSQL8_PASSWORD ?=
TEST_PGSQL_HOST ?= pgsql:5432 TEST_PGSQL_HOST ?= pgsql:5432
TEST_PGSQL_DBNAME ?= testgitea TEST_PGSQL_DBNAME ?= testgitea
TEST_PGSQL_USERNAME ?= postgres TEST_PGSQL_USERNAME ?= postgres
@ -60,12 +73,6 @@ TEST_MSSQL_DBNAME ?= gitea
TEST_MSSQL_USERNAME ?= sa TEST_MSSQL_USERNAME ?= sa
TEST_MSSQL_PASSWORD ?= MwantsaSecurePassword1 TEST_MSSQL_PASSWORD ?= MwantsaSecurePassword1
ifeq ($(OS), Windows_NT)
EXECUTABLE := gitea.exe
else
EXECUTABLE := gitea
endif
# $(call strip-suffix,filename) # $(call strip-suffix,filename)
strip-suffix = $(firstword $(subst ., ,$(1))) strip-suffix = $(firstword $(subst ., ,$(1)))
@ -79,9 +86,9 @@ clean:
$(GO) clean -i ./... $(GO) clean -i ./...
rm -rf $(EXECUTABLE) $(DIST) $(BINDATA) \ rm -rf $(EXECUTABLE) $(DIST) $(BINDATA) \
integrations*.test \ integrations*.test \
integrations/gitea-integration-pgsql/ integrations/gitea-integration-mysql/ integrations/gitea-integration-sqlite/ integrations/gitea-integration-mssql/ \ integrations/gitea-integration-pgsql/ integrations/gitea-integration-mysql/ integrations/gitea-integration-mysql8/ integrations/gitea-integration-sqlite/ \
integrations/indexers-mysql/ integrations/indexers-pgsql integrations/indexers-sqlite integrations/indexers-mssql \ integrations/gitea-integration-mssql/ integrations/indexers-mysql/ integrations/indexers-mysql8/ integrations/indexers-pgsql integrations/indexers-sqlite \
integrations/mysql.ini integrations/pgsql.ini integrations/mssql.ini integrations/indexers-mssql integrations/mysql.ini integrations/mysql8.ini integrations/pgsql.ini integrations/mssql.ini
.PHONY: fmt .PHONY: fmt
fmt: fmt:
@ -93,18 +100,13 @@ vet:
.PHONY: generate .PHONY: generate
generate: generate:
@hash go-bindata > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ GO111MODULE=on $(GO) generate -mod=vendor $(PACKAGES)
$(GO) get -u github.com/jteeuwen/go-bindata/go-bindata; \
fi
$(GO) generate $(PACKAGES)
.PHONY: generate-swagger .PHONY: generate-swagger
generate-swagger: generate-swagger:
@hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ $(SWAGGER) generate spec -o './$(SWAGGER_SPEC)'
$(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \
fi
swagger generate spec -o './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
$(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)'
.PHONY: swagger-check .PHONY: swagger-check
swagger-check: generate-swagger swagger-check: generate-swagger
@ -117,11 +119,8 @@ swagger-check: generate-swagger
.PHONY: swagger-validate .PHONY: swagger-validate
swagger-validate: swagger-validate:
@hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \
fi
$(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)'
swagger validate './$(SWAGGER_SPEC)' $(SWAGGER) validate './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
.PHONY: errcheck .PHONY: errcheck
@ -133,6 +132,10 @@ errcheck:
.PHONY: lint .PHONY: lint
lint: lint:
@echo 'make lint is depricated. Use "make revive" if you want to use the old lint tool, or "make golangci-lint" to run a complete code check.'
.PHONY: revive
revive:
@hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/mgechev/revive; \ $(GO) get -u github.com/mgechev/revive; \
fi fi
@ -143,7 +146,7 @@ misspell-check:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/client9/misspell/cmd/misspell; \ $(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi fi
misspell -error -i unknwon $(GOFILES) misspell -error -i unknwon,destory $(GOFILES)
.PHONY: misspell .PHONY: misspell
misspell: misspell:
@ -164,7 +167,11 @@ fmt-check:
.PHONY: test .PHONY: test
test: test:
$(GO) test -tags='sqlite sqlite_unlock_notify' $(PACKAGES) GO111MODULE=on $(GO) test -mod=vendor -tags='sqlite sqlite_unlock_notify' $(PACKAGES)
.PHONY: test\#%
test\#%:
GO111MODULE=on $(GO) test -mod=vendor -tags='sqlite sqlite_unlock_notify' -run $* $(PACKAGES)
.PHONY: coverage .PHONY: coverage
coverage: coverage:
@ -175,14 +182,11 @@ coverage:
.PHONY: unit-test-coverage .PHONY: unit-test-coverage
unit-test-coverage: unit-test-coverage:
for PKG in $(PACKAGES); do $(GO) test -tags='sqlite sqlite_unlock_notify' -cover -coverprofile $$GOPATH/src/$$PKG/coverage.out $$PKG || exit 1; done; $(GO) test -tags='sqlite sqlite_unlock_notify' -cover -coverprofile coverage.out $(PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
.PHONY: vendor .PHONY: vendor
vendor: vendor:
@hash dep > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ GO111MODULE=on $(GO) mod tidy && GO111MODULE=on $(GO) mod vendor
$(GO) get -u github.com/golang/dep/cmd/dep; \
fi
dep ensure -vendor-only
.PHONY: test-vendor .PHONY: test-vendor
test-vendor: vendor test-vendor: vendor
@ -192,57 +196,97 @@ test-vendor: vendor
echo "$${diff}"; \ echo "$${diff}"; \
exit 1; \ exit 1; \
fi; fi;
#TODO add dep status -missing when implemented
.PHONY: test-sqlite .PHONY: test-sqlite
test-sqlite: integrations.sqlite.test test-sqlite: integrations.sqlite.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test
.PHONY: test-sqlite\#%
test-sqlite\#%: integrations.sqlite.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test -test.run $*
.PHONY: test-sqlite-migration .PHONY: test-sqlite-migration
test-sqlite-migration: migrations.sqlite.test test-sqlite-migration: migrations.sqlite.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./migrations.sqlite.test GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./migrations.sqlite.test
generate-ini: generate-ini-mysql:
sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \ sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \
-e 's|{{TEST_MYSQL_DBNAME}}|${TEST_MYSQL_DBNAME}|g' \ -e 's|{{TEST_MYSQL_DBNAME}}|${TEST_MYSQL_DBNAME}|g' \
-e 's|{{TEST_MYSQL_USERNAME}}|${TEST_MYSQL_USERNAME}|g' \ -e 's|{{TEST_MYSQL_USERNAME}}|${TEST_MYSQL_USERNAME}|g' \
-e 's|{{TEST_MYSQL_PASSWORD}}|${TEST_MYSQL_PASSWORD}|g' \ -e 's|{{TEST_MYSQL_PASSWORD}}|${TEST_MYSQL_PASSWORD}|g' \
integrations/mysql.ini.tmpl > integrations/mysql.ini integrations/mysql.ini.tmpl > integrations/mysql.ini
.PHONY: test-mysql
test-mysql: integrations.mysql.test generate-ini-mysql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test
.PHONY: test-mysql\#%
test-mysql\#%: integrations.mysql.test generate-ini-mysql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test -test.run $*
.PHONY: test-mysql-migration
test-mysql-migration: migrations.mysql.test generate-ini-mysql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./migrations.mysql.test
generate-ini-mysql8:
sed -e 's|{{TEST_MYSQL8_HOST}}|${TEST_MYSQL8_HOST}|g' \
-e 's|{{TEST_MYSQL8_DBNAME}}|${TEST_MYSQL8_DBNAME}|g' \
-e 's|{{TEST_MYSQL8_USERNAME}}|${TEST_MYSQL8_USERNAME}|g' \
-e 's|{{TEST_MYSQL8_PASSWORD}}|${TEST_MYSQL8_PASSWORD}|g' \
integrations/mysql8.ini.tmpl > integrations/mysql8.ini
.PHONY: test-mysql8
test-mysql8: integrations.mysql8.test generate-ini-mysql8
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql8.ini ./integrations.mysql8.test
.PHONY: test-mysql8\#%
test-mysql8\#%: integrations.mysql8.test generate-ini-mysql8
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql8.ini ./integrations.mysql8.test -test.run $*
.PHONY: test-mysql8-migration
test-mysql8-migration: migrations.mysql8.test generate-ini-mysql8
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql8.ini ./migrations.mysql8.test
generate-ini-pgsql:
sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \ sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \
-e 's|{{TEST_PGSQL_DBNAME}}|${TEST_PGSQL_DBNAME}|g' \ -e 's|{{TEST_PGSQL_DBNAME}}|${TEST_PGSQL_DBNAME}|g' \
-e 's|{{TEST_PGSQL_USERNAME}}|${TEST_PGSQL_USERNAME}|g' \ -e 's|{{TEST_PGSQL_USERNAME}}|${TEST_PGSQL_USERNAME}|g' \
-e 's|{{TEST_PGSQL_PASSWORD}}|${TEST_PGSQL_PASSWORD}|g' \ -e 's|{{TEST_PGSQL_PASSWORD}}|${TEST_PGSQL_PASSWORD}|g' \
integrations/pgsql.ini.tmpl > integrations/pgsql.ini integrations/pgsql.ini.tmpl > integrations/pgsql.ini
.PHONY: test-pgsql
test-pgsql: integrations.pgsql.test generate-ini-pgsql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test
.PHONY: test-pgsql\#%
test-pgsql\#%: integrations.pgsql.test generate-ini-pgsql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test -test.run $*
.PHONY: test-pgsql-migration
test-pgsql-migration: migrations.pgsql.test generate-ini-pgsql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./migrations.pgsql.test
generate-ini-mssql:
sed -e 's|{{TEST_MSSQL_HOST}}|${TEST_MSSQL_HOST}|g' \ sed -e 's|{{TEST_MSSQL_HOST}}|${TEST_MSSQL_HOST}|g' \
-e 's|{{TEST_MSSQL_DBNAME}}|${TEST_MSSQL_DBNAME}|g' \ -e 's|{{TEST_MSSQL_DBNAME}}|${TEST_MSSQL_DBNAME}|g' \
-e 's|{{TEST_MSSQL_USERNAME}}|${TEST_MSSQL_USERNAME}|g' \ -e 's|{{TEST_MSSQL_USERNAME}}|${TEST_MSSQL_USERNAME}|g' \
-e 's|{{TEST_MSSQL_PASSWORD}}|${TEST_MSSQL_PASSWORD}|g' \ -e 's|{{TEST_MSSQL_PASSWORD}}|${TEST_MSSQL_PASSWORD}|g' \
integrations/mssql.ini.tmpl > integrations/mssql.ini integrations/mssql.ini.tmpl > integrations/mssql.ini
.PHONY: test-mysql
test-mysql: integrations.test generate-ini
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.test
.PHONY: test-mysql-migration
test-mysql-migration: migrations.test generate-ini
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./migrations.test
.PHONY: test-pgsql
test-pgsql: integrations.test generate-ini
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.test
.PHONY: test-pgsql-migration
test-pgsql-migration: migrations.test generate-ini
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./migrations.test
.PHONY: test-mssql .PHONY: test-mssql
test-mssql: integrations.test generate-ini test-mssql: integrations.mssql.test generate-ini-mssql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mssql.ini ./integrations.test GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mssql.ini ./integrations.mssql.test
.PHONY: test-mssql\#%
test-mssql\#%: integrations.mssql.test generate-ini-mssql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mssql.ini ./integrations.mssql.test -test.run $*
.PHONY: test-mssql-migration .PHONY: test-mssql-migration
test-mssql-migration: migrations.test generate-ini test-mssql-migration: migrations.mssql.test generate-ini-mssql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mssql.ini ./migrations.test GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mssql.ini ./migrations.mssql.test
.PHONY: bench-sqlite .PHONY: bench-sqlite
@ -250,30 +294,55 @@ bench-sqlite: integrations.sqlite.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
.PHONY: bench-mysql .PHONY: bench-mysql
bench-mysql: integrations.test generate-ini bench-mysql: integrations.mysql.test generate-ini-mysql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
.PHONY: bench-mssql
bench-mssql: integrations.mssql.test generate-ini-mssql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mssql.ini ./integrations.mssql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
.PHONY: bench-pgsql .PHONY: bench-pgsql
bench-pgsql: integrations.test generate-ini bench-pgsql: integrations.pgsql.test generate-ini-pgsql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
.PHONY: integration-test-coverage .PHONY: integration-test-coverage
integration-test-coverage: integrations.cover.test generate-ini integration-test-coverage: integrations.cover.test generate-ini-mysql
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out
integrations.test: $(SOURCES) integrations.mysql.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations -o integrations.test GO111MODULE=on $(GO) test -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mysql.test
integrations.mysql8.test: $(SOURCES)
GO111MODULE=on $(GO) test -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mysql8.test
integrations.pgsql.test: $(SOURCES)
GO111MODULE=on $(GO) test -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.pgsql.test
integrations.mssql.test: $(SOURCES)
GO111MODULE=on $(GO) test -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mssql.test
integrations.sqlite.test: $(SOURCES) integrations.sqlite.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags 'sqlite sqlite_unlock_notify' GO111MODULE=on $(GO) test -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags 'sqlite sqlite_unlock_notify'
integrations.cover.test: $(SOURCES) integrations.cover.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(PACKAGES) | tr ' ' ',') -o integrations.cover.test GO111MODULE=on $(GO) test -mod=vendor -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(PACKAGES) | tr ' ' ',') -o integrations.cover.test
.PHONY: migrations.test .PHONY: migrations.mysql.test
migrations.test: $(SOURCES) migrations.mysql.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations/migration-test -o migrations.test $(GO) test -c code.gitea.io/gitea/integrations/migration-test -o migrations.mysql.test
.PHONY: migrations.mysql8.test
migrations.mysql8.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations/migration-test -o migrations.mysql8.test
.PHONY: migrations.pgsql.test
migrations.pgsql.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations/migration-test -o migrations.pgsql.test
.PHONY: migrations.mssql.test
migrations.mssql.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations/migration-test -o migrations.mssql.test
.PHONY: migrations.sqlite.test .PHONY: migrations.sqlite.test
migrations.sqlite.test: $(SOURCES) migrations.sqlite.test: $(SOURCES)
@ -290,7 +359,7 @@ install: $(wildcard *.go)
build: $(EXECUTABLE) build: $(EXECUTABLE)
$(EXECUTABLE): $(SOURCES) $(EXECUTABLE): $(SOURCES)
$(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@ GO111MODULE=on $(GO) build -mod=vendor $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
.PHONY: release .PHONY: release
release: release-dirs release-windows release-linux release-darwin release-copy release-compress release-check release: release-dirs release-windows release-linux release-darwin release-copy release-compress release-check
@ -302,68 +371,100 @@ release-dirs:
.PHONY: release-windows .PHONY: release-windows
release-windows: release-windows:
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/karalabe/xgo; \ $(GO) get -u src.techknowlogick.com/xgo; \
fi fi
xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) . xgo -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
ifeq ($(CI),drone) ifeq ($(CI),drone)
mv /build/* $(DIST)/binaries cp /build/* $(DIST)/binaries
endif endif
.PHONY: release-linux .PHONY: release-linux
release-linux: release-linux:
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/karalabe/xgo; \ $(GO) get -u src.techknowlogick.com/xgo; \
fi fi
xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/*' -out gitea-$(VERSION) . xgo -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,linux/mips64le,linux/mips,linux/mipsle' -out gitea-$(VERSION) .
ifeq ($(CI),drone) ifeq ($(CI),drone)
mv /build/* $(DIST)/binaries cp /build/* $(DIST)/binaries
endif endif
.PHONY: release-darwin .PHONY: release-darwin
release-darwin: release-darwin:
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/karalabe/xgo; \ $(GO) get -u src.techknowlogick.com/xgo; \
fi fi
xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) . xgo -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
ifeq ($(CI),drone) ifeq ($(CI),drone)
mv /build/* $(DIST)/binaries cp /build/* $(DIST)/binaries
endif endif
.PHONY: release-copy .PHONY: release-copy
release-copy: release-copy:
$(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),cp $(file) $(DIST)/release/$(notdir $(file));) cd $(DIST); for file in `find /build -type f -name "*"`; do cp $${file} ./release/; done;
.PHONY: release-check .PHONY: release-check
release-check: release-check:
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;) cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "checksumming $${file}" && $(SHASUM) `echo $${file} | sed 's/^..//'` > $${file}.sha256; done;
.PHONY: release-compress .PHONY: release-compress
release-compress: release-compress:
@hash gxz > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash gxz > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/ulikunitz/xz/cmd/gxz; \ $(GO) get -u github.com/ulikunitz/xz/cmd/gxz; \
fi fi
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),gxz -k -9 $(notdir $(file));) cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done;
.PHONY: javascripts npm-check:
javascripts: public/js/index.js @hash npm > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
echo "Please install Node.js 8.x or greater with npm"; \
exit 1; \
fi;
@hash npx > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
echo "Please install Node.js 8.x or greater with npm"; \
exit 1; \
fi;
.IGNORE: public/js/index.js .PHONY: npm
public/js/index.js: $(JAVASCRIPTS) npm: npm-check
cat $< >| $@ npm install --no-save
.PHONY: npm-update
npm-update: npm-check
npx updates -cu
rm -rf node_modules package-lock.json
npm install --package-lock
.PHONY: js
js: npm
npx eslint public/js
.PHONY: css
css: npm
npx stylelint public/less
npx lessc --clean-css="--s0 -b" public/less/index.less public/css/index.css
$(foreach file, $(filter-out public/less/themes/_base.less, $(wildcard public/less/themes/*)),npx lessc --clean-css="--s0 -b" public/less/themes/$(notdir $(file)) > public/css/theme-$(notdir $(call strip-suffix,$(file))).css;)
npx postcss --use autoprefixer --no-map --replace public/css/*
.PHONY: stylesheets-check
stylesheets-check: generate-stylesheets
@diff=$$(git diff public/css/*); \ @diff=$$(git diff public/css/*); \
if [ -n "$$diff" ]; then \ if ([ -n "$$CI" ] && [ -n "$$diff" ]); then \
echo "Please run 'make generate-stylesheets' and commit the result:"; \ echo "Generated files in public/css have changed, please commit the result:"; \
echo "$${diff}"; \ echo "$${diff}"; \
exit 1; \ exit 1; \
fi; fi;
.PHONY: javascripts
javascripts:
echo "'make javascripts' is deprecated, please use 'make js'"
$(MAKE) js
.PHONY: stylesheets-check
stylesheets-check:
echo "'make stylesheets-check' is deprecated, please use 'make css'"
$(MAKE) css
.PHONY: generate-stylesheets .PHONY: generate-stylesheets
generate-stylesheets: generate-stylesheets:
node_modules/.bin/lessc --clean-css public/less/index.less public/css/index.css echo "'make generate-stylesheets' is deprecated, please use 'make css'"
$(foreach file, $(filter-out public/less/themes/_base.less, $(wildcard public/less/themes/*)),node_modules/.bin/lessc --clean-css public/less/themes/$(notdir $(file)) > public/css/theme-$(notdir $(call strip-suffix,$(file))).css;) $(MAKE) css
.PHONY: swagger-ui .PHONY: swagger-ui
swagger-ui: swagger-ui:
@ -400,12 +501,25 @@ generate-images:
inkscape -f $(PWD)/assets/logo.svg -w 32 -h 32 -jC -i layer2 -e $(TMPDIR)/images/32-2.png inkscape -f $(PWD)/assets/logo.svg -w 32 -h 32 -jC -i layer2 -e $(TMPDIR)/images/32-2.png
composite -compose atop $(TMPDIR)/images/32-2.png $(TMPDIR)/images/32-1.png $(TMPDIR)/images/32-raw.png composite -compose atop $(TMPDIR)/images/32-2.png $(TMPDIR)/images/32-1.png $(TMPDIR)/images/32-raw.png
inkscape -f $(PWD)/assets/logo.svg -w 16 -h 16 -jC -i layer1 -e $(TMPDIR)/images/16-raw.png inkscape -f $(PWD)/assets/logo.svg -w 16 -h 16 -jC -i layer1 -e $(TMPDIR)/images/16-raw.png
zopflipng $(TMPDIR)/images/128-raw.png $(TMPDIR)/images/128.png zopflipng -m -y $(TMPDIR)/images/128-raw.png $(TMPDIR)/images/128.png
zopflipng $(TMPDIR)/images/64-raw.png $(TMPDIR)/images/64.png zopflipng -m -y $(TMPDIR)/images/64-raw.png $(TMPDIR)/images/64.png
zopflipng $(TMPDIR)/images/32-raw.png $(TMPDIR)/images/32.png zopflipng -m -y $(TMPDIR)/images/32-raw.png $(TMPDIR)/images/32.png
zopflipng $(TMPDIR)/images/16-raw.png $(TMPDIR)/images/16.png zopflipng -m -y $(TMPDIR)/images/16-raw.png $(TMPDIR)/images/16.png
rm -f $(TMPDIR)/images/*-*.png rm -f $(TMPDIR)/images/*-*.png
convert $(TMPDIR)/images/16.png $(TMPDIR)/images/32.png \ convert $(TMPDIR)/images/16.png $(TMPDIR)/images/32.png \
$(TMPDIR)/images/64.png $(TMPDIR)/images/128.png \ $(TMPDIR)/images/64.png $(TMPDIR)/images/128.png \
$(PWD)/public/img/favicon.ico $(PWD)/public/img/favicon.ico
rm -rf $(TMPDIR)/images rm -rf $(TMPDIR)/images
$(foreach file, $(shell find public/img -type f -name '*.png'),zopflipng -m -y $(file) $(file);)
.PHONY: pr
pr:
$(GO) run contrib/pr/checkout.go $(PR)
.PHONY: golangci-lint
golangci-lint:
@hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
export BINARY="golangci-lint"; \
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.20.0; \
fi
golangci-lint run --timeout 5m

View File

@ -14,3 +14,6 @@ More info: https://docs.gitea.io/en-us/install-from-source/
NOTE: If you're interested in using our APIs, we have experimental NOTE: If you're interested in using our APIs, we have experimental
support with [documentation](https://try.gitea.io/api/swagger). support with [documentation](https://try.gitea.io/api/swagger).
Updated v1.

View File

@ -1,15 +1,18 @@
[English](https://github.com/go-gitea/gitea/blob/master/README.md) [English](README.md)
# Gitea - Git with a cup of tea <h1> <img src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea-192.png" alt="logo" width="30" height="30"> Gitea - Git with a cup of tea</h1>
[![Build Status](https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg)](https://drone.gitea.io/go-gitea/gitea) [![Build Status](https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg)](https://drone.gitea.io/go-gitea/gitea)
[![Join the chat at https://img.shields.io/discord/322538954119184384.svg](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/NsatcWJ) [![Join the Discord chat at https://discord.gg/NsatcWJ](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/NsatcWJ)
[![](https://images.microbadger.com/badges/image/gitea/gitea.svg)](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/image/gitea/gitea.svg)](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
[![Coverage Status](https://coverage.gitea.io/badges/go-gitea/gitea/coverage.svg)](https://coverage.gitea.io/go-gitea/gitea) [![codecov](https://codecov.io/gh/go-gitea/gitea/branch/master/graph/badge.svg)](https://codecov.io/gh/go-gitea/gitea)
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea) [![Go Report Card](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea)
[![GoDoc](https://godoc.org/code.gitea.io/gitea?status.svg)](https://godoc.org/code.gitea.io/gitea) [![GoDoc](https://godoc.org/code.gitea.io/gitea?status.svg)](https://godoc.org/code.gitea.io/gitea)
[![GitHub release](https://img.shields.io/github/release/go-gitea/gitea.svg)](https://github.com/go-gitea/gitea/releases/latest) [![GitHub release](https://img.shields.io/github/release/go-gitea/gitea.svg)](https://github.com/go-gitea/gitea/releases/latest)
[![Become a backer/sponsor of gitea](https://opencollective.com/gitea/tiers/backer/badge.svg?label=backer&color=brightgreen)](https://opencollective.com/gitea) [![Help Contribute to Open Source](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea)
[![Become a backer/sponsor of gitea](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea)
## 目标 ## 目标
@ -25,7 +28,7 @@ Gitea 的首要目标是创建一个极易安装,运行非常快速,安装
## 文档 ## 文档
关于如何安装请访问我们的 [文档站](https://docs.gitea.io/zh-cn/),如果没有找到对应的文档,你也可以通过 [Discord - 英文](https://discord.gg/NsatcWJ) 和 QQ群 328432459 来和我们交流。 关于如何安装请访问我们的 [文档站](https://docs.gitea.io/zh-cn/),如果没有找到对应的文档,你也可以通过 [Discord - 英文](https://discord.gg/gitea) 和 QQ群 328432459 来和我们交流。
## 贡献流程 ## 贡献流程
@ -43,9 +46,8 @@ Fork -> Patch -> Push -> Pull Request
## 截图 ## 截图
| | | | |![Dashboard](https://dl.gitea.io/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.io/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.io/screenshots/global_issues.png)|
|:---:|:---:|:---:| |:---:|:---:|:---:|
|![Dashboard](https://image.ibb.co/dms6DG/1.png)|![Repository](https://image.ibb.co/m6MSLw/2.png)|![Commits History](https://image.ibb.co/cjrSLw/3.png)| |![Branches](https://dl.gitea.io/screenshots/branches.png)|![Web Editor](https://dl.gitea.io/screenshots/web_editor.png)|![Activity](https://dl.gitea.io/screenshots/activity.png)|
|![Branches](https://image.ibb.co/e6vbDG/4.png)|![Issues](https://image.ibb.co/bJTJSb/5.png)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)| |![New Migration](https://dl.gitea.io/screenshots/migration.png)|![Migrating](https://dl.gitea.io/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)
|![Releases](https://image.ibb.co/cUzgfw/7.png)|![Activity](https://image.ibb.co/eZgGDG/8.png)|![Wiki](https://image.ibb.co/dYV9YG/9.png)| ![Pull Request Dark](https://dl.gitea.io/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.io/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.io/screenshots/diff_dark.png)|
|![Diff](https://image.ibb.co/ewA9YG/10.png)|![Organization](https://image.ibb.co/ceOwDG/11.png)|![Profile](https://image.ibb.co/c44Q7b/12.png)|

View File

@ -11,11 +11,11 @@ import (
"os" "os"
"text/tabwriter" "text/tabwriter"
"code.gitea.io/git"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth/oauth2" "code.gitea.io/gitea/modules/auth/oauth2"
"code.gitea.io/gitea/modules/generate" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
pwd "code.gitea.io/gitea/modules/password"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -42,6 +42,10 @@ var (
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "name", Name: "name",
Usage: "Username. DEPRECATED: use username instead",
},
cli.StringFlag{
Name: "username",
Usage: "Username", Usage: "Username",
}, },
cli.StringFlag{ cli.StringFlag{
@ -56,24 +60,23 @@ var (
Name: "admin", Name: "admin",
Usage: "User is an admin", Usage: "User is an admin",
}, },
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
cli.BoolFlag{ cli.BoolFlag{
Name: "random-password", Name: "random-password",
Usage: "Generate a random password for the user", Usage: "Generate a random password for the user",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "must-change-password", Name: "must-change-password",
Usage: "Force the user to change his/her password after initial login", Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
}, },
cli.IntFlag{ cli.IntFlag{
Name: "random-password-length", Name: "random-password-length",
Usage: "Length of the random password to be generated", Usage: "Length of the random password to be generated",
Value: 12, Value: 12,
}, },
cli.BoolFlag{
Name: "access-token",
Usage: "Generate access token for the user",
},
}, },
} }
@ -92,11 +95,6 @@ var (
Value: "", Value: "",
Usage: "New password to set for user", Usage: "New password to set for user",
}, },
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
}, },
} }
@ -119,26 +117,12 @@ var (
Name: "hooks", Name: "hooks",
Usage: "Regenerate git-hooks", Usage: "Regenerate git-hooks",
Action: runRegenerateHooks, Action: runRegenerateHooks,
Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
},
} }
microcmdRegenKeys = cli.Command{ microcmdRegenKeys = cli.Command{
Name: "keys", Name: "keys",
Usage: "Regenerate authorized_keys file", Usage: "Regenerate authorized_keys file",
Action: runRegenerateKeys, Action: runRegenerateKeys,
Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
},
} }
subcmdAuth = cli.Command{ subcmdAuth = cli.Command{
@ -147,6 +131,10 @@ var (
Subcommands: []cli.Command{ Subcommands: []cli.Command{
microcmdAuthAddOauth, microcmdAuthAddOauth,
microcmdAuthUpdateOauth, microcmdAuthUpdateOauth,
cmdAuthAddLdapBindDn,
cmdAuthUpdateLdapBindDn,
cmdAuthAddLdapSimpleAuth,
cmdAuthUpdateLdapSimpleAuth,
microcmdAuthList, microcmdAuthList,
microcmdAuthDelete, microcmdAuthDelete,
}, },
@ -156,40 +144,20 @@ var (
Name: "list", Name: "list",
Usage: "List auth sources", Usage: "List auth sources",
Action: runListAuth, Action: runListAuth,
Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
},
} }
idFlag = cli.Int64Flag{ idFlag = cli.Int64Flag{
Name: "id", Name: "id",
Usage: "ID of OAuth authentication source", Usage: "ID of authentication source",
} }
microcmdAuthDelete = cli.Command{ microcmdAuthDelete = cli.Command{
Name: "delete", Name: "delete",
Usage: "Delete specific auth source", Usage: "Delete specific auth source",
Action: runDeleteAuth, Action: runDeleteAuth,
Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
idFlag,
},
} }
oauthCLIFlags = []cli.Flag{ oauthCLIFlags = []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
cli.StringFlag{ cli.StringFlag{
Name: "name", Name: "name",
Value: "", Value: "",
@ -262,14 +230,12 @@ func runChangePassword(c *cli.Context) error {
return err return err
} }
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
if err := initDB(); err != nil { if err := initDB(); err != nil {
return err return err
} }
if !pwd.IsComplexEnough(c.String("password")) {
return errors.New("Password does not meet complexity requirements")
}
uname := c.String("username") uname := c.String("username")
user, err := models.GetUserByName(uname) user, err := models.GetUserByName(uname)
if err != nil { if err != nil {
@ -279,6 +245,7 @@ func runChangePassword(c *cli.Context) error {
return err return err
} }
user.HashPassword(c.String("password")) user.HashPassword(c.String("password"))
if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil { if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil {
return err return err
} }
@ -288,38 +255,47 @@ func runChangePassword(c *cli.Context) error {
} }
func runCreateUser(c *cli.Context) error { func runCreateUser(c *cli.Context) error {
if err := argsSet(c, "name", "email"); err != nil { if err := argsSet(c, "email"); err != nil {
return err return err
} }
if c.IsSet("name") && c.IsSet("username") {
return errors.New("Cannot set both --name and --username flags")
}
if !c.IsSet("name") && !c.IsSet("username") {
return errors.New("One of --name or --username flags must be set")
}
if c.IsSet("password") && c.IsSet("random-password") { if c.IsSet("password") && c.IsSet("random-password") {
return errors.New("cannot set both -random-password and -password flags") return errors.New("cannot set both -random-password and -password flags")
} }
var password string var username string
if c.IsSet("username") {
if c.IsSet("password") { username = c.String("username")
password = c.String("password")
} else if c.IsSet("random-password") {
var err error
password, err = generate.GetRandomString(c.Int("random-password-length"))
if err != nil {
return err
}
fmt.Printf("generated random password is '%s'\n", password)
} else { } else {
return errors.New("must set either password or random-password flag") username = c.String("name")
} fmt.Fprintf(os.Stderr, "--name flag is deprecated. Use --username instead.\n")
if c.IsSet("config") {
setting.CustomConf = c.String("config")
} }
if err := initDB(); err != nil { if err := initDB(); err != nil {
return err return err
} }
var password string
if c.IsSet("password") {
password = c.String("password")
} else if c.IsSet("random-password") {
var err error
password, err = pwd.Generate(c.Int("random-password-length"))
if err != nil {
return err
}
fmt.Printf("generated random password is '%s'\n", password)
} else {
return errors.New("must set either password or random-password flag")
}
// always default to true // always default to true
var changePassword = true var changePassword = true
@ -333,19 +309,34 @@ func runCreateUser(c *cli.Context) error {
changePassword = c.Bool("must-change-password") changePassword = c.Bool("must-change-password")
} }
if err := models.CreateUser(&models.User{ u := &models.User{
Name: c.String("name"), Name: username,
Email: c.String("email"), Email: c.String("email"),
Passwd: password, Passwd: password,
IsActive: true, IsActive: true,
IsAdmin: c.Bool("admin"), IsAdmin: c.Bool("admin"),
MustChangePassword: changePassword, MustChangePassword: changePassword,
Theme: setting.UI.DefaultTheme, Theme: setting.UI.DefaultTheme,
}); err != nil { }
if err := models.CreateUser(u); err != nil {
return fmt.Errorf("CreateUser: %v", err) return fmt.Errorf("CreateUser: %v", err)
} }
fmt.Printf("New user '%s' has been successfully created!\n", c.String("name")) if c.Bool("access-token") {
t := &models.AccessToken{
Name: "gitea-admin",
UID: u.ID,
}
if err := models.NewAccessToken(t); err != nil {
return err
}
fmt.Printf("Access token was successfully created... %s\n", t.Token)
}
fmt.Printf("New user '%s' has been successfully created!\n", username)
return nil return nil
} }
@ -411,10 +402,6 @@ func getReleaseCount(id int64) (int64, error) {
} }
func runRegenerateHooks(c *cli.Context) error { func runRegenerateHooks(c *cli.Context) error {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
if err := initDB(); err != nil { if err := initDB(); err != nil {
return err return err
} }
@ -422,10 +409,6 @@ func runRegenerateHooks(c *cli.Context) error {
} }
func runRegenerateKeys(c *cli.Context) error { func runRegenerateKeys(c *cli.Context) error {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
if err := initDB(); err != nil { if err := initDB(); err != nil {
return err return err
} }
@ -454,10 +437,6 @@ func parseOAuth2Config(c *cli.Context) *models.OAuth2Config {
} }
func runAddOauth(c *cli.Context) error { func runAddOauth(c *cli.Context) error {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
if err := initDB(); err != nil { if err := initDB(); err != nil {
return err return err
} }
@ -471,10 +450,6 @@ func runAddOauth(c *cli.Context) error {
} }
func runUpdateOauth(c *cli.Context) error { func runUpdateOauth(c *cli.Context) error {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
if !c.IsSet("id") { if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing") return fmt.Errorf("--id flag is missing")
} }
@ -511,7 +486,7 @@ func runUpdateOauth(c *cli.Context) error {
} }
// update custom URL mapping // update custom URL mapping
var customURLMapping *oauth2.CustomURLMapping var customURLMapping = &oauth2.CustomURLMapping{}
if oAuth2Config.CustomURLMapping != nil { if oAuth2Config.CustomURLMapping != nil {
customURLMapping.TokenURL = oAuth2Config.CustomURLMapping.TokenURL customURLMapping.TokenURL = oAuth2Config.CustomURLMapping.TokenURL
@ -542,10 +517,6 @@ func runUpdateOauth(c *cli.Context) error {
} }
func runListAuth(c *cli.Context) error { func runListAuth(c *cli.Context) error {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
if err := initDB(); err != nil { if err := initDB(); err != nil {
return err return err
} }
@ -568,10 +539,6 @@ func runListAuth(c *cli.Context) error {
} }
func runDeleteAuth(c *cli.Context) error { func runDeleteAuth(c *cli.Context) error {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
if !c.IsSet("id") { if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing") return fmt.Errorf("--id flag is missing")
} }

View File

@ -0,0 +1,359 @@
// Copyright 2019 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 (
"fmt"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth/ldap"
"github.com/urfave/cli"
)
type (
authService struct {
initDB func() error
createLoginSource func(loginSource *models.LoginSource) error
updateLoginSource func(loginSource *models.LoginSource) error
getLoginSourceByID func(id int64) (*models.LoginSource, error)
}
)
var (
commonLdapCLIFlags = []cli.Flag{
cli.StringFlag{
Name: "name",
Usage: "Authentication name.",
},
cli.BoolFlag{
Name: "not-active",
Usage: "Deactivate the authentication source.",
},
cli.StringFlag{
Name: "security-protocol",
Usage: "Security protocol name.",
},
cli.BoolFlag{
Name: "skip-tls-verify",
Usage: "Disable TLS verification.",
},
cli.StringFlag{
Name: "host",
Usage: "The address where the LDAP server can be reached.",
},
cli.IntFlag{
Name: "port",
Usage: "The port to use when connecting to the LDAP server.",
},
cli.StringFlag{
Name: "user-search-base",
Usage: "The LDAP base at which user accounts will be searched for.",
},
cli.StringFlag{
Name: "user-filter",
Usage: "An LDAP filter declaring how to find the user record that is attempting to authenticate.",
},
cli.StringFlag{
Name: "admin-filter",
Usage: "An LDAP filter specifying if a user should be given administrator privileges.",
},
cli.StringFlag{
Name: "username-attribute",
Usage: "The attribute of the users LDAP record containing the user name.",
},
cli.StringFlag{
Name: "firstname-attribute",
Usage: "The attribute of the users LDAP record containing the users first name.",
},
cli.StringFlag{
Name: "surname-attribute",
Usage: "The attribute of the users LDAP record containing the users surname.",
},
cli.StringFlag{
Name: "email-attribute",
Usage: "The attribute of the users LDAP record containing the users email address.",
},
cli.StringFlag{
Name: "public-ssh-key-attribute",
Usage: "The attribute of the users LDAP record containing the users public ssh key.",
},
}
ldapBindDnCLIFlags = append(commonLdapCLIFlags,
cli.StringFlag{
Name: "bind-dn",
Usage: "The DN to bind to the LDAP server with when searching for the user.",
},
cli.StringFlag{
Name: "bind-password",
Usage: "The password for the Bind DN, if any.",
},
cli.BoolFlag{
Name: "attributes-in-bind",
Usage: "Fetch attributes in bind DN context.",
},
cli.BoolFlag{
Name: "synchronize-users",
Usage: "Enable user synchronization.",
},
cli.UintFlag{
Name: "page-size",
Usage: "Search page size.",
})
ldapSimpleAuthCLIFlags = append(commonLdapCLIFlags,
cli.StringFlag{
Name: "user-dn",
Usage: "The users DN.",
})
cmdAuthAddLdapBindDn = cli.Command{
Name: "add-ldap",
Usage: "Add new LDAP (via Bind DN) authentication source",
Action: func(c *cli.Context) error {
return newAuthService().addLdapBindDn(c)
},
Flags: ldapBindDnCLIFlags,
}
cmdAuthUpdateLdapBindDn = cli.Command{
Name: "update-ldap",
Usage: "Update existing LDAP (via Bind DN) authentication source",
Action: func(c *cli.Context) error {
return newAuthService().updateLdapBindDn(c)
},
Flags: append([]cli.Flag{idFlag}, ldapBindDnCLIFlags...),
}
cmdAuthAddLdapSimpleAuth = cli.Command{
Name: "add-ldap-simple",
Usage: "Add new LDAP (simple auth) authentication source",
Action: func(c *cli.Context) error {
return newAuthService().addLdapSimpleAuth(c)
},
Flags: ldapSimpleAuthCLIFlags,
}
cmdAuthUpdateLdapSimpleAuth = cli.Command{
Name: "update-ldap-simple",
Usage: "Update existing LDAP (simple auth) authentication source",
Action: func(c *cli.Context) error {
return newAuthService().updateLdapSimpleAuth(c)
},
Flags: append([]cli.Flag{idFlag}, ldapSimpleAuthCLIFlags...),
}
)
// newAuthService creates a service with default functions.
func newAuthService() *authService {
return &authService{
initDB: initDB,
createLoginSource: models.CreateLoginSource,
updateLoginSource: models.UpdateSource,
getLoginSourceByID: models.GetLoginSourceByID,
}
}
// parseLoginSource assigns values on loginSource according to command line flags.
func parseLoginSource(c *cli.Context, loginSource *models.LoginSource) {
if c.IsSet("name") {
loginSource.Name = c.String("name")
}
if c.IsSet("not-active") {
loginSource.IsActived = !c.Bool("not-active")
}
if c.IsSet("synchronize-users") {
loginSource.IsSyncEnabled = c.Bool("synchronize-users")
}
}
// parseLdapConfig assigns values on config according to command line flags.
func parseLdapConfig(c *cli.Context, config *models.LDAPConfig) error {
if c.IsSet("name") {
config.Source.Name = c.String("name")
}
if c.IsSet("host") {
config.Source.Host = c.String("host")
}
if c.IsSet("port") {
config.Source.Port = c.Int("port")
}
if c.IsSet("security-protocol") {
p, ok := findLdapSecurityProtocolByName(c.String("security-protocol"))
if !ok {
return fmt.Errorf("Unknown security protocol name: %s", c.String("security-protocol"))
}
config.Source.SecurityProtocol = p
}
if c.IsSet("skip-tls-verify") {
config.Source.SkipVerify = c.Bool("skip-tls-verify")
}
if c.IsSet("bind-dn") {
config.Source.BindDN = c.String("bind-dn")
}
if c.IsSet("user-dn") {
config.Source.UserDN = c.String("user-dn")
}
if c.IsSet("bind-password") {
config.Source.BindPassword = c.String("bind-password")
}
if c.IsSet("user-search-base") {
config.Source.UserBase = c.String("user-search-base")
}
if c.IsSet("username-attribute") {
config.Source.AttributeUsername = c.String("username-attribute")
}
if c.IsSet("firstname-attribute") {
config.Source.AttributeName = c.String("firstname-attribute")
}
if c.IsSet("surname-attribute") {
config.Source.AttributeSurname = c.String("surname-attribute")
}
if c.IsSet("email-attribute") {
config.Source.AttributeMail = c.String("email-attribute")
}
if c.IsSet("attributes-in-bind") {
config.Source.AttributesInBind = c.Bool("attributes-in-bind")
}
if c.IsSet("public-ssh-key-attribute") {
config.Source.AttributeSSHPublicKey = c.String("public-ssh-key-attribute")
}
if c.IsSet("page-size") {
config.Source.SearchPageSize = uint32(c.Uint("page-size"))
}
if c.IsSet("user-filter") {
config.Source.Filter = c.String("user-filter")
}
if c.IsSet("admin-filter") {
config.Source.AdminFilter = c.String("admin-filter")
}
return nil
}
// findLdapSecurityProtocolByName finds security protocol by its name ignoring case.
// It returns the value of the security protocol and if it was found.
func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
for i, n := range models.SecurityProtocolNames {
if strings.EqualFold(name, n) {
return i, true
}
}
return 0, false
}
// getLoginSource gets the login source by its id defined in the command line flags.
// It returns an error if the id is not set, does not match any source or if the source is not of expected type.
func (a *authService) getLoginSource(c *cli.Context, loginType models.LoginType) (*models.LoginSource, error) {
if err := argsSet(c, "id"); err != nil {
return nil, err
}
loginSource, err := a.getLoginSourceByID(c.Int64("id"))
if err != nil {
return nil, err
}
if loginSource.Type != loginType {
return nil, fmt.Errorf("Invalid authentication type. expected: %s, actual: %s", models.LoginNames[loginType], models.LoginNames[loginSource.Type])
}
return loginSource, nil
}
// addLdapBindDn adds a new LDAP via Bind DN authentication source.
func (a *authService) addLdapBindDn(c *cli.Context) error {
if err := argsSet(c, "name", "security-protocol", "host", "port", "user-search-base", "user-filter", "email-attribute"); err != nil {
return err
}
if err := a.initDB(); err != nil {
return err
}
loginSource := &models.LoginSource{
Type: models.LoginLDAP,
IsActived: true, // active by default
Cfg: &models.LDAPConfig{
Source: &ldap.Source{
Enabled: true, // always true
},
},
}
parseLoginSource(c, loginSource)
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
return err
}
return a.createLoginSource(loginSource)
}
// updateLdapBindDn updates a new LDAP via Bind DN authentication source.
func (a *authService) updateLdapBindDn(c *cli.Context) error {
if err := a.initDB(); err != nil {
return err
}
loginSource, err := a.getLoginSource(c, models.LoginLDAP)
if err != nil {
return err
}
parseLoginSource(c, loginSource)
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
return err
}
return a.updateLoginSource(loginSource)
}
// addLdapSimpleAuth adds a new LDAP (simple auth) authentication source.
func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
if err := argsSet(c, "name", "security-protocol", "host", "port", "user-dn", "user-filter", "email-attribute"); err != nil {
return err
}
if err := a.initDB(); err != nil {
return err
}
loginSource := &models.LoginSource{
Type: models.LoginDLDAP,
IsActived: true, // active by default
Cfg: &models.LDAPConfig{
Source: &ldap.Source{
Enabled: true, // always true
},
},
}
parseLoginSource(c, loginSource)
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
return err
}
return a.createLoginSource(loginSource)
}
// updateLdapBindDn updates a new LDAP (simple auth) authentication source.
func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
if err := a.initDB(); err != nil {
return err
}
loginSource, err := a.getLoginSource(c, models.LoginDLDAP)
if err != nil {
return err
}
parseLoginSource(c, loginSource)
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
return err
}
return a.updateLoginSource(loginSource)
}

File diff suppressed because it is too large Load Diff

View File

@ -170,17 +170,28 @@ func runCert(c *cli.Context) error {
if err != nil { if err != nil {
log.Fatalf("Failed to open cert.pem for writing: %v", err) log.Fatalf("Failed to open cert.pem for writing: %v", err)
} }
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close() if err != nil {
log.Fatalf("Failed to encode certificate: %v", err)
}
err = certOut.Close()
if err != nil {
log.Fatalf("Failed to write cert: %v", err)
}
log.Println("Written cert.pem") log.Println("Written cert.pem")
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil { if err != nil {
log.Fatalf("Failed to open key.pem for writing: %v", err) log.Fatalf("Failed to open key.pem for writing: %v", err)
} }
pem.Encode(keyOut, pemBlockForKey(priv)) err = pem.Encode(keyOut, pemBlockForKey(priv))
keyOut.Close() if err != nil {
log.Fatalf("Failed to encode key: %v", err)
}
err = keyOut.Close()
if err != nil {
log.Fatalf("Failed to write key: %v", err)
}
log.Println("Written key.pem") log.Println("Written key.pem")
return nil return nil
} }

View File

@ -38,7 +38,7 @@ func initDB() error {
func initDBDisableConsole(disableConsole bool) error { func initDBDisableConsole(disableConsole bool) error {
setting.NewContext() setting.NewContext()
models.LoadConfigs() setting.InitDBConfig()
setting.NewXORMLogService(disableConsole) setting.NewXORMLogService(disableConsole)
if err := models.SetEngine(); err != nil { if err := models.SetEngine(); err != nil {

49
cmd/convert.go 100644
View File

@ -0,0 +1,49 @@
// Copyright 2019 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 (
"fmt"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli"
)
// CmdConvert represents the available convert sub-command.
var CmdConvert = cli.Command{
Name: "convert",
Usage: "Convert the database",
Description: "A command to convert an existing MySQL database from utf8 to utf8mb4",
Action: runConvert,
}
func runConvert(ctx *cli.Context) error {
if err := initDB(); err != nil {
return err
}
log.Trace("AppPath: %s", setting.AppPath)
log.Trace("AppWorkPath: %s", setting.AppWorkPath)
log.Trace("Custom path: %s", setting.CustomPath)
log.Trace("Log path: %s", setting.LogRootPath)
setting.InitDBConfig()
if !setting.Database.UseMySQL {
fmt.Println("This command can only be used with a MySQL database")
return nil
}
if err := models.ConvertUtf8ToUtf8mb4(); err != nil {
log.Fatal("Failed to convert database from utf8 to utf8mb4: %v", err)
return err
}
fmt.Println("Converted successfully, please confirm your database's character set is now utf8mb4")
return nil
}

View File

@ -17,8 +17,8 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/cae/zip" "github.com/unknwon/cae/zip"
"github.com/Unknwon/com" "github.com/unknwon/com"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -31,12 +31,12 @@ It can be used for backup and capture Gitea server image to send to maintainer`,
Action: runDump, Action: runDump,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "config, c", Name: "file, f",
Value: "custom/conf/app.ini", Value: fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()),
Usage: "Custom configuration file path", Usage: "Name of the dump file which will be created.",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "verbose, v", Name: "verbose, V",
Usage: "Show process details", Usage: "Show process details",
}, },
cli.StringFlag{ cli.StringFlag{
@ -56,12 +56,8 @@ It can be used for backup and capture Gitea server image to send to maintainer`,
} }
func runDump(ctx *cli.Context) error { func runDump(ctx *cli.Context) error {
if ctx.IsSet("config") {
setting.CustomConf = ctx.String("config")
}
setting.NewContext() setting.NewContext()
setting.NewServices() // cannot access session settings otherwise setting.NewServices() // cannot access session settings otherwise
models.LoadConfigs()
err := models.SetEngine() err := models.SetEngine()
if err != nil { if err != nil {
@ -85,7 +81,7 @@ func runDump(ctx *cli.Context) error {
dbDump := path.Join(tmpWorkDir, "gitea-db.sql") dbDump := path.Join(tmpWorkDir, "gitea-db.sql")
fileName := fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()) fileName := ctx.String("file")
log.Printf("Packing dump files...") log.Printf("Packing dump files...")
z, err := zip.Create(fileName) z, err := zip.Create(fileName)
if err != nil { if err != nil {
@ -107,8 +103,8 @@ func runDump(ctx *cli.Context) error {
} }
targetDBType := ctx.String("database") targetDBType := ctx.String("database")
if len(targetDBType) > 0 && targetDBType != models.DbCfg.Type { if len(targetDBType) > 0 && targetDBType != setting.Database.Type {
log.Printf("Dumping database %s => %s...", models.DbCfg.Type, targetDBType) log.Printf("Dumping database %s => %s...", setting.Database.Type, targetDBType)
} else { } else {
log.Printf("Dumping database...") log.Printf("Dumping database...")
} }
@ -120,6 +116,14 @@ func runDump(ctx *cli.Context) error {
if err := z.AddFile("gitea-db.sql", dbDump); err != nil { if err := z.AddFile("gitea-db.sql", dbDump); err != nil {
log.Fatalf("Failed to include gitea-db.sql: %v", err) log.Fatalf("Failed to include gitea-db.sql: %v", err)
} }
if len(setting.CustomConf) > 0 {
log.Printf("Adding custom configuration file from %s", setting.CustomConf)
if err := z.AddFile("app.ini", setting.CustomConf); err != nil {
log.Fatalf("Failed to include specified app.ini: %v", err)
}
}
customDir, err := os.Stat(setting.CustomPath) customDir, err := os.Stat(setting.CustomPath)
if err == nil && customDir.IsDir() { if err == nil && customDir.IsDir() {
if err := z.AddDir("custom", setting.CustomPath); err != nil { if err := z.AddDir("custom", setting.CustomPath); err != nil {

View File

@ -40,8 +40,9 @@ var (
} }
microcmdGenerateLfsJwtSecret = cli.Command{ microcmdGenerateLfsJwtSecret = cli.Command{
Name: "LFS_JWT_SECRET", Name: "JWT_SECRET",
Usage: "Generate a new LFS_JWT_SECRET", Aliases: []string{"LFS_JWT_SECRET"},
Usage: "Generate a new JWT_SECRET",
Action: runGenerateLfsJwtSecret, Action: runGenerateLfsJwtSecret,
} }
@ -63,7 +64,7 @@ func runGenerateInternalToken(c *cli.Context) error {
} }
func runGenerateLfsJwtSecret(c *cli.Context) error { func runGenerateLfsJwtSecret(c *cli.Context) error {
JWTSecretBase64, err := generate.NewLfsJwtSecret() JWTSecretBase64, err := generate.NewJwtSecret()
if err != nil { if err != nil {
return err return err
} }

View File

@ -8,16 +8,14 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
"net/url" "net/http"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"code.gitea.io/git"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -28,13 +26,6 @@ var (
Name: "hook", Name: "hook",
Usage: "Delegate commands to corresponding Git hooks", Usage: "Delegate commands to corresponding Git hooks",
Description: "This should only be called by Git", Description: "This should only be called by Git",
Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
},
Subcommands: []cli.Command{ Subcommands: []cli.Command{
subcmdHookPreReceive, subcmdHookPreReceive,
subcmdHookUpdate, subcmdHookUpdate,
@ -67,21 +58,15 @@ func runHookPreReceive(c *cli.Context) error {
return nil return nil
} }
if c.IsSet("config") {
setting.CustomConf = c.String("config")
} else if c.GlobalIsSet("config") {
setting.CustomConf = c.GlobalString("config")
}
setup("hooks/pre-receive.log") setup("hooks/pre-receive.log")
// the environment setted on serv command // the environment setted on serv command
repoID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchRepoID), 10, 64)
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)
userIDStr := os.Getenv(models.EnvPusherID) userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
repoPath := models.RepoPath(username, reponame) prID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchPRID), 10, 64)
isDeployKey, _ := strconv.ParseBool(os.Getenv(models.EnvIsDeployKey))
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
scanner := bufio.NewScanner(os.Stdin) scanner := bufio.NewScanner(os.Stdin)
@ -103,34 +88,24 @@ func runHookPreReceive(c *cli.Context) error {
newCommitID := string(fields[1]) newCommitID := string(fields[1])
refFullName := string(fields[2]) refFullName := string(fields[2])
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix) // If the ref is a branch, check if it's protected
protectBranch, err := private.GetProtectedBranchBy(repoID, branchName) if strings.HasPrefix(refFullName, git.BranchPrefix) {
if err != nil { statusCode, msg := private.HookPreReceive(username, reponame, private.HookOptions{
fail("Internal error", fmt.Sprintf("retrieve protected branches information failed: %v", err)) OldCommitID: oldCommitID,
} NewCommitID: newCommitID,
RefFullName: refFullName,
if protectBranch != nil && protectBranch.IsProtected() { UserID: userID,
// check and deletion GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
if newCommitID == git.EmptySHA { GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "") GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
} ProtectedBranchID: prID,
IsDeployKey: isDeployKey,
// detect force push })
if git.EmptySHA != oldCommitID { switch statusCode {
output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).RunInDir(repoPath) case http.StatusInternalServerError:
if err != nil { fail("Internal Server Error", msg)
fail("Internal error", "Fail to detect force push: %v", err) case http.StatusForbidden:
} else if len(output) > 0 { fail(msg, "")
fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
}
}
userID, _ := strconv.ParseInt(userIDStr, 10, 64)
canPush, err := private.CanUserPush(protectBranch.ID, userID)
if err != nil {
fail("Internal error", "Fail to detect user can push: %v", err)
} else if !canPush {
fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "")
} }
} }
} }
@ -143,12 +118,6 @@ func runHookUpdate(c *cli.Context) error {
return nil return nil
} }
if c.IsSet("config") {
setting.CustomConf = c.String("config")
} else if c.GlobalIsSet("config") {
setting.CustomConf = c.GlobalString("config")
}
setup("hooks/update.log") setup("hooks/update.log")
return nil return nil
@ -159,16 +128,9 @@ func runHookPostReceive(c *cli.Context) error {
return nil return nil
} }
if c.IsSet("config") {
setting.CustomConf = c.String("config")
} else if c.GlobalIsSet("config") {
setting.CustomConf = c.GlobalString("config")
}
setup("hooks/post-receive.log") setup("hooks/post-receive.log")
// the environment setted on serv command // the environment setted on serv command
repoID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchRepoID), 10, 64)
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)
@ -195,59 +157,32 @@ func runHookPostReceive(c *cli.Context) error {
newCommitID := string(fields[1]) newCommitID := string(fields[1])
refFullName := string(fields[2]) refFullName := string(fields[2])
if err := private.PushUpdate(models.PushUpdateOptions{ res, err := private.HookPostReceive(repoUser, repoName, private.HookOptions{
RefFullName: refFullName,
OldCommitID: oldCommitID, OldCommitID: oldCommitID,
NewCommitID: newCommitID, NewCommitID: newCommitID,
PusherID: pusherID, RefFullName: refFullName,
PusherName: pusherName, UserID: pusherID,
RepoUserName: repoUser, UserName: pusherName,
RepoName: repoName, })
}); err != nil {
log.GitLogger.Error(2, "Update: %v", err) if res == nil {
fail("Internal Server Error", err)
} }
if newCommitID != git.EmptySHA && strings.HasPrefix(refFullName, git.BranchPrefix) { if res["message"] == false {
branch := strings.TrimPrefix(refFullName, git.BranchPrefix) continue
repo, pullRequestAllowed, err := private.GetRepository(repoID)
if err != nil {
log.GitLogger.Error(2, "get repo: %v", err)
break
}
if !pullRequestAllowed {
break
}
baseRepo := repo
if repo.IsFork {
baseRepo = repo.BaseRepo
}
if !repo.IsFork && branch == baseRepo.DefaultBranch {
break
}
pr, err := private.ActivePullRequest(baseRepo.ID, repo.ID, baseRepo.DefaultBranch, branch)
if err != nil {
log.GitLogger.Error(2, "get active pr: %v", err)
break
} }
fmt.Fprintln(os.Stderr, "") fmt.Fprintln(os.Stderr, "")
if pr == nil { if res["create"] == true {
if repo.IsFork { fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", res["branch"])
branch = fmt.Sprintf("%s:%s", repo.OwnerName, branch) fmt.Fprintf(os.Stderr, " %s\n", res["url"])
}
fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", branch)
fmt.Fprintf(os.Stderr, " %s/compare/%s...%s\n", baseRepo.HTMLURL(), url.QueryEscape(baseRepo.DefaultBranch), url.QueryEscape(branch))
} else { } else {
fmt.Fprint(os.Stderr, "Visit the existing pull request:\n") fmt.Fprint(os.Stderr, "Visit the existing pull request:\n")
fmt.Fprintf(os.Stderr, " %s/pulls/%d\n", baseRepo.HTMLURL(), pr.Index) fmt.Fprintf(os.Stderr, " %s\n", res["url"])
} }
fmt.Fprintln(os.Stderr, "") fmt.Fprintln(os.Stderr, "")
} }
}
return nil return nil
} }

View File

@ -10,7 +10,6 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -41,19 +40,10 @@ var CmdKeys = cli.Command{
Value: "", Value: "",
Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)", Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
}, },
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
}, },
} }
func runKeys(c *cli.Context) error { func runKeys(c *cli.Context) error {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
if !c.IsSet("username") { if !c.IsSet("username") {
return errors.New("No username provided") return errors.New("No username provided")
} }

View File

@ -19,20 +19,9 @@ var CmdMigrate = cli.Command{
Usage: "Migrate the database", Usage: "Migrate the database",
Description: "This is a command for migrating the database, so that you can run gitea admin create-user before starting the server.", Description: "This is a command for migrating the database, so that you can run gitea admin create-user before starting the server.",
Action: runMigrate, Action: runMigrate,
Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
},
} }
func runMigrate(ctx *cli.Context) error { func runMigrate(ctx *cli.Context) error {
if ctx.IsSet("config") {
setting.CustomConf = ctx.String("config")
}
if err := initDB(); err != nil { if err := initDB(); err != nil {
return err return err
} }
@ -41,10 +30,10 @@ func runMigrate(ctx *cli.Context) error {
log.Trace("AppWorkPath: %s", setting.AppWorkPath) log.Trace("AppWorkPath: %s", setting.AppWorkPath)
log.Trace("Custom path: %s", setting.CustomPath) log.Trace("Custom path: %s", setting.CustomPath)
log.Trace("Log path: %s", setting.LogRootPath) log.Trace("Log path: %s", setting.LogRootPath)
models.LoadConfigs() setting.InitDBConfig()
if err := models.NewEngine(migrations.Migrate); err != nil { if err := models.NewEngine(migrations.Migrate); err != nil {
log.Fatal(4, "Failed to initialize ORM engine: %v", err) log.Fatal("Failed to initialize ORM engine: %v", err)
return err return err
} }

View File

@ -8,27 +8,26 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http"
"net/url"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "strconv"
"strings" "strings"
"time" "time"
"code.gitea.io/git"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"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"
"github.com/Unknwon/com"
"github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go"
version "github.com/mcuadros/go-version" "github.com/unknwon/com"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
const ( const (
accessDenied = "Repository does not exist or you do not have access"
lfsAuthenticateVerb = "git-lfs-authenticate" lfsAuthenticateVerb = "git-lfs-authenticate"
) )
@ -39,40 +38,15 @@ var CmdServ = cli.Command{
Description: `Serv provide access auth for repositories`, Description: `Serv provide access auth for repositories`,
Action: runServ, Action: runServ,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
cli.BoolFlag{ cli.BoolFlag{
Name: "enable-pprof", Name: "enable-pprof",
}, },
}, },
} }
func checkLFSVersion() {
if setting.LFS.StartServer {
//Disable LFS client hooks if installed for the current OS user
//Needs at least git v2.1.2
binVersion, err := git.BinVersion()
if err != nil {
fail(fmt.Sprintf("Error retrieving git version: %v", err), fmt.Sprintf("Error retrieving git version: %v", err))
}
if !version.Compare(binVersion, "2.1.2", ">=") {
setting.LFS.StartServer = false
println("LFS server support needs at least Git v2.1.2, disabled")
} else {
git.GlobalCommandArgs = append(git.GlobalCommandArgs, "-c", "filter.lfs.required=",
"-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
}
}
}
func setup(logPath string) { func setup(logPath string) {
_ = log.DelLogger("console")
setting.NewContext() setting.NewContext()
checkLFSVersion()
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
} }
func parseCmd(cmd string) (string, string) { func parseCmd(cmd string) (string, string) {
@ -99,18 +73,13 @@ func fail(userMessage, logMessage string, args ...interface{}) {
if !setting.ProdMode { if !setting.ProdMode {
fmt.Fprintf(os.Stderr, logMessage+"\n", args...) fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
} }
log.GitLogger.Fatal(3, logMessage, args...)
return
} }
log.GitLogger.Close()
os.Exit(1) os.Exit(1)
} }
func runServ(c *cli.Context) error { func runServ(c *cli.Context) error {
if c.IsSet("config") { // FIXME: This needs to internationalised
setting.CustomConf = c.String("config")
}
setup("serv.log") setup("serv.log")
if setting.SSH.Disabled { if setting.SSH.Disabled {
@ -119,13 +88,29 @@ func runServ(c *cli.Context) error {
} }
if len(c.Args()) < 1 { if len(c.Args()) < 1 {
cli.ShowSubcommandHelp(c) if err := cli.ShowSubcommandHelp(c); err != nil {
fmt.Printf("error showing subcommand help: %v\n", err)
}
return nil return nil
} }
keys := strings.Split(c.Args()[0], "-")
if len(keys) != 2 || keys[0] != "key" {
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
}
keyID := com.StrTo(keys[1]).MustInt64()
cmd := os.Getenv("SSH_ORIGINAL_COMMAND") cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if len(cmd) == 0 { if len(cmd) == 0 {
println("Hi there, You've successfully authenticated, but Gitea does not provide shell access.") key, user, err := private.ServNoCommand(keyID)
if err != nil {
fail("Internal error", "Failed to check provided key: %v", err)
}
if key.Type == models.KeyTypeDeploy {
println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.")
} else {
println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.")
}
println("If this is unexpected, please log in with password and setup Gitea under another user.") println("If this is unexpected, please log in with password and setup Gitea under another user.")
return nil return nil
} }
@ -159,39 +144,17 @@ func runServ(c *cli.Context) error {
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 := pprof.DumpCPUProfileForUsername(setting.PprofDataPath, username) stopCPUProfiler, err := pprof.DumpCPUProfileForUsername(setting.PprofDataPath, username)
if err != nil {
fail("Internal Server Error", "Unable to start CPU profile: %v", err)
}
defer func() { defer func() {
stopCPUProfiler() stopCPUProfiler()
pprof.DumpMemProfileForUsername(setting.PprofDataPath, username) err := pprof.DumpMemProfileForUsername(setting.PprofDataPath, username)
}()
}
var (
isWiki bool
unitType = models.UnitTypeCode
unitName = "code"
)
if strings.HasSuffix(reponame, ".wiki") {
isWiki = true
unitType = models.UnitTypeWiki
unitName = "wiki"
reponame = reponame[:len(reponame)-5]
}
os.Setenv(models.EnvRepoUsername, username)
if isWiki {
os.Setenv(models.EnvRepoIsWiki, "true")
} else {
os.Setenv(models.EnvRepoIsWiki, "false")
}
os.Setenv(models.EnvRepoName, reponame)
repo, err := private.GetRepositoryByOwnerAndName(username, reponame)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "Failed to get repository: repository does not exist") { fail("Internal Server Error", "Unable to dump Mem Profile: %v", err)
fail(accessDenied, "Repository does not exist: %s/%s", username, reponame)
} }
fail("Internal error", "Failed to get repository: %v", err) }()
} }
requestedMode, has := allowedCommands[verb] requestedMode, has := allowedCommands[verb]
@ -209,90 +172,39 @@ func runServ(c *cli.Context) error {
} }
} }
// Prohibit push to mirror repositories. results, err := private.ServCommand(keyID, username, reponame, requestedMode, verb, lfsVerb)
if requestedMode > models.AccessModeRead && repo.IsMirror {
fail("mirror repository is read-only", "")
}
// Allow anonymous clone for public repositories.
var (
keyID int64
user *models.User
)
if requestedMode == models.AccessModeWrite || repo.IsPrivate || setting.Service.RequireSignInView {
keys := strings.Split(c.Args()[0], "-")
if len(keys) != 2 {
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
}
key, err := private.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
if err != nil { if err != nil {
fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err) if private.IsErrServCommand(err) {
} errServCommand := err.(private.ErrServCommand)
keyID = key.ID if errServCommand.StatusCode != http.StatusInternalServerError {
fail("Unauthorized", "%s", errServCommand.Error())
// Check deploy key or user key.
if key.Type == models.KeyTypeDeploy {
if key.Mode < requestedMode {
fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
}
// Check if this deploy key belongs to current repository.
has, err := private.HasDeployKey(key.ID, repo.ID)
if err != nil {
fail("Key access denied", "Failed to access internal api: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
}
if !has {
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
}
// Update deploy key activity.
if err = private.UpdateDeployKeyUpdated(key.ID, repo.ID); err != nil {
fail("Internal error", "UpdateDeployKey: %v", err)
}
} else { } else {
user, err = private.GetUserByKeyID(key.ID) fail("Internal Server Error", "%s", errServCommand.Error())
if err != nil {
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
}
if !user.IsActive || user.ProhibitLogin {
fail("Your account is not active or has been disabled by Administrator",
"User %s is disabled and have no access to repository %s",
user.Name, repoPath)
}
mode, err := private.CheckUnitUser(user.ID, repo.ID, user.IsAdmin, unitType)
if err != nil {
fail("Internal error", "Failed to check access: %v", err)
} else if *mode < requestedMode {
clientMessage := accessDenied
if *mode >= models.AccessModeRead {
clientMessage = "You do not have sufficient authorization for this action"
}
fail(clientMessage,
"User %s does not have level %v access to repository %s's "+unitName,
user.Name, requestedMode, repoPath)
}
os.Setenv(models.EnvPusherName, user.Name)
os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", user.ID))
} }
} }
fail("Internal Server Error", "%s", err.Error())
}
os.Setenv(models.EnvRepoIsWiki, strconv.FormatBool(results.IsWiki))
os.Setenv(models.EnvRepoName, results.RepoName)
os.Setenv(models.EnvRepoUsername, results.OwnerName)
os.Setenv(models.EnvPusherName, results.UserName)
os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
os.Setenv(models.ProtectedBranchRepoID, strconv.FormatInt(results.RepoID, 10))
os.Setenv(models.ProtectedBranchPRID, fmt.Sprintf("%d", 0))
os.Setenv(models.EnvIsDeployKey, fmt.Sprintf("%t", results.IsDeployKey))
os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID))
//LFS token authentication //LFS token authentication
if verb == lfsAuthenticateVerb { if verb == lfsAuthenticateVerb {
url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, username, repo.Name) url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, url.PathEscape(results.OwnerName), url.PathEscape(results.RepoName))
now := time.Now() now := time.Now()
claims := jwt.MapClaims{ claims := jwt.MapClaims{
"repo": repo.ID, "repo": results.RepoID,
"op": lfsVerb, "op": lfsVerb,
"exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(), "exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
"nbf": now.Unix(), "nbf": now.Unix(),
} "user": results.UserID,
if user != nil {
claims["user"] = user.ID
} }
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
@ -313,7 +225,6 @@ func runServ(c *cli.Context) error {
if err != nil { if err != nil {
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
} }
@ -329,13 +240,6 @@ func runServ(c *cli.Context) error {
} else { } else {
gitcmd = exec.Command(verb, repoPath) gitcmd = exec.Command(verb, repoPath)
} }
if isWiki {
if err = private.InitWiki(repo.ID); err != nil {
fail("Internal error", "Failed to init wiki repo: %v", err)
}
}
os.Setenv(models.ProtectedBranchRepoID, fmt.Sprintf("%d", repo.ID))
gitcmd.Dir = setting.RepoRootPath gitcmd.Dir = setting.RepoRootPath
gitcmd.Stdout = os.Stdout gitcmd.Stdout = os.Stdout
@ -346,9 +250,9 @@ func runServ(c *cli.Context) error {
} }
// Update user key activity. // Update user key activity.
if keyID > 0 { if results.KeyID > 0 {
if err = private.UpdatePublicKeyUpdated(keyID); err != nil { if err = private.UpdatePublicKeyInRepo(results.KeyID, results.RepoID); err != nil {
fail("Internal error", "UpdatePublicKey: %v", err) fail("Internal error", "UpdatePublicKeyInRepo: %v", err)
} }
} }

View File

@ -5,7 +5,6 @@
package cmd package cmd
import ( import (
"crypto/tls"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
@ -14,14 +13,14 @@ import (
"os" "os"
"strings" "strings"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup/external"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers" "code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/routes" "code.gitea.io/gitea/routers/routes"
"github.com/Unknwon/com"
context2 "github.com/gorilla/context" context2 "github.com/gorilla/context"
"github.com/unknwon/com"
"github.com/urfave/cli" "github.com/urfave/cli"
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
ini "gopkg.in/ini.v1" ini "gopkg.in/ini.v1"
@ -40,11 +39,6 @@ and it takes care of all the other things for you`,
Value: "3000", Value: "3000",
Usage: "Temporary port number to prevent conflict", Usage: "Temporary port number to prevent conflict",
}, },
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path",
},
cli.StringFlag{ cli.StringFlag{
Name: "pid, P", Name: "pid, P",
Value: "/var/run/gitea.pid", Value: "/var/run/gitea.pid",
@ -69,7 +63,7 @@ func runHTTPRedirector() {
var err = runHTTP(source, context2.ClearHandler(handler)) var err = runHTTP(source, context2.ClearHandler(handler))
if err != nil { if err != nil {
log.Fatal(4, "Failed to start port redirection: %v", err) log.Fatal("Failed to start port redirection: %v", err)
} }
} }
@ -82,19 +76,13 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
} }
go func() { go func() {
log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect) log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
var err = http.ListenAndServe(setting.HTTPAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler))) // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here) // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here)
var err = runHTTP(setting.HTTPAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)))
if err != nil { if err != nil {
log.Fatal(4, "Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err) log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err)
} }
}() }()
server := &http.Server{ return runHTTPSWithTLSConfig(listenAddr, certManager.TLSConfig(), context2.ClearHandler(m))
Addr: listenAddr,
Handler: m,
TLSConfig: &tls.Config{
GetCertificate: certManager.GetCertificate,
},
}
return server.ListenAndServeTLS("", "")
} }
func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) { func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
@ -110,18 +98,21 @@ func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
} }
func runWeb(ctx *cli.Context) error { func runWeb(ctx *cli.Context) error {
if ctx.IsSet("config") { if os.Getppid() > 1 && len(os.Getenv("LISTEN_FDS")) > 0 {
setting.CustomConf = ctx.String("config") log.Info("Restarting Gitea on PID: %d from parent PID: %d", os.Getpid(), os.Getppid())
} else {
log.Info("Starting Gitea on PID: %d", os.Getpid())
} }
// Set pid file setting
if ctx.IsSet("pid") { if ctx.IsSet("pid") {
setting.CustomPID = ctx.String("pid") setting.CustomPID = ctx.String("pid")
} }
// Perform global initialization
routers.GlobalInit() routers.GlobalInit()
external.RegisterParsers() // Set up Macaron
m := routes.NewMacaron() m := routes.NewMacaron()
routes.RegisterRoutes(m) routes.RegisterRoutes(m)
@ -179,6 +170,7 @@ func runWeb(ctx *cli.Context) error {
var err error var err error
switch setting.Protocol { switch setting.Protocol {
case setting.HTTP: case setting.HTTP:
NoHTTPRedirector()
err = runHTTP(listenAddr, context2.ClearHandler(m)) err = runHTTP(listenAddr, context2.ClearHandler(m))
case setting.HTTPS: case setting.HTTPS:
if setting.EnableLetsEncrypt { if setting.EnableLetsEncrypt {
@ -187,18 +179,33 @@ func runWeb(ctx *cli.Context) error {
} }
if setting.RedirectOtherPort { if setting.RedirectOtherPort {
go runHTTPRedirector() go runHTTPRedirector()
} else {
NoHTTPRedirector()
} }
err = runHTTPS(listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m)) err = runHTTPS(listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
case setting.FCGI: case setting.FCGI:
listener, err := net.Listen("tcp", listenAddr) NoHTTPRedirector()
// FCGI listeners are provided as stdin - this is orthogonal to the LISTEN_FDS approach
// in graceful and systemD
NoMainListener()
var listener net.Listener
listener, err = net.Listen("tcp", listenAddr)
if err != nil { if err != nil {
log.Fatal(4, "Failed to bind %s", listenAddr, err) log.Fatal("Failed to bind %s: %v", listenAddr, err)
} }
defer listener.Close() defer func() {
if err := listener.Close(); err != nil {
log.Fatal("Failed to stop server: %v", err)
}
}()
err = fcgi.Serve(listener, context2.ClearHandler(m)) err = fcgi.Serve(listener, context2.ClearHandler(m))
case setting.UnixSocket: case setting.UnixSocket:
// This could potentially be inherited using LISTEN_FDS but currently
// these cannot be inherited
NoHTTPRedirector()
NoMainListener()
if err := os.Remove(listenAddr); err != nil && !os.IsNotExist(err) { if err := os.Remove(listenAddr); err != nil && !os.IsNotExist(err) {
log.Fatal(4, "Failed to remove unix socket directory %s: %v", listenAddr, err) log.Fatal("Failed to remove unix socket directory %s: %v", listenAddr, err)
} }
var listener *net.UnixListener var listener *net.UnixListener
listener, err = net.ListenUnix("unix", &net.UnixAddr{Name: listenAddr, Net: "unix"}) listener, err = net.ListenUnix("unix", &net.UnixAddr{Name: listenAddr, Net: "unix"})
@ -209,16 +216,18 @@ func runWeb(ctx *cli.Context) error {
// FIXME: add proper implementation of signal capture on all protocols // FIXME: add proper implementation of signal capture on all protocols
// execute this on SIGTERM or SIGINT: listener.Close() // execute this on SIGTERM or SIGINT: listener.Close()
if err = os.Chmod(listenAddr, os.FileMode(setting.UnixSocketPermission)); err != nil { if err = os.Chmod(listenAddr, os.FileMode(setting.UnixSocketPermission)); err != nil {
log.Fatal(4, "Failed to set permission of unix socket: %v", err) log.Fatal("Failed to set permission of unix socket: %v", err)
} }
err = http.Serve(listener, context2.ClearHandler(m)) err = http.Serve(listener, context2.ClearHandler(m))
default: default:
log.Fatal(4, "Invalid protocol: %s", setting.Protocol) log.Fatal("Invalid protocol: %s", setting.Protocol)
} }
if err != nil { if err != nil {
log.Fatal(4, "Failed to start server: %v", err) log.Critical("Failed to start server: %v", err)
} }
log.Info("HTTP Listener: %s Closed", listenAddr)
graceful.WaitForServers()
log.Close()
return nil return nil
} }

View File

@ -10,36 +10,28 @@ import (
"crypto/tls" "crypto/tls"
"net/http" "net/http"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/graceful"
"github.com/facebookgo/grace/gracehttp"
) )
func runHTTP(listenAddr string, m http.Handler) error { func runHTTP(listenAddr string, m http.Handler) error {
return gracehttp.Serve(&http.Server{ return graceful.HTTPListenAndServe("tcp", listenAddr, m)
Addr: listenAddr,
Handler: m,
})
} }
func runHTTPS(listenAddr, certFile, keyFile string, m http.Handler) error { func runHTTPS(listenAddr, certFile, keyFile string, m http.Handler) error {
config := &tls.Config{ return graceful.HTTPListenAndServeTLS("tcp", listenAddr, certFile, keyFile, m)
MinVersion: tls.VersionTLS10, }
}
if config.NextProtos == nil { func runHTTPSWithTLSConfig(listenAddr string, tlsConfig *tls.Config, m http.Handler) error {
config.NextProtos = []string{"http/1.1"} return graceful.HTTPListenAndServeTLSConfig("tcp", listenAddr, tlsConfig, m)
} }
config.Certificates = make([]tls.Certificate, 1) // NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector
var err error func NoHTTPRedirector() {
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile) graceful.InformCleanup()
if err != nil { }
log.Fatal(4, "Failed to load https cert file %s: %v", listenAddr, err)
} // NoMainListener tells our cleanup routine that we will not be using a possibly provided listener
// for our main HTTP/HTTPS service
return gracehttp.Serve(&http.Server{ func NoMainListener() {
Addr: listenAddr, graceful.InformCleanup()
Handler: m,
TLSConfig: config,
})
} }

View File

@ -7,6 +7,7 @@
package cmd package cmd
import ( import (
"crypto/tls"
"net/http" "net/http"
) )
@ -17,3 +18,20 @@ func runHTTP(listenAddr string, m http.Handler) error {
func runHTTPS(listenAddr, certFile, keyFile string, m http.Handler) error { func runHTTPS(listenAddr, certFile, keyFile string, m http.Handler) error {
return http.ListenAndServeTLS(listenAddr, certFile, keyFile, m) return http.ListenAndServeTLS(listenAddr, certFile, keyFile, m)
} }
func runHTTPSWithTLSConfig(listenAddr string, tlsConfig *tls.Config, m http.Handler) error {
server := &http.Server{
Addr: listenAddr,
Handler: m,
TLSConfig: tlsConfig,
}
return server.ListenAndServeTLS("", "")
}
// NoHTTPRedirector is a no-op on Windows
func NoHTTPRedirector() {
}
// NoMainListener is a no-op on Windows
func NoMainListener() {
}

View File

@ -0,0 +1,42 @@
#!/bin/bash
########################################################################
# This script some defaults for gitea to run in a FHS compliant manner #
########################################################################
# It assumes that you place this script as gitea in /usr/bin
#
# And place the original in /usr/lib/gitea with working files in /var/lib/gitea
# and main configuration in /etc/gitea/app.ini
GITEA="/usr/lib/gitea/gitea"
WORK_DIR="/var/lib/gitea"
APP_INI="/etc/gitea/app.ini"
APP_INI_SET=""
for i in "$@"; do
case "$i" in
"-c")
APP_INI_SET=1
;;
"-c="*)
APP_INI_SET=1
;;
"--config")
APP_INI_SET=1
;;
"--config="*)
APP_INI_SET=1
;;
*)
;;
esac
done
if [ -z "$APP_INI_SET" ]; then
CONF_ARG="-c \"$APP_INI\""
fi
# Provide FHS compliant defaults to
GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" "$GITEA" $CONF_ARG "$@"

View File

@ -0,0 +1,264 @@
package main
/*
Checkout a PR and load the tests data into sqlite database
*/
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"os/exec"
"os/user"
"path"
"path/filepath"
"runtime"
"strconv"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/external"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/routes"
context2 "github.com/gorilla/context"
"github.com/unknwon/com"
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/config"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/testfixtures.v2"
"xorm.io/xorm"
)
var codeFilePath = "contrib/pr/checkout.go"
func runPR() {
log.Printf("[PR] Starting gitea ...\n")
curDir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
setting.SetCustomPathAndConf("", "", "")
setting.NewContext()
setting.RepoRootPath, err = ioutil.TempDir(os.TempDir(), "repos")
if err != nil {
log.Fatalf("TempDir: %v\n", err)
}
setting.AppDataPath, err = ioutil.TempDir(os.TempDir(), "appdata")
if err != nil {
log.Fatalf("TempDir: %v\n", err)
}
setting.AppWorkPath = curDir
setting.StaticRootPath = curDir
setting.GravatarSourceURL, err = url.Parse("https://secure.gravatar.com/avatar/")
if err != nil {
log.Fatalf("url.Parse: %v\n", err)
}
setting.AppURL = "http://localhost:8080/"
setting.HTTPPort = "8080"
setting.SSH.Domain = "localhost"
setting.SSH.Port = 3000
setting.InstallLock = true
setting.SecretKey = "9pCviYTWSb"
setting.InternalToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTI3OTU5ODN9.OQkH5UmzID2XBdwQ9TAI6Jj2t1X-wElVTjbE7aoN4I8"
curUser, err := user.Current()
if err != nil {
log.Fatal(err)
}
setting.RunUser = curUser.Username
log.Printf("[PR] Loading fixtures data ...\n")
setting.CheckLFSVersion()
//models.LoadConfigs()
/*
setting.Database.Type = "sqlite3"
setting.Database.Path = ":memory:"
setting.Database.Timeout = 500
*/
db := setting.Cfg.Section("database")
db.NewKey("DB_TYPE", "sqlite3")
db.NewKey("PATH", ":memory:")
routers.NewServices()
setting.Database.LogSQL = true
//x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
var helper testfixtures.Helper = &testfixtures.SQLite{}
models.NewEngine(func(_ *xorm.Engine) error {
return nil
})
models.HasEngine = true
//x.ShowSQL(true)
err = models.InitFixtures(
helper,
path.Join(curDir, "models/fixtures/"),
)
if err != nil {
fmt.Printf("Error initializing test database: %v\n", err)
os.Exit(1)
}
models.LoadFixtures()
os.RemoveAll(setting.RepoRootPath)
os.RemoveAll(models.LocalCopyPath())
com.CopyDir(path.Join(curDir, "integrations/gitea-repositories-meta"), setting.RepoRootPath)
log.Printf("[PR] Setting up router\n")
//routers.GlobalInit()
external.RegisterParsers()
markup.Init()
m := routes.NewMacaron()
routes.RegisterRoutes(m)
log.Printf("[PR] Ready for testing !\n")
log.Printf("[PR] Login with user1, user2, user3, ... with pass: password\n")
/*
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
if setting.LFS.StartServer {
log.Info("LFS server enabled")
}
if setting.EnablePprof {
go func() {
log.Info("Starting pprof server on localhost:6060")
log.Info("%v", http.ListenAndServe("localhost:6060", nil))
}()
}
*/
//Start the server
http.ListenAndServe(":8080", context2.ClearHandler(m))
log.Printf("[PR] Cleaning up ...\n")
/*
if err = os.RemoveAll(setting.Indexer.IssuePath); err != nil {
fmt.Printf("os.RemoveAll: %v\n", err)
os.Exit(1)
}
if err = os.RemoveAll(setting.Indexer.RepoPath); err != nil {
fmt.Printf("Unable to remove repo indexer: %v\n", err)
os.Exit(1)
}
*/
if err = os.RemoveAll(setting.RepoRootPath); err != nil {
log.Fatalf("os.RemoveAll: %v\n", err)
}
if err = os.RemoveAll(setting.AppDataPath); err != nil {
log.Fatalf("os.RemoveAll: %v\n", err)
}
}
func main() {
var runPRFlag = flag.Bool("run", false, "Run the PR code")
flag.Parse()
if *runPRFlag {
runPR()
return
}
// To force checkout (e.g. Windows complains about unclean work tree) set env variable FORCE=true
force, err := strconv.ParseBool(os.Getenv("FORCE"))
if err != nil {
force = false
}
//Otherwise checkout PR
if len(os.Args) != 2 {
log.Fatal("Need only one arg: the PR number")
}
pr := os.Args[1]
codeFilePath = filepath.FromSlash(codeFilePath) //Convert to running OS
//Copy this file if it will not exist in the PR branch
dat, err := ioutil.ReadFile(codeFilePath)
if err != nil {
log.Fatalf("Failed to cache this code file : %v", err)
}
repo, err := git.PlainOpen(".")
if err != nil {
log.Fatalf("Failed to open the repo : %v", err)
}
//Find remote upstream
remotes, err := repo.Remotes()
if err != nil {
log.Fatalf("Failed to list remotes of repo : %v", err)
}
remoteUpstream := "origin" //Default
for _, r := range remotes {
if r.Config().URLs[0] == "https://github.com/go-gitea/gitea" || r.Config().URLs[0] == "git@github.com:go-gitea/gitea.git" { //fetch at index 0
remoteUpstream = r.Config().Name
break
}
}
branch := fmt.Sprintf("pr-%s-%d", pr, time.Now().Unix())
branchRef := plumbing.NewBranchReferenceName(branch)
log.Printf("Fetching PR #%s in %s\n", pr, branch)
if runtime.GOOS == "windows" {
//Use git cli command for windows
runCmd("git", "fetch", remoteUpstream, fmt.Sprintf("pull/%s/head:%s", pr, branch))
} else {
ref := fmt.Sprintf("refs/pull/%s/head:%s", pr, branchRef)
err = repo.Fetch(&git.FetchOptions{
RemoteName: remoteUpstream,
RefSpecs: []config.RefSpec{
config.RefSpec(ref),
},
})
if err != nil {
log.Fatalf("Failed to fetch %s from %s : %v", ref, remoteUpstream, err)
}
}
tree, err := repo.Worktree()
if err != nil {
log.Fatalf("Failed to parse git tree : %v", err)
}
log.Printf("Checkout PR #%s in %s\n", pr, branch)
err = tree.Checkout(&git.CheckoutOptions{
Branch: branchRef,
Force: force,
})
if err != nil {
log.Fatalf("Failed to checkout %s : %v", branch, err)
}
//Copy this file if not exist
if _, err := os.Stat(codeFilePath); os.IsNotExist(err) {
err = os.MkdirAll(filepath.Dir(codeFilePath), 0755)
if err != nil {
log.Fatalf("Failed to duplicate this code file in PR : %v", err)
}
err = ioutil.WriteFile(codeFilePath, dat, 0644)
if err != nil {
log.Fatalf("Failed to duplicate this code file in PR : %v", err)
}
}
time.Sleep(5 * time.Second)
//Start with integration test
runCmd("go", "run", "-tags", "sqlite sqlite_unlock_notify", codeFilePath, "-run")
}
func runCmd(cmd ...string) {
log.Printf("Executing : %s ...\n", cmd)
c := exec.Command(cmd[0], cmd[1:]...)
c.Stdout = os.Stdout
c.Stderr = os.Stderr
if err := c.Start(); err != nil {
log.Panicln(err)
}
if err := c.Wait(); err != nil {
log.Panicln(err)
}
}

View File

@ -2,11 +2,42 @@
Description=Gitea (Git with a cup of tea) 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 requirements
###
#
#Requires=mysql.service #Requires=mysql.service
#Requires=mariadb.service #Requires=mariadb.service
#Requires=postgresql.service #Requires=postgresql.service
#Requires=memcached.service #Requires=memcached.service
#Requires=redis.service #Requires=redis.service
#
###
# If using socket activation for main http/s
###
#
#After=gitea.main.socket
#Requires=gitea.main.socket
#
###
# (You can also provide gitea an http fallback and/or ssh socket too)
#
# An example of /etc/systemd/system/gitea.main.socket
###
##
## [Unit]
## Description=Gitea Web Socket
## PartOf=gitea.service
##
## [Socket]
## Service=gitea.service
## ListenStream=<some_port>
## NoDelay=true
##
## [Install]
## WantedBy=sockets.target
##
###
[Service] [Service]
# Modify these two values and uncomment them if you have # Modify these two values and uncomment them if you have
@ -20,14 +51,18 @@ Type=simple
User=git User=git
Group=git Group=git
WorkingDirectory=/var/lib/gitea/ WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini # If using unix socket: Tells Systemd to create /run/gitea folder to home gitea.sock
# Manual cration would vanish after reboot.
#RuntimeDirectory=gitea
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
# If you want to bind Gitea to a port below 1024 uncomment # If you want to bind Gitea to a port below 1024, uncomment
# the two values below # the two values below, or use socket activation to pass Gitea its ports as above
### ###
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE #CapabilityBoundingSet=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_BIND_SERVICE #AmbientCapabilities=CAP_NET_BIND_SERVICE
###
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -1,3 +1,4 @@
; This file lists the default values used by Gitea ; This file lists the default values used by Gitea
; Copy required sections to your own app.ini (default is custom/conf/app.ini) ; Copy required sections to your own app.ini (default is custom/conf/app.ini)
; and modify as needed. ; and modify as needed.
@ -36,6 +37,8 @@ DISABLE_HTTP_GIT = false
ACCESS_CONTROL_ALLOW_ORIGIN = ACCESS_CONTROL_ALLOW_ORIGIN =
; Force ssh:// clone url instead of scp-style uri when default SSH port is used ; Force ssh:// clone url instead of scp-style uri when default SSH port is used
USE_COMPAT_SSH_URI = false USE_COMPAT_SSH_URI = false
; Close issues as long as a commit on any branch marks it as fixed
DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH = false
[repository.editor] [repository.editor]
; List of file extensions for which lines should be wrapped in the CodeMirror editor ; List of file extensions for which lines should be wrapped in the CodeMirror editor
@ -66,6 +69,62 @@ MAX_FILES = 5
[repository.pull-request] [repository.pull-request]
; List of prefixes used in Pull Request title to mark them as Work In Progress ; List of prefixes used in Pull Request title to mark them as Work In Progress
WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP]
; List of keywords used in Pull Request comments to automatically close a related issue
CLOSE_KEYWORDS=close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved
; List of keywords used in Pull Request comments to automatically reopen a related issue
REOPEN_KEYWORDS=reopen,reopens,reopened
[repository.issue]
; List of reasons why a Pull Request or Issue can be locked
LOCK_REASONS=Too heated,Off-topic,Resolved,Spam
[repository.signing]
; GPG key to use to sign commits, Defaults to the default - that is the value of git config --get user.signingkey
; run in the context of the RUN_USER
; Switch to none to stop signing completely
SIGNING_KEY = default
; If a SIGNING_KEY ID is provided and is not set to default, use the provided Name and Email address as the signer.
; These should match a publicized name and email address for the key. (When SIGNING_KEY is default these are set to
; the results of git config --get user.name and git config --get user.email respectively and can only be overrided
; by setting the SIGNING_KEY ID to the correct ID.)
SIGNING_NAME =
SIGNING_EMAIL =
; Determines when gitea should sign the initial commit when creating a repository
; Either:
; - never
; - pubkey: only sign if the user has a pubkey
; - twofa: only sign if the user has logged in with twofa
; - always
; options other than none and always can be combined as comma separated list
INITIAL_COMMIT = always
; Determines when to sign for CRUD actions
; - as above
; - parentsigned: requires that the parent commit is signed.
CRUD_ACTIONS = pubkey, twofa, parentsigned
; Determines when to sign Wiki commits
; - as above
WIKI = never
; Determines when to sign on merges
; - basesigned: require that the parent of commit on the base repo is signed.
; - commitssigned: require that all the commits in the head branch are signed.
MERGES = pubkey, twofa, basesigned, commitssigned
[cors]
; More information about CORS can be found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#The_HTTP_response_headers
; enable cors headers (disabled by default)
ENABLED=false
; scheme of allowed requests
SCHEME=http
; list of requesting domains that are allowed
ALLOW_DOMAIN=*
; allow subdomains of headers listed above to request
ALLOW_SUBDOMAIN=false
; list of methods allowed to request
METHODS=GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
; max time to cache response
MAX_AGE=10m
; allow request with credentials
ALLOW_CREDENTIALS=false
[ui] [ui]
; Number of repositories that are displayed on one explore page ; Number of repositories that are displayed on one explore page
@ -90,6 +149,10 @@ SHOW_USER_EMAIL = true
DEFAULT_THEME = gitea DEFAULT_THEME = gitea
; All available themes. Allow users select personalized themes regardless of the value of `DEFAULT_THEME`. ; All available themes. Allow users select personalized themes regardless of the value of `DEFAULT_THEME`.
THEMES = gitea,arc-green THEMES = gitea,arc-green
; 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 to search within description at repository search on explore page.
SEARCH_REPO_DESCRIPTION = true
[ui.admin] [ui.admin]
; Number of users that are displayed on one page ; Number of users that are displayed on one page
@ -113,8 +176,9 @@ KEYWORDS = go,git,self-hosted,gitea
[markdown] [markdown]
; Enable hard line break extension ; Enable hard line break extension
ENABLE_HARD_LINE_BREAK = false ENABLE_HARD_LINE_BREAK = false
; List of custom URL-Schemes that are allowed as links when rendering Markdown ; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown
; for example git,magnet ; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes)
; URLs starting with http and https are always displayed, whatever is put in this entry.
CUSTOM_URL_SCHEMES = CUSTOM_URL_SCHEMES =
; List of file extensions that should be rendered/edited as Markdown ; List of file extensions that should be rendered/edited as Markdown
; Separate the extensions with a comma. To render files without any extension as markdown, just put a comma ; Separate the extensions with a comma. To render files without any extension as markdown, just put a comma
@ -125,6 +189,8 @@ FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
PROTOCOL = http PROTOCOL = http
DOMAIN = localhost DOMAIN = localhost
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/ ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
; when STATIC_URL_PREFIX is empty it will follow APP_URL
STATIC_URL_PREFIX =
; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket. ; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket.
HTTP_ADDR = 0.0.0.0 HTTP_ADDR = 0.0.0.0
HTTP_PORT = 3000 HTTP_PORT = 3000
@ -215,6 +281,14 @@ LFS_CONTENT_PATH = data/lfs
LFS_JWT_SECRET = LFS_JWT_SECRET =
; LFS authentication validity period (in time.Duration), pushes taking longer than this may fail. ; LFS authentication validity period (in time.Duration), pushes taking longer than this may fail.
LFS_HTTP_AUTH_EXPIRY = 20m LFS_HTTP_AUTH_EXPIRY = 20m
; Allow graceful restarts using SIGHUP to fork
ALLOW_GRACEFUL_RESTARTS = true
; After a restart the parent will finish ongoing requests before
; shutting down. Force shutdown if this process takes longer than this delay.
; set to a negative value to disable
GRACEFUL_HAMMER_TIME = 60s
; Static resources, includes resources on custom/, public/ and all uploaded avatars web browser cache time, default is 6h
STATIC_CACHE_TIME = 6h
; Define allowed algorithms and their minimum key length (use -1 to disable a type) ; Define allowed algorithms and their minimum key length (use -1 to disable a type)
[ssh.minimum_key_sizes] [ssh.minimum_key_sizes]
@ -234,6 +308,9 @@ PASSWD =
; For Postgres, either "disable" (default), "require", or "verify-full" ; For Postgres, either "disable" (default), "require", or "verify-full"
; For MySQL, either "false" (default), "true", or "skip-verify" ; For MySQL, either "false" (default), "true", or "skip-verify"
SSL_MODE = disable SSL_MODE = disable
; For MySQL only, either "utf8" or "utf8mb4", default is "utf8".
; NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
CHARSET = utf8
; For "sqlite3" and "tidb", use an absolute path when you start gitea as service ; For "sqlite3" and "tidb", use an absolute path when you start gitea as service
PATH = data/gitea.db PATH = data/gitea.db
; For "sqlite3" only. Query timeout ; For "sqlite3" only. Query timeout
@ -246,26 +323,54 @@ LOG_SQL = true
DB_RETRIES = 10 DB_RETRIES = 10
; Backoff time per DB retry (time.Duration) ; Backoff time per DB retry (time.Duration)
DB_RETRY_BACKOFF = 3s DB_RETRY_BACKOFF = 3s
; Max idle database connections on connnection pool, default is 2
MAX_IDLE_CONNS = 2
; Database connection max life time, default is 0 or 3s mysql (See #6804 & #7071 for reasoning)
CONN_MAX_LIFETIME = 3s
; Database maximum number of open connections, default is 0 meaning no maximum
MAX_OPEN_CONNS = 0
[indexer] [indexer]
; Issue indexer type, currently support: bleve or db, default is bleve
ISSUE_INDEXER_TYPE = bleve
; Issue indexer storage path, available when ISSUE_INDEXER_TYPE is bleve
ISSUE_INDEXER_PATH = indexers/issues.bleve ISSUE_INDEXER_PATH = indexers/issues.bleve
; Issue indexer queue, currently support: channel, levelqueue or redis, default is levelqueue
ISSUE_INDEXER_QUEUE_TYPE = levelqueue
; When ISSUE_INDEXER_QUEUE_TYPE is levelqueue, this will be the queue will be saved path,
; default is indexers/issues.queue
ISSUE_INDEXER_QUEUE_DIR = indexers/issues.queue
; When `ISSUE_INDEXER_QUEUE_TYPE` is `redis`, this will store the redis connection string.
ISSUE_INDEXER_QUEUE_CONN_STR = "addrs=127.0.0.1:6379 db=0"
; Batch queue number, default is 20
ISSUE_INDEXER_QUEUE_BATCH_NUMBER = 20
; Timeout the indexer if it takes longer than this to start.
; Set to zero to disable timeout.
STARTUP_TIMEOUT=30s
; repo indexer by default disabled, since it uses a lot of disk space ; repo indexer by default disabled, since it uses a lot of disk space
REPO_INDEXER_ENABLED = false REPO_INDEXER_ENABLED = false
REPO_INDEXER_PATH = indexers/repos.bleve REPO_INDEXER_PATH = indexers/repos.bleve
UPDATE_BUFFER_LEN = 20 UPDATE_BUFFER_LEN = 20
MAX_FILE_SIZE = 1048576 MAX_FILE_SIZE = 1048576
; A comma separated list of glob patterns (see https://github.com/gobwas/glob) to include
; in the index; default is empty
REPO_INDEXER_INCLUDE =
; A comma separated list of glob patterns to exclude from the index; ; default is empty
REPO_INDEXER_EXCLUDE =
[admin] [admin]
; Disallow regular (non-admin) users from creating organizations. ; Disallow regular (non-admin) users from creating organizations.
DISABLE_REGULAR_ORG_CREATION = false DISABLE_REGULAR_ORG_CREATION = false
; Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
DEFAULT_EMAIL_NOTIFICATIONS = enabled
[security] [security]
; Whether the installer is disabled ; Whether the installer is disabled
INSTALL_LOCK = false INSTALL_LOCK = false
; !!CHANGE THIS TO KEEP YOUR USER DATA SAFE!! ; !!CHANGE THIS TO KEEP YOUR USER DATA SAFE!!
SECRET_KEY = !#@FDEWREWR&*( SECRET_KEY = !#@FDEWREWR&*(
; How long to remember that an user is logged in before requiring relogin (in days) ; How long to remember that a user is logged in before requiring relogin (in days)
LOGIN_REMEMBER_DAYS = 7 LOGIN_REMEMBER_DAYS = 7
COOKIE_USERNAME = gitea_awesome COOKIE_USERNAME = gitea_awesome
COOKIE_REMEMBER_NAME = gitea_incredible COOKIE_REMEMBER_NAME = gitea_incredible
@ -278,6 +383,14 @@ MIN_PASSWORD_LENGTH = 6
IMPORT_LOCAL_PATHS = false IMPORT_LOCAL_PATHS = false
; Set to true to prevent all users (including admin) from creating custom git hooks ; Set to true to prevent all users (including admin) from creating custom git hooks
DISABLE_GIT_HOOKS = false DISABLE_GIT_HOOKS = false
;Comma separated list of character classes required to pass minimum complexity.
;If left empty or no valid values are specified, the default values ("lower,upper,digit,spec") will be used.
;Use "off" to disable checking.
PASSWORD_COMPLEXITY = lower,upper,digit,spec
; Password Hash algorithm, either "pbkdf2", "argon2", "scrypt" or "bcrypt"
PASSWORD_HASH_ALGO = pbkdf2
; Set false to allow JavaScript to read CSRF cookie
CSRF_COOKIE_HTTP_ONLY = true
[openid] [openid]
; ;
@ -331,6 +444,10 @@ ALLOW_ONLY_EXTERNAL_REGISTRATION = false
REQUIRE_SIGNIN_VIEW = false REQUIRE_SIGNIN_VIEW = false
; Mail notification ; Mail notification
ENABLE_NOTIFY_MAIL = false ENABLE_NOTIFY_MAIL = false
; This setting enables gitea to be signed in with HTTP BASIC Authentication using the user's password
; If you set this to false you will not be able to access the tokens endpoints on the API with your password
; Please note that setting this to false will not disable OAuth Basic or Basic authentication using a token
ENABLE_BASIC_AUTHENTICATION = true
; More detail: https://github.com/gogits/gogs/issues/165 ; More detail: https://github.com/gogits/gogs/issues/165
ENABLE_REVERSE_PROXY_AUTHENTICATION = false ENABLE_REVERSE_PROXY_AUTHENTICATION = false
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
@ -343,15 +460,27 @@ CAPTCHA_TYPE = image
; Go to https://www.google.com/recaptcha/admin to sign up for a key ; Go to https://www.google.com/recaptcha/admin to sign up for a key
RECAPTCHA_SECRET = RECAPTCHA_SECRET =
RECAPTCHA_SITEKEY = RECAPTCHA_SITEKEY =
; Change this to use recaptcha.net or other recaptcha service
RECAPTCHA_URL = https://www.google.com/recaptcha/
; Default value for KeepEmailPrivate ; Default value for KeepEmailPrivate
; Each new user will get the value of this setting copied into their profile ; Each new user will get the value of this setting copied into their profile
DEFAULT_KEEP_EMAIL_PRIVATE = false DEFAULT_KEEP_EMAIL_PRIVATE = false
; Default value for AllowCreateOrganization ; Default value for AllowCreateOrganization
; Every new user will have rights set to create organizations depending on this setting ; Every new user will have rights set to create organizations depending on this setting
DEFAULT_ALLOW_CREATE_ORGANIZATION = true DEFAULT_ALLOW_CREATE_ORGANIZATION = true
; Either "public", "limited" or "private", default is "public"
; Limited is for signed user only
; Private is only for member of the organization
; Public is for everyone
DEFAULT_ORG_VISIBILITY = public
; Default value for DefaultOrgMemberVisible
; True will make the membership of the users visible when added to the organisation
DEFAULT_ORG_MEMBER_VISIBLE = false
; Default value for EnableDependencies ; Default value for EnableDependencies
; Repositories will use dependencies by default depending on this setting ; Repositories will use dependencies by default depending on this setting
DEFAULT_ENABLE_DEPENDENCIES = true DEFAULT_ENABLE_DEPENDENCIES = true
; Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting.
ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true
; Enable heatmap on users profiles. ; Enable heatmap on users profiles.
ENABLE_USER_HEATMAP = true ENABLE_USER_HEATMAP = true
; Enable Timetracking ; Enable Timetracking
@ -387,8 +516,8 @@ PAGING_NUM = 10
ENABLED = false ENABLED = false
; Buffer length of channel, keep it as it is if you don't know what it is. ; Buffer length of channel, keep it as it is if you don't know what it is.
SEND_BUFFER_LEN = 100 SEND_BUFFER_LEN = 100
; Name displayed in mail title ; Prefix displayed before subject in mail
SUBJECT = %(APP_NAME)s SUBJECT_PREFIX =
; Mail server ; Mail server
; Gmail: smtp.gmail.com:587 ; Gmail: smtp.gmail.com:587
; QQ: smtp.qq.com:465 ; QQ: smtp.qq.com:465
@ -414,8 +543,8 @@ USER =
PASSWD = PASSWD =
; Send mails as plain text ; Send mails as plain text
SEND_AS_PLAIN_TEXT = false SEND_AS_PLAIN_TEXT = false
; Enable sendmail (override SMTP) ; Set Mailer Type (either SMTP, sendmail or dummy to just send to the log)
USE_SENDMAIL = false MAILER_TYPE = smtp
; Specify an alternative sendmail binary ; Specify an alternative sendmail binary
SENDMAIL_PATH = sendmail SENDMAIL_PATH = sendmail
; Specify any extra sendmail arguments ; Specify any extra sendmail arguments
@ -456,10 +585,18 @@ SESSION_LIFE_TIME = 86400
[picture] [picture]
AVATAR_UPLOAD_PATH = data/avatars AVATAR_UPLOAD_PATH = data/avatars
; Max Width and Height of uploaded avatars. This is to limit the amount of RAM REPOSITORY_AVATAR_UPLOAD_PATH = data/repo-avatars
; used when resizing the image. ; How Gitea deals with missing repository avatars
; none = no avatar will be displayed; random = random avatar will be displayed; image = default image will be used
REPOSITORY_AVATAR_FALLBACK = none
REPOSITORY_AVATAR_FALLBACK_IMAGE = /img/repo_default.png
; Max Width and Height of uploaded avatars.
; This is to limit the amount of RAM used when resizing the image.
AVATAR_MAX_WIDTH = 4096 AVATAR_MAX_WIDTH = 4096
AVATAR_MAX_HEIGHT = 3072 AVATAR_MAX_HEIGHT = 3072
; Maximum alloved file size for uploaded avatars.
; This is to limit the amount of RAM used when resizing the image.
AVATAR_MAX_FILE_SIZE = 1048576
; Chinese users can choose "duoshuo" ; Chinese users can choose "duoshuo"
; or a custom avatar source, like: http://cn.gravatar.com/avatar/ ; or a custom avatar source, like: http://cn.gravatar.com/avatar/
GRAVATAR_SOURCE = gravatar GRAVATAR_SOURCE = gravatar
@ -487,6 +624,9 @@ MAX_FILES = 5
; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano ; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano
; For more information about the format see http://golang.org/pkg/time/#pkg-constants ; For more information about the format see http://golang.org/pkg/time/#pkg-constants
FORMAT = FORMAT =
; Location the UI time display i.e. Asia/Shanghai
; Empty means server's location setting
DEFAULT_UI_LOCATION =
[log] [log]
ROOT_PATH = ROOT_PATH =
@ -495,16 +635,37 @@ ROOT_PATH =
MODE = console MODE = console
; Buffer length of the channel, keep it as it is if you don't know what it is. ; Buffer length of the channel, keep it as it is if you don't know what it is.
BUFFER_LEN = 10000 BUFFER_LEN = 10000
REDIRECT_MACARON_LOG = false
MACARON = file
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Info"
ROUTER_LOG_LEVEL = Info
ROUTER = console
ENABLE_ACCESS_LOG = false
ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"
ACCESS = file
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace" ; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
LEVEL = Trace LEVEL = Info
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "None"
STACKTRACE_LEVEL = None
; Generic log modes
[log.x]
FLAGS = stdflags
EXPRESSION =
PREFIX =
COLORIZE = false
; For "console" mode only ; For "console" mode only
[log.console] [log.console]
LEVEL = LEVEL =
STDERR = false
; For "file" mode only ; For "file" mode only
[log.file] [log.file]
LEVEL = LEVEL =
; Set the file_name for the logger. If this is a relative path this
; will be relative to ROOT_PATH
FILE_NAME =
; This enables automated log rotate(switch of following options), default is true ; This enables automated log rotate(switch of following options), default is true
LOG_ROTATE = true LOG_ROTATE = true
; Max number of lines in a single file, default is 1000000 ; Max number of lines in a single file, default is 1000000
@ -515,6 +676,10 @@ MAX_SIZE_SHIFT = 28
DAILY_ROTATE = true DAILY_ROTATE = true
; delete the log file after n days, default is 7 ; delete the log file after n days, default is 7
MAX_DAYS = 7 MAX_DAYS = 7
; compress logs with gzip
COMPRESS = true
; compression level see godoc for compress/gzip
COMPRESSION_LEVEL = -1
; For "conn" mode only ; For "conn" mode only
[log.conn] [log.conn]
@ -542,14 +707,6 @@ PASSWD =
; Receivers, can be one or more, e.g. 1@example.com,2@example.com ; Receivers, can be one or more, e.g. 1@example.com,2@example.com
RECEIVERS = RECEIVERS =
; For "database" mode only
[log.database]
LEVEL =
; Either "mysql" or "postgres"
DRIVER =
; Based on xorm, e.g.: root:root@localhost/gitea?charset=utf8
CONN =
[cron] [cron]
; Enable running cron tasks periodically. ; Enable running cron tasks periodically.
ENABLED = true ENABLED = true
@ -594,7 +751,14 @@ SCHEDULE = @every 24h
; or only create new users if UPDATE_EXISTING is set to false ; or only create new users if UPDATE_EXISTING is set to false
UPDATE_EXISTING = true UPDATE_EXISTING = true
; Update migrated repositories' issues and comments' posterid, it will always attempt synchronization when the instance starts.
[cron.update_migration_post_id]
; Interval as a duration between each synchronization. (default every 24h)
SCHEDULE = @every 24h
[git] [git]
; The path of git executable. If empty, Gitea searches through the PATH environment.
PATH =
; Disables highlight of added and removed changes ; Disables highlight of added and removed changes
DISABLE_DIFF_HIGHLIGHT = false DISABLE_DIFF_HIGHLIGHT = false
; Max number of lines allowed in a single file in diff view ; Max number of lines allowed in a single file in diff view
@ -606,9 +770,12 @@ MAX_GIT_DIFF_FILES = 100
; Arguments for command 'git gc', e.g. "--aggressive --auto" ; Arguments for command 'git gc', e.g. "--aggressive --auto"
; see more on http://git-scm.com/docs/git-gc/ ; see more on http://git-scm.com/docs/git-gc/
GC_ARGS = GC_ARGS =
; 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
EnableAutoGitWireProtocol = true
; Operation timeout in seconds ; Operation timeout in seconds
[git.timeout] [git.timeout]
DEFAULT = 360
MIGRATE = 600 MIGRATE = 600
MIRROR = 300 MIRROR = 300
CLONE = 300 CLONE = 300
@ -628,6 +795,22 @@ ENABLE_SWAGGER = true
MAX_RESPONSE_ITEMS = 50 MAX_RESPONSE_ITEMS = 50
; Default paging number of api ; Default paging number of api
DEFAULT_PAGING_NUM = 30 DEFAULT_PAGING_NUM = 30
; Default and maximum number of items per page for git trees api
DEFAULT_GIT_TREES_PER_PAGE = 1000
; Default size of a blob returned by the blobs API (default is 10MiB)
DEFAULT_MAX_BLOB_SIZE = 10485760
[oauth2]
; Enables OAuth2 provider
ENABLE = true
; Lifetime of an OAuth2 access token in seconds
ACCESS_TOKEN_EXPIRATION_TIME=3600
; Lifetime of an OAuth2 access token in hours
REFRESH_TOKEN_EXPIRATION_TIME=730
; Check if refresh token got already used
INVALIDATE_REFRESH_TOKENS=false
; OAuth2 authentication secret for access and refresh tokens, change this to a unique string.
JWT_SECRET=Bk0yK7Y9g_p56v86KaHqjSbxvNvu3SbKoOdOt2ZcXvU
[i18n] [i18n]
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
@ -659,11 +842,12 @@ sv-SE = sv
ko-KR = ko ko-KR = ko
[U2F] [U2F]
; NOTE: THE DEFAULT VALUES HERE WILL NEED TO BE CHANGED
; Two Factor authentication with security keys ; Two Factor authentication with security keys
; https://developers.yubico.com/U2F/App_ID.html ; https://developers.yubico.com/U2F/App_ID.html
APP_ID = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/ ;APP_ID = http://localhost:3000/
; Comma seperated list of truisted facets ; Comma seperated list of trusted facets
TRUSTED_FACETS = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/ ;TRUSTED_FACETS = http://localhost:3000/
; Extension mapping to highlight class ; Extension mapping to highlight class
; e.g. .toml=ini ; e.g. .toml=ini
@ -690,3 +874,12 @@ IS_INPUT_FILE = false
ENABLED = false ENABLED = false
; If you want to add authorization, specify a token here ; If you want to add authorization, specify a token here
TOKEN = TOKEN =
[task]
; Task queue type, could be `channel` or `redis`.
QUEUE_TYPE = channel
; Task queue length, available only when `QUEUE_TYPE` is `channel`.
QUEUE_LENGTH = 1000
; Task queue connection string, available only when `QUEUE_TYPE` is `redis`.
; If there is a password of redis, use `addrs=127.0.0.1:6379 password=123 db=0`.
QUEUE_CONN_STR = "addrs=127.0.0.1:6379 db=0"

3
docker/Makefile vendored
View File

@ -4,7 +4,6 @@ DOCKER_IMAGE ?= gitea/gitea
DOCKER_TAG ?= latest DOCKER_TAG ?= latest
DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG) DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
.PHONY: docker .PHONY: docker
docker: docker:
docker build --disable-content-trust=false -t $(DOCKER_REF) . docker build --disable-content-trust=false -t $(DOCKER_REF) .
@ -12,4 +11,4 @@ docker:
.PHONY: docker-build .PHONY: docker-build
docker-build: docker-build:
docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" webhippie/golang:edge make clean generate build docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" webhippie/golang:edge make clean generate build

View File

@ -1,2 +0,0 @@
#!/bin/bash
export GITEA_CUSTOM=/data/gitea

View File

@ -1,2 +0,0 @@
#!/bin/bash
exit 0

View File

@ -1,6 +0,0 @@
#!/bin/bash
[[ -f ./setup ]] && source ./setup
pushd /root > /dev/null
exec su-exec root /sbin/syslogd -nS -O-
popd

View File

@ -1 +0,0 @@
#!/bin/bash

19
docker/manifest.tmpl vendored 100644
View File

@ -0,0 +1,19 @@
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
-
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64
platform:
architecture: amd64
os: linux
-
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64
platform:
architecture: arm64
os: linux
variant: v8

View File

@ -6,12 +6,16 @@ if [ ! -d /data/git/.ssh ]; then
fi fi
if [ ! -f /data/git/.ssh/environment ]; then if [ ! -f /data/git/.ssh/environment ]; then
echo "GITEA_CUSTOM=/data/gitea" >| /data/git/.ssh/environment echo "GITEA_CUSTOM=$GITEA_CUSTOM" >| /data/git/.ssh/environment
chmod 600 /data/git/.ssh/environment chmod 600 /data/git/.ssh/environment
elif ! grep -q "^GITEA_CUSTOM=$GITEA_CUSTOM$" /data/git/.ssh/environment; then
sed -i /^GITEA_CUSTOM=/d /data/git/.ssh/environment
echo "GITEA_CUSTOM=$GITEA_CUSTOM" >> /data/git/.ssh/environment
fi fi
if [ ! -f /data/gitea/conf/app.ini ]; then if [ ! -f ${GITEA_CUSTOM}/conf/app.ini ]; then
mkdir -p /data/gitea/conf mkdir -p ${GITEA_CUSTOM}/conf
# Set INSTALL_LOCK to true only if SECRET_KEY is not empty and # Set INSTALL_LOCK to true only if SECRET_KEY is not empty and
# INSTALL_LOCK is empty # INSTALL_LOCK is empty
@ -27,6 +31,8 @@ if [ ! -f /data/gitea/conf/app.ini ]; then
ROOT_URL=${ROOT_URL:-""} \ ROOT_URL=${ROOT_URL:-""} \
DISABLE_SSH=${DISABLE_SSH:-"false"} \ DISABLE_SSH=${DISABLE_SSH:-"false"} \
SSH_PORT=${SSH_PORT:-"22"} \ SSH_PORT=${SSH_PORT:-"22"} \
SSH_LISTEN_PORT=${SSH_LISTEN_PORT:-"${SSH_PORT}"} \
LFS_START_SERVER=${LFS_START_SERVER:-"false"} \
DB_TYPE=${DB_TYPE:-"sqlite3"} \ DB_TYPE=${DB_TYPE:-"sqlite3"} \
DB_HOST=${DB_HOST:-"localhost:3306"} \ DB_HOST=${DB_HOST:-"localhost:3306"} \
DB_NAME=${DB_NAME:-"gitea"} \ DB_NAME=${DB_NAME:-"gitea"} \
@ -36,7 +42,9 @@ if [ ! -f /data/gitea/conf/app.ini ]; then
DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-"false"} \ DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-"false"} \
REQUIRE_SIGNIN_VIEW=${REQUIRE_SIGNIN_VIEW:-"false"} \ REQUIRE_SIGNIN_VIEW=${REQUIRE_SIGNIN_VIEW:-"false"} \
SECRET_KEY=${SECRET_KEY:-""} \ SECRET_KEY=${SECRET_KEY:-""} \
envsubst < /etc/templates/app.ini > /data/gitea/conf/app.ini envsubst < /etc/templates/app.ini > ${GITEA_CUSTOM}/conf/app.ini
chown ${USER}:git ${GITEA_CUSTOM}/conf/app.ini
fi fi
# 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

View File

@ -2,5 +2,5 @@
[[ -f ./setup ]] && source ./setup [[ -f ./setup ]] && source ./setup
pushd /root > /dev/null pushd /root > /dev/null
exec su-exec root /usr/sbin/sshd -D exec su-exec root /usr/sbin/sshd -D -e 2>&1
popd popd

View File

@ -6,7 +6,7 @@ fi
if [ ! -f /data/ssh/ssh_host_ed25519_key ]; then if [ ! -f /data/ssh/ssh_host_ed25519_key ]; then
echo "Generating /data/ssh/ssh_host_ed25519_key..." echo "Generating /data/ssh/ssh_host_ed25519_key..."
ssh-keygen -t ed25519 -b 4096 -f /data/ssh/ssh_host_ed25519_key -N "" > /dev/null ssh-keygen -t ed25519 -f /data/ssh/ssh_host_ed25519_key -N "" > /dev/null
fi fi
if [ ! -f /data/ssh/ssh_host_rsa_key ]; then if [ ! -f /data/ssh/ssh_host_rsa_key ]; then
@ -24,6 +24,14 @@ 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 [ -d /etc/ssh ]; then
SSH_PORT=${SSH_PORT:-"22"} \
SSH_LISTEN_PORT=${SSH_LISTEN_PORT:-"${SSH_PORT}"} \
envsubst < /etc/templates/sshd_config > /etc/ssh/sshd_config
chmod 0644 /etc/ssh/sshd_config
fi
chown root:root /data/ssh/* chown root:root /data/ssh/*
chmod 0700 /data/ssh chmod 0700 /data/ssh
chmod 0600 /data/ssh/* chmod 0600 /data/ssh/*

View File

@ -17,6 +17,8 @@ HTTP_PORT = $HTTP_PORT
ROOT_URL = $ROOT_URL ROOT_URL = $ROOT_URL
DISABLE_SSH = $DISABLE_SSH DISABLE_SSH = $DISABLE_SSH
SSH_PORT = $SSH_PORT SSH_PORT = $SSH_PORT
SSH_LISTEN_PORT = $SSH_LISTEN_PORT
LFS_START_SERVER = $LFS_START_SERVER
LFS_CONTENT_PATH = /data/git/lfs LFS_CONTENT_PATH = /data/git/lfs
[database] [database]
@ -35,6 +37,7 @@ PROVIDER_CONFIG = /data/gitea/sessions
[picture] [picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars AVATAR_UPLOAD_PATH = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
[attachment] [attachment]
PATH = /data/gitea/attachments PATH = /data/gitea/attachments

View File

@ -1,4 +1,4 @@
Port 22 Port ${SSH_LISTEN_PORT}
Protocol 2 Protocol 2
AddressFamily any AddressFamily any
@ -25,7 +25,7 @@ ChallengeResponseAuthentication no
PasswordAuthentication no PasswordAuthentication no
PermitEmptyPasswords no PermitEmptyPasswords no
AllowUsers git AllowUsers ${USER}
Banner none Banner none
Subsystem sftp /usr/lib/ssh/sftp-server Subsystem sftp /usr/lib/ssh/sftp-server

View File

@ -3,8 +3,6 @@
if [ "${USER}" != "git" ]; then if [ "${USER}" != "git" ]; then
# rename user # rename user
sed -i -e "s/^git\:/${USER}\:/g" /etc/passwd sed -i -e "s/^git\:/${USER}\:/g" /etc/passwd
# switch sshd config to different user
sed -i -e "s/AllowUsers git$/AllowUsers ${USER}/g" /etc/ssh/sshd_config
fi fi
if [ -z "${USER_GID}" ]; then if [ -z "${USER_GID}" ]; then

View File

@ -1,20 +1,16 @@
# Gitea: Docs # Gitea: Docs
[![Build Status](http://drone.gitea.io/api/badges/go-gitea/docs/status.svg)](http://drone.gitea.io/go-gitea/docs) [![Join the chat at https://img.shields.io/discord/322538954119184384.svg](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/Gitea)
[![Join the chat at https://img.shields.io/discord/322538954119184384.svg](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/NsatcWJ)
[![](https://images.microbadger.com/badges/image/gitea/docs.svg)](http://microbadger.com/images/gitea/docs "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/image/gitea/docs.svg)](http://microbadger.com/images/gitea/docs "Get your own image badge on microbadger.com")
## Hosting ## Hosting
This page is hosted on our infrastructure within Docker containers, it gets These pages are hosted using [netlifycms](https://www.netlifycms.org/) and get
automatically updated on every push to the `master` branch. automatically updated on every push to the `master` branch.
If you want to host this page on your own you can take our docker image
[gitea/docs](https://hub.docker.com/r/gitea/docs/).
## Install ## Install
This pages uses the [Hugo](https://github.com/spf13/hugo) static site generator. These pages use the [Hugo](https://gohugo.io/) static site generator.
If you are planning to contribute you'll want to download and install Hugo on If you are planning to contribute you'll want to download and install Hugo on
your local machine. your local machine.

View File

@ -6,6 +6,7 @@ theme: gitea
defaultContentLanguage: en-us defaultContentLanguage: en-us
defaultContentLanguageInSubdir: true defaultContentLanguageInSubdir: true
enableMissingTranslationPlaceholders: true enableMissingTranslationPlaceholders: true
enableEmoji: true
permalinks: permalinks:
post: /:year/:month/:title/ post: /:year/:month/:title/
@ -17,6 +18,7 @@ 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.9.5
menu: menu:
page: page:

View File

@ -31,18 +31,26 @@ Gitea supports these methods of API authentication:
- `access_token=...` parameter in URL query string - `access_token=...` parameter in URL query string
- `Authorization: token ...` header in HTTP headers - `Authorization: token ...` header in HTTP headers
All of these methods accept the same apiKey token type. You can All of these methods accept the same API key token type. You can
better understand this by looking at the code -- as of this writing, 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).
You can create an apiKey token via your gitea install's web interface: You can create an API key token via your Gitea installation's web interface:
`Settings | Applications | Generate New Token`. `Settings | Applications | Generate New Token`.
### OAuth2
Access tokens obtained from Gitea's [OAuth2 provider](https://docs.gitea.io/en-us/oauth2-provider) are accepted by these methods:
- `Authorization bearer ...` header in HTTP headers
- `token=...` parameter in URL query string
- `access_token=...` parameter in URL query string
### More on the `Authorization:` header ### More on the `Authorization:` header
For historical reasons, Gitea needs the word `token` included before For historical reasons, Gitea needs the word `token` included before
the apiKey token in an authorization header, like this: the API key token in an authorization header, like this:
``` ```
Authorization: token 65eaa9c8ef52460d22a93307fe0aee76289dc675 Authorization: token 65eaa9c8ef52460d22a93307fe0aee76289dc675
@ -60,6 +68,14 @@ curl -X POST "http://localhost:4000/api/v1/repos/test1/test1/issues" \
As mentioned above, the token used is the same one you would use in As mentioned above, the token used is the same one you would use in
the `token=` string in a GET request. the `token=` string in a GET request.
## API Guide:
API Reference guide is auto-generated by swagger and available on:
`https://gitea.your.host/api/swagger`
or on
[gitea demo instance](https://try.gitea.io/api/swagger)
## Listing your issued tokens via the API ## Listing your issued tokens via the API
As mentioned in As mentioned in
@ -74,6 +90,12 @@ $ curl --request GET --url https://yourusername:yourpassword@gitea.your.host/api
[{"name":"test","sha1":"..."},{"name":"dev","sha1":"..."}] [{"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:
```
$ curl -H "X-Gitea-OTP: 123456" --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens
```
## Sudo ## Sudo
The API allows admin users to sudo API requests as another user. Simply add either a `sudo=` parameter or `Sudo:` request header with the username of the user to sudo. The API allows admin users to sudo API requests as another user. Simply add either a `sudo=` parameter or `Sudo:` request header with the username of the user to sudo.

View File

@ -0,0 +1,34 @@
---
date: "2019-08-27:00:00+02:00"
title: "CI/CD Usage"
slug: "ci-cd"
weight: 40
toc: true
draft: false
menu:
sidebar:
parent: "advanced"
name: "CI/CD Usage"
weight: 40
identifier: "ci-cd"
---
# Gitea and CI/CD
**NOTE:** These tools are not endorsed by Gitea. They are listed here for convenience only.
## Listing
CI/CD solutions that have integration with Gitea. Following list is not complete,
the purpose is to give a starting point to integrate a CI/CD process with your Gitea instance.
- [Drone](https://drone.io) with [Gitea documentation](https://docs.drone.io/installation/providers/gitea/)
- [Jenkins](https://jenkins.io/) with [Gitea plugin](https://plugins.jenkins.io/gitea)
- [Agola](https://agola.io)
- [Buildkite](https://buildkite.com) with [Gitea connector](https://github.com/techknowlogick/gitea-buildkite-connector)
- [AppVeyor](https://www.appveyor.com) with [built-in Gitea support](https://www.appveyor.com/blog/2019/09/05/gitea-receives-first-class-support-in-appveyor/)
- [Buildbot](https://www.buildbot.net/) with [Gitea plugin](https://github.com/lab132/buildbot-gitea)
Others CI/CD solutions that partially can be integrated with Gitea:
- [Concourse](https://www.concourse-ci.org), see more information at [Concourse community forum](https://discuss.concourse-ci.org/t/concourse-ci-and-gitea-oauth/1475)

View File

@ -15,8 +15,8 @@ menu:
# Configuration Cheat Sheet # Configuration Cheat Sheet
This is a cheat sheet for the Gitea configuration file. It contains most settings This is a cheat sheet for the Gitea configuration file. It contains most of the settings
that can configured as well as their default values. that can be configured as well as their default values.
Any changes to the Gitea configuration file should be made in `custom/conf/app.ini` Any changes to the Gitea configuration file should be made in `custom/conf/app.ini`
or any corresponding location. When installing from a distribution, this will or any corresponding location. When installing from a distribution, this will
@ -44,7 +44,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `ROOT`: **~/gitea-repositories/**: Root path for storing all repository data. It must be - `ROOT`: **~/gitea-repositories/**: Root path for storing all repository data. It must be
an absolute path. an absolute path.
- `SCRIPT_TYPE`: **bash**: The script type this server supports, usually this is `bash`, - `SCRIPT_TYPE`: **bash**: The script type this server supports. Usually this is `bash`,
but some users report that only `sh` is available. but some users report that only `sh` is available.
- `ANSI_CHARSET`: **\<empty\>**: The default charset for an unrecognized charset. - `ANSI_CHARSET`: **\<empty\>**: The default charset for an unrecognized charset.
- `FORCE_PRIVATE`: **false**: Force every new repository to be private. - `FORCE_PRIVATE`: **false**: Force every new repository to be private.
@ -65,10 +65,49 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `ACCESS_CONTROL_ALLOW_ORIGIN`: **\<empty\>**: Value for Access-Control-Allow-Origin header, - `ACCESS_CONTROL_ALLOW_ORIGIN`: **\<empty\>**: Value for Access-Control-Allow-Origin header,
default is not to present. **WARNING**: This maybe harmful to you website if you do not default is not to present. **WARNING**: This maybe harmful to you website if you do not
give it a right value. give it a right value.
- `DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH`: **false**: Close an issue if a commit on a non default branch marks it as closed.
### Repository - Pull Request (`repository.pull-request`) ### Repository - Pull Request (`repository.pull-request`)
- `WORK_IN_PROGRESS_PREFIXES`: **WIP:,\[WIP\]**: List of prefixes used in Pull Request - `WORK_IN_PROGRESS_PREFIXES`: **WIP:,\[WIP\]**: List of prefixes used in Pull Request
title to mark them as Work In Progress title to mark them as Work In Progress
- `CLOSE_KEYWORDS`: **close**, **closes**, **closed**, **fix**, **fixes**, **fixed**, **resolve**, **resolves**, **resolved**: List of
keywords used in Pull Request comments to automatically close a related issue
- `REOPEN_KEYWORDS`: **reopen**, **reopens**, **reopened**: List of keywords used in Pull Request comments to automatically reopen
a related issue
### Repository - Issue (`repository.issue`)
- `LOCK_REASONS`: **Too heated,Off-topic,Resolved,Spam**: A list of reasons why a Pull Request or Issue can be locked
### Repository - Signing (`repository.signing`)
- `SIGNING_KEY`: **default**: \[none, KEYID, default \]: Key to sign with.
- `SIGNING_NAME` &amp; `SIGNING_EMAIL`: if a KEYID is provided as the `SIGNING_KEY`, use these as the Name and Email address of the signer. These should match publicized name and email address for the key.
- `INITIAL_COMMIT`: **always**: \[never, pubkey, twofa, always\]: Sign initial commit.
- `never`: Never sign
- `pubkey`: Only sign if the user has a public key
- `twofa`: Only sign if the user is logged in with twofa
- `always`: Always sign
- Options other than `never` and `always` can be combined as a comma separated list.
- `WIKI`: **never**: \[never, pubkey, twofa, always, parentsigned\]: Sign commits to wiki.
- `CRUD_ACTIONS`: **pubkey, twofa, parentsigned**: \[never, pubkey, twofa, parentsigned, always\]: Sign CRUD actions.
- Options as above, with the addition of:
- `parentsigned`: Only sign if the parent commit is signed.
- `MERGES`: **pubkey, twofa, basesigned, commitssigned**: \[never, pubkey, twofa, basesigned, commitssigned, always\]: Sign merges.
- `basesigned`: Only sign if the parent commit in the base repo is signed.
- `headsigned`: Only sign if the head commit in the head branch is signed.
- `commitssigned`: Only sign if all the commits in the head branch to the merge point are signed.
## CORS (`cors`)
- `ENABLED`: **false**: enable cors headers (disabled by default)
- `SCHEME`: **http**: scheme of allowed requests
- `ALLOW_DOMAIN`: **\***: list of requesting domains that are allowed
- `ALLOW_SUBDOMAIN`: **false**: allow subdomains of headers listed above to request
- `METHODS`: **GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS**: list of methods allowed to request
- `MAX_AGE`: **10m**: max time to cache response
- `ALLOW_CREDENTIALS`: **false**: allow request with credentials
## UI (`ui`) ## UI (`ui`)
@ -79,6 +118,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `DEFAULT_THEME`: **gitea**: \[gitea, arc-green\]: Set the default theme for the Gitea install. - `DEFAULT_THEME`: **gitea**: \[gitea, arc-green\]: Set the default theme for the Gitea install.
- `THEMES`: **gitea,arc-green**: All available themes. Allow users select personalized themes - `THEMES`: **gitea,arc-green**: All available themes. Allow users select personalized themes
regardless of the value of `DEFAULT_THEME`. regardless of the value of `DEFAULT_THEME`.
- `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.
### UI - Admin (`ui.admin`) ### UI - Admin (`ui.admin`)
@ -90,6 +131,9 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
## Markdown (`markdown`) ## Markdown (`markdown`)
- `ENABLE_HARD_LINE_BREAK`: **false**: Enable Markdown's hard line break extension. - `ENABLE_HARD_LINE_BREAK`: **false**: Enable Markdown's hard line break extension.
- `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional
URL hyperlinks to be rendered in Markdown. URLs beginning in http and https are
always displayed
## Server (`server`) ## Server (`server`)
@ -98,6 +142,13 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**: - `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**:
Overwrite the automatically generated public URL. Overwrite the automatically generated public URL.
This is useful if the internal and the external URL don't match (e.g. in Docker). This is useful if the internal and the external URL don't match (e.g. in Docker).
- `STATIC_URL_PREFIX`: **\<empty\>**:
Overwrite this option to request static resources from a different URL.
This includes CSS files, images, JS files and web fonts.
Avatar images are dynamic resources and still served by gitea.
The option can be just a different path, as in `/static`, or another domain, as in `https://cdn.example.com`.
Requests are then made as `%(ROOT_URL)s/static/css/index.css` and `https://cdn.example.com/css/index.css` respective.
The static files are located in the `public/` directory of the gitea source repository.
- `HTTP_ADDR`: **0.0.0.0**: HTTP listen address. - `HTTP_ADDR`: **0.0.0.0**: HTTP listen address.
- If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings. defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
@ -115,12 +166,14 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server. - `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server.
- `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL. - `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL.
- `SSH_PORT`: **22**: SSH port displayed in clone URL. - `SSH_PORT`: **22**: SSH port displayed in clone URL.
- `SSH_LISTEN_HOST`: **0.0.0.0**: Listen address for the built-in SSH server.
- `SSH_LISTEN_PORT`: **%(SSH\_PORT)s**: Port for the built-in SSH server. - `SSH_LISTEN_PORT`: **%(SSH\_PORT)s**: Port for the built-in SSH server.
- `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.
- `DISABLE_ROUTER_LOG`: **false**: Mute printing of the router log. - `DISABLE_ROUTER_LOG`: **false**: Mute printing of the router log.
- `CERT_FILE`: **custom/https/cert.pem**: Cert file path used for HTTPS. - `CERT_FILE`: **custom/https/cert.pem**: Cert file path used for HTTPS.
- `KEY_FILE`: **custom/https/key.pem**: Key file path used for HTTPS. - `KEY_FILE`: **custom/https/key.pem**: Key file path used for HTTPS.
- `STATIC_ROOT_PATH`: **./**: Upper level of template and static files path. - `STATIC_ROOT_PATH`: **./**: Upper level of template and static files path.
- `STATIC_CACHE_TIME`: **6h**: Web browser cache time for static resources on `custom/`, `public/` and all uploaded avatars.
- `ENABLE_GZIP`: **false**: Enables application-level GZIP support. - `ENABLE_GZIP`: **false**: Enables application-level GZIP support.
- `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore\]. - `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore\].
- `LFS_START_SERVER`: **false**: Enables git-lfs support. - `LFS_START_SERVER`: **false**: Enables git-lfs support.
@ -134,27 +187,48 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt. - `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt.
- `LETSENCRYPT_DIRECTORY`: **https**: Directory that Letsencrypt will use to cache information such as certs and private keys. - `LETSENCRYPT_DIRECTORY`: **https**: Directory that Letsencrypt will use to cache information such as certs and private keys.
- `LETSENCRYPT_EMAIL`: **email@example.com**: Email used by Letsencrypt to notify about problems with issued certificates. (No default) - `LETSENCRYPT_EMAIL`: **email@example.com**: Email used by Letsencrypt to notify about problems with issued certificates. (No default)
- `ALLOW_GRACEFUL_RESTARTS`: **true**: Perform a graceful restart on SIGHUP
- `GRACEFUL_HAMMER_TIME`: **60s**: After a restart the parent process will stop accepting new connections and will allow requests to finish before stopping. Shutdown will be forced if it takes longer than this time.
## Database (`database`) ## Database (`database`)
- `DB_TYPE`: **mysql**: The database type in use \[mysql, postgres, mssql, sqlite3\]. - `DB_TYPE`: **mysql**: The database type in use \[mysql, postgres, mssql, sqlite3\].
- `HOST`: **127.0.0.1:3306**: Database host address and port. - `HOST`: **127.0.0.1:3306**: Database host address and port or absolute path for unix socket \[mysql, postgres\] (ex: /var/run/mysqld/mysqld.sock).
- `NAME`: **gitea**: Database name. - `NAME`: **gitea**: Database name.
- `USER`: **root**: Database username. - `USER`: **root**: Database username.
- `PASSWD`: **\<empty\>**: Database user password. Use \`your password\` for quoting if you use special characters in the password. - `PASSWD`: **\<empty\>**: Database user password. Use \`your password\` for quoting if you use special characters in the password.
- `SSL_MODE`: **disable**: For PostgreSQL and MySQL only. - `SSL_MODE`: **disable**: For PostgreSQL and MySQL only.
- `CHARSET`: **utf8**: For MySQL only, either "utf8" or "utf8mb4", default is "utf8". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
- `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 occured. - `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_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).
Please see #8540 & #8273 for further discussion of the appropriate values for `MAX_OPEN_CONNS`, `MAX_IDLE_CONNS` & `CONN_MAX_LIFETIME` and their
relation to port exhaustion.
## Indexer (`indexer`) ## Indexer (`indexer`)
- `ISSUE_INDEXER_TYPE`: **bleve**: Issue indexer type, currently support: bleve or db, if it's db, below issue indexer item will be invalid.
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search. - `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search.
- `REPO_INDEXER_ENABLED`: **false**: Enables code search (uses a lot of disk space). - `ISSUE_INDEXER_QUEUE_TYPE`: **levelqueue**: Issue indexer queue, currently supports:`channel`, `levelqueue`, `redis`.
- `ISSUE_INDEXER_QUEUE_DIR`: **indexers/issues.queue**: When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this will be the queue will be saved path.
- `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.
- `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_PATH`: **indexers/repos.bleve**: Index file used for code search. - `REPO_INDEXER_PATH`: **indexers/repos.bleve**: Index file used for code search.
- `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`.
- `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request. - `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.
## Admin (`admin`)
- `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
## Security (`security`) ## Security (`security`)
@ -171,6 +245,16 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `DISABLE_GIT_HOOKS`: **false**: Set to `true` to prevent all users (including admin) from creating custom - `DISABLE_GIT_HOOKS`: **false**: Set to `true` to prevent all users (including admin) from creating custom
git hooks. git hooks.
- `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_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 \[pbkdf2, argon2, scrypt, bcrypt\].
- `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie.
- `PASSWORD_COMPLEXITY`: **lower,upper,digit,spec**: Comma separated list of character classes required to pass minimum complexity. If left empty or no valid values are specified, the default values will be used. Possible values are:
- lower - use one or more lower latin characters
- upper - use one or more upper latin characters
- digit - use one or more digits
- spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~``
- off - do not check password complexity
## OpenID (`openid`) ## OpenID (`openid`)
@ -190,24 +274,37 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
Requires `Mailer` to be enabled. Requires `Mailer` to be enabled.
- `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create - `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create
accounts for users. accounts for users.
- `REQUIRE_EXTERNAL_REGISTRATION_PASSWORD`: **false**: Enable this to force externally created
accounts (via GitHub, OpenID Connect, etc) to create a password. Warning: enabling this will
decrease security, so you should only enable it if you know what you're doing.
- `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page. - `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page.
- `ENABLE_NOTIFY_MAIL`: **false**: Enable this to send e-mail to watchers of a repository when - `ENABLE_NOTIFY_MAIL`: **false**: Enable this to send e-mail to watchers of a repository when
something happens, like creating issues. Requires `Mailer` to be enabled. something happens, like creating issues. Requires `Mailer` to be enabled.
- `ENABLE_BASIC_AUTHENTICATION`: **true**: Disable this to disallow authenticaton using HTTP
BASIC and the user's password. Please note if you disable this you will not be able to access the
tokens API endpoints using a password. Further, this only disables BASIC authentication using the
password - not tokens or OAuth Basic.
- `ENABLE_REVERSE_PROXY_AUTHENTICATION`: **false**: Enable this to allow reverse proxy authentication. - `ENABLE_REVERSE_PROXY_AUTHENTICATION`: **false**: Enable this to allow reverse proxy authentication.
- `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: **false**: Enable this to allow auto-registration - `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: **false**: Enable this to allow auto-registration
for reverse authentication. for reverse authentication.
- `ENABLE_REVERSE_PROXY_EMAIL`: **false**: Enable this to allow to auto-registration with a - `ENABLE_REVERSE_PROXY_EMAIL`: **false**: Enable this to allow to auto-registration with a
provided email rather than a generated email. provided email rather than a generated email.
- `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration. - `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration.
- `REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA`: **false**: Enable this to force captcha validation
even for External Accounts (i.e. GitHub, OpenID Connect, etc). You must `ENABLE_CAPTCHA` also.
- `CAPTCHA_TYPE`: **image**: \[image, recaptcha\] - `CAPTCHA_TYPE`: **image**: \[image, recaptcha\]
- `RECAPTCHA_SECRET`: **""**: Go to https://www.google.com/recaptcha/admin to get a secret for recaptcha. - `RECAPTCHA_SECRET`: **""**: Go to https://www.google.com/recaptcha/admin to get a secret for recaptcha.
- `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha. - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha.
- `DEFAULT_ENABLE_DEPENDENCIES`: **true** Enable this to have dependencies enabled by default. - `RECAPTCHA_URL`: **https://www.google.com/recaptcha/**: Set the recaptcha url - allows the use of recaptcha net.
- `ENABLE_USER_HEATMAP`: **true** Enable this to display the heatmap on users profiles. - `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.
- `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles.
- `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.
- `SHOW_REGISTRATION_BUTTON`: **! DISABLE\_REGISTRATION**: Show Registration Button - `SHOW_REGISTRATION_BUTTON`: **! DISABLE\_REGISTRATION**: Show Registration Button
- `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
- `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.
## Webhook (`webhook`) ## Webhook (`webhook`)
@ -228,10 +325,15 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `PASSWD`: **\<empty\>**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password. - `PASSWD`: **\<empty\>**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password.
- `SKIP_VERIFY`: **\<empty\>**: Do not verify the self-signed certificates. - `SKIP_VERIFY`: **\<empty\>**: Do not verify the self-signed certificates.
- **Note:** Gitea only supports SMTP with STARTTLS. - **Note:** Gitea only supports SMTP with STARTTLS.
- `USE_SENDMAIL`: **false** Use the operating system's `sendmail` command instead of SMTP. - `SUBJECT_PREFIX`: **\<empty\>**: Prefix to be placed before e-mail subject lines.
- `MAILER_TYPE`: **smtp**: \[smtp, sendmail, dummy\]
- **smtp** Use SMTP to send mail
- **sendmail** Use the operating system's `sendmail` command instead of SMTP.
This is common on linux systems. This is common on linux systems.
- **dummy** Send email messages to the log as a testing phase.
- Note that enabling sendmail will ignore all other `mailer` settings except `ENABLED`, - Note that enabling sendmail will ignore all other `mailer` settings except `ENABLED`,
`FROM` and `SENDMAIL_PATH`. `FROM`, `SUBJECT_PREFIX` and `SENDMAIL_PATH`.
- Enabling dummy will ignore all settings except `ENABLED`, `SUBJECT_PREFIX` and `FROM`.
- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be - `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be
command or full path). command or full path).
- ``IS_TLS_ENABLED`` : **false** : Decide if SMTP connections should use TLS. - ``IS_TLS_ENABLED`` : **false** : Decide if SMTP connections should use TLS.
@ -242,11 +344,12 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `INTERVAL`: **60**: Garbage Collection interval (sec), for memory cache only. - `INTERVAL`: **60**: Garbage Collection interval (sec), for memory cache only.
- `HOST`: **\<empty\>**: Connection string for `redis` and `memcache`. - `HOST`: **\<empty\>**: Connection string for `redis` and `memcache`.
- Redis: `network=tcp,addr=127.0.0.1:6379,password=macaron,db=0,pool_size=100,idle_timeout=180` - Redis: `network=tcp,addr=127.0.0.1:6379,password=macaron,db=0,pool_size=100,idle_timeout=180`
- Memache: `127.0.0.1:9090;127.0.0.1:9091` - Memcache: `127.0.0.1:9090;127.0.0.1:9091`
- `ITEM_TTL`: **16h**: Time to keep items in cache if not used, Setting it to 0 disables caching.
## Session (`session`) ## Session (`session`)
- `PROVIDER`: **memory**: Session engine provider \[memory, file, redis, mysql\]. - `PROVIDER`: **memory**: Session engine provider \[memory, file, redis, mysql, couchbase, memcache, nodb, postgres\].
- `PROVIDER_CONFIG`: **data/sessions**: For file, the root path; 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.
@ -259,7 +362,16 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `DISABLE_GRAVATAR`: **false**: Enable this to use local avatars only. - `DISABLE_GRAVATAR`: **false**: Enable this to use local avatars only.
- `ENABLE_FEDERATED_AVATAR`: **false**: Enable support for federated avatars (see - `ENABLE_FEDERATED_AVATAR`: **false**: Enable support for federated avatars (see
[http://www.libravatar.org](http://www.libravatar.org)). [http://www.libravatar.org](http://www.libravatar.org)).
- `AVATAR_UPLOAD_PATH`: **data/avatars**: Path to store local and cached files. - `AVATAR_UPLOAD_PATH`: **data/avatars**: Path to store user avatar image files.
- `REPOSITORY_AVATAR_UPLOAD_PATH`: **data/repo-avatars**: Path to store repository avatar image files.
- `REPOSITORY_AVATAR_FALLBACK`: **none**: How Gitea deals with missing repository avatars
- none = no avatar will be displayed
- random = random avatar will be generated
- image = default image will be used (which is set in `REPOSITORY_AVATAR_DEFAULT_IMAGE`)
- `REPOSITORY_AVATAR_FALLBACK_IMAGE`: **/img/repo_default.png**: Image used as default repository avatar (if `REPOSITORY_AVATAR_FALLBACK` is set to image and none was uploaded)
- `AVATAR_MAX_WIDTH`: **4096**: Maximum avatar image width in pixels.
- `AVATAR_MAX_HEIGHT`: **3072**: Maximum avatar image height in pixels.
- `AVATAR_MAX_FILE_SIZE`: **1048576** (1Mb): Maximum avatar image file size in bytes.
## Attachment (`attachment`) ## Attachment (`attachment`)
@ -273,8 +385,64 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
## Log (`log`) ## Log (`log`)
- `ROOT_PATH`: **\<empty\>**: Root path for log files. - `ROOT_PATH`: **\<empty\>**: Root path for log files.
- `MODE`: **console**: Logging mode. For multiple modes, use a comma to separate values. - `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`: **Trace**: General log level. \[Trace, Debug, Info, Warn, Error, Critical\] - `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\]
- `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`: **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 `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
- `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.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:
- `Ctx`: the `macaron.Context` of the request.
- `Identity`: the SignedUserName or `"-"` if not logged in.
- `Start`: the start time of the request.
- `ResponseWriter`: the responseWriter from the request.
- You must be very careful to ensure that this template does not throw errors or panics as this template runs outside of the panic/recovery script.
- `ENABLE_XORM_LOG`: **true**: Set whether to perform XORM logging. Please note SQL statement logging can be disabled by setting `LOG_SQL` to false in the `[database]` section.
### Log subsections (`log.name`, `log.name.*`)
- `LEVEL`: **log.LEVEL**: Sets the log-level of this sublogger. Defaults to the `LEVEL` set in the global `[log]` section.
- `STACKTRACE_LEVEL`: **log.STACKTRACE_LEVEL**: Sets the log level at which to log stack traces.
- `MODE`: **name**: Sets the mode of this sublogger - Defaults to the provided subsection name. This allows you to have two different file loggers at different levels.
- `EXPRESSION`: **""**: A regular expression to match either the function name, file or message. Defaults to empty. Only log messages that match the expression will be saved in the logger.
- `FLAGS`: **stdflags**: A comma separated string representing the log flags. Defaults to `stdflags` which represents the prefix: `2009/01/23 01:23:23 ...a/b/c/d.go:23:runtime.Caller() [I]: message`. `none` means don't prefix log lines. See `modules/log/base.go` for more information.
- `PREFIX`: **""**: An additional prefix for every log line in this logger. Defaults to empty.
- `COLORIZE`: **false**: Colorize the log lines by default
### Console log mode (`log.console`, `log.console.*`, or `MODE=console`)
- For the console logger `COLORIZE` will default to `true` if not on windows or the terminal is determined to be able to color.
- `STDERR`: **false**: Use Stderr instead of Stdout.
### File log mode (`log.file`, `log.file.*` or `MODE=file`)
- `FILE_NAME`: Set the file name for this logger. Defaults as described above. If relative will be relative to the `ROOT_PATH`
- `LOG_ROTATE`: **true**: Rotate the log files.
- `MAX_SIZE_SHIFT`: **28**: Maximum size shift of a single file, 28 represents 256Mb.
- `DAILY_ROTATE`: **true**: Rotate logs daily.
- `MAX_DAYS`: **7**: Delete the log file after n days
- `COMPRESS`: **true**: Compress old log files by default with gzip
- `COMPRESSION_LEVEL`: **-1**: Compression level
### Conn log mode (`log.conn`, `log.conn.*` or `MODE=conn`)
- `RECONNECT_ON_MSG`: **false**: Reconnect host for every single message.
- `RECONNECT`: **false**: Try to reconnect when connection is lost.
- `PROTOCOL`: **tcp**: Set the protocol, either "tcp", "unix" or "udp".
- `ADDR`: **:7020**: Sets the address to connect to.
### SMTP log mode (`log.smtp`, `log.smtp.*` or `MODE=smtp`)
- `USER`: User email address to send from.
- `PASSWD`: Password for the smtp server.
- `HOST`: **127.0.0.1:25**: The SMTP host to connect to.
- `RECEIVERS`: Email addresses to send to.
- `SUBJECT`: **Diagnostic message from Gitea**
## Cron (`cron`) ## Cron (`cron`)
@ -303,14 +471,21 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `RUN_AT_START`: **true**: Run repository statistics check at start time. - `RUN_AT_START`: **true**: Run repository statistics check at start time.
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository statistics check. - `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository statistics check.
### Cron - Update Migration Poster ID (`cron.update_migration_post_id`)
- `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
## Git (`git`) ## Git (`git`)
- `PATH`: **""**: The path of git executable. If empty, Gitea searches through the PATH environment.
- `MAX_GIT_DIFF_LINES`: **100**: 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.
- `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
## Git - Timeout settings (`git.timeout`) ## Git - Timeout settings (`git.timeout`)
- `DEFAUlT`: **360**: Git operations default timeout seconds.
- `MIGRATE`: **600**: Migrate external repositories timeout seconds. - `MIGRATE`: **600**: Migrate external repositories timeout seconds.
- `MIRROR`: **300**: Mirror external repositories timeout seconds. - `MIRROR`: **300**: Mirror external repositories timeout seconds.
- `CLONE`: **300**: Git clone from internal repositories timeout seconds. - `CLONE`: **300**: Git clone from internal repositories timeout seconds.
@ -326,7 +501,17 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `ENABLE_SWAGGER`: **true**: Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true. - `ENABLE_SWAGGER`: **true**: Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true.
- `MAX_RESPONSE_ITEMS`: **50**: Max number of items in a page. - `MAX_RESPONSE_ITEMS`: **50**: Max number of items in a page.
- `DEFAULT_PAGING_NUM`: **30**: Default paging number of api. - `DEFAULT_PAGING_NUM`: **30**: Default paging number of API.
- `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: Default and maximum number of items per page for git trees API.
- `DEFAULT_MAX_BLOB_SIZE`: **10485760**: Default max size of a blob that can be return by the blobs API.
## OAuth2 (`oauth2`)
- `ENABLE`: **true**: Enables OAuth2 provider.
- `ACCESS_TOKEN_EXPIRATION_TIME`: **3600**: Lifetime of an OAuth2 access token in seconds
- `REFRESH_TOKEN_EXPIRATION_TIME`: **730**: Lifetime of an OAuth2 access token in hours
- `INVALIDATE_REFRESH_TOKEN`: **false**: Check if refresh token got already used
- `JWT_SECRET`: **\<empty\>**: OAuth2 authentication secret for access and refresh tokens, change this a unique string.
## i18n (`i18n`) ## i18n (`i18n`)
@ -384,6 +569,17 @@ Two special environment variables are passed to the render command:
- `GITEA_PREFIX_SRC`, which contains the current URL prefix in the `src` path tree. To be used as prefix for links. - `GITEA_PREFIX_SRC`, which contains the current URL prefix in the `src` path tree. To be used as prefix for links.
- `GITEA_PREFIX_RAW`, which contains the current URL prefix in the `raw` path tree. To be used as prefix for image paths. - `GITEA_PREFIX_RAW`, which contains the current URL prefix in the `raw` path tree. To be used as prefix for image paths.
## Time (`time`)
- `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
## Task (`task`)
- `QUEUE_TYPE`: **channel**: Task queue type, could be `channel` or `redis`.
- `QUEUE_LENGTH`: **1000**: Task queue length, available only when `QUEUE_TYPE` is `channel`.
- `QUEUE_CONN_STR`: **addrs=127.0.0.1:6379 db=0**: Task queue connection string, available only when `QUEUE_TYPE` is `redis`. If there redis needs a password, use `addrs=127.0.0.1:6379 password=123 db=0`.
## Other (`other`) ## Other (`other`)
- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer. - `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.

View File

@ -65,6 +65,7 @@ menu:
- `CERT_FILE`: 启用HTTPS的证书文件。 - `CERT_FILE`: 启用HTTPS的证书文件。
- `KEY_FILE`: 启用HTTPS的密钥文件。 - `KEY_FILE`: 启用HTTPS的密钥文件。
- `STATIC_ROOT_PATH`: 存放模板和静态文件的根目录,默认是 Gitea 的根目录。 - `STATIC_ROOT_PATH`: 存放模板和静态文件的根目录,默认是 Gitea 的根目录。
- `STATIC_CACHE_TIME`: **6h**: 静态资源文件,包括 `custom/`, `public/` 和所有上传的头像的浏览器缓存时间。
- `ENABLE_GZIP`: 启用应用级别的 GZIP 压缩。 - `ENABLE_GZIP`: 启用应用级别的 GZIP 压缩。
- `LANDING_PAGE`: 未登录用户的默认页面,可选 `home``explore` - `LANDING_PAGE`: 未登录用户的默认页面,可选 `home``explore`
- `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true``false` 默认是 `false` - `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true``false` 默认是 `false`
@ -78,9 +79,26 @@ menu:
- `NAME`: 数据库名称。 - `NAME`: 数据库名称。
- `USER`: 数据库用户名。 - `USER`: 数据库用户名。
- `PASSWD`: 数据库用户密码。 - `PASSWD`: 数据库用户密码。
- `SSL_MODE`: PostgreSQL数据库是否启用SSL模式。 - `SSL_MODE`: MySQL 或 PostgreSQL数据库是否启用SSL模式。
- `CHARSET`: **utf8**: 仅当数据库为 MySQL 时有效, 可以为 "utf8" 或 "utf8mb4"。注意:如果使用 "utf8mb4",你的 MySQL InnoDB 版本必须在 5.6 以上。
- `PATH`: Tidb 或者 SQLite3 数据文件存放路径。 - `PATH`: Tidb 或者 SQLite3 数据文件存放路径。
- `LOG_SQL`: **true**: 显示生成的SQL默认为真。 - `LOG_SQL`: **true**: 显示生成的SQL默认为真。
- `MAX_IDLE_CONNS` **0**: 最大空闲数据库连接
- `CONN_MAX_LIFETIME` **3s**: 数据库连接最大存活时间
## Indexer (`indexer`)
- `ISSUE_INDEXER_TYPE`: **bleve**: 工单索引类型,当前支持 `bleve``db`,当为 `db` 时其它工单索引项可不用设置。
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: 工单索引文件存放路径,当索引类型为 `bleve` 时有效。
- `ISSUE_INDEXER_QUEUE_TYPE`: **levelqueue**: 工单索引队列类型,当前支持 `channel` `levelqueue``redis`
- `ISSUE_INDEXER_QUEUE_DIR`: **indexers/issues.queue**: 当 `ISSUE_INDEXER_QUEUE_TYPE``levelqueue` 时,保存索引队列的磁盘路径。
- `ISSUE_INDEXER_QUEUE_CONN_STR`: **addrs=127.0.0.1:6379 db=0**: 当 `ISSUE_INDEXER_QUEUE_TYPE``redis`保存Redis队列的连接字符串。
- `ISSUE_INDEXER_QUEUE_BATCH_NUMBER`: **20**: 队列处理中批量提交数量。
- `REPO_INDEXER_ENABLED`: **false**: 是否启用代码搜索(启用后会占用比较大的磁盘空间)。
- `REPO_INDEXER_PATH`: **indexers/repos.bleve**: 用于代码搜索的索引文件路径。
- `UPDATE_BUFFER_LEN`: **20**: 代码索引请求的缓冲区长度。
- `MAX_FILE_SIZE`: **1048576**: 进行解析的源代码文件的最大长度,小于该值时才会索引。
## Security (`security`) ## Security (`security`)
@ -127,11 +145,12 @@ menu:
## Cache (`cache`) ## Cache (`cache`)
- `ADAPTER`: 缓存引擎,可以为 `memory`, `redis``memcache` - `ADAPTER`: **memory**: 缓存引擎,可以为 `memory`, `redis``memcache`
- `INTERVAL`: 只对内存缓存有效GC间隔单位秒。 - `INTERVAL`: **60**: 只对内存缓存有效GC间隔单位秒。
- `HOST`: 针对redis和memcache有效主机地址和端口。 - `HOST`: **\<empty\>**: 针对redis和memcache有效主机地址和端口。
- Redis: `network=tcp,addr=127.0.0.1:6379,password=macaron,db=0,pool_size=100,idle_timeout=180` - Redis: `network=tcp,addr=127.0.0.1:6379,password=macaron,db=0,pool_size=100,idle_timeout=180`
- Memache: `127.0.0.1:9090;127.0.0.1:9091` - Memache: `127.0.0.1:9090;127.0.0.1:9091`
- `ITEM_TTL`: **16h**: 缓存项目失效时间,设置为 0 则禁用缓存。
## Session (`session`) ## Session (`session`)
@ -154,6 +173,20 @@ menu:
- `MAX_SIZE`: 附件最大限制,单位 MB比如 `4` - `MAX_SIZE`: 附件最大限制,单位 MB比如 `4`
- `MAX_FILES`: 一次最多上传的附件数量,比如: `5` - `MAX_FILES`: 一次最多上传的附件数量,比如: `5`
关于 `ALLOWED_TYPES` 在 (*)unix 系统中可以使用`file -I <filename>` 来快速获得对应的 `MIME type`
```shell
$ file -I test00.tar.xz
test00.tar.xz: application/x-xz; charset=binary
$ file --mime test00.xlsx
test00.xlsx: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=binary
file -I test01.xls
test01.xls: application/vnd.ms-excel; charset=binary
```
## Log (`log`) ## Log (`log`)
- `ROOT_PATH`: 日志文件根目录。 - `ROOT_PATH`: 日志文件根目录。
@ -178,7 +211,11 @@ menu:
### Cron - Repository Statistics Check (`cron.check_repo_stats`) ### Cron - Repository Statistics Check (`cron.check_repo_stats`)
- `RUN_AT_START`: 是否启动时自动运行仓库统计。 - `RUN_AT_START`: 是否启动时自动运行仓库统计。
- `SCHEDULE`: 藏亏统计时的Cron 语法,比如:`@every 24h`. - `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@every 24h`.
### Cron - Update Migration Poster ID (`cron.update_migration_post_id`)
- `SCHEDULE`: **@every 24h** : 每次同步的间隔时间。此任务总是在启动时自动进行。
## Git (`git`) ## Git (`git`)
@ -188,17 +225,22 @@ menu:
- `GC_ARGS`: 执行 `git gc` 命令的参数, 比如: `--aggressive --auto` - `GC_ARGS`: 执行 `git gc` 命令的参数, 比如: `--aggressive --auto`
## Git - 超时设置 (`git.timeout`) ## Git - 超时设置 (`git.timeout`)
- `DEFAUlT`: **360**: Git操作默认超时时间单位秒
- `MIGRATE`: **600**: 迁移外部仓库时的超时时间,单位秒 - `MIGRATE`: **600**: 迁移外部仓库时的超时时间,单位秒
- `MIRROR`: **300**: 镜像外部仓库的超时时间,单位秒 - `MIRROR`: **300**: 镜像外部仓库的超时时间,单位秒
- `CLONE`: **300**: 内部仓库间克隆的超时时间,单位秒 - `CLONE`: **300**: 内部仓库间克隆的超时时间,单位秒
- `PULL`: **300**: 内部仓库间拉取的超时时间,单位秒 - `PULL`: **300**: 内部仓库间拉取的超时时间,单位秒
- `GC`: **60**: git仓库GC的超时时间单位秒 - `GC`: **60**: git仓库GC的超时时间单位秒
- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: 是否根据 Git Wire Protocol协议支持情况自动切换版本当 git 版本在 2.18 及以上时会自动切换到版本2。为 `false` 则不切换。
## API (`api`) ## API (`api`)
- `ENABLE_SWAGGER`: **true**: 是否启用swagger路由 /api/swagger, /api/v1/swagger etc. endpoints. True 或 false; 默认是 true. - `ENABLE_SWAGGER`: **true**: 是否启用swagger路由 /api/swagger, /api/v1/swagger etc. endpoints. True 或 false; 默认是 true.
- `MAX_RESPONSE_ITEMS`: **50**: 一个页面最大的项目数。 - `MAX_RESPONSE_ITEMS`: **50**: 一个页面最大的项目数。
- `DEFAULT_PAGING_NUM`: **30**: API中默认分页条数。 - `DEFAULT_PAGING_NUM`: **30**: API中默认分页条数。
- `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: GIT TREES API每页的默认最大项数.
- `DEFAULT_MAX_BLOB_SIZE`: **10485760**: BLOBS API默认最大大小.
## Markup (`markup`) ## Markup (`markup`)
@ -217,7 +259,16 @@ IS_INPUT_FILE = false
- RENDER_COMMAND: 工具的命令行命令及参数。 - RENDER_COMMAND: 工具的命令行命令及参数。
- IS_INPUT_FILE: 输入方式是最后一个参数为文件路径还是从标准输入读取。 - IS_INPUT_FILE: 输入方式是最后一个参数为文件路径还是从标准输入读取。
## Time (`time`)
- `FORMAT`: 显示在界面上的时间格式。比如: RFC1123 或者 2006-01-02 15:04:05
- `DEFAULT_UI_LOCATION`: 默认显示在界面上的时区,默认为本地时区。比如: Asia/Shanghai
## Task (`task`)
- `QUEUE_TYPE`: **channel**: 任务队列类型,可以为 `channel``redis`
- `QUEUE_LENGTH`: **1000**: 任务队列长度,当 `QUEUE_TYPE``channel` 时有效。
- `QUEUE_CONN_STR`: **addrs=127.0.0.1:6379 db=0**: 任务队列连接字符串,当 `QUEUE_TYPE``redis` 时有效。如果redis有密码则可以 `addrs=127.0.0.1:6379 password=123 db=0`
## Other (`other`) ## Other (`other`)

View File

@ -15,19 +15,28 @@ menu:
# Customizing Gitea # Customizing Gitea
Customizing Gitea is typically done using the `custom` folder. This is the central Customizing Gitea is typically done using the `CustomPath` folder - by default this is
place to override configuration settings, templates, etc. the `custom` folder from the running directory, but may be different if your build has
set this differently. This is the central place to override configuration settings,
templates, etc. You can check the `CustomPath` using `gitea help`. You can override
the `CustomPath` by setting either the `GITEA_CUSTOM` environment variable or by
using the `--custom-path` option on the `gitea` binary. (The option will override the
environment variable.)
If Gitea is deployed from binary, all default paths will be relative to the gitea If Gitea is deployed from binary, all default paths will be relative to the Gitea
binary. If installed from a distribution, these paths will likely be modified to binary. If installed from a distribution, these paths will likely be modified to
the Linux Filesystem Standard. Gitea will create required folders, including `custom/`. the Linux Filesystem Standard. Gitea will attempt to create required folders, including
Application settings are configured in `custom/conf/app.ini`. Distributions may `custom/`. Distributions may provide a symlink for `custom` using `/etc/gitea/`.
provide a symlink for `custom` using `/etc/gitea/`.
Application settings can be found in file `CustomConf` which is by default,
`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
`--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/master/custom/conf/app.ini.sample) - [Complete List](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample)
If the `custom` folder can't be found next to the binary, 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. `GITEA_CUSTOM` might, for example, be set by an init script.
@ -38,7 +47,8 @@ environment variable; this can be used to override the default path to something
## Customizing /robots.txt ## Customizing /robots.txt
To make Gitea serve a custom `/robots.txt` (default: empty 404), create a file called To make Gitea serve a custom `/robots.txt` (default: empty 404), create a file called
`robots.txt` in the `custom` folder with [expected contents](http://www.robotstxt.org/). `robots.txt` in the `custom` folder (or `CustomPath`) with
[expected contents](http://www.robotstxt.org/).
## Serving custom public files ## Serving custom public files
@ -50,18 +60,24 @@ the url `http://gitea.domain.tld/image.png`.
## Changing the default avatar ## Changing the default avatar
Place the png image at the following path: `custom/public/img/avatar\_default.png` Place the png image at the following path: `custom/public/img/avatar_default.png`
## Customizing Gitea pages ## Customizing Gitea pages
The `custom/templates` folder allows changing every single page of Gitea. Templates The `custom/templates` folder allows changing every single page of Gitea. Templates
to override can be found in the `templates` directory of Gitea source. Override by to override can be found in the [`templates`](https://github.com/go-gitea/gitea/tree/master/templates) directory of Gitea source. Override by
making a copy of the file under `custom/templates` using a full path structure making a copy of the file under `custom/templates` using a full path structure
matching source. matching source.
Any statement contained inside `{{` and `}}` are Gitea's template syntax and 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
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.
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 extra tabs to the repository view, you can put them in `extra_links.tmpl` and `extra_tabs.tmpl` inside your `custom/templates/custom/` directory. If all you want is to add extra links to the top navigation bar, or extra tabs to the repository view, you can put them in `extra_links.tmpl` and `extra_tabs.tmpl` inside your `custom/templates/custom/` directory.
@ -88,6 +104,20 @@ Apart from `extra_links.tmpl` and `extra_tabs.tmpl`, there are other useful temp
- `body_outer_post.tmpl`, before the bottom `<footer>` element. - `body_outer_post.tmpl`, before the bottom `<footer>` element.
- `footer.tmpl`, right before the end of the `<body>` tag, a good place for additional Javascript. - `footer.tmpl`, right before the end of the `<body>` tag, a good place for additional Javascript.
## Customizing Gitea mails
The `custom/templates/mail` folder allows changing the body of every mail of Gitea.
Templates to override can be found in the
[`templates/mail`](https://github.com/go-gitea/gitea/tree/master/templates/mail)
directory of Gitea source.
Override by making a copy of the file under `custom/templates/mail` using a
full path structure matching source.
Any statement contained inside `{{` and `}}` are Gitea's template
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 `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.
@ -96,6 +126,42 @@ Google Analytics, Matomo (previously Piwik), and other analytics services can be
Place custom files in corresponding sub-folder under `custom/options`. Place custom files in corresponding sub-folder under `custom/options`.
**NOTE:** The files should not have a file extension, e.g. `Labels` rather than `Labels.txt`
### gitignores
To add custom .gitignore, add a file with existing [.gitignore rules](https://git-scm.com/docs/gitignore) in it to `custom/options/gitignore`
### Labels
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`
### Licenses
To add a custom license, add a file with the license text to `custom/options/license`
### Locales
Locales are managed via our [crowdin](https://crowdin.com/project/gitea).
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/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.
```
[i18n]
LANGS = en-US,foo-BAR
NAMES = English,FooBar
```
Locales may change between versions, so keeping track of your customized locales is highly encouraged.
### Readmes
To add a custom Readme, add a markdown formatted file (without an `.md` extension) to `custom/options/readme`
## Customizing the look of Gitea ## Customizing the look of Gitea
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. 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.
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)

View File

@ -16,10 +16,11 @@ menu:
# Custom files rendering configuration # Custom files rendering configuration
Gitea supports custom file renderings (i.e., Jupyter notebooks, asciidoc, etc.) through external binaries, Gitea supports custom file renderings (i.e., Jupyter notebooks, asciidoc, etc.) through external binaries,
it is just matter of: it is just a matter of:
* installing external binaries * installing external binaries
* add some configuration to your `app.ini` file * add some configuration to your `app.ini` file
* restart your gitea instance * restart your Gitea instance
## Installing external binaries ## Installing external binaries
@ -27,13 +28,13 @@ In order to get file rendering through external binaries, their associated packa
If you're using a Docker image, your `Dockerfile` should contain something along this lines: If you're using a Docker image, your `Dockerfile` should contain something along this lines:
``` ```
FROM gitea/gitea:1.6.0 FROM gitea/gitea:{{< version >}}
[...] [...]
COPY custom/app.ini /data/gitea/conf/app.ini COPY custom/app.ini /data/gitea/conf/app.ini
[...] [...]
RUN apk --no-cache add asciidoctor freetype freetype-dev gcc g++ libpng python-dev py-pip python3-dev py3-pip RUN apk --no-cache add asciidoctor freetype freetype-dev gcc g++ libpng python-dev py-pip python3-dev py3-pip py3-zmq
# install any other package you need for your external renderers # install any other package you need for your external renderers
RUN pip3 install --upgrade pip RUN pip3 install --upgrade pip
@ -50,7 +51,7 @@ add one `[markup.XXXXX]` section per external renderer on your custom `app.ini`:
[markup.asciidoc] [markup.asciidoc]
ENABLED = true ENABLED = true
FILE_EXTENSIONS = .adoc,.asciidoc FILE_EXTENSIONS = .adoc,.asciidoc
RENDER_COMMAND = "asciidoctor --out-file=- -" RENDER_COMMAND = "asciidoctor -e -a leveloffset=-1 --out-file=- -"
; Input is not a standard input but a file ; Input is not a standard input but a file
IS_INPUT_FILE = false IS_INPUT_FILE = false

View File

@ -15,41 +15,275 @@ menu:
# Hacking on Gitea # Hacking on Gitea
Familiarity with the existing [installation instructions](https://golang.org/doc/install) ## Installing go and setting the GOPATH
is required for this section.
To contribute to Gitea, fork the project and work on the `master` branch. You should [install go](https://golang.org/doc/install) and set up your go
environment correctly. In particular, it is recommended to set the `$GOPATH`
environment variable and to add the go bin directory or directories
`${GOPATH//://bin:}/bin` to the `$PATH`. See the Go wiki entry for
[GOPATH](https://github.com/golang/go/wiki/GOPATH).
Some internal packages are referenced using their respective Github URL. This can You will also need make.
become problematic. To "trick" the Go tool into thinking this is a clone from the <a href='{{< relref "doc/advanced/make.en-us.md" >}}'>(See here how to get Make)</a>
official repository, download the source code using "go get" and follow these instructions.
``` **Note**: When executing make tasks that require external tools, like
`make misspell-check`, Gitea will automatically download and build these as
necessary. To be able to use these you must have the `"$GOPATH"/bin` directory
on the executable path. If you don't add the go bin directory to the
executable path you will have to manage this yourself.
**Note 2**: Go version 1.11 or higher is required; however, it is important
to note that our continuous integration will check that the formatting of the
source code is not changed by `gofmt` using `make fmt-check`. Unfortunately,
the results of `gofmt` can differ by the version of `go`. It is therefore
recommended to install the version of go that our continuous integration is
running. At the time of writing this is Go version 1.12; however, this can be
checked by looking at the
[master `.drone.yml`](https://github.com/go-gitea/gitea/blob/master/.drone.yml)
(At the time of writing
[line 67](https://github.com/go-gitea/gitea/blob/8917d66571a95f3da232a0c27bc1300210d10fde/.drone.yml#L67)
is the relevant line - but this may change.)
## Downloading and cloning the Gitea source code
Go is quite opinionated about where it expects its source code, and simply
cloning the Gitea repository to an arbitrary path is likely to lead to
problems - the fixing of which is out of scope for this document. Further, some
internal packages are referenced using their respective GitHub URL and at
present we use `vendor/` directories.
The recommended method of obtaining the source code is by using the `go get` command:
```bash
go get -d code.gitea.io/gitea go get -d code.gitea.io/gitea
cd "$GOPATH/src/code.gitea.io/gitea"
``` ```
Fork the [Gitea repository](https://github.com/go-gitea/gitea) on GitHub, it should This will clone the Gitea source code to: `"$GOPATH/src/code.gitea.io/gitea"`, or if `$GOPATH`
then be possible to switch the source directory on the command line. is not set `"$HOME/go/src/code.gitea.io/gitea"`.
``` ## Forking Gitea
cd $GOPATH/src/code.gitea.io/gitea
```
To be able to create pull requests, the forked repository should be added as a remote As stated above, you cannot clone Gitea to an arbitrary path. Download the master Gitea source
to the Gitea sources, otherwise changes can't be pushed. code as above. Then, fork the [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:
``` ```bash
# Rename original Gitea origin to upstream
cd "$GOPATH/src/code.gitea.io/gitea"
git remote rename origin upstream git remote rename origin upstream
git remote add origin git@github.com:<USERNAME>/gitea.git git remote add origin "git@github.com:$GITHUB_USERNAME/gitea.git"
git fetch --all --prune git fetch --all --prune
``` ```
This should provide a working development environment for Gitea. Take a look at or:
the `Makefile` to get an overview about the available tasks. The most common tasks
should be `make test` which will start our test environment and `make build` which
will build a `gitea` binary into the working directory. Writing test cases is not
mandatory to contribute, but it is highly encouraged and helps developers sleep
at night.
That's it! You are ready to hack on Gitea. Test changes, push them to the repository, ```bash
and open a pull request. # Add new remote for our fork
cd "$GOPATH/src/code.gitea.io/gitea"
git remote add "$FORK_NAME" "git@github.com:$GITHUB_USERNAME/gitea.git"
git fetch --all --prune
```
To be able to create pull requests, the forked repository should be added as a remote
to the Gitea sources. Otherwise, changes can't be pushed.
## Building Gitea (Basic)
Take a look at our
<a href='{{< relref "doc/installation/from-source.en-us.md" >}}'>instructions</a>
for <a href='{{< relref "doc/installation/from-source.en-us.md" >}}'>building
from source</a>.
The simplest recommended way to build from source is:
```bash
TAGS="bindata sqlite sqlite_unlock_notify" make generate build
```
However, there are a number of additional make tasks you should be aware of.
These are documented below but you can look at our
[`Makefile`](https://github.com/go-gitea/gitea/blob/master/Makefile) for more,
and look at our
[`.drone.yml`](https://github.com/go-gitea/gitea/blob/master/.drone.yml) to see
how our continuous integration works.
### Formatting, code analysis and spell check
Our continous integration will reject PRs that are not properly formatted, fail
code analysis or spell check.
You should format your code with `go fmt` using:
```bash
make fmt
```
and can test whether your changes would match the results with:
```bash
make fmt-check # which runs make fmt internally
```
**Note**: The results of `go fmt` are dependent on the version of `go` present.
You should run the same version of go that is on the continuous integration
server as mentioned above. `make fmt-check` will only check if your `go` would
format differently - this may be different from the CI server version.
You should run revive, vet and spell-check on the code with:
```bash
make revive vet misspell-check
```
### Updating CSS
To generate the CSS, you will need [Node.js](https://nodejs.org/) 8.0 or greater with npm. At present we use [less](http://lesscss.org/) and [postcss](https://postcss.org) to generate our CSS. Do **not** edit the files in `public/css` directly, as they are generated from `lessc` from the files in `public/less`.
Edit files in `public/less`, run the linter, regenerate the CSS and commit all changed files:
```bash
make css
```
### Updating JS
To run the JavaScript linter you will need [Node.js](https://nodejs.org/) 8.0 or greater with npm. Edit files in `public/js` and run the linter:
```bash
make js
```
### Updating the API
When creating new API routes or modifying existing API routes, you **MUST**
update and/or create [Swagger](https://swagger.io/docs/specification/2-0/what-is-swagger/)
documentation for these using [go-swagger](https://goswagger.io/) comments.
The structure of these comments is described in the [specification](https://goswagger.io/use/spec.html#annotation-syntax).
If you want more information about the Swagger structure, you can look at the
[Swagger 2.0 Documentation](https://swagger.io/docs/specification/2-0/basic-structure/)
or compare with a previous PR adding a new API endpoint, e.g. [PR #5483](https://github.com/go-gitea/gitea/pull/5843/files#diff-2e0a7b644cf31e1c8ef7d76b444fe3aaR20)
You should be careful not to break the API for downstream users which depend
on a stable API. In general, this means additions are acceptable, but deletions
or fundamental changes to the API will be rejected.
Once you have created or changed an API endpoint, please regenerate the Swagger
documentation using:
```bash
make generate-swagger
```
You should validate your generated Swagger file and spell-check it with:
```bash
make swagger-validate misspell-check
```
You should commit the changed swagger JSON file. The continous integration
server will check that this has been done using:
```bash
make swagger-check
```
**Note**: Please note you should use the Swagger 2.0 documentation, not the
OpenAPI 3 documentation.
### Creating new configuration options
When creating new configuration options, it is not enough to add them to the
`modules/setting` files. You should add information to `custom/conf/app.ini`
and to the
<a href='{{< relref "doc/advanced/config-cheat-sheet.en-us.md" >}}'>configuration cheat sheet</a>
found in `docs/content/doc/advanced/config-cheat-sheet.en-us.md`
### Changing the logo
When changing the Gitea logo SVG, you will need to run and commit the results
of:
```bash
make generate-images
```
This will create the necessary Gitea favicon and others.
### Database Migrations
If you make breaking changes to any of the database persisted structs in the
`models/` directory, you will need to make a new migration. These can be found
in `models/migrations/`. You can ensure that your migrations work for the main
database types using:
```bash
make test-sqlite-migration # with sqlite switched for the appropriate database
```
## Testing
There are two types of test run by Gitea: Unit tests and Integration Tests.
```bash
TAGS="bindata sqlite sqlite_unlock_notify" make test # Runs the unit tests
```
Unit tests will not and cannot completely test Gitea alone. Therefore, we
have written integration tests; however, these are database dependent.
```bash
TAGS="bindata sqlite sqlite_unlock_notify" make generate build test-sqlite
```
will run the integration tests in an sqlite environment. Other database tests
are available but may need adjustment to the local environment.
Look at
[`integrations/README.md`](https://github.com/go-gitea/gitea/blob/master/integrations/README.md)
for more information and how to run a single test.
Our continuous integration will test the code passes its unit tests and that
all supported databases will pass integration test in a Docker environment.
Migration from several recent versions of Gitea will also be tested.
Please submit your PR with additional tests and integration tests as
appropriate.
## Documentation for the website
Documentation for the website is found in `docs/`. If you change this you
can test your changes to ensure that they pass continuous integration using:
```bash
cd "$GOPATH/src/code.gitea.io/gitea/docs"
make trans-copy clean build
```
You will require a copy of [Hugo](https://gohugo.io/) to run this task. Please
note: this may generate a number of untracked git objects, which will need to
be cleaned up.
## Visual Studio Code
A `launch.json` and `tasks.json` are provided within `contrib/ide/vscode` for
Visual Studio Code. Look at
[`contrib/ide/README.md`](https://github.com/go-gitea/gitea/blob/master/contrib/ide/README.md)
for more information.
## Submitting PRs
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
branches as we will need to update it to master before merging and/or may be
able to help fix issues directly.
Any PR requires two approvals from the Gitea maintainers and needs to pass the
continous integration. Take a look at our
[`CONTRIBUTING.md`](https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md)
document.
If you need more help pop on to [Discord](https://discord.gg/gitea) #Develop
and chat there.
That's it! You are ready to hack on Gitea.

View File

@ -0,0 +1,390 @@
---
date: "2019-04-02T17:06:00+01:00"
title: "Advanced: Logging Configuration"
slug: "logging-configuration"
weight: 55
toc: true
draft: false
menu:
sidebar:
parent: "advanced"
name: "Logging Configuration"
weight: 55
identifier: "logging-configuration"
---
# Logging Configuration
The logging framework has been revamped in Gitea 1.9.0.
## Log Groups
The fundamental thing to be aware of in Gitea is that there are several
log groups:
* The "Default" logger
* The Macaron logger
* The Router logger
* The Access logger
* The XORM logger
There is also the go log logger.
### The go log logger
Go provides its own extremely basic logger in the `log` package,
however, this is not sufficient for our purposes as it does not provide
a way of logging at multiple levels, nor does it provide a good way of
controlling where these logs are logged except through setting of a
writer.
We have therefore redirected this logger to our Default logger, and we
will log anything that is logged using the go logger at the INFO level.
### The "Default" logger
Calls to `log.Info`, `log.Debug`, `log.Error` etc. from the `code.gitea.io/gitea/modules/log` package will log to this logger.
You can configure the outputs of this logger by setting the `MODE`
value in the `[log]` section of the configuration.
Each output sublogger is configured in a separate `[log.sublogger]`
section, but there are certain default values. These will not be inherited from the `[log]` section:
* `FLAGS` is `stdflags` (Equal to
`date,time,medfile,shortfuncname,levelinitial`)
* `FILE_NAME` will default to `%(ROOT_PATH)/gitea.log`
* `EXPRESSION` will default to `""`
* `PREFIX` will default to `""`
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
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.
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
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`.
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
configuration. `ROUTER` will default to `console` if unset. The Gitea
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.
Each output sublogger for this logger is configured in
`[log.sublogger.router]` sections. There are certain default values
which will not be inherited from the `[log]` or relevant
`[log.sublogger]` sections:
* `FILE_NAME` will default to `%(ROOT_PATH)/router.log`
* `FLAGS` defaults to `date,time`
* `EXPRESSION` will default to `""`
* `PREFIX` will default to `""`
NB: You can redirect the router logger to send its events to the Gitea
log using the value: `ROUTER = ,`
### The "Access" logger
The Access logger is a new logger for version 1.9. It provides a NCSA
Common Log compliant log format. It's highly configurable but caution
should be taken when changing its template. The main benefit of this
logger is that Gitea can now log accesses in a standard log format so
standard tools may be used.
You can enable this logger using `ENABLE_ACCESS_LOG`. Its outputs are
configured by setting the `ACCESS` value in the `[log]` section of the
configuration. `ACCESS` defaults to `file` if unset.
Each output sublogger for this logger is configured in
`[log.sublogger.access]` sections. There are certain default values
which will not be inherited from the `[log]` or relevant
`[log.sublogger]` sections:
* `FILE_NAME` will default to `%(ROOT_PATH)/access.log`
* `FLAGS` defaults to `` or None
* `EXPRESSION` will default to `""`
* `PREFIX` will default to `""`
If desired the format of the Access logger can be changed by changing
the value of the `ACCESS_LOG_TEMPLATE`.
NB: You can redirect the access logger to send its events to the Gitea
log using the value: `ACCESS = ,`
#### The ACCESS_LOG_TEMPLATE
This value represent a go template. It's default value is:
`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`
The template is passed following options:
* `Ctx` is the `macaron.Context`
* `Identity` is the `SignedUserName` or `"-"` if the user is not logged
in
* `Start` is the start time of the request
* `ResponseWriter` is the `macaron.ResponseWriter`
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
as it runs for every request.
### The "XORM" logger
The XORM logger is a long-standing logger that exists to collect XORM
log events. It is enabled by default but can be switched off by setting
`ENABLE_XORM_LOG` to `false` in the `[log]` section. Its outputs are
configured by setting the `XORM` value in the `[log]` section of the
configuration. `XORM` defaults to `,` if unset, meaning it is redirected
to the main Gitea log.
XORM will log SQL events by default. This can be changed by setting
the `LOG_SQL` value to `false` in the `[database]` section.
Each output sublogger for this logger is configured in
`[log.sublogger.xorm]` sections. There are certain default values
which will not be inherited from the `[log]` or relevant
`[log.sublogger]` sections:
* `FILE_NAME` will default to `%(ROOT_PATH)/xorm.log`
* `FLAGS` defaults to `date,time`
* `EXPRESSION` will default to `""`
* `PREFIX` will default to `""`
## Log outputs
Gitea provides 4 possible log outputs:
* `console` - Log to `os.Stdout` or `os.Stderr`
* `file` - Log to a file
* `conn` - Log to a keep-alive TCP connection
* `smtp` - Log via email
Certain configuration is common to all modes of log output:
* `LEVEL` is the lowest level that this output will log. This value
is inherited from `[log]` and in the case of the non-default loggers
from `[log.sublogger]`.
* `STACKTRACE_LEVEL` is the lowest level that this output will print
a stacktrace. This value is inherited.
* `MODE` is the mode of the log output. It will default to the sublogger
name. Thus `[log.console.macaron]` will default to `MODE = console`.
* `COLORIZE` will default to `true` for `console` as
described, otherwise it will default to `false`.
### Non-inherited default values
There are several values which are not inherited as described above but
rather default to those specific to type of logger, these are:
`EXPRESSION`, `FLAGS`, `PREFIX` and `FILE_NAME`.
#### `EXPRESSION`
`EXPRESSION` represents a regular expression that log events must match to be logged by the sublogger. Either the log message, (with colors removed), must match or the `longfilename:linenumber:functionname` must match. NB: the whole message or string doesn't need to completely match.
Please note this expression will be run in the sublogger's goroutine
not the logging event subroutine. Therefore it can be complicated.
#### `FLAGS`
`FLAGS` represents the preceding logging context information that is
printed before each message. It is a comma-separated string set. The order of values does not matter.
Possible values are:
* `none` or `,` - No flags.
* `date` - the date in the local time zone: `2009/01/23`.
* `time` - the time in the local time zone: `01:23:23`.
* `microseconds` - microsecond resolution: `01:23:23.123123`. Assumes
time.
* `longfile` - full file name and line number: `/a/b/c/d.go:23`.
* `shortfile` - final file name element and line number: `d.go:23`.
* `funcname` - function name of the caller: `runtime.Caller()`.
* `shortfuncname` - last part of the function name. Overrides
`funcname`.
* `utc` - if date or time is set, use UTC rather than the local time
zone.
* `levelinitial` - Initial character of the provided level in brackets eg. `[I]` for info.
* `level` - Provided level in brackets `[INFO]`
* `medfile` - Last 20 characters of the filename - equivalent to
`shortfile,longfile`.
* `stdflags` - Equivalent to `date,time,medfile,shortfuncname,levelinitial`
### Console mode
For loggers in console mode, `COLORIZE` will default to `true` if not
on windows, or the windows terminal can be set into ANSI mode or is a
cygwin or Msys pipe.
If `STDERR` is set to `true` the logger will use `os.Stderr` instead of
`os.Stdout`.
### File mode
The `FILE_NAME` defaults as described above. If set it will be relative
to the provided `ROOT_PATH` in the master `[log]` section.
Other values:
* `LOG_ROTATE`: **true**: Rotate the log files.
* `MAX_SIZE_SHIFT`: **28**: Maximum size shift of a single file, 28 represents 256Mb.
* `DAILY_ROTATE`: **true**: Rotate logs daily.
* `MAX_DAYS`: **7**: Delete the log file after n days
* `COMPRESS`: **true**: Compress old log files by default with gzip
* `COMPRESSION_LEVEL`: **-1**: Compression level
### Conn mode
* `RECONNECT_ON_MSG`: **false**: Reconnect host for every single message.
* `RECONNECT`: **false**: Try to reconnect when connection is lost.
* `PROTOCOL`: **tcp**: Set the protocol, either "tcp", "unix" or "udp".
* `ADDR`: **:7020**: Sets the address to connect to.
### SMTP mode
It is not recommended to use this logger to send general logging
messages. However, you could perhaps set this logger to work on `FATAL`.
* `USER`: User email address to send from.
* `PASSWD`: Password for the smtp server.
* `HOST`: **127.0.0.1:25**: The SMTP host to connect to.
* `RECEIVERS`: Email addresses to send to.
* `SUBJECT`: **Diagnostic message from Gitea**
## Default Configuration
The default empty configuration is equivalent to:
```ini
[log]
ROOT_PATH = %(GITEA_WORK_DIR)/log
MODE = console
LEVEL = Info
STACKTRACE_LEVEL = None
REDIRECT_MACARON_LOG = false
ENABLE_ACCESS_LOG = false
ENABLE_XORM_LOG = true
XORM = ,
[log.console]
MODE = console
LEVEL = %(LEVEL)
STACKTRACE_LEVEL = %(STACKTRACE_LEVEL)
FLAGS = stdflags
PREFIX =
COLORIZE = true # Or false if your windows terminal cannot color
```
This is equivalent to sending all logs to the console, with default go log being sent to the console log too.
## Log colorization
Logs to the console will be colorized by default when not running on
Windows. Terminal sniffing will occur on Windows and if it is
determined that we are running on a terminal capable of color we will
colorize.
Further, on *nix it is becoming common to have file logs that are
colored by default. Therefore file logs will be colorised by default
when not running on Windows.
You can switch on or off colorization by using the `COLORIZE` value.
From a development point of view. If you write
`log.Info("A %s string", "formatted")` the `formatted` part of the log
message will be Bolded on colorized logs.
You can change this by either rendering the formatted string yourself.
Or you can wrap the value in a `log.ColoredValue` struct.
The `log.ColoredValue` struct contains a pointer to value, a pointer to
string of bytes which should represent a color and second set of reset
bytes. Pointers were chosen to prevent copying of large numbers of
values. There are several helper methods:
* `log.NewColoredValue` takes a value and 0 or more color attributes
that represent the color. If 0 are provided it will default to a cached
bold. Note, it is recommended that color bytes constructed from
attributes should be cached if this is a commonly used log message.
* `log.NewColoredValuePointer` takes a pointer to a value, and
0 or more color attributes that represent the color.
* `log.NewColoredValueBytes` takes a value and a pointer to an array
of bytes representing the color.
These functions will not double wrap a `log.ColoredValue`. They will
also set the `resetBytes` to the cached `resetBytes`.
The `colorBytes` and `resetBytes` are not exported to prevent
accidental overwriting of internal values.
## ColorFormat & ColorFormatted
Structs may implement the `log.ColorFormatted` interface by implementing the `ColorFormat(fmt.State)` function.
If a `log.ColorFormatted` struct is logged with `%-v` format, its `ColorFormat` will be used instead of the usual `%v`. The full `fmt.State` will be passed to allow implementers to look at additional flags.
In order to help implementers provide `ColorFormat` methods. There is a
`log.ColorFprintf(...)` function in the log module that will wrap values in `log.ColoredValue` and recognise `%-v`.
In general it is recommended not to make the results of this function too verbose to help increase its versatility. Usually this should simply be an `ID`:`Name`. If you wish to make a more verbose result, it is recommended to use `%-+v` as your marker.
## Log Spoofing protection
In order to protect the logs from being spoofed with cleverly
constructed messages. Newlines are now prefixed with a tab and control
characters except those used in an ANSI CSI are escaped with a
preceding `\` and their octal value.
## Creating a new named logger group
Should a developer wish to create a new named logger, `NEWONE`. It is
recommended to add an `ENABLE_NEWONE_LOG` value to the `[log]`
section, and to add a new `NEWONE` value for the modes.
A function like `func newNewOneLogService()` is recommended to manage
construction of the named logger. e.g.
```go
func newNewoneLogService() {
EnableNewoneLog = Cfg.Section("log").Key("ENABLE_NEWONE_LOG").MustBool(false)
Cfg.Section("log").Key("NEWONE").MustString("file") // or console? or "," if you want to send this to default logger by default
if EnableNewoneLog {
options := newDefaultLogOptions()
options.filename = filepath.Join(LogRootPath, "newone.log")
options.flags = "stdflags"
options.bufferLength = Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000)
generateNamedLogger("newone", options)
}
}
```
You should then add `newOneLogService` to `NewServices()` in
`modules/setting/setting.go`

View File

@ -0,0 +1,73 @@
---
date: "2019-04-15T17:29:00+08:00"
title: "Advanced: Migrations Interfaces"
slug: "migrations-interfaces"
weight: 30
toc: true
draft: false
menu:
sidebar:
parent: "advanced"
name: "Migrations Interfaces"
weight: 55
identifier: "migrations-interfaces"
---
# Migration Features
The new migration features were introduced in Gitea 1.9.0. It defines two interfaces to support migrating
repositories data from other git host platforms to gitea or, in the future migrating gitea data to other
git host platforms. Currently, only the migrations from github via APIv3 to Gitea is implemented.
First of all, Gitea defines some standard objects in packages `modules/migrations/base`. They are
`Repository`, `Milestone`, `Release`, `Label`, `Issue`, `Comment`, `PullRequest`.
## Downloader Interfaces
To migrate from a new git host platform, there are two steps to be updated.
- You should implement a `Downloader` which will get all kinds of repository informations.
- You should implement a `DownloaderFactory` which is used to detect if the URL matches and
create a Downloader.
- You'll need to register the `DownloaderFactory` via `RegisterDownloaderFactory` on init.
```Go
type Downloader interface {
GetRepoInfo() (*Repository, error)
GetTopics() ([]string, error)
GetMilestones() ([]*Milestone, error)
GetReleases() ([]*Release, error)
GetLabels() ([]*Label, error)
GetIssues(start, limit int) ([]*Issue, error)
GetComments(issueNumber int64) ([]*Comment, error)
GetPullRequests(start, limit int) ([]*PullRequest, error)
}
```
```Go
type DownloaderFactory interface {
Match(opts MigrateOptions) (bool, error)
New(opts MigrateOptions) (Downloader, error)
}
```
## Uploader Interface
Currently, only a `GiteaLocalUploader` is implemented, so we only save downloaded
data via this `Uploader` on the local Gitea instance. Other uploaders are not supported
and will be implemented in future.
```Go
// Uploader uploads all the informations
type Uploader interface {
CreateRepo(repo *Repository, includeWiki bool) error
CreateMilestone(milestone *Milestone) error
CreateRelease(release *Release) error
CreateLabel(label *Label) error
CreateIssue(issue *Issue) error
CreateComment(issueNumber int64, comment *Comment) error
CreatePullRequest(pr *PullRequest) error
Rollback() error
}
```

View File

@ -0,0 +1,92 @@
---
date: "2019-04-19:44:00+01:00"
title: "OAuth2 provider"
slug: "oauth2-provider"
weight: 41
toc: true
draft: false
menu:
sidebar:
parent: "advanced"
name: "OAuth2 Provider"
weight: 41
identifier: "oauth2-provider"
---
# OAuth2 provider
Gitea supports acting as an OAuth2 provider to allow third party applications to access its resources with the user's consent. This feature is available since release 1.8.0.
## Endpoints
Endpoint | URL
-----------------------|----------------------------
Authorization Endpoint | `/login/oauth/authorize`
Access Token Endpoint | `/login/oauth/access_token`
## Supported OAuth2 Grants
At the moment Gitea only supports the [**Authorization Code Grant**](https://tools.ietf.org/html/rfc6749#section-1.3.1) standard with additional support of the [Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636) extension.
To use the Authorization Code Grant as a third party application it is required to register a new application via the "Settings" (`/user/settings/applications`) section of the settings.
## Scopes
Currently Gitea does not support scopes (see [#4300](https://github.com/go-gitea/gitea/issues/4300)) and all third party applications will be granted access to all resources of the user and his/her organizations.
## Example
**Note:** This example does not use PKCE.
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
```
The `CLIENT_ID` can be obtained by registering an application in the settings. The `STATE` is a random string that will be send back to your application after the user authorizes. The `state` parameter is optional but should be used to prevent CSRF attacks.
![Authorization Page](/authorize.png)
The user will now be asked to authorize your application. If they authorize it, the user will be redirected to the `REDIRECT_URL`, for example:
```curl
https://[REDIRECT_URI]?code=RETURNED_CODE&state=STATE
```
2. Using the provided `code` from the redirect, you can request a new application and refresh token. The access token endpoints accepts POST requests with `application/json` and `application/x-www-form-urlencoded` body, for example:
```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"
}
```
Response:
```json
{
"access_token":"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJnbnQiOjIsInR0IjowLCJleHAiOjE1NTUxNzk5MTIsImlhdCI6MTU1NTE3NjMxMn0.0-iFsAwBtxuckA0sNZ6QpBQmywVPz129u75vOM7wPJecw5wqGyBkmstfJHAjEOqrAf_V5Z-1QYeCh_Cz4RiKug",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJnbnQiOjIsInR0IjoxLCJjbnQiOjEsImV4cCI6MTU1NzgwNDMxMiwiaWF0IjoxNTU1MTc2MzEyfQ.S_HZQBy4q9r5SEzNGNIoFClT43HPNDbUdHH-GYNYYdkRfft6XptJBkUQscZsGxOW975Yk6RbgtGvq1nkEcklOw"
}
```
The `CLIENT_SECRET` is the unique secret code generated for this application. Please note that the secret will only be visible after you created/registered the application with Gitea and cannot be recovered. If you lose the secret you must regenerate the secret via the application's settings.
The `REDIRECT_URI` in the `access_token` request must match the `REDIRECT_URI` in the `authorize` request.
3. Use the `access_token` to make [API requests](https://docs.gitea.io/en-us/api-usage#oauth2) to access the user's resources.

View File

@ -0,0 +1,58 @@
---
date: "2019-09-06T01:35:00-03:00"
title: "Repository indexer"
slug: "repo-indexer"
weight: 45
toc: true
draft: false
menu:
sidebar:
parent: "advanced"
name: "Repository indexer"
weight: 45
identifier: "repo-indexer"
---
# Repository indexer
## Setting up the repository indexer
Gitea can search through the files of the repositories by enabling this function in your [`app.ini`](https://docs.gitea.io/en-us/config-cheat-sheet/):
```
[indexer]
; ...
REPO_INDEXER_ENABLED = true
REPO_INDEXER_PATH = indexers/repos.bleve
UPDATE_BUFFER_LEN = 20
MAX_FILE_SIZE = 1048576
REPO_INDEXER_INCLUDE =
REPO_INDEXER_EXCLUDE = resources/bin/**
```
Please bear in mind that indexing the contents can consume a lot of system resources, especially when the index is created for the first time or globally updated (e.g. after upgrading Gitea).
### Choosing the files for indexing by size
The `MAX_FILE_SIZE` option will make the indexer skip all files larger than the specified value.
### Choosing the files for indexing by path
Gitea applies glob pattern matching from the [`gobwas/glob` library](https://github.com/gobwas/glob) to choose which files will be included in the index.
Limiting the list of files prevents the indexes from becoming polluted with derived or irrelevant files (e.g. lss, sym, map, etc.), so the search results are more relevant. It can also help reduce the index size.
`REPO_INDEXER_INCLUDE` (default: empty) is a comma separated list of glob patterns to **include** in the index. An empty list means "_include all files_".
`REPO_INDEXER_EXCLUDE` (default: empty) is a comma separated list of glob patterns to **exclude** from the index. Files that match this list will not be indexed. `REPO_INDEXER_EXCLUDE` takes precedence over `REPO_INDEXER_INCLUDE`.
Pattern matching works as follows:
* To match all files with a `.txt` extension no matter what directory, use `**.txt`.
* To match all files with a `.txt` extension _only at the root level of the repository_, use `*.txt`.
* To match all files inside `resources/bin` and below, use `resources/bin/**`.
* To match all files _immediately inside_ `resources/bin`, use `resources/bin/*`.
* To match all files named `Makefile`, use `**Makefile`.
* Matching a directory has no effect; the pattern `resources/bin` will not include/exclude files inside that directory; `resources/bin/**` will.
* All files and patterns are normalized to lower case, so `**Makefile`, `**makefile` and `**MAKEFILE` are equivalent.

View File

@ -0,0 +1,162 @@
---
date: "2019-08-17T10:20:00+01:00"
title: "GPG Commit Signatures"
slug: "signing"
weight: 20
toc: false
draft: false
menu:
sidebar:
parent: "advanced"
name: "GPG Commit Signatures"
weight: 20
identifier: "signing"
---
# GPG Commit Signatures
Gitea will verify GPG commit signatures in the provided tree by
checking if the commits are signed by a key within the gitea database,
or if the commit matches the default key for git.
Keys are not checked to determine if they have expired or revoked.
Keys are also not checked with keyservers.
A commit will be marked with a grey unlocked icon if no key can be
found to verify it. If a commit is marked with a red unlocked icon,
it is reported to be signed with a key with an id.
Please note: The signer of a commit does not have to be an author or
committer of a commit.
This functionality requires git >= 1.7.9 but for full functionality
this requires git >= 2.0.0.
## Automatic Signing
There are a number of places where Gitea will generate commits itself:
* Repository Initialisation
* Wiki Changes
* CRUD actions using the editor or the API
* Merges from Pull Requests
Depending on configuration and server trust you may want Gitea to
sign these commits.
## General Configuration
Gitea's configuration for signing can be found with the
`[repository.signing]` section of `app.ini`:
```ini
...
[repository.signing]
SIGNING_KEY = default
SIGNING_NAME =
SIGNING_EMAIL =
INITIAL_COMMIT = always
CRUD_ACTIONS = pubkey, twofa, parentsigned
WIKI = never
MERGES = pubkey, twofa, basesigned, commitssigned
...
```
### `SIGNING_KEY`
The first option to discuss is the `SIGNING_KEY`. There are three main
options:
* `none` - this prevents Gitea from signing any commits
* `default` - Gitea will default to the key configured within
`git config`
* `KEYID` - Gitea will sign commits with the gpg key with the ID
`KEYID`. In this case you should provide a `SIGNING_NAME` and
`SIGNING_EMAIL` to be displayed for this key.
The `default` option will interrogate `git config` for
`commit.gpgsign` option - if this is set, then it will use the results
of the `user.signingkey`, `user.name` and `user.email` as appropriate.
Please note: by adjusting git's `config` file within Gitea's
repositories, `SIGNING_KEY=default` could be used to provide different
signing keys on a per-repository basis. However, this is cleary not an
ideal UI and therefore subject to change.
### `INITIAL_COMMIT`
This option determines whether Gitea should sign the initial commit
when creating a repository. The possible values are:
* `never`: Never sign
* `pubkey`: Only sign if the user has a public key
* `twofa`: Only sign if the user logs in with two factor authentication
* `always`: Always sign
Options other than `never` and `always` can be combined as a comma
separated list.
### `WIKI`
This options determines if Gitea should sign commits to the Wiki.
The possible values are:
* `never`: Never sign
* `pubkey`: Only sign if the user has a public key
* `twofa`: Only sign if the user logs in with two factor authentication
* `parentsigned`: Only sign if the parent commit is signed.
* `always`: Always sign
Options other than `never` and `always` can be combined as a comma
separated list.
### `CRUD_ACTIONS`
This option determines if Gitea should sign commits from the web
editor or API CRUD actions. The possible values are:
* `never`: Never sign
* `pubkey`: Only sign if the user has a public key
* `twofa`: Only sign if the user logs in with two factor authentication
* `parentsigned`: Only sign if the parent commit is signed.
* `always`: Always sign
Options other than `never` and `always` can be combined as a comma
separated list.
### `MERGES`
This option determines if Gitea should sign merge commits from PRs.
The possible options are:
* `never`: Never sign
* `pubkey`: Only sign if the user has a public key
* `twofa`: Only sign if the user logs in with two factor authentication
* `basesigned`: Only sign if the parent commit in the base repo is signed.
* `headsigned`: Only sign if the head commit in the head branch is signed.
* `commitssigned`: Only sign if all the commits in the head branch to the merge point are signed.
* `always`: Always sign
Options other than `never` and `always` can be combined as a comma
separated list.
## Installing and generating a GPG key for Gitea
It is up to a server administrator to determine how best to install
a signing key. Gitea generates all its commits using the server `git`
command at present - and therefore the server `gpg` will be used for
signing (if configured.) Administrators should review best-practices
for gpg - in particular it is probably advisable to only install a
signing secret subkey without the master signing and certifying secret
key.
## Obtaining the Public Key of the Signing Key
The public key used to sign Gitea's commits can be obtained from the API at:
```/api/v1/signing-key.gpg```
In cases where there is a repository specific key this can be obtained from:
```/api/v1/repos/:username/:reponame/signing-key.gpg```

View File

@ -59,7 +59,7 @@ For documentation about each of the variables available, refer to the
* `HOST`: Host Macaron will listen on * `HOST`: Host Macaron will listen on
* `PORT`: Port Macaron will listen on * `PORT`: Port Macaron will listen on
* `MACARON_ENV`: global variable to provide special functionality for development environments * `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 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 be recompiled on every request. For more performance, set the MACARON_ENV environment variable
to "production". to "production".

View File

@ -0,0 +1,37 @@
---
date: "2018-05-22T11:00:00+00:00"
title: "Advanced: Third Party Tools"
slug: "third-party-tools"
weight: 50
toc: true
draft: false
menu:
sidebar:
parent: "advanced"
name: "Third Party Tools"
weight: 50
identifier: "third-party-tools"
---
# List of third-party tools
**NOTE:** These tools are not endorsed by Gitea. They are listed here for convenience only.
*This is by no means a complete list, so feel free to ask about adding more!*
### Continuous Integration
Check our [CI/CD page]({{< relref "doc/advanced/ci-cd.en-us.md" >}})
### Internationalization
[Weblate](https://docs.weblate.org/en/latest/admin/continuous.html#gitea-setup)
### Migrating
[Installation script for Gitea](https://git.coolaj86.com/coolaj86/gitea-installer.sh)
[GitHub Migrator](https://gitea.com/gitea/migrator)
### Mobile
[GitNex for Android](https://gitlab.com/mmarif4u/gitnex)
### Editor Extensions
- [Gitea Extension for Visual Studio](https://github.com/maikebing/Gitea.VisualStudio) Download from [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=MysticBoy.GiteaExtensionforVisualStudio)

View File

@ -91,7 +91,7 @@ Both the LDAP via BindDN and the simple auth LDAP share the following fields:
name given on sign-in form. name given on sign-in form.
- Example: `(&(objectClass=posixAccount)(uid=%s))` - Example: `(&(objectClass=posixAccount)(uid=%s))`
- Example for Microsoft Active Directory (AD): `(&(objectCategory=Person)(memberOf=CN=user-group,OU=example,DC=example,DC=org)(sAMAccountName=%s)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))` - Example for Microsoft Active Directory (AD): `(&(objectCategory=Person)(memberOf=CN=user-group,OU=example,DC=example,DC=org)(sAMAccountName=%s)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))`
- To substitute more than once `%[1]s` should be used instead, e.g. when - To substitute more than once, `%[1]s` should be used instead, e.g. when
matching supplied login name against multiple attributes such as user matching supplied login name against multiple attributes such as user
identifier, email or even phone number. identifier, email or even phone number.
- Example: `(&(objectClass=Person)(|(uid=%[1]s)(mail=%[1]s)(mobile=%[1]s)))` - Example: `(&(objectClass=Person)(|(uid=%[1]s)(mail=%[1]s)(mobile=%[1]s)))`
@ -115,6 +115,10 @@ Both the LDAP via BindDN and the simple auth LDAP share the following fields:
- Example: `cn=%s,ou=Users,dc=mydomain,dc=com` - Example: `cn=%s,ou=Users,dc=mydomain,dc=com`
- Example: `uid=%s,ou=Users,dc=mydomain,dc=com` - Example: `uid=%s,ou=Users,dc=mydomain,dc=com`
- User Search Base (optional)
- The LDAP base at which user accounts will be searched for.
- Example: `ou=Users,dc=mydomain,dc=com`
- User Filter **(required)** - User Filter **(required)**
- An LDAP filter declaring when a user should be allowed to log in. The `%s` - An LDAP filter declaring when a user should be allowed to log in. The `%s`
matching parameter will be substituted with login name given on sign-in matching parameter will be substituted with login name given on sign-in
@ -181,7 +185,7 @@ configure this, set the fields below:
## FreeIPA ## FreeIPA
- In order to log in to Gitea using FreeIPA credentials,a bind account needs to - In order to log in to Gitea using FreeIPA credentials, a bind account needs to
be created for Gitea: be created for Gitea:
- On the FreeIPA server, create a `gitea.ldif` file, replacing `dc=example,dc=com` - On the FreeIPA server, create a `gitea.ldif` file, replacing `dc=example,dc=com`

View File

@ -15,9 +15,9 @@ menu:
# Gitea compared to other Git hosting options # Gitea compared to other Git hosting options
To help decide if Gitea is suited for your needs here is how it compares to other Git self hosted options. To help decide if Gitea is suited for your needs, here is how it compares to other Git self hosted options.
Be warned that we don't regularly check for feature changes in other products so this list can be outdated. If you find anything that needs to be updated in table below please report [issue on Github](https://github.com/go-gitea/gitea/issues). Be warned that we don't regularly check for feature changes in other products, so this list may be outdated. If you find anything that needs to be updated in the table below, please report it in an [issue on GitHub](https://github.com/go-gitea/gitea/issues).
_Symbols used in table:_ _Symbols used in table:_
@ -40,11 +40,11 @@ _Symbols used in table:_
| Orgmode support | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? | | Orgmode support | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? |
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? | | CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? | | Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
| Static Git-powered pages | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Static Git-powered pages | [](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | | Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ | | Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
| Built-in Container Registry | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Built-in Container Registry | [](https://github.com/go-gitea/gitea/issues/2316) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
| FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Built-in CI/CD | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Built-in CI/CD | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
@ -62,7 +62,7 @@ _Symbols used in table:_
| 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 | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ | | Reject unsigned commits | [](https://github.com/go-gitea/gitea/issues/2770) | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
@ -81,13 +81,15 @@ _Symbols used in table:_
| Related issues | ✘ | ✘ | | ✘ | ✓ | ✘ | ✘ | | Related issues | ✘ | ✘ | | ✘ | ✓ | ✘ | ✘ |
| Confidential issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Confidential issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Lock Discussion | | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Lock Discussion | | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Issue Boards | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Issue Boards | [](https://github.com/go-gitea/gitea/issues/3476) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Create new branches from issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Create new branches from issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Global issue search | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Global issue search | [](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | | Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
| Create issue via email | [](https://github.com/go-gitea/gitea/issues/6226) | [](https://github.com/gogs/gogs/issues/2602) | ✘ | ✘ | ✓ | ✓ | ✘ |
| Service Desk | [](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | ✘ | ✓ | ✘ | ✘ |
#### Pull/Merge requests #### Pull/Merge requests
@ -98,11 +100,12 @@ _Symbols used in table:_
| Rebase merging | ✓ | ✓ | ✓ | ✘ | | ✘ | ✓ | | Rebase merging | ✓ | ✓ | ✓ | ✘ | | ✘ | ✓ |
| Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Pull/Merge request approval | ✓ | ✘ | | ✓ | ✓ | ✓ | ✓ | | Pull/Merge request approval | ✓ | ✘ | | ✓ | ✓ | ✓ | ✓ |
| Merge conflict resolution | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Merge conflict resolution | [](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | | ✓ | ✓ | ✓ | | Restrict push and merge access to certain users | ✓ | ✘ | ✓ | | ✓ | ✓ | ✓ |
| Revert specific commits or a merge request | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Revert specific commits or a merge request | [](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | | Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Cherry-picking changes | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Cherry-picking changes | [](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | [/](https://jira.atlassian.com/plugins/servlet/mobile#issue/BCLOUD-8323) | ✘ |
#### 3rd-party integrations #### 3rd-party integrations
@ -116,8 +119,9 @@ _Symbols used in table:_
| LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| OpenId Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ | | OpenId Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
| OAuth 2.0 integration (external authorization) | ✓ | ✘ | | ✓ | ✓ | ? | ✓ | | OAuth 2.0 integration (external authorization) | ✓ | ✘ | | ✓ | ✓ | ? | ✓ |
| Act as OAuth 2.0 provider | | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Act as OAuth 2.0 provider | [](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | | Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Mattermost/Slack integration | ✓ | ✓ | | ✓ | ✓ | | ✓ | | Mattermost/Slack integration | ✓ | ✓ | | ✓ | ✓ | | ✓ |
| Discord integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | | Discord integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Microsoft Teams integration | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| External CI/CD status display | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | External CI/CD status display | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |

View File

@ -0,0 +1,127 @@
---
date: "2019-02-14T11:51:04+08:00"
title: "横向对比 Gitea 与其它 Git 托管工具"
slug: "comparison"
weight: 5
toc: true
draft: false
menu:
sidebar:
parent: "features"
name: "横向对比"
weight: 5
identifier: "comparison"
---
# 横向对比 Gitea 与其它 Git 托管工具
这里列出了 Gitea 与其它一些 Git 托管工具之间的异同,以便确认 Gitea 是否能够满足您的需求。
请注意,此列表中的某些表项可能已经过时,因为我们并没有定期检查其它产品的功能是否有所更改。你可以前往 [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 驱动的静态 pages | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Git 驱动的集成化 wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
| 部署令牌 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 仓库写权限令牌 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
| 内置容器 Registry | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| 外部 Git 镜像 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
| FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| 内置 CI/CD | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| 子组织:组织内的组织 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
#### 代码管理
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|------------------------------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
| 仓库主题描述 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| 仓库内代码搜索 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 全局代码搜索 | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | | ✓ |
| 组织里程碑 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| 细粒度用户角色 (例如 Code, Issues, Wiki) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| 提交人的身份验证 | ✘ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
| GPG 签名的提交 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 拒绝未用通过验证的提交 | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
| 仓库活跃度页面 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 分支管理 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 建立新分支 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| 在线代码编辑 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 提交的统计图表 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
#### Issue 管理
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|----------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
| 跟踪 Issue | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Issue 模板 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| 标签 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| 跟踪时间 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Issue 可有多个负责人 | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
| 关联的 issues | ✘ | ✘ | | ✘ | ✓ | ✘ | ✘ |
| 私密 issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| 评论反馈 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| 锁定讨论 | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Issue 批量处理 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Issue 看板 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| 从 issues 创建分支 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Issue 搜索 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| 全局 Issue 搜索 | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Issue 依赖 | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
| 通过 Email 创建工单 | [](https://github.com/go-gitea/gitea/issues/6226) | [](https://github.com/gogs/gogs/issues/2602) | ✘ | ✘ | ✓ | ✓ | ✘ |
| Service Desk | [](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | ✘ | ✓ | ✘ | ✘ |
#### Pull/Merge requests
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|--------------------------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Squash merging | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
| Rebase merging | ✓ | ✓ | ✓ | ✘ | | ✘ | ✓ |
| 评论 Pull/Merge request 中的某行代码 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 指定 Pull/Merge request 的审核人 | ✓ | ✘ | | ✓ | ✓ | ✓ | ✓ |
| 解决 Merge 冲突 | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| 限制某些用户的 push 和 merge 权限 | ✓ | ✘ | ✓ | | ✓ | ✓ | ✓ |
| 回退某些 commits 或 merge request | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Pull/Merge requests 模板 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| 查看 Cherry-picking 的更改 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
#### 第三方集成
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|----------------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
| 支持 Webhook | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 自定义 Git 钩子 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 集成 AD / LDAP | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 支持多个 LDAP / AD 服务 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
| LDAP 用户同步 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 支持 OpenId 连接 | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
| 集成 OAuth 2.0(外部授权) | ✓ | ✘ | | ✓ | ✓ | ? | ✓ |
| 作为 OAuth 2.0 provider | [](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| 二次验证 (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
| 集成 Mattermost/Slack | ✓ | ✓ | | ✓ | ✓ | | ✓ |
| 集成 Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| 显示外部 CI/CD 的状态 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |

View File

@ -15,9 +15,17 @@ menu:
# Webhooks # Webhooks
Gitea supports web hooks for repository events, this can be found in the settings Gitea supports web hooks for repository events. This can be found in the settings
page(`/:username/:reponame/settings/hooks`). All event pushes are POST requests. page `/:username/:reponame/settings/hooks`. All event pushes are POST requests.
The two methods currently supported are Gitea and Slack. The methods currently supported are:
- Gitea
- Gogs
- Slack
- Discord
- Dingtalk
- Telegram
- Microsoft Teams
### Event information ### Event information
@ -26,8 +34,8 @@ a Payload URL:
``` ```
X-Github-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473 X-GitHub-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
X-Github-Event: push X-GitHub-Event: push
X-Gogs-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473 X-Gogs-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
X-Gogs-Event: push X-Gogs-Event: push
X-Gitea-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473 X-Gitea-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
@ -104,3 +112,75 @@ X-Gitea-Event: push
} }
} }
``` ```
### Example
This is an example of how to use webhooks to run a php script upon push requests to the repository.
In your repository Settings, under Webhooks, Setup a Gitea webhook as follows:
- Target URL: http://mydomain.com/webhook.php
- HTTP Method: POST
- POST Content Type: application/json
- Secret: 123
- Trigger On: Push Events
- Active: Checked
Now on your server create the php file 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
```
There is a Test Delivery button in the webhook settings that allows to test the configuration as well as a list of the most Recent Deliveries.

View File

@ -0,0 +1,278 @@
---
date: "2019-04-05T16:00:00+02:00"
title: "FAQ"
slug: "faq"
weight: 5
toc: true
draft: false
menu:
sidebar:
parent: "help"
name: "FAQ"
weight: 5
identifier: "faq"
---
# Frequently Asked Questions
This page contains some common questions and answers.
Also see [Support Options]({{< relref "doc/help/seek-help.en-us.md" >}})
* [Difference between 1.x and 1.x.x downloads](#difference-between-1-x-and-1-x-x-downloads)
* [How to migrate from Gogs/GitHub/etc. to Gitea](#how-to-migrate-from-gogs-github-etc-to-gitea)
* [Where does Gitea store "x" file](#where-does-gitea-store-x-file)
* [Not seeing a clone URL or the clone URL being incorrect](#not-seeing-a-clone-url-or-the-clone-url-being-incorrect)
* [Custom Templates not loading or working incorrectly](#custom-templates-not-loading-or-working-incorrectly)
* [Active user vs login prohibited user](#active-user-vs-login-prohibited-user)
* [Setting up logging](#setting-up-logging)
* [What is Swagger?](#what-is-swagger)
* [Adjusting your server for public/private use](#adjusting-your-server-for-public-private-use)
* [Preventing spammers](#preventing-spammers)
* [Only allow certain email domains](#only-allow-certain-email-domains)
* [Only allow/block certain OpenID providers](#only-allow-block-certain-openid-providers)
* [Issue only users](#issue-only-users)
* [Enable Fail2ban](#enable-fail2ban)
* [Adding custom themes](#how-to-add-use-custom-themes)
* [SSHD vs built-in SSH](#sshd-vs-built-in-ssh)
* [Gitea is running slow](#gitea-is-running-slow)
* [Can't create repositories/files](#cant-create-repositories-files)
* [Translation is incorrect/how to add more translations](#translation-is-incorrect-how-to-add-more-translations)
* [Hooks aren't running](#hooks-aren-t-running)
* [SSH Issues](#ssh-issues)
* [SSH Common Errors](#ssh-common-errors)
* [Missing releases after migration repository with tags](#missing-releases-after-migrating-repository-with-tags)
* [LFS Issues](#lfs-issues)
* [How can I create users before starting Gitea](#how-can-i-create-users-before-starting-gitea)
## Difference between 1.x and 1.x.x downloads
Version 1.7.x will be used for this example.
**NOTE:** this example applies to Docker images as well!
On our [downloads page](https://dl.gitea.io/gitea/) you will see a 1.7 directory, as well as directories for 1.7.0, 1.7.1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, and 1.7.6.
The 1.7 and 1.7.0 directories are **not** the same. The 1.7 directory is built on each merged commit to the [`release/v1.7`](https://github.com/go-gitea/gitea/tree/release/v1.7) branch.
The 1.7.0 directory, however, is a build that was created when the [`v1.7.0`](https://github.com/go-gitea/gitea/releases/tag/v1.7.0) tag was created.
This means that 1.x downloads will change as commits are merged to their respective branch (think of it as a separate "master" branch for each release).
On the other hand, 1.x.x downloads should never change.
## How to migrate from Gogs/GitHub/etc. to Gitea
To migrate from Gogs to Gitea:
* [Gogs version 0.9.146 or less]({{< relref "doc/upgrade/from-gogs.en-us.md" >}})
* [Gogs version 0.11.46.0418](https://github.com/go-gitea/gitea/issues/4286)
To migrate from GitHub to Gitea, you can use Gitea's [Migrator tool](https://gitea.com/gitea/migrator)
To migrate from Gitlab to Gitea, you can use this non-affiliated tool:
https://github.com/loganinak/MigrateGitlabToGogs
## Where does Gitea store "x" file
* WorkPath
* Environment variable `GITEA_WORK_DIR`
* Else binary location
* AppDataPath (default for database, indexers, etc.)
* `APP_DATA_PATH` from `app.ini`
* Else `%(WorkPath)/data`
* CustomPath (custom templates)
* Environment variable `GITEA_CUSTOM`
* Else `%(WorkPath)/custom`
* HomeDir
* Unix: Environment variable `HOME`
* Windows: Environment variable `USERPROFILE`, else environment variables `HOMEDRIVE`+`HOMEPATH`
* RepoRootPath
* `ROOT` in `app.ini`
* Else `%(HomeDir)/gitea-repositories`
* INI (config file)
* `-c` flag
* Else `%(CustomPath)/conf/app.ini`
* SQLite Database
* `PATH` in `database` section of `app.ini`
* Else `%(AppDataPath)/gitea.db`
## Not seeing a clone URL or the clone URL being incorrect
There are a few places that could make this show incorrectly.
1. If using a reverse proxy, make sure you have followed the correction directions in the [reverse proxy guide]({{< relref "doc/usage/reverse-proxies.en-us.md" >}})
2. Make sure you have correctly set `ROOT_URL` in the `server` section of your `app.ini`
If certain clone options aren't showing up (HTTP/S or SSH), the following options can be checked in your `app.ini`
`DISABLE_HTTP_GIT`: if set to true, there will be no HTTP/HTTPS 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
## 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.
The correct path for the template(s) will be relative to the `CustomPath`
1. To find `CustomPath`, look for Custom File Root Path in Site Administration -> Configuration
* If that doesn't exist, you can try `echo $GITEA_CUSTOM`
2. If you are still unable to find a path, the default can be [calculated above](#where-does-gitea-store-x-file)
3. Once you have figured out the correct custom path, you can refer to the [customizing Gitea]({{< relref "doc/advanced/customizing-gitea.en-us.md" >}}) page to add your template to the correct location.
## Active user vs login prohibited user
In Gitea, an "active" user refers to a user that has activated their account via email.
A "login prohibited" user is a user that is not allowed to log in to Gitea anymore
## Setting up logging
* [Official Docs]({{< relref "doc/advanced/logging-documentation.en-us.md" >}})
## What is Swagger?
[Swagger](https://swagger.io/) is what Gitea uses for its API.
All Gitea instances have the built-in API, though it can be disabled by setting `ENABLE_SWAGGER` to `false` in the `api` section of your `app.ini`
For more information, refer to Gitea's [API docs]({{< relref "doc/advanced/api-usage.en-us.md" >}})
[Swagger Example](https://try.gitea.io/api/swagger)
## Adjusting your server for public/private use
### Preventing spammers
There are multiple things you can combine to prevent spammers.
1. 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. Settings `DISABLE_REGISTRATION` to `true` and creating new users via the [CLI]({{< relref "doc/usage/command-line.en-us.md" >}}), [API]({{< relref "doc/advanced/api-usage.en-us.md" >}}), or Gitea's Admin UI
### Only allow certain email domains
You can configure `EMAIL_DOMAIN_WHITELIST` in your app.ini under `[service]`
### Only allow/block certain OpenID providers
You can configure `WHITELISTED_URIS` or `BLACKLISTED_URIS` under `[openid]` in your `app.ini`
**NOTE:** whitelisted takes precedence, so if it is non-blank then blacklisted is ignored
### Issue only users
The current way to achieve this is to create/modify a user with a max repo creation limit of 0.
### Enable Fail2ban
Use [Fail2Ban]({{ relref "doc/usage/fail2ban-setup.md" >}}) to monitor and stop automated login attempts or other malicious behavior based on log patterns
## How to add/use custom themes
Gitea supports two official themes right now, `gitea` and `arc-green` (`light` and `dark` respectively)
To add your own theme, currently the only way is to provide a complete theme (not just color overrides)
As an example, let's say our theme is `arc-blue` (this is a real theme, and can be found [in this issue](https://github.com/go-gitea/gitea/issues/6011))
Name the `.css` file `theme-arc-blue.css` and add it to your custom folder in `custom/pulic/css`
Allow users to use it by adding `arc-blue` to the list of `THEMES` in your `app.ini`
## SSHD vs built-in SSH
SSHD is the built-in SSH server on most Unix systems.
Gitea also provides its own SSH server, for usage when SSHD is not available.
## Gitea is running slow
The most common culprit for this is loading federated avatars.
This can be turned off by setting `ENABLE_FEDERATED_AVATAR` to `false` in your `app.ini`
Another option that may need to be changed is setting `DISABLE_GRAVATAR` to `true` in your `app.ini`
## Can't create repositories/files
Make sure that Gitea has sufficient permissions to write to its home directory and data directory.
See [AppDataPath and RepoRootPath](#where-does-gitea-store-x-file)
**Note for Arch users:** At the time of writing this, there is an issue with the Arch package's systemd file including this line:
`ReadWritePaths=/etc/gitea/app.ini`
Which makes all other paths non-writeable to Gitea.
## Translation is incorrect/how to add more translations
Our translations are currently crowd-sourced on our [Crowdin project](https://crowdin.com/project/gitea)
Whether you want to change a translation or add a new one, it will need to be there as all translations are overwritten in our CI via the Crowdin integration.
## Hooks aren't running
If Gitea is not running hooks, a common cause is incorrect setup of SSH keys.
See [SSH Issues](#ssh-issues) for more information.
You can also try logging into the administration panel and running the `Resynchronize pre-receive, update and post-receive hooks of all repositories.` option.
## SSH issues
If you cannot reach repositories over `ssh`, but `https` works fine, consider looking into the following.
First, make sure you can access Gitea via SSH.
`ssh git@myremote.example`
If the connection is successful, you should receive an error message like the following:
```
Hi there, You've successfully authenticated, but Gitea does not provide shell access.
If this is unexpected, please log in with password and setup Gitea under another user.
```
If you do not get the above message but still connect, it means your SSH key is **not** being managed by Gitea. This means hooks won't run, among other potential problems.
If you cannot connect at all, your SSH key may not be configured correctly locally.
This is specific to SSH and not Gitea, so will not be covered here.
### SSH Common Errors
```
Permission denied (publickey).
fatal: Could not read from remote repository.
```
This error signifies that the server rejected a log in attempt, check the
following things:
* On the client:
* Ensure the public and private ssh keys are added to the correct Gitea user.
* Make sure there are no issues in the remote url. In particular, ensure the name of the
git user (before the `@`) is spelled correctly.
* Ensure public and private ssh keys are correct on client machine.
* On the server:
* Make sure the repository exists and is correctly named.
* Check the permissions of the `.ssh` directory in the system user's home directory.
* Verify that the correct public keys are added to `.ssh/authorized_keys`.
Try to run `Rewrite '.ssh/authorized_keys' file (for Gitea SSH keys)` on the
Gitea admin panel.
* Read Gitea logs.
* Read /var/log/auth (or similar).
* Check permissions of repositories.
The following is an example of a missing public SSH key where authentication
succeeded, but some other setting is preventing SSH from reaching the correct
repository.
```
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
```
In this case, look into the following settings:
* On the server:
* Make sure that the `git` system user has a usable shell set
* Verify this with `getent passwd git | cut -d: -f7`
* `usermod` or `chsh` can be used to modify this.
* Ensure that the `gitea serv` command in `.ssh/authorized_keys` uses the
correct configuration file.
## Missing releases after migrating repository with tags
To migrate an repository *with* all tags, you need to do two things:
* Push tags to the repository:
```
git push --tags
```
* (Re-)sync tags of all repositories within Gitea:
```
gitea admin repo-sync-releases
```
## LFS Issues
For issues concerning LFS data upload
```
batch response: Authentication required: Authorization error: <GITEA_LFS_URL>/info/lfs/objects/batch
Check that you have proper access to the repository
error: failed to push some refs to '<GIT_REPO_URL>'
```
Check the value of `LFS_HTTP_AUTH_EXPIRY` in your `app.ini` file.
By default, your LFS token will expire after 20 minutes. If you have a slow connection or a large file (or both), it may not finish uploading within the time limit.
You may want to set this value to `60m` or `120m`.
## How can I create users before starting Gitea
Gitea provides a sub-command `gitea migrate` to initialize the database, after which you can use the [admin CLI commands]({{< relref "doc/usage/command-line.en-us.md" >}}) to add users like normal.

View File

@ -15,13 +15,22 @@ menu:
# Support Options # Support Options
- [Discord](https://discord.gg/NsatcWJ) - [Discord](https://discord.gg/Gitea)
- [Discourse Forum](https://discourse.gitea.io/) - [Discourse Forum](https://discourse.gitea.io/)
**NOTE:** When asking for support, it may be a good idea to have the following available so that the person helping has all the info they need:
1. Your `app.ini` (with any sensitive data scrubbed as necessary)
2. The `gitea.log` (and any other appropriate log files for the situation)
* e.g. If the error is related to the database, the `xorm.log` might be helpful
3. Any error messages you are seeing
4. When possible, try to replicate the issue on [try.gitea.io](https://try.gitea.io) and include steps so that others can reproduce the issue.
* This will greatly improve the chance that the root of the issue can be quickly discovered and resolved.
## Bugs ## Bugs
If you found a bug, please create an [issue on Github](https://github.com/go-gitea/gitea/issues). If you found a bug, please create an [issue on GitHub](https://github.com/go-gitea/gitea/issues).
## Chinese Support ## Chinese Support
Support for the Chinese language is provided at [gocn.io](https://gocn.io/topic/Gitea). Support for the Chinese language is provided at [gocn.vip](https://gocn.vip/topic/gitea).

View File

@ -18,6 +18,6 @@ menu:
如果您在使用或者开发过程中遇到问题,请到以下渠道咨询: 如果您在使用或者开发过程中遇到问题,请到以下渠道咨询:
- 到[Github issue](https://github.com/go-gitea/gitea/issues)提问(因为项目维护人员来自世界各地,为保证沟通顺畅,请使用英文提问) - 到[Github issue](https://github.com/go-gitea/gitea/issues)提问(因为项目维护人员来自世界各地,为保证沟通顺畅,请使用英文提问)
- 中文问题到[gocn.io](https://gocn.io/topic/Gitea)提问 - 中文问题到[gocn.vip](https://gocn.vip/topic/gitea)提问
- 访问 [Discord server - 英文](https://discord.gg/NsatcWJ) - 访问 [Discord server - 英文](https://discord.gg/NsatcWJ)
- 加入 QQ群 328432459 获得进一步的支持 - 加入 QQ群 328432459 获得进一步的支持

View File

@ -1,96 +0,0 @@
---
date: "2016-11-08T16:00:00+02:00"
title: "Troubleshooting"
slug: "troubleshooting"
weight: 10
toc: true
draft: false
menu:
sidebar:
parent: "help"
name: "Troubleshooting"
weight: 20
identifier: "troubleshooting"
---
# Troubleshooting
This page contains some common seen issues and their solutions.
## SSH issues
For issues reaching repositories over `ssh` while the gitea web front-end, but
`https` based git repository access works fine, consider looking into the following.
```
Permission denied (publickey).
fatal: Could not read from remote repository.
```
This error signifies that the server rejected a log in attempt, check the
following things:
* On the client:
* Ensure the public and private ssh keys are added to the correct Gitea user.
* Make sure there are no issues in the remote url, ensure the name of the
git user (before the `@`) is spelled correctly.
* Ensure public and private ssh keys are correct on client machine.
* Try to connect using ssh (ssh git@myremote.example) to ensure a connection
can be made.
* On the server:
* Make sure the repository exists and is correctly named.
* Check the permissions of the `.ssh` directory in the system user's home directory.
* Verify that the correct public keys are added to `.ssh/authorized_keys`.
Try to run `Rewrite '.ssh/authorized_keys' file (for Gitea SSH keys)` on the
Gitea admin panel.
* Read gitea logs.
* Read /var/log/auth (or similar).
* Check permissions of repositories.
The following is an example of a missing public SSH key where authentication
succeeded, but some other setting is preventing SSH from reaching the correct
repository.
```
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
```
In this case, look into the following settings:
* On the server:
* Make sure that the `git` system user has a usable shell set
* Verify this with `getent passwd git | cut -d: -f7`
* `usermod` or `chsh` can be used to modify this.
* Ensure that the `gitea serv` command in `.ssh/authorized_keys` uses the
correct configuration file.
## Missing releases after migrating repository with tags
To migrate an repository *with* all tags you need to do two things
* Push tags to the repository:
```
git push --tags
```
* (Re-)sync tags of all repositories within gitea:
```
gitea admin repo-sync-releases
```
## LFS Issues
For issues concerning LFS data upload
```
batch response: Authentication required: Authorization error: <GITEA_LFS_URL>/info/lfs/objects/batch
Check that you have proper access to the repository
error: failed to push some refs to '<GIT_REPO_URL>'
```
Have you checked the value of `LFS_HTTP_AUTH_EXPIRY` in your `app.ini` file? By default your LFS token will expire after 20 minutes. If you have a slow connection or a large file (or both) it may not finish uploading within the time limit.
You may want to set this value to `60m` or `120m`.

View File

@ -21,16 +21,16 @@ the destination platform from the [downloads page](https://dl.gitea.io/gitea/),
the URL and replace the URL within the commands below: the URL and replace the URL within the commands below:
```sh ```sh
wget -O gitea https://dl.gitea.io/gitea/1.7.0/gitea-1.7.0-linux-amd64 wget -O gitea https://dl.gitea.io/gitea/{{< version >}}/gitea-{{< version >}}-linux-amd64
chmod +x gitea chmod +x gitea
``` ```
## Verify GPG signature ## Verify GPG signature
Gitea signs all binaries with a [GPG key](https://pgp.mit.edu/pks/lookup?op=vindex&fingerprint=on&search=0x2D9AE806EC1592E2) to prevent against unwanted modification of binaries. To validate the binary download the signature file which ends in `.asc` for the binary you downloaded and use the gpg command line tool. Gitea signs all binaries with a [GPG key](https://pgp.mit.edu/pks/lookup?op=vindex&fingerprint=on&search=0x2D9AE806EC1592E2) to prevent against unwanted modification of binaries. To validate the binary, download the signature file which ends in `.asc` for the binary you downloaded and use the gpg command line tool.
```sh ```sh
gpg --keyserver pgp.mit.edu --recv 7C9E68152594688862D62AF62D9AE806EC1592E2 gpg --keyserver pgp.mit.edu --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
gpg --verify gitea-1.7.0-linux-amd64.asc gitea-1.7.0-linux-amd64 gpg --verify gitea-{{< version >}}-linux-amd64.asc gitea-{{< version >}}-linux-amd64
``` ```
## Test ## Test
@ -44,14 +44,17 @@ location. When launched manually, Gitea can be killed using `Ctrl+C`.
## Recommended server configuration ## Recommended server configuration
**NOTE:** Many of the following directories can be configured using [Environment Variables]({{< relref "doc/advanced/specific-variables.en-us.md" >}}) as well!
Of note, configuring `GITEA_WORK_DIR` will tell Gitea where to base its working directory, as well as ease installation.
### Prepare environment ### Prepare environment
Check that git is installed on the server, if it is not install it first. Check that Git is installed on the server. If it is not, install it first.
```sh ```sh
git --version git --version
``` ```
Create user to run gitea (ex. `git`) Create user to run Gitea (ex. `git`)
```sh ```sh
adduser \ adduser \
--system \ --system \
@ -66,33 +69,51 @@ adduser \
### Create required directory structure ### Create required directory structure
```sh ```sh
mkdir -p /var/lib/gitea/{custom,data,indexers,public,log} mkdir -p /var/lib/gitea/{custom,data,log}
chown git:git /var/lib/gitea/{data,indexers,log} chown -R git:git /var/lib/gitea/
chmod 750 /var/lib/gitea/{data,indexers,log} chmod -R 750 /var/lib/gitea/
mkdir /etc/gitea mkdir /etc/gitea
chown root:git /etc/gitea chown root:git /etc/gitea
chmod 770 /etc/gitea chmod 770 /etc/gitea
``` ```
**NOTE:** `/etc/gitea` is temporary set with write rights for user `git` so that Web installer could write configuration file. After installation is done it is recommended to set rights to read-only using: **NOTE:** `/etc/gitea` is temporary set with write rights for user `git` so that Web installer could write configuration file. After installation is done, it is recommended to set rights to read-only using:
``` ```
chmod 750 /etc/gitea chmod 750 /etc/gitea
chmod 644 /etc/gitea/app.ini chmod 640 /etc/gitea/app.ini
```
If you don't want the web installer to be able to write the config file at all, it is also possible to make the config file read-only for the gitea user (owner/group `root:root`, mode `0660`), and set `INSTALL_LOCK = true`. In that case all database configuration details must be set beforehand in the config file, as well as the `SECRET_KEY` and `INTERNAL_TOKEN` values. See the [command line documentation]({{< relref "doc/usage/command-line.en-us.md" >}}) for information on using `gitea generate secret INTERNAL_TOKEN`.
### Configure Gitea's working directory
**NOTE:** If you plan on running Gitea as a Linux service, you can skip this step as the service file allows you to set `WorkingDirectory`. Otherwise, consider setting this environment variable (semi-)permanently so that Gitea consistently uses the correct working directory.
```
export GITEA_WORK_DIR=/var/lib/gitea/
``` ```
### Copy gitea binary to global location ### Copy Gitea binary to global location
``` ```
cp gitea /usr/local/bin/gitea cp gitea /usr/local/bin/gitea
``` ```
### Create service file to start gitea automatically ## Running Gitea
After the above steps, two options to run Gitea are:
### 1. Creating a service file to start Gitea automatically (recommended)
See how to create [Linux service]({{< relref "run-as-service-in-ubuntu.en-us.md" >}}) See how to create [Linux service]({{< relref "run-as-service-in-ubuntu.en-us.md" >}})
### 2. Running from command-line/terminal
```
GITEA_WORK_DIR=/var/lib/gitea/ /usr/local/bin/gitea web -c /etc/gitea/app.ini
```
## Updating to a new version ## Updating to a new version
You can update to a new version of gitea by stopping gitea, replacing the binary at `/usr/local/bin/gitea` and restarting the instance. You can update to a new version of Gitea by stopping Gitea, replacing the binary at `/usr/local/bin/gitea` and restarting the instance.
The binary file name should not be changed during the update to avoid problems The binary file name should not be changed during the update to avoid problems
in existing repositories. in existing repositories.
@ -102,7 +123,7 @@ If you have carried out the installation steps as described above, the binary sh
have the generic name `gitea`. Do not change this, i.e. to include the version number. have the generic name `gitea`. Do not change this, i.e. to include the version number.
See below for troubleshooting instructions to repair broken repositories after See below for troubleshooting instructions to repair broken repositories after
an update of your gitea version. an update of your Gitea version.
## Troubleshooting ## Troubleshooting
@ -115,16 +136,25 @@ SQLite support in the binaries provided by dl.gitea.io. In this situation, it is
possible to [install from source]({{< relref "from-source.en-us.md" >}}) without sqlite possible to [install from source]({{< relref "from-source.en-us.md" >}}) without sqlite
support. support.
### Running gitea on another port ### Running Gitea on another port
For errors like `702 runWeb()] [E] Failed to start server: listen tcp 0.0.0.0:3000: For errors like `702 runWeb()] [E] Failed to start server: listen tcp 0.0.0.0:3000:
bind: address already in use` gitea needs to be started on another free port. This bind: address already in use` Gitea needs to be started on another free port. This
is possible using `./gitea web -p $PORT`. It's possible another instance of gitea is possible using `./gitea web -p $PORT`. It's possible another instance of Gitea
is already running. is already running.
### Git error after updating to a new version of gitea ### Running Gitea on Raspbian
If the binary file name has been changed during the update to a new version of gitea, As of v1.8, there is a problem with the arm7 version of Gitea and it doesn't run on Raspberry Pi and similar devices.
It is therefore recommended to switch to the arm6 version which has been tested and shown to work on Raspberry Pi and similar devices.
<!---
please remove after fixing the arm7 bug
--->
### Git error after updating to a new version of Gitea
If the binary file name has been changed during the update to a new version of Gitea,
git hooks in existing repositories will not work any more. In that case, a git git hooks in existing repositories will not work any more. In that case, a git
error will be displayed when pushing to the repository. error will be displayed when pushing to the repository.
@ -132,7 +162,7 @@ error will be displayed when pushing to the repository.
remote: ./hooks/pre-receive.d/gitea: line 2: [...]: No such file or directory remote: ./hooks/pre-receive.d/gitea: line 2: [...]: No such file or directory
``` ```
The `[...]` part of the error message will contain the path to your previous gitea The `[...]` part of the error message will contain the path to your previous Gitea
binary. binary.
To solve this, go to the admin options and run the task `Resynchronize pre-receive, To solve this, go to the admin options and run the task `Resynchronize pre-receive,
@ -140,6 +170,6 @@ update and post-receive hooks of all repositories` to update all hooks to contai
the new binary path. Please note that this overwrite all git hooks including ones the new binary path. Please note that this overwrite all git hooks including ones
with customizations made. with customizations made.
If you aren't using the built-in to Gitea ssh server you will also need to re-write If you aren't using the built-in to Gitea SSH server you will also need to re-write
the authorized key file by running the `Update the '.ssh/authorized_keys' file with the authorized key file by running the `Update the '.ssh/authorized_keys' file with
Gitea SSH keys.` task in the admin options. Gitea SSH keys.` task in the admin options.

View File

@ -18,7 +18,7 @@ menu:
Tous les binaires sont livrés avec le support de SQLite, MySQL et PostgreSQL, et sont construits avec les ressources incorporées. Gardez à l'esprit que cela peut être différent pour les versions antérieures. L'installation basée sur nos binaires est assez simple, il suffit de choisir le fichier correspondant à votre plateforme à partir de la [page de téléchargement](https://dl.gitea.io/gitea). Copiez l'URL et remplacer l'URL dans les commandes suivantes par la nouvelle: Tous les binaires sont livrés avec le support de SQLite, MySQL et PostgreSQL, et sont construits avec les ressources incorporées. Gardez à l'esprit que cela peut être différent pour les versions antérieures. L'installation basée sur nos binaires est assez simple, il suffit de choisir le fichier correspondant à votre plateforme à partir de la [page de téléchargement](https://dl.gitea.io/gitea). Copiez l'URL et remplacer l'URL dans les commandes suivantes par la nouvelle:
``` ```
wget -O gitea https://dl.gitea.io/gitea/1.3.2/gitea-1.3.2-linux-amd64 wget -O gitea https://dl.gitea.io/gitea/{{< version >}}/gitea-{{< version >}}-linux-amd64
chmod +x gitea chmod +x gitea
``` ```

View File

@ -18,7 +18,7 @@ menu:
所有下载均包括 SQLite, MySQL 和 PostgreSQL 的支持,同时所有资源均已嵌入到可执行程序中,这一点和老版本有所不同。 基于二进制的安装非常简单,只要从 [下载页面](https://dl.gitea.io/gitea) 选择对应平台拷贝下载URL执行以下命令即可以Linux为例 所有下载均包括 SQLite, MySQL 和 PostgreSQL 的支持,同时所有资源均已嵌入到可执行程序中,这一点和老版本有所不同。 基于二进制的安装非常简单,只要从 [下载页面](https://dl.gitea.io/gitea) 选择对应平台拷贝下载URL执行以下命令即可以Linux为例
``` ```
wget -O gitea https://dl.gitea.io/gitea/1.3.2/gitea-1.3.2-linux-amd64 wget -O gitea https://dl.gitea.io/gitea/{{< version >}}/gitea-{{< version >}}-linux-amd64
chmod +x gitea chmod +x gitea
``` ```

View File

@ -18,7 +18,7 @@ menu:
所有的執行檔皆支援 SQLite, MySQL and PostgreSQL且所有檔案都已經包在執行檔內這一點跟之前的版本有所不同。關於執行檔的安裝方式非常簡單只要從[下載頁面](https://dl.gitea.io/gitea)選擇相對應平台,複製下載連結,使用底下指令就可以完成了: 所有的執行檔皆支援 SQLite, MySQL and PostgreSQL且所有檔案都已經包在執行檔內這一點跟之前的版本有所不同。關於執行檔的安裝方式非常簡單只要從[下載頁面](https://dl.gitea.io/gitea)選擇相對應平台,複製下載連結,使用底下指令就可以完成了:
``` ```
wget -O gitea https://dl.gitea.io/gitea/1.3.2/gitea-1.3.2-linux-amd64 wget -O gitea https://dl.gitea.io/gitea/{{< version >}}/gitea-{{< version >}}-linux-amd64
chmod +x gitea chmod +x gitea
``` ```

View File

@ -20,7 +20,7 @@ menu:
Although there is a package of Gitea in Debian's [contrib](https://wiki.debian.org/SourcesList), Although there is a package of Gitea in Debian's [contrib](https://wiki.debian.org/SourcesList),
it is not supported directly by us. it is not supported directly by us.
Unfortunately the package is not maintained anymore and broken because of missing sources. Unfortunately, the package is not maintained anymore and broken because of missing sources.
Please follow the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide instead. Please follow the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide instead.
Should the packages get updated and fixed, we will provide up-to-date installation instructions here. Should the packages get updated and fixed, we will provide up-to-date installation instructions here.

View File

@ -15,76 +15,128 @@ menu:
# Installation from source # Installation from source
This section will not include basic [installation instructions](https://golang.org/doc/install). You should [install go](https://golang.org/doc/install) and set up your go
environment correctly. In particular, it is recommended to set the `$GOPATH`
environment variable and to add the go bin directory or directories
`${GOPATH//://bin:}/bin` to the `$PATH`. See the Go wiki entry for
[GOPATH](https://github.com/golang/go/wiki/GOPATH).
**Note**: Go version 1.8 or higher is required **Note**: When executing make tasks that require external tools, like
`make misspell-check`, Gitea will automatically download and build these as
necessary. To be able to use these, you must have the `"$GOPATH/bin"` directory
on the executable path. If you don't add the go bin directory to the
executable path, you will have to manage this yourself.
**Note 2**: Go version 1.11 or higher is required. However, it is recommended to
obtain the same version as our continuous integration, see the advice given in
<a href='{{< relref "doc/advanced/hacking-on-gitea.en-us.md" >}}'>Hacking on
Gitea</a>
## Download ## Download
First retrieve the source code. The easiest way is to use the Go tool. Use the following First, retrieve the source code. The easiest way is to use the Go tool. Use the
commands to fetch the source and switch into the source directory. following commands to fetch the source and switch into the source directory.
Go is quite opinionated about where it expects its source code, and simply
cloning the Gitea repository to an arbitrary path is likely to lead to
problems - the fixing of which is out of scope for this document.
``` ```bash
go get -d -u code.gitea.io/gitea go get -d -u code.gitea.io/gitea
cd $GOPATH/src/code.gitea.io/gitea cd "$GOPATH/src/code.gitea.io/gitea"
``` ```
Decide which version of Gitea to build and install. Currently, there are multiple options Decide which version of Gitea to build and install. Currently, there are
to choose from. The `master` branch represents the current development version. To build multiple options to choose from. The `master` branch represents the current
with master, skip to the [build section](#build). development version. To build with master, skip to the [build section](#build).
To work with tagged releases, the following commands can be used: To work with tagged releases, the following commands can be used:
```
```bash
git branch -a git branch -a
git checkout v1.0 git checkout v{{< version >}}
``` ```
To validate a Pull Request, first enable the new branch (`xyz` is the PR id; for example To validate a Pull Request, first enable the new branch (`xyz` is the PR id;
`2663` for [#2663](https://github.com/go-gitea/gitea/pull/2663)): for example `2663` for [#2663](https://github.com/go-gitea/gitea/pull/2663)):
``` ```bash
git fetch origin pull/xyz/head:pr-xyz git fetch origin pull/xyz/head:pr-xyz
``` ```
To build Gitea from source at a specific tagged release (like v1.0.0), list the available To build Gitea from source at a specific tagged release (like v{{< version >}}), list the
tags and check out the specific tag. available tags and check out the specific tag.
List available tags with the following. List available tags with the following.
``` ```bash
git tag -l git tag -l
git checkout v1.0.0 # or git checkout pr-xyz git checkout v{{< version >}} # or git checkout pr-xyz
``` ```
## Build ## Build
Since all required libraries are already bundled in the Gitea source, it's Since all required libraries are already bundled in the Gitea source, it's
possible to build Gitea with no additional downloads. Various possible to build Gitea with no additional downloads apart from Make
[make tasks](https://github.com/go-gitea/gitea/blob/master/Makefile) are <a href='{{< relref "doc/advanced/make.en-us.md" >}}'>(See here how to get Make)</a>.
provided to keep the build process as simple as possible. Various [make tasks](https://github.com/go-gitea/gitea/blob/master/Makefile)
<a href='{{< relref "doc/advanced/make.en-us.md" >}}'>See here how to get Make</a>. are provided to keep the build process as simple as possible.
Depending on requirements, the following build tags can be included. Depending on requirements, the following build tags can be included.
* `bindata`: Build a single monolithic binary, with all assets included. * `bindata`: Build a single monolithic binary, with all assets included.
* `sqlite sqlite_unlock_notify`: Enable support for a [SQLite3](https://sqlite.org/) database. Suggested only * `sqlite sqlite_unlock_notify`: Enable support for a
for tiny installations. [SQLite3](https://sqlite.org/) database. Suggested only for tiny
* `pam`: Enable support for PAM (Linux Pluggable Authentication Modules). Can be used to installations.
authenticate local users or extend authentication to methods available to PAM. * `pam`: Enable support for PAM (Linux Pluggable Authentication Modules). Can
be used to authenticate local users or extend authentication to methods
available to PAM.
Bundling assets into the binary using the `bindata` build tag can make development and Bundling assets into the binary using the `bindata` build tag can make
testing easier, but is not ideal for a production deployment. To include assets, they development and testing easier, but is not ideal for a production deployment.
must be built separately using the `generate` make task. To include assets, they must be built separately using the `generate` make
task e.g.:
``` ```bash
TAGS="bindata" make generate build TAGS="bindata" make generate build
``` ```
In the default release build of our continuous integration system, the build
tags are: `TAGS="bindata sqlite sqlite_unlock_notify"`. The simplest
recommended way to build from source is therefore:
```bash
TAGS="bindata sqlite sqlite_unlock_notify" make generate build
```
## Test ## Test
After following the steps above a `gitea` binary will be available in the working directory. After following the steps above, a `gitea` binary will be available in the working directory.
It can be tested from this directory or moved to a directory with test data. When Gitea is It can be tested from this directory or moved to a directory with test data. When Gitea is
launched manually from command line, it can be killed by pressing `Ctrl + C`. launched manually from command line, it can be killed by pressing `Ctrl + C`.
``` ```bash
./gitea web ./gitea web
``` ```
## Changing the default CustomPath, CustomConf and AppWorkPath
Gitea will search for a number of things from the `CustomPath`. By default this is
the `custom/` directory in the current working directory when running Gitea. It will also
look for its configuration file `CustomConf` in `$CustomPath/conf/app.ini`, and will use the
current working directory as the relative base path `AppWorkPath` for a number configurable
values.
These values, although useful when developing, may conflict with downstream users preferences.
One option is to use a script file to shadow the `gitea` binary and create an appropriate
environment before running Gitea. However, when building you can change these defaults
using the `LDFLAGS` environment variable for `make`. The appropriate settings are as follows
* To set the `CustomPath` use `LDFLAGS="-X \"code.gitea.io/gitea/modules/setting.CustomPath=custom-path\""`
* For `CustomConf` you should use `-X \"code.gitea.io/gitea/modules/setting.CustomConf=conf.ini\"`
* For `AppWorkPath` you should use `-X \"code.gitea.io/gitea/modules/setting.AppWorkPath=working-path\"`
Add as many of the strings with their preceding `-X` to the `LDFLAGS` variable and run `make build`
with the appropriate `TAGS` as above.
Running `gitea help` will allow you to review what the computed settings will be for your `gitea`.

View File

@ -35,7 +35,7 @@ Si vous souhaitez compiler la dernière version stable, utilisez les étiquettes
``` ```
git branch -a git branch -a
git checkout v1.0 git checkout v{{< version >}}
``` ```
Si vous souhaitez valider une demande d'ajout (_Pull request_), vous devez activer cette branche en premier : Si vous souhaitez valider une demande d'ajout (_Pull request_), vous devez activer cette branche en premier :
@ -44,11 +44,11 @@ Si vous souhaitez valider une demande d'ajout (_Pull request_), vous devez activ
git fetch origin pull/xyz/head:pr-xyz # xyz is PR value git fetch origin pull/xyz/head:pr-xyz # xyz is PR value
``` ```
Enfin, vous pouvez directement utiliser les versions étiquettées (ex : `v1.0.0`). Pour utiliser les étiquettes, vous devez lister les étiquettes disponibles et choisir une étiquette spécifique avec les commandes suivantes : Enfin, vous pouvez directement utiliser les versions étiquettées (ex : `v{{< version >}}`). Pour utiliser les étiquettes, vous devez lister les étiquettes disponibles et choisir une étiquette spécifique avec les commandes suivantes :
``` ```
git tag -l git tag -l
git checkout v1.0.0 git checkout v{{< version >}}
git checkout pr-xyz git checkout pr-xyz
``` ```

View File

@ -32,14 +32,14 @@ cd $GOPATH/src/code.gitea.io/gitea
``` ```
git branch -a git branch -a
git checkout v1.0 git checkout v{{< version >}}
``` ```
最后,你也可以直接使用标签版本如 `v1.0.0`。你可以执行以下命令列出可用的版本并选择某个版本签出: 最后,你也可以直接使用标签版本如 `v{{< version >}}`。你可以执行以下命令列出可用的版本并选择某个版本签出:
``` ```
git tag -l git tag -l
git checkout v1.0.0 git checkout v{{< version >}}
``` ```
## 编译 ## 编译

View File

@ -32,14 +32,14 @@ cd $GOPATH/src/code.gitea.io/gitea
``` ```
git branch -a git branch -a
git checkout v1.0 git checkout v{{< version >}}
``` ```
最後您也可以直接編譯最新的標籤版本像是 `v1.0.0`,假如您想要從原始碼編譯,這方法是最合適的,在編譯標籤版本前,您需要列出當下所有標籤,並且直接切換到標籤版本,請使用底下指令:: 最後您也可以直接編譯最新的標籤版本像是 `v{{< version >}}`,假如您想要從原始碼編譯,這方法是最合適的,在編譯標籤版本前,您需要列出當下所有標籤,並且直接切換到標籤版本,請使用底下指令::
``` ```
git tag -l git tag -l
git checkout v1.0.0 git checkout v{{< version >}}
``` ```
## 編譯 ## 編譯

View File

@ -29,7 +29,7 @@ Uncomment any service that needs to be enabled on this host, such as MySQL.
Change the user, home directory, and other required startup values. Change the Change the user, home directory, and other required startup values. Change the
PORT or remove the -p flag if default port is used. PORT or remove the -p flag if default port is used.
Enable and start gitea at boot: Enable and start Gitea at boot:
``` ```
sudo systemctl enable gitea sudo systemctl enable gitea
sudo systemctl start gitea sudo systemctl start gitea
@ -45,7 +45,7 @@ sudo apt install supervisor
Create a log dir for the supervisor logs: Create a log dir for the supervisor logs:
``` ```
# assuming gitea is installed in /home/git/gitea/ # assuming Gitea is installed in /home/git/gitea/
mkdir /home/git/gitea/log/supervisor mkdir /home/git/gitea/log/supervisor
``` ```
@ -57,7 +57,7 @@ sudo vim /etc/supervisor/supervisord.conf
Append the configuration from the sample Append the configuration from the sample
[supervisord config](https://github.com/go-gitea/gitea/blob/master/contrib/supervisor/gitea). [supervisord config](https://github.com/go-gitea/gitea/blob/master/contrib/supervisor/gitea).
Change the user(git) and home(/home/git) settings to match the deployment Change the user (git) and home (/home/git) settings to match the deployment
environment. Change the PORT or remove the -p flag if default port is used. environment. Change the PORT or remove the -p flag if default port is used.
Lastly enable and start supervisor at boot: Lastly enable and start supervisor at boot:

View File

@ -46,7 +46,7 @@ sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gite
Do not forget to replace `C:\gitea` with the correct Gitea directory. Do not forget to replace `C:\gitea` with the correct Gitea directory.
Open "Windows Services", search for the service named "gitea", right-click it and click on Open "Windows Services", search for the service named "gitea", right-click it and click on
"Run". If everything is OK Gitea will be reachable on `http://localhost:3000` (or the port "Run". If everything is OK, Gitea will be reachable on `http://localhost:3000` (or the port
that was configured). that was configured).
## Unregister as a service ## Unregister as a service

View File

@ -20,18 +20,18 @@ possible to always use the latest stable tag or to use another service that hand
Docker images. Docker images.
This reference setup guides users through the setup based on `docker-compose`, but the installation This reference setup guides users through the setup based on `docker-compose`, but the installation
of `docker-compose` is out of scope of this documentation. To install `docker-compose` itself follow of `docker-compose` is out of scope of this documentation. To install `docker-compose` itself, follow
the official [install instructions](https://docs.docker.com/compose/install/). the official [install instructions](https://docs.docker.com/compose/install/).
## Basics ## Basics
The most simple setup just creates a volume and a network and starts the `gitea/gitea:latest` The most simple setup just creates a volume and a network and starts the `gitea/gitea:latest`
image as a service. Since there is no database available one can be initialized using SQLite3. image as a service. Since there is no database available, one can be initialized using SQLite3.
Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`. Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`.
Note that the volume should be owned by the user/group with the UID/GID specified in the config file. Note that the volume should be owned by the user/group with the UID/GID specified in the config file.
If you don't give the volume correct permissions, the container may not start. If you don't give the volume correct permissions, the container may not start.
Also be aware that the tag `:latest` will install the current development version. Also be aware that the tag `:latest` will install the current development version.
For a stable release you can use `:1` or specify a certain release like `:1.5.1`. For a stable release you can use `:1` or specify a certain release like `:{{< version >}}`.
```yaml ```yaml
version: "2" version: "2"
@ -187,7 +187,7 @@ services:
To use named volumes instead of host volumes, define and use the named volume To use named volumes instead of host volumes, define and use the named volume
within the `docker-compose.yml` configuration. This change will automatically within the `docker-compose.yml` configuration. This change will automatically
create the required volume. You don't need to worry about permissions with create the required volume. You don't need to worry about permissions with
named volumes, Docker will deal with that automatically. named volumes; Docker will deal with that automatically.
```diff ```diff
version: "2" version: "2"
@ -230,10 +230,10 @@ Notice: if using a non-3000 port on http, change app.ini to match
## Install ## Install
After starting the Docker setup via `docker-compose` Gitea should be available using a After starting the Docker setup via `docker-compose`, Gitea should be available using a
favorite browser to finalize the installation. Visit http://server-ip:3000 and follow the favorite browser to finalize the installation. Visit http://server-ip:3000 and follow the
installation wizard. If the database was started with the `docker-compose` setup as installation wizard. If the database was started with the `docker-compose` setup as
documented above please note that `db` must be used as the database hostname. documented above, please note that `db` must be used as the database hostname.
## Environments variables ## Environments variables
@ -245,14 +245,16 @@ You can configure some of Gitea's settings via environment variables:
* `RUN_MODE`: **dev**: For performance and other purposes, change this to `prod` when deployed to a production environment. * `RUN_MODE`: **dev**: For performance and other purposes, change this to `prod` when deployed to a production environment.
* `SSH_DOMAIN`: **localhost**: Domain name of this server, used for the displayed clone URL in Gitea's UI. * `SSH_DOMAIN`: **localhost**: Domain name of this server, used for the displayed clone URL in Gitea's UI.
* `SSH_PORT`: **22**: SSH port displayed in clone URL. * `SSH_PORT`: **22**: SSH port displayed in clone URL.
* `SSH_LISTEN_PORT`: **%(SSH\_PORT)s**: Port for the built-in SSH server.
* `DISABLE_SSH`: **false**: Disable SSH feature when it's not available. * `DISABLE_SSH`: **false**: Disable SSH feature when it's not available.
* `HTTP_PORT`: **3000**: HTTP listen port. * `HTTP_PORT`: **3000**: HTTP listen port.
* `ROOT_URL`: **""**: Overwrite the automatically generated public URL. This is useful if the internal and the external URL don't match (e.g. in Docker). * `ROOT_URL`: **""**: Overwrite the automatically generated public URL. This is useful if the internal and the external URL don't match (e.g. in Docker).
* `LFS_START_SERVER`: **false**: Enables git-lfs support.
* `DB_TYPE`: **sqlite3**: The database type in use \[mysql, postgres, mssql, sqlite3\]. * `DB_TYPE`: **sqlite3**: The database type in use \[mysql, postgres, mssql, sqlite3\].
* `DB_HOST`: **localhost:3306**: Database host address and port. * `DB_HOST`: **localhost:3306**: Database host address and port.
* `DB_NAME`: **gitea**: Database name. * `DB_NAME`: **gitea**: Database name.
* `DB_USER`: **root**: Database username. * `DB_USER`: **root**: Database username.
* `DB_PASSWD`: **"<empty>"**: Database user password. Use \`your password\` for quoting if you use special characters in the password. * `DB_PASSWD`: **"\<empty>"**: Database user password. Use \`your password\` for quoting if you use special characters in the password.
* `INSTALL_LOCK`: **false**: Disallow access to the install page. * `INSTALL_LOCK`: **false**: Disallow access to the install page.
* `SECRET_KEY`: **""**: Global secret key. This should be changed. If this has a value and `INSTALL_LOCK` is empty, `INSTALL_LOCK` will automatically set to `true`. * `SECRET_KEY`: **""**: Global secret key. This should be changed. If this has a value and `INSTALL_LOCK` is empty, `INSTALL_LOCK` will automatically set to `true`.
* `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create accounts for users. * `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create accounts for users.
@ -263,14 +265,14 @@ You can configure some of Gitea's settings via environment variables:
# Customization # Customization
Customization files described [here](https://docs.gitea.io/en-us/customizing-gitea/) should Customization files described [here](https://docs.gitea.io/en-us/customizing-gitea/) should
be placed in `/data/gitea` directory. If using host volumes it's quite easy to access these be placed in `/data/gitea` directory. If using host volumes, it's quite easy to access these
files; for named volumes this is done through another container or by direct access at files; for named volumes, this is done through another container or by direct access at
`/var/lib/docker/volumes/gitea_gitea/_data`. The configuration file will be saved at `/var/lib/docker/volumes/gitea_gitea/_data`. The configuration file will be saved at
`/data/gitea/conf/app.ini` after the installation. `/data/gitea/conf/app.ini` after the installation.
# Upgrading # Upgrading
:exclamation::exclamation: **Make sure you have volumed data to somewhere outside Docker container** :exclamation::exclamation:** :exclamation::exclamation: **Make sure you have volumed data to somewhere outside Docker container** :exclamation::exclamation:
To upgrade your installation to the latest release: To upgrade your installation to the latest release:
``` ```
@ -285,7 +287,7 @@ docker-compose up -d
Since SSH is running inside the container, you'll have to pass SSH from the host to the Since SSH is running inside the container, you'll have to pass SSH from the host to the
container if you wish to use SSH support. If you wish to do this without running the container container if you wish to use SSH support. If you wish to do this without running the container
SSH on a non-standard port (or move your host port to a non-standard port) you can forward SSH on a non-standard port (or move your host port to a non-standard port), you can forward
SSH connections destined for the container with a little extra setup. SSH connections destined for the container with a little extra setup.
This guide assumes that you have created a user on the host called `git` which shares the same This guide assumes that you have created a user on the host called `git` which shares the same

View File

@ -21,7 +21,7 @@ There are some basic steps to follow. On a Linux system run as the Gogs user:
* Create a Gogs backup with `gogs backup`. This creates `gogs-backup-[timestamp].zip` file * Create a Gogs backup with `gogs backup`. This creates `gogs-backup-[timestamp].zip` file
containing all important Gogs data. You would need it if you wanted to move to the `gogs` back later. containing all important Gogs data. You would need it if you wanted to move to the `gogs` back later.
* Download the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea). * Download the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea/).
It should be `1.0.x` version. Migrating from `gogs` to any other version is impossible. It should be `1.0.x` version. Migrating from `gogs` to any other version is impossible.
* Put the binary at the desired install location. * Put the binary at the desired install location.
* Copy `gogs/custom/conf/app.ini` to `gitea/custom/conf/app.ini`. * Copy `gogs/custom/conf/app.ini` to `gitea/custom/conf/app.ini`.
@ -70,10 +70,15 @@ There are some basic steps to follow. On a Linux system run as the Gogs user:
## Upgrading to most recent `gitea` version ## Upgrading to most recent `gitea` version
After successful migration from `gogs` to `gitea 1.0.x` it is possible to upgrade to the recent `gitea` version. After successful migration from `gogs` to `gitea 1.0.x`, it is possible to upgrade to the recent `gitea` version.
Simply download the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea) Simply download the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea)
and replace the binary. and replace the binary.
## Upgrading from a more recent version of Gogs
Upgrading from a more recent version of Gogs is also possible, but requires a bit more work.
See [#4286](https://github.com/go-gitea/gitea/issues/4286).
## Troubleshooting ## Troubleshooting
* If errors are encountered relating to custom templates in the `gitea/custom/templates` * If errors are encountered relating to custom templates in the `gitea/custom/templates`

View File

@ -20,10 +20,10 @@ file can be unpacked and used to restore an instance.
## Backup Command (`dump`) ## Backup Command (`dump`)
Switch to the user running gitea: `su git`. Run `./gitea dump -c /path/to/app.ini` in the gitea installation Switch to the user running Gitea: `su git`. Run `./gitea dump -c /path/to/app.ini` in the Gitea installation
directory. There should be some output similar to the following: directory. There should be some output similar to the following:
``` ```none
2016/12/27 22:32:09 Creating tmp work dir: /tmp/gitea-dump-417443001 2016/12/27 22:32:09 Creating tmp work dir: /tmp/gitea-dump-417443001
2016/12/27 22:32:09 Dumping local repositories.../home/git/gitea-repositories 2016/12/27 22:32:09 Dumping local repositories.../home/git/gitea-repositories
2016/12/27 22:32:22 Dumping database... 2016/12/27 22:32:22 Dumping database...
@ -34,7 +34,8 @@ directory. There should be some output similar to the following:
Inside the `gitea-dump-1482906742.zip` file, will be the following: Inside the `gitea-dump-1482906742.zip` file, will be the following:
* `custom` - All config or customerize files in `custom/`. * `app.ini` - Optional copy of configuration file if originally stored outside of the default `custom/` directory
* `custom` - All config or customization files in `custom/`.
* `data` - Data directory in <GITEA_WORK_DIR>, except sessions if you are using file session. This directory includes `attachments`, `avatars`, `lfs`, `indexers`, sqlite file if you are using sqlite. * `data` - Data directory in <GITEA_WORK_DIR>, except sessions if you are using file session. This directory includes `attachments`, `avatars`, `lfs`, `indexers`, sqlite file if you are using sqlite.
* `gitea-db.sql` - SQL dump of database * `gitea-db.sql` - SQL dump of database
* `gitea-repo.zip` - Complete copy of the repository directory. * `gitea-repo.zip` - Complete copy of the repository directory.
@ -43,17 +44,34 @@ Inside the `gitea-dump-1482906742.zip` file, will be the following:
Intermediate backup files are created in a temporary directory specified either with the Intermediate backup files are created in a temporary directory specified either with the
`--tempdir` command-line parameter or the `TMPDIR` environment variable. `--tempdir` command-line parameter or the `TMPDIR` environment variable.
### Using Docker (`dump`)
There are a few caveats for using the `dump` command with Docker.
The command has to be executed with the `RUN_USER = <OS_USERNAME>` specified in `gitea/conf/app.ini`; and, for the zipping of the backup folder to occur without permission error the command `docker exec` must be executed inside of the `--tempdir`.
Example:
```none
docker exec -u <OS_USERNAME> -it -w <--tempdir> $(docker ps -qf "name=<NAME_OF_DOCKER_CONTAINER>") bash -c '/app/gitea/gitea dump -c </path/to/app.ini>'
```
*Note: `--tempdir` refers to the temporary directory of the docker environment used by Gitea; if you have not specified a custom `--tempdir`, then Gitea uses `/tmp` or the `TMPDIR` environment variable of the docker container. For `--tempdir` adjust your `docker exec` command options accordingly.
The result should be a file, stored in the `--tempdir` specified, along the lines of: `gitea-dump-1482906742.zip`
## Restore Command (`restore`) ## Restore Command (`restore`)
There is currently no support for a recovery command. It is a manual process that mostly There is currently no support for a recovery command. It is a manual process that mostly
involves moving files to their correct locations and restoring a database dump. involves moving files to their correct locations and restoring a database dump.
Example: Example:
```
```none
apt-get install gitea apt-get install gitea
unzip gitea-dump-1482906742.zip unzip gitea-dump-1482906742.zip
cd gitea-dump-1482906742 cd gitea-dump-1482906742
mv custom/conf/app.ini /etc/gitea/conf/app.ini mv custom/conf/app.ini /etc/gitea/conf/app.ini # or mv app.ini /etc/gitea/conf/app.ini
unzip gitea-repo.zip unzip gitea-repo.zip
mv gitea-repo/* /var/lib/gitea/repositories/ mv gitea-repo/* /var/lib/gitea/repositories/
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea/repositories/ chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea/repositories/
@ -61,3 +79,9 @@ mysql -u$USER -p$PASS $DATABASE <gitea-db.sql
# or sqlite3 $DATABASE_PATH <gitea-db.sql # or sqlite3 $DATABASE_PATH <gitea-db.sql
service gitea restart service gitea restart
``` ```
Repository git-hooks should be regenerated if installation method is changed (eg. binary -> Docker), or if Gitea is installed to a different directory than the previous installation.
With Gitea running, and from the directory Gitea's binary is located, execute: `./gitea admin regenerate hooks`
This ensures that application and configuration file paths in repository git-hooks are consistent and applicable to the current installation. If these paths are not updated, repository `push` actions will fail.

View File

@ -0,0 +1,290 @@
---
date: "2017-01-01T16:00:00+02:00"
title: "Usage: Command Line"
slug: "command-line"
weight: 10
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "Command Line"
weight: 10
identifier: "command-line"
---
## Command Line
### Usage
`gitea [global options] command [command or global options] [arguments...]`
### Global options
All global options can be placed at the command level.
- `--help`, `-h`: Show help text and exit. Optional.
- `--version`, `-v`: Show version and exit. Optional. (example: `Gitea version 1.1.0+218-g7b907ed built with: bindata, sqlite`).
- `--custom-path path`, `-C path`: Location of the Gitea custom folder. Optional. (default: `AppWorkPath`/custom or `$GITEA_CUSTOM`).
- `--config path`, `-c path`: Gitea configuration file path. Optional. (default: `custom`/conf/app.ini).
- `--work-path path`, `-w path`: Gitea `AppWorkPath`. Optional. (default: LOCATION_OF_GITEA_BINARY or `$GITEA_WORK_DIR`)
NB: The defaults custom-path, config and work-path can also be
changed at build time (if preferred).
### Commands
#### web
Starts the server:
- Options:
- `--port number`, `-p number`: Port number. Optional. (default: 3000). Overrides configuration file.
- `--pid path`, `-P path`: Pidfile path. Optional.
- Examples:
- `gitea web`
- `gitea web --port 80`
- `gitea web --config /etc/gitea.ini --pid /var/run/gitea.pid`
- Notes:
- Gitea should not be run as root. To bind to a port below 1000, you can use setcap on
Linux: `sudo setcap 'cap_net_bind_service=+ep' /path/to/gitea`. This will need to be
redone every time you update Gitea.
#### admin
Admin operations:
- Commands:
- `create-user`
- Options:
- `--name value`: Username. Required. As of gitea 1.9.0, use the `--username` flag instead.
- `--username value`: Username. Required. New in gitea 1.9.0.
- `--password value`: Password. Required.
- `--email value`: Email. Required.
- `--admin`: If provided, this makes the user an admin. Optional.
- `--access-token`: If provided, an access token will be created for the user. Optional. (default: false).
- `--must-change-password`: If provided, the created user will be required to choose a newer password after
the initial login. Optional. (default: true).
- ``--random-password``: If provided, a randomly generated password will be used as the password of
the created user. The value of `--password` will be discarded. Optional.
- `--random-password-length`: If provided, it will be used to configure the length of the randomly
generated password. Optional. (default: 12)
- Examples:
- `gitea admin create-user --username myname --password asecurepassword --email me@example.com`
- `change-password`
- Options:
- `--username value`, `-u value`: Username. Required.
- `--password value`, `-p value`: New password. Required.
- Examples:
- `gitea admin change-password --username myname --password asecurepassword`
- `regenerate`
- Options:
- `hooks`: Regenerate git-hooks for all repositories
- `keys`: Regenerate authorized_keys file
- Examples:
- `gitea admin regenerate hooks`
- `gitea admin regenerate keys`
- `auth`:
- `list`:
- Description: lists all external authentication sources that exist
- Examples:
- `gitea admin auth list`
- `delete`:
- Options:
- `--id`: ID of source to be deleted. Required.
- Examples:
- `gitea admin auth delete --id 1`
- `add-oauth`:
- Options:
- `--name`: Application Name.
- `--provider`: OAuth2 Provider.
- `--key`: Client ID (Key).
- `--secret`: Client Secret.
- `--auto-discover-url`: OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider).
- `--use-custom-urls`: Use custom URLs for GitLab/GitHub OAuth endpoints.
- `--custom-auth-url`: Use a custom Authorization URL (option for GitLab/GitHub).
- `--custom-token-url`: Use a custom Token URL (option for GitLab/GitHub).
- `--custom-profile-url`: Use a custom Profile URL (option for GitLab/GitHub).
- `--custom-email-url`: Use a custom Email URL (option for GitHub).
- Examples:
- `gitea admin auth add-oauth --name external-github --provider github --key OBTAIN_FROM_SOURCE --secret OBTAIN_FROM_SOURCE`
- `update-oauth`:
- Options:
- `--id`: ID of source to be updated. Required.
- `--name`: Application Name.
- `--provider`: OAuth2 Provider.
- `--key`: Client ID (Key).
- `--secret`: Client Secret.
- `--auto-discover-url`: OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider).
- `--use-custom-urls`: Use custom URLs for GitLab/GitHub OAuth endpoints.
- `--custom-auth-url`: Use a custom Authorization URL (option for GitLab/GitHub).
- `--custom-token-url`: Use a custom Token URL (option for GitLab/GitHub).
- `--custom-profile-url`: Use a custom Profile URL (option for GitLab/GitHub).
- `--custom-email-url`: Use a custom Email URL (option for GitHub).
- Examples:
- `gitea admin auth update-oauth --id 1 --name external-github-updated`
- `add-ldap`: Add new LDAP (via Bind DN) authentication source
- Options:
- `--name value`: Authentication name. Required.
- `--not-active`: Deactivate the authentication source.
- `--security-protocol value`: Security protocol name. Required.
- `--skip-tls-verify`: Disable TLS verification.
- `--host value`: The address where the LDAP server can be reached. Required.
- `--port value`: The port to use when connecting to the LDAP server. Required.
- `--user-search-base value`: The LDAP base at which user accounts will be searched for. Required.
- `--user-filter value`: An LDAP filter declaring how to find the user record that is attempting to authenticate. Required.
- `--admin-filter value`: An LDAP filter specifying if a user should be given administrator privileges.
- `--username-attribute value`: The attribute of the users LDAP record containing the user name.
- `--firstname-attribute value`: The attribute of the users LDAP record containing the users first name.
- `--surname-attribute value`: The attribute of the users LDAP record containing the users surname.
- `--email-attribute value`: The attribute of the users LDAP record containing the users email address. Required.
- `--public-ssh-key-attribute value`: The attribute of the users LDAP record containing the users public ssh key.
- `--bind-dn value`: The DN to bind to the LDAP server with when searching for the user.
- `--bind-password value`: The password for the Bind DN, if any.
- `--attributes-in-bind`: Fetch attributes in bind DN context.
- `--synchronize-users`: Enable user synchronization.
- `--page-size value`: Search page size.
- Examples:
- `gitea admin auth add-ldap --name ldap --security-protocol unencrypted --host mydomain.org --port 389 --user-search-base "ou=Users,dc=mydomain,dc=org" --user-filter "(&(objectClass=posixAccount)(uid=%s))" --email-attribute mail`
- `update-ldap`: Update existing LDAP (via Bind DN) authentication source
- Options:
- `--id value`: ID of authentication source. Required.
- `--name value`: Authentication name.
- `--not-active`: Deactivate the authentication source.
- `--security-protocol value`: Security protocol name.
- `--skip-tls-verify`: Disable TLS verification.
- `--host value`: The address where the LDAP server can be reached.
- `--port value`: The port to use when connecting to the LDAP server.
- `--user-search-base value`: The LDAP base at which user accounts will be searched for.
- `--user-filter value`: An LDAP filter declaring how to find the user record that is attempting to authenticate.
- `--admin-filter value`: An LDAP filter specifying if a user should be given administrator privileges.
- `--username-attribute value`: The attribute of the users LDAP record containing the user name.
- `--firstname-attribute value`: The attribute of the users LDAP record containing the users first name.
- `--surname-attribute value`: The attribute of the users LDAP record containing the users surname.
- `--email-attribute value`: The attribute of the users LDAP record containing the users email address.
- `--public-ssh-key-attribute value`: The attribute of the users LDAP record containing the users public ssh key.
- `--bind-dn value`: The DN to bind to the LDAP server with when searching for the user.
- `--bind-password value`: The password for the Bind DN, if any.
- `--attributes-in-bind`: Fetch attributes in bind DN context.
- `--synchronize-users`: Enable user synchronization.
- `--page-size value`: Search page size.
- Examples:
- `gitea admin auth update-ldap --id 1 --name "my ldap auth source"`
- `gitea admin auth update-ldap --id 1 --username-attribute uid --firstname-attribute givenName --surname-attribute sn`
- `add-ldap-simple`: Add new LDAP (simple auth) authentication source
- Options:
- `--name value`: Authentication name. Required.
- `--not-active`: Deactivate the authentication source.
- `--security-protocol value`: Security protocol name. Required.
- `--skip-tls-verify`: Disable TLS verification.
- `--host value`: The address where the LDAP server can be reached. Required.
- `--port value`: The port to use when connecting to the LDAP server. Required.
- `--user-search-base value`: The LDAP base at which user accounts will be searched for.
- `--user-filter value`: An LDAP filter declaring how to find the user record that is attempting to authenticate. Required.
- `--admin-filter value`: An LDAP filter specifying if a user should be given administrator privileges.
- `--username-attribute value`: The attribute of the users LDAP record containing the user name.
- `--firstname-attribute value`: The attribute of the users LDAP record containing the users first name.
- `--surname-attribute value`: The attribute of the users LDAP record containing the users surname.
- `--email-attribute value`: The attribute of the users LDAP record containing the users email address. Required.
- `--public-ssh-key-attribute value`: The attribute of the users LDAP record containing the users public ssh key.
- `--user-dn value`: The users DN. Required.
- Examples:
- `gitea admin auth add-ldap-simple --name ldap --security-protocol unencrypted --host mydomain.org --port 389 --user-dn "cn=%s,ou=Users,dc=mydomain,dc=org" --user-filter "(&(objectClass=posixAccount)(cn=%s))" --email-attribute mail`
- `update-ldap-simple`: Update existing LDAP (simple auth) authentication source
- Options:
- `--id value`: ID of authentication source. Required.
- `--name value`: Authentication name.
- `--not-active`: Deactivate the authentication source.
- `--security-protocol value`: Security protocol name.
- `--skip-tls-verify`: Disable TLS verification.
- `--host value`: The address where the LDAP server can be reached.
- `--port value`: The port to use when connecting to the LDAP server.
- `--user-search-base value`: The LDAP base at which user accounts will be searched for.
- `--user-filter value`: An LDAP filter declaring how to find the user record that is attempting to authenticate.
- `--admin-filter value`: An LDAP filter specifying if a user should be given administrator privileges.
- `--username-attribute value`: The attribute of the users LDAP record containing the user name.
- `--firstname-attribute value`: The attribute of the users LDAP record containing the users first name.
- `--surname-attribute value`: The attribute of the users LDAP record containing the users surname.
- `--email-attribute value`: The attribute of the users LDAP record containing the users email address.
- `--public-ssh-key-attribute value`: The attribute of the users LDAP record containing the users public ssh key.
- `--user-dn value`: The users DN.
- Examples:
- `gitea admin auth update-ldap-simple --id 1 --name "my ldap auth source"`
- `gitea admin auth update-ldap-simple --id 1 --username-attribute uid --firstname-attribute givenName --surname-attribute sn`
#### cert
Generates a self-signed SSL certificate. Outputs to `cert.pem` and `key.pem` in the current
directory and will overwrite any existing files.
- Options:
- `--host value`: Comma seperated hostnames and ips which this certificate is valid for.
Wildcards are supported. Required.
- `--ecdsa-curve value`: ECDSA curve to use to generate a key. Optional. Valid options
are P224, P256, P384, P521.
- `--rsa-bits value`: Size of RSA key to generate. Optional. Ignored if --ecdsa-curve is
set. (default: 2048).
- `--start-date value`: Creation date. Optional. (format: `Jan 1 15:04:05 2011`).
- `--duration value`: Duration which the certificate is valid for. Optional. (default: 8760h0m0s)
- `--ca`: If provided, this cert generates it's own certificate authority. Optional.
- Examples:
- `gitea cert --host git.example.com,example.com,www.example.com --ca`
#### dump
Dumps all files and databases into a zip file. Outputs into a file like `gitea-dump-1482906742.zip`
in the current directory.
- Options:
- `--file name`, `-f name`: Name of the dump file with will be created. Optional. (default: gitea-dump-[timestamp].zip).
- `--tempdir path`, `-t path`: Path to the temporary directory used. Optional. (default: /tmp).
- `--skip-repository`, `-R`: Skip the repository dumping. Optional.
- `--database`, `-d`: Specify the database SQL syntax. Optional.
- `--verbose`, `-V`: If provided, shows additional details. Optional.
- Examples:
- `gitea dump`
- `gitea dump --verbose`
#### generate
Generates random values and tokens for usage in configuration file. Useful for generating values
for automatic deployments.
- Commands:
- `secret`:
- Options:
- `INTERNAL_TOKEN`: Token used for an internal API call authentication.
- `JWT_SECRET`: LFS & OAUTH2 JWT authentication secret (LFS_JWT_SECRET is aliased to this option for backwards compatibility).
- `SECRET_KEY`: Global secret key.
- Examples:
- `gitea generate secret INTERNAL_TOKEN`
- `gitea generate secret JWT_SECRET`
- `gitea generate secret SECRET_KEY`
#### keys
Provides an SSHD AuthorizedKeysCommand. Needs to be configured in the sshd config file:
```ini
...
# The value of -e and the AuthorizedKeysCommandUser should match the
# username running gitea
AuthorizedKeysCommandUser git
AuthorizedKeysCommand /path/to/gitea keys -e git -u %u -t %t -k %k
```
The command will return the appropriate authorized_keys line for the
provided key. You should also set the value
`SSH_CREATE_AUTHORIZED_KEYS_FILE=false` in the `[server]` section of
`app.ini`.
NB: opensshd requires the gitea program to be owned by root and not
writable by group or others. The program must be specified by an absolute
path.
#### migrate
Migrates the database. This command can be used to run other commands before starting the server for the first time.
This command is idempotent.
#### convert
Converts an existing MySQL database from utf8 to utf8mb4.

View File

@ -1,194 +0,0 @@
---
date: "2017-01-01T16:00:00+02:00"
title: "Usage: Command Line"
slug: "command-line"
weight: 10
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "Command Line"
weight: 10
identifier: "command-line"
---
## Command Line
### Usage
`gitea [global options] command [command options] [arguments...]`
### Global options
- `--help`, `-h`: Show help text and exit. Optional. This can be used with any of the
subcommands to see help text for it.
- `--version`, `-v`: Show version and exit. Optional. (example: `Gitea version
1.1.0+218-g7b907ed built with: bindata, sqlite`).
### Commands
#### web
Starts the server:
- Options:
- `--port number`, `-p number`: Port number. Optional. (default: 3000). Overrides configuration file.
- `--config path`, `-c path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini).
- `--pid path`, `-P path`: Pidfile path. Optional.
- Examples:
- `gitea web`
- `gitea web --port 80`
- `gitea web --config /etc/gitea.ini --pid /var/run/gitea.pid`
- Notes:
- Gitea should not be run as root. To bind to a port below 1000, you can use setcap on
Linux: `sudo setcap 'cap_net_bind_service=+ep' /path/to/gitea`. This will need to be
redone every time you update Gitea.
#### admin
Admin operations:
- Commands:
- `create-user`
- Options:
- `--name value`: Username. Required.
- `--password value`: Password. Required.
- `--email value`: Email. Required.
- `--admin`: If provided, this makes the user an admin. Optional.
- `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini).
- `--must-change-password`: If provided, the created user will be required to choose a newer password after
the initial login. Optional. (default: false).
- ``--random-password``: If provided, a randomly generated password will be used as the password of
the created user. The value of `--password` will be discarded. Optional.
- `--random-password-length`: If provided, it will be used to configure the length of the randomly
generated password. Optional. (default: 12)
- Examples:
- `gitea admin create-user --name myname --password asecurepassword --email me@example.com`
- `change-password`
- Options:
- `--username value`, `-u value`: Username. Required.
- `--password value`, `-p value`: New password. Required.
- `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini).
- Examples:
- `gitea admin change-password --username myname --password asecurepassword`
- `regenerate`
- Options:
- `hooks`: Regenerate git-hooks for all repositories
- `keys`: Regenerate authorized_keys file
- Examples:
- `gitea admin regenerate hooks`
- `gitea admin regenerate keys`
- `auth`:
- `list`:
- Description: lists all external authentication sources that exist
- Options:
- `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini).
- Examples:
- `gitea auth list`
- `delete`:
- Options:
- `--id`: ID of source to be deleted. Required.
- `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini).
- Examples:
- `gitea auth delete --id 1`
- `add-oauth`:
- Options:
- `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini).
- `--name`: Application Name.
- `--provider`: OAuth2 Provider.
- `--key`: Client ID (Key).
- `--secret`: Client Secret.
- `--auto-discover-url`: OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider).
- `--use-custom-urls`: Use custom URLs for GitLab/GitHub OAuth endpoints.
- `--custom-auth-url`: Use a custom Authorization URL (option for GitLab/GitHub).
- `--custom-token-url`: Use a custom Token URL (option for GitLab/GitHub).
- `--custom-profile-url`: Use a custom Profile URL (option for GitLab/GitHub).
- `--custom-email-url`: Use a custom Email URL (option for GitHub).
- Examples:
- `gitea auth add-oauth --name external-github --provider github --key OBTAIN_FROM_SOURCE --secret OBTAIN_FROM_SOURCE`
- `update-oauth`:
- Options:
- `--id`: ID of source to be updated. Required.
- `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini).
- `--name`: Application Name.
- `--provider`: OAuth2 Provider.
- `--key`: Client ID (Key).
- `--secret`: Client Secret.
- `--auto-discover-url`: OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider).
- `--use-custom-urls`: Use custom URLs for GitLab/GitHub OAuth endpoints.
- `--custom-auth-url`: Use a custom Authorization URL (option for GitLab/GitHub).
- `--custom-token-url`: Use a custom Token URL (option for GitLab/GitHub).
- `--custom-profile-url`: Use a custom Profile URL (option for GitLab/GitHub).
- `--custom-email-url`: Use a custom Email URL (option for GitHub).
- Examples:
- `gitea auth update-oauth --id 1 --name external-github-updated`
#### cert
Generates a self-signed SSL certificate. Outputs to `cert.pem` and `key.pem` in the current
directory and will overwrite any existing files.
- Options:
- `--host value`: Comma seperated hostnames and ips which this certificate is valid for.
Wildcards are supported. Required.
- `--ecdsa-curve value`: ECDSA curve to use to generate a key. Optional. Valid options
are P224, P256, P384, P521.
- `--rsa-bits value`: Size of RSA key to generate. Optional. Ignored if --ecdsa-curve is
set. (default: 2048).
- `--start-date value`: Creation date. Optional. (format: `Jan 1 15:04:05 2011`).
- `--duration value`: Duration which the certificate is valid for. Optional. (default: 8760h0m0s)
- `--ca`: If provided, this cert generates it's own certificate authority. Optional.
- Examples:
- `gitea cert --host git.example.com,example.com,www.example.com --ca`
#### dump
Dumps all files and databases into a zip file. Outputs into a file like `gitea-dump-1482906742.zip`
in the current directory.
- Options:
- `--config path`, `-c path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini).
- `--tempdir path`, `-t path`: Path to the temporary directory used. Optional. (default: /tmp).
- `--skip-repository`, `-R`: Skip the repository dumping. Optional.
- `--database`, `-d`: Specify the database SQL syntax. Optional.
- `--verbose`, `-v`: If provided, shows additional details. Optional.
- Examples:
- `gitea dump`
- `gitea dump --verbose`
#### generate
Generates random values and tokens for usage in configuration file. Useful for generating values
for automatic deployments.
- Commands:
- `secret`:
- Options:
- `INTERNAL_TOKEN`: Token used for an internal API call authentication.
- `LFS_JWT_SECRET`: LFS authentication secret.
- `SECRET_KEY`: Global secret key.
- Examples:
- `gitea generate secret INTERNAL_TOKEN`
- `gitea generate secret LFS_JWT_SECRET`
- `gitea generate secret SECRET_KEY`
#### keys
Provides an SSHD AuthorizedKeysCommand. Needs to be configured in the sshd config file:
```ini
...
# The value of -e and the AuthorizedKeysCommandUser should match the
# username running gitea
AuthorizedKeysCommandUser git
AuthorizedKeysCommand /path/to/gitea keys -e git -u %u -t %t -k %k
```
The command will return the appropriate authorized_keys line for the
provided key. You should also set the value
`SSH_CREATE_AUTHORIZED_KEYS_FILE=false` in the `[server]` section of
`app.ini`.
NB: opensshd requires the gitea program to be owned by root and not
writable by group or others. The program must be specified by an absolute
path.

View File

@ -0,0 +1,33 @@
---
date: "2019-10-15T10:10:00+05:00"
title: "Usage: Email setup"
slug: "email-setup"
weight: 12
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "Email setup"
weight: 12
identifier: "email-setup"
---
# Email setup
- To use Gitea's built-in Email support, update the `app.ini` config file [mailer] section:
```ini
[mailer]
ENABLED = true
HOST = mail.mydomain.com:587
FROM = gitea@mydomain.com
USER = gitea@mydomain.com
PASSWD = `password`
```
- Restart Gitea for the configuration changes to take effect.
- To send a test email to validate the settings, go to Gitea > Site Administration > Configuration > SMTP Mailer Configuration.
For the full list of options check the [Config Cheat Sheet]({{< relref "doc/advanced/config-cheat-sheet.en-us.md" >}})

View File

@ -19,14 +19,14 @@ menu:
sure to test this before relying on it so you don't lock yourself out.** sure to test this before relying on it so you don't lock yourself out.**
Gitea returns an HTTP 200 for bad logins in the web logs, but if you have logging options on in Gitea returns an HTTP 200 for bad logins in the web logs, but if you have logging options on in
`app.ini`, then you should be able to go off of log/gitea.log, which gives you something like this `app.ini`, then you should be able to go off of `log/gitea.log`, which gives you something like this
on a bad authentication: on a bad authentication:
```log ```log
2018/04/26 18:15:54 [I] Failed authentication attempt for user from xxx.xxx.xxx.xxx 2018/04/26 18:15:54 [I] Failed authentication attempt for user from xxx.xxx.xxx.xxx
``` ```
So we set our filter in `/etc/fail2ban/filter.d/gitea.conf`: Add our filter in `/etc/fail2ban/filter.d/gitea.conf`:
```ini ```ini
# gitea.conf # gitea.conf
@ -35,12 +35,11 @@ failregex = .*Failed authentication attempt for .* from <HOST>
ignoreregex = ignoreregex =
``` ```
And configure it in `/etc/fail2ban/jail.d/jail.local`: Add our jail in `/etc/fail2ban/jail.d/gitea.conf`:
```ini ```ini
[gitea] [gitea]
enabled = true enabled = true
port = http,https
filter = gitea filter = gitea
logpath = /home/git/gitea/log/gitea.log logpath = /home/git/gitea/log/gitea.log
maxretry = 10 maxretry = 10
@ -49,11 +48,28 @@ bantime = 900
action = iptables-allports action = iptables-allports
``` ```
If you're using Docker, you'll also need to add an additional jail to handle the **FORWARD**
chain in **iptables**. Configure it in `/etc/fail2ban/jail.d/gitea-docker.conf`:
```ini
[gitea-docker]
enabled = true
filter = gitea
logpath = /home/git/gitea/log/gitea.log
maxretry = 10
findtime = 3600
bantime = 900
action = iptables-allports[chain="FORWARD"]
```
Then simply run `service fail2ban restart` to apply your changes. You can check to see if
fail2ban has accepted your configuration using `service fail2ban status`.
Make sure and read up on fail2ban and configure it to your needs, this bans someone Make sure and read up on fail2ban and configure it to your needs, this bans someone
for **15 minutes** (from all ports) when they fail authentication 10 times in an hour. for **15 minutes** (from all ports) when they fail authentication 10 times in an hour.
If you run Gitea behind a reverse proxy with nginx (for example with docker), you need to add If you run Gitea behind a reverse proxy with Nginx (for example with Docker), you need to add
this to your nginx configuration so that IPs don't show up as 127.0.0.1: this to your Nginx configuration so that IPs don't show up as 127.0.0.1:
``` ```
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;

View File

@ -0,0 +1,26 @@
---
date: "2019-10-06T08:00:00+05:00"
title: "Usage: Git LFS setup"
slug: "git-lfs-setup"
weight: 12
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "Git LFS setup"
weight: 12
identifier: "git-lfs-setup"
---
# Git Large File Storage setup
To use Gitea's built-in LFS support, you must update the `app.ini` file:
```ini
[server]
; Enables git-lfs support. true or false, default is false.
LFS_START_SERVER = true
; Where your lfs files reside, default is data/lfs.
LFS_CONTENT_PATH = /home/gitea/data/lfs
```

View File

@ -15,17 +15,19 @@ menu:
# HTTPS setup to encrypt connections to Gitea # HTTPS setup to encrypt connections to Gitea
## Using built-in server ## Using the built-in server
Before you enable HTTPS make sure that you have valid SSL/TLS certificates. Before you enable HTTPS, make sure that you have valid SSL/TLS certificates.
You could use self-generated certificates for evaluation and testing. Please run `gitea cert --host [HOST]` to generate a self signed certificate. You could use self-generated certificates for evaluation and testing. Please run `gitea cert --host [HOST]` to generate a self signed certificate.
To use Gitea's built-in HTTPS support you must change your `app.ini` file: If you are using Apache or nginx on the server, it's recommended to check the [reverse proxy guide]({{< relref "doc/usage/reverse-proxies.en-us.md" >}}).
To use Gitea's built-in HTTPS support, you must change your `app.ini` file:
```ini ```ini
[server] [server]
PROTOCOL=https PROTOCOL = https
ROOT_URL = `https://git.example.com:3000/` ROOT_URL = https://git.example.com:3000/
HTTP_PORT = 3000 HTTP_PORT = 3000
CERT_FILE = cert.pem CERT_FILE = cert.pem
KEY_FILE = key.pem KEY_FILE = key.pem
@ -33,7 +35,7 @@ KEY_FILE = key.pem
To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server). To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server).
### Setting-up HTTP redirection ### Setting up HTTP redirection
The Gitea server is only able to listen to one port; to redirect HTTP requests to the HTTPS port, you will need to enable the HTTP redirection service: The Gitea server is only able to listen to one port; to redirect HTTP requests to the HTTPS port, you will need to enable the HTTP redirection service:
@ -48,9 +50,9 @@ If you are using Docker, make sure that this port is configured in your `docker-
## Using Let's Encrypt ## Using Let's Encrypt
[Let's Encrypt](https://letsencrypt.org/) is a Certificate Authority that allows you to automatically request and renew SSL/TLS certificates. In addition to starting Gitea on your configured port, to request HTTPS certificates Gitea will also need to listed on port 80, and will set up an autoredirect to HTTPS for you. Let's Encrypt will need to be able to access Gitea via the Internet to verify your ownership of the domain. [Let's Encrypt](https://letsencrypt.org/) is a Certificate Authority that allows you to automatically request and renew SSL/TLS certificates. In addition to starting Gitea on your configured port, to request HTTPS certificates, Gitea will also need to listed on port 80, and will set up an autoredirect to HTTPS for you. Let's Encrypt will need to be able to access Gitea via the Internet to verify your ownership of the domain.
By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf) By using Let's Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf).
```ini ```ini
[server] [server]
@ -66,7 +68,7 @@ To learn more about the config values, please checkout the [Config Cheat Sheet](
## Using reverse proxy ## Using reverse proxy
Setup up your reverse proxy like shown in the [reverse proxy guide](../reverse-proxies). Setup up your reverse proxy as shown in the [reverse proxy guide](../reverse-proxies).
After that, enable HTTPS by following one of these guides: After that, enable HTTPS by following one of these guides:
@ -74,5 +76,5 @@ After that, enable HTTPS by following one of these guides:
* [apache2/httpd](https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html) * [apache2/httpd](https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html)
* [caddy](https://caddyserver.com/docs/tls) * [caddy](https://caddyserver.com/docs/tls)
Note: Your connection between your reverse proxy and gitea might be unencrypted. To encrypt it too follow the [built-in server guide](#using-built-in-server) and change Note: Your connection between your reverse proxy and Gitea might be unencrypted. To encrypt it too, follow the [built-in server guide](#using-built-in-server) and change
the proxy url to `https://[URL]`. the proxy url to `https://[URL]`.

View File

@ -15,10 +15,10 @@ menu:
# Issue and Pull Request Templates # Issue and Pull Request Templates
For some projects there are a standard list of questions that users need to be asked Some projects have a standard list of questions that users need to answer
for creating an issue, or adding a pull request. Gitea supports adding templates to the when creating an issue or pull request. Gitea supports adding templates to the
main branch of the repository so that they can autopopulate the form when users are main branch of the repository so that they can autopopulate the form when users are
creating issues, and pull requests. This will cut down on the initial back and forth creating issues and pull requests. This will cut down on the initial back and forth
of getting some clarifying details. of getting some clarifying details.
Possible file names for issue templates: Possible file names for issue templates:

View File

@ -28,4 +28,4 @@ The first value of the list will be used in helpers.
## Pull Request Templates ## Pull Request Templates
You can find more information about pull request templates in the dedicated page : [Issue and Pull Request templates](../issue-pull-request-templates) You can find more information about pull request templates at the page [Issue and Pull Request templates](../issue-pull-request-templates).

Some files were not shown because too many files have changed in this diff Show More