mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-26 05:08:20 +02:00
Merge remote-tracking branch 'upstream/main' into limit-repo-size
This commit is contained in:
+48
-18
@@ -12,7 +12,8 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
- "*.md"
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
@@ -181,7 +182,7 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
@@ -266,6 +267,35 @@ steps:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: compliance-docs
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- pull_request
|
||||
paths:
|
||||
include:
|
||||
- "docs/**"
|
||||
- "*.md"
|
||||
|
||||
steps:
|
||||
- name: deps-frontend
|
||||
image: node:18
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-frontend
|
||||
|
||||
- name: lint-md
|
||||
image: node:18
|
||||
commands:
|
||||
- make lint-md
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
@@ -283,7 +313,7 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
@@ -444,7 +474,7 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
@@ -530,7 +560,7 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
@@ -616,7 +646,7 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
@@ -696,7 +726,7 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
@@ -726,7 +756,7 @@ steps:
|
||||
|
||||
# TODO: We should probably build all dependencies into a test image
|
||||
- name: test-e2e
|
||||
image: mcr.microsoft.com/playwright:v1.31.2-focal
|
||||
image: mcr.microsoft.com/playwright:v1.32.1-focal
|
||||
commands:
|
||||
- curl -sLO https://go.dev/dl/go1.20.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.20.linux-amd64.tar.gz
|
||||
- groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea
|
||||
@@ -867,7 +897,7 @@ trigger:
|
||||
- push
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
depends_on:
|
||||
- testing-mysql
|
||||
@@ -1125,7 +1155,7 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
include:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: build-docs
|
||||
@@ -1176,7 +1206,7 @@ trigger:
|
||||
- cron
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
@@ -1253,7 +1283,7 @@ trigger:
|
||||
- cron
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
@@ -1468,7 +1498,7 @@ trigger:
|
||||
- pull_request
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: dryrun
|
||||
@@ -1515,7 +1545,7 @@ trigger:
|
||||
- cron
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
@@ -1592,7 +1622,7 @@ trigger:
|
||||
- cron
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
@@ -1667,7 +1697,7 @@ trigger:
|
||||
- cron
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
@@ -1834,7 +1864,7 @@ trigger:
|
||||
- cron
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
depends_on:
|
||||
- docker-linux-amd64-release-version
|
||||
@@ -1884,7 +1914,7 @@ trigger:
|
||||
- cron
|
||||
paths:
|
||||
exclude:
|
||||
- docs/**
|
||||
- "docs/**"
|
||||
|
||||
depends_on:
|
||||
- docker-linux-amd64-release
|
||||
|
||||
+15
-1
@@ -13,6 +13,7 @@ plugins:
|
||||
- eslint-plugin-import
|
||||
- eslint-plugin-jquery
|
||||
- eslint-plugin-sonarjs
|
||||
- eslint-plugin-custom-elements
|
||||
|
||||
env:
|
||||
es2022: true
|
||||
@@ -62,6 +63,19 @@ rules:
|
||||
consistent-this: [0]
|
||||
constructor-super: [2]
|
||||
curly: [0]
|
||||
custom-elements/expose-class-on-global: [0]
|
||||
custom-elements/extends-correct-class: [2]
|
||||
custom-elements/file-name-matches-element: [0]
|
||||
custom-elements/no-constructor: [2]
|
||||
custom-elements/no-customized-built-in-elements: [2]
|
||||
custom-elements/no-dom-traversal-in-attributechangedcallback: [2]
|
||||
custom-elements/no-dom-traversal-in-connectedcallback: [2]
|
||||
custom-elements/no-exports-with-element: [2]
|
||||
custom-elements/no-method-prefixed-with-on: [2]
|
||||
custom-elements/no-unchecked-define: [0]
|
||||
custom-elements/one-element-per-file: [0]
|
||||
custom-elements/tag-name-matches-class: [2]
|
||||
custom-elements/valid-tag-name: [2]
|
||||
default-case-last: [2]
|
||||
default-case: [0]
|
||||
default-param-last: [0]
|
||||
@@ -164,7 +178,7 @@ rules:
|
||||
jquery/no-parse-html: [2]
|
||||
jquery/no-prop: [0]
|
||||
jquery/no-proxy: [2]
|
||||
jquery/no-ready: [0]
|
||||
jquery/no-ready: [2]
|
||||
jquery/no-serialize: [2]
|
||||
jquery/no-show: [2]
|
||||
jquery/no-size: [2]
|
||||
|
||||
@@ -23,13 +23,6 @@ tasks:
|
||||
gp sync-await setup
|
||||
make watch-frontend
|
||||
openMode: split-right
|
||||
- name: Run docs
|
||||
command: |
|
||||
gp sync-await setup
|
||||
cd docs
|
||||
make clean update
|
||||
hugo server -D -F --baseUrl $(gp url 1313) --liveReloadPort=443 --appendPort=false --bind=0.0.0.0
|
||||
openMode: split-right
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
@@ -46,5 +39,3 @@ vscode:
|
||||
ports:
|
||||
- name: Gitea
|
||||
port: 3000
|
||||
- name: Docs
|
||||
port: 1313
|
||||
|
||||
@@ -88,6 +88,7 @@ rules:
|
||||
no-invalid-position-at-import-rule: null
|
||||
no-irregular-whitespace: true
|
||||
no-unknown-animations: null
|
||||
no-unknown-custom-properties: null
|
||||
number-max-precision: null
|
||||
property-allowed-list: null
|
||||
property-disallowed-list: null
|
||||
|
||||
+20
-13
@@ -1,6 +1,7 @@
|
||||
# GNU makefile proxy script for BSD make
|
||||
#
|
||||
# Written and maintained by Mahmoud Al-Qudsi <mqudsi@neosmart.net>
|
||||
# Copyright NeoSmart Technologies <https://neosmart.net/> 2014-2018
|
||||
# Copyright NeoSmart Technologies <https://neosmart.net/> 2014-2019
|
||||
# Obtain updates from <https://github.com/neosmart/gmake-proxy>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -26,26 +27,32 @@
|
||||
|
||||
JARG =
|
||||
GMAKE = "gmake"
|
||||
#When gmake is called from another make instance, -w is automatically added
|
||||
#which causes extraneous messages about directory changes to be emitted.
|
||||
#--no-print-directory silences these messages.
|
||||
# When gmake is called from another make instance, -w is automatically added
|
||||
# which causes extraneous messages about directory changes to be emitted.
|
||||
# Running with --no-print-directory silences these messages.
|
||||
GARGS = "--no-print-directory"
|
||||
|
||||
.if "$(.MAKE.JOBS)" != ""
|
||||
JARG = -j$(.MAKE.JOBS)
|
||||
JARG = -j$(.MAKE.JOBS)
|
||||
.endif
|
||||
|
||||
#by default bmake will cd into ./obj first
|
||||
# bmake prefers out-of-source builds and tries to cd into ./obj (among others)
|
||||
# where possible. GNU Make doesn't, so override that value.
|
||||
.OBJDIR: ./
|
||||
|
||||
# The GNU convention is to use the lowercased `prefix` variable/macro to
|
||||
# specify the installation directory. Humor them.
|
||||
GPREFIX = ""
|
||||
.if defined(PREFIX) && ! defined(prefix)
|
||||
GPREFIX = 'prefix = "$(PREFIX)"'
|
||||
.endif
|
||||
|
||||
.BEGIN: .SILENT
|
||||
which $(GMAKE) || printf "Error: GNU Make is required!\n\n" 1>&2 && false
|
||||
|
||||
.PHONY: FRC
|
||||
$(.TARGETS): FRC
|
||||
$(GMAKE) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
|
||||
$(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
|
||||
|
||||
.DONE .DEFAULT: .SILENT
|
||||
$(GMAKE) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
|
||||
|
||||
.ERROR: .SILENT
|
||||
if ! which $(GMAKE) > /dev/null; then \
|
||||
echo "GNU Make is required!"; \
|
||||
fi
|
||||
$(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
|
||||
|
||||
+90
-1
@@ -4,7 +4,96 @@ This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.19.0](https://github.com/go-gitea/gitea/releases/tag/1.19.0) - 2023-03-19
|
||||
## [1.19.1](https://github.com/go-gitea/gitea/releases/tag/v1.19.1) - 2023-04-12
|
||||
|
||||
* BREAKING
|
||||
* Rename actions unit to `repo.actions` and add docs for it (#23733) (#23881)
|
||||
* ENHANCEMENTS
|
||||
* Add card type to org/user level project on creation, edit and view (#24043) (#24066)
|
||||
* Refactor commit status for Actions jobs (#23786) (#24060)
|
||||
* Show errors for KaTeX and mermaid on the preview tab (#24009) (#24019)
|
||||
* Show protected branch rule names again (#23907) (#24018)
|
||||
* Adjust sticky PR header to cover background (#23956) (#23999)
|
||||
* Discolor pull request tab labels (#23950) (#23987)
|
||||
* Treat PRs with agit flow as fork PRs when triggering actions. (#23884) (#23967)
|
||||
* Left-align review comments (#23937)
|
||||
* Fix image border-radius (#23886) (#23930)
|
||||
* Scroll collapsed file into view (#23702) (#23929)
|
||||
* Fix code view (diff) broken layout (#23096) (#23918)
|
||||
* Org pages style fixes (#23901) (#23914)
|
||||
* Fix user profile description rendering (#23882) (#23902)
|
||||
* Fix review box viewport overflow issue (#23800) (#23898)
|
||||
* Prefill input values in OAuth settings as intended (#23829) (#23871)
|
||||
* CSS color tweaks (#23828) (#23842)
|
||||
* Fix incorrect visibility dropdown list in add/edit user page (#23804) (#23833)
|
||||
* Add CSS rules for basic colored labels (#23774) (#23777)
|
||||
* Add creation time in tag list page (#23693) (#23773)
|
||||
* Fix br display for packages curls (#23737) (#23764)
|
||||
* Fix issue due date edit toggle bug (#23723) (#23758)
|
||||
* Improve commit graph page UI alignment (#23751) (#23754)
|
||||
* Use GitHub Actions compatible globbing for `branches`, `tag`, `path` filter (#22804) (#23740)
|
||||
* Redirect to project again after editing it (#23326) (#23739)
|
||||
* Remove row clicking from notification table (#22695) (#23706)
|
||||
* Remove conflicting CSS rules on notifications, improve notifications table (#23565) (#23621)
|
||||
* Fix diff tree height and adjust target file style (#23616)
|
||||
* BUGFIXES
|
||||
* Improve error logging for LFS (#24072) (#24082)
|
||||
* Fix custom mailer template on Windows platform (#24081)
|
||||
* Update the value of `diffEnd` when clicking the `Show More` button in the DiffFileTree (#24069) (#24078)
|
||||
* Make label templates have consistent behavior and priority (#23749)
|
||||
* Fix accidental overwriting of LDAP team memberships (#24050) (#24065)
|
||||
* Fix branch protection priority (#24045) (#24061)
|
||||
* Use actions job link as commit status URL instead of run link (#24023) (#24032)
|
||||
* Add actions support to package auth verification (#23729) (#24028)
|
||||
* Fix protected branch for API (#24013) (#24027)
|
||||
* Do not escape space between PyPI repository URL and package name… (#23981) (#24008)
|
||||
* Fix redirect bug when creating issue from a project (#23971) (#23997)
|
||||
* Set `ref` to fully-formed of the tag when trigger event is `release` (#23944) (#23989)
|
||||
* Use Get/Set instead of Rename when regenerating session ID (#23975) (#23983)
|
||||
* Ensure RSS icon is present on all repo tabs (#23904) (#23973)
|
||||
* Remove `Repository.getFilesChanged` to fix Actions `paths` and `paths-ignore` filter (#23920) (#23969)
|
||||
* Delete deleted release attachments immediately from storage (#23913) (#23958)
|
||||
* Use ghost user if package creator does not exist (#23822) (#23915)
|
||||
* User/Org Feed render description as per web (#23887) (#23906)
|
||||
* Fix `cases.Title` crash for concurrency (#23885) (#23903)
|
||||
* Convert .Source.SkipVerify to $cfg.SkipVerify (#23839) (#23899)
|
||||
* Support "." char as user name for User/Orgs in RSS/ATOM/GPG/KEYS path ... (#23874) (#23878)
|
||||
* Fix JS error when changing PR's target branch (#23862) (#23864)
|
||||
* Fix 500 error if there is a name conflict when editing authentication source (#23832) (#23852)
|
||||
* Fix closed PR also triggers Webhooks and actions (#23782) (#23834)
|
||||
* Fix checks for `needs` in Actions (#23789) (#23831)
|
||||
* Fix "Updating branch by merge" bug in "update_branch_by_merge.tmpl" (#23790) (#23825)
|
||||
* Fix cancel button in the page of project edit not work (#23655) (#23813)
|
||||
* Don't apply the group filter when listing LDAP group membership if it is empty (#23745) (#23788)
|
||||
* Fix profile page email display, respect settings (#23747) (#23756)
|
||||
* Fix project card preview select and template select (#23684) (#23731)
|
||||
* Check LFS/Packages settings in dump and doctor command (#23631) (#23730)
|
||||
* Add git dashes separator to some "log" and "diff" commands (#23606) (#23720)
|
||||
* Create commit status when event is `pull_request_sync` (#23683) (#23691)
|
||||
* Fix incorrect `HookEventType` of pull request review comments (#23650) (#23678)
|
||||
* Fix incorrect `show-modal` and `show-panel` class (#23660) (#23663)
|
||||
* Improve workflow event triggers (#23613) (#23648)
|
||||
* Introduce path Clean/Join helper functions, partially backport&refactor (#23495) (#23607)
|
||||
* Fix pagination on `/notifications/watching` (#23564) (#23603)
|
||||
* Fix submodule is nil panic (#23588) (#23601)
|
||||
* Polyfill the window.customElements (#23592) (#23595)
|
||||
* Avoid too long names for actions (#23162) (#23190)
|
||||
* TRANSLATION
|
||||
* Backport locales (with manual fixes) (#23808, #23634, #24083)
|
||||
* BUILD
|
||||
* Hardcode the path to docker images (#23955) (#23968)
|
||||
* DOCS
|
||||
* Update documentation to explain which projects allow Gitea to host static pages (#23993) (#24058)
|
||||
* Merge `push to create`, `open PR from push`, and `push options` docs articles into one (#23744) (#23959)
|
||||
* Fix code blocks in the cheat sheet (#23664) (#23669)
|
||||
* MISC
|
||||
* Do not crash when parsing an invalid workflow file (#23972) (#23976)
|
||||
* Remove assertion debug code for show/hide refactoring (#23576) (#23868)
|
||||
* Add ONLY_SHOW_RELEVANT_REPOS back, fix explore page bug, make code more strict (#23766) (#23791)
|
||||
* Make minio package support legacy MD5 checksum (#23768) (#23770)
|
||||
* Improve template error reporting (#23396) (#23600)
|
||||
|
||||
## [1.19.0](https://github.com/go-gitea/gitea/releases/tag/v1.19.0) - 2023-03-19
|
||||
|
||||
* BREAKING
|
||||
* Add loading yaml label template files (#22976) (#23232)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#Build stage
|
||||
FROM golang:1.20-alpine3.17 AS build-env
|
||||
FROM docker.io/library/golang:1.20-alpine3.17 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
@@ -23,7 +23,7 @@ RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||
# Begin env-to-ini build
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
||||
|
||||
FROM alpine:3.17
|
||||
FROM docker.io/library/alpine:3.17
|
||||
LABEL maintainer="maintainers@gitea.io"
|
||||
|
||||
EXPOSE 22 3000
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#Build stage
|
||||
FROM golang:1.20-alpine3.17 AS build-env
|
||||
FROM docker.io/library/golang:1.20-alpine3.17 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
@@ -23,7 +23,7 @@ RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||
# Begin env-to-ini build
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
||||
|
||||
FROM alpine:3.17
|
||||
FROM docker.io/library/alpine:3.17
|
||||
LABEL maintainer="maintainers@gitea.io"
|
||||
|
||||
EXPOSE 2222 3000
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ Jimmy Praet <jimmy.praet@telenet.be> (@jpraet)
|
||||
Leon Hofmeister <dev.lh@web.de> (@delvh)
|
||||
Wim <wim@42.be> (@42wim)
|
||||
Jason Song <i@wolfogre.com> (@wolfogre)
|
||||
Yarden Shoham <hrsi88@gmail.com> (@yardenshoham)
|
||||
Yarden Shoham <git@yardenshoham.com> (@yardenshoham)
|
||||
Yu Tian <zettat123@gmail.com> (@Zettat123)
|
||||
Eddie Yang <576951401@qq.com> (@yp05327)
|
||||
Dong Ge <gedong_1994@163.com> (@sillyguodong)
|
||||
|
||||
@@ -131,7 +131,7 @@ TEST_TAGS ?= sqlite sqlite_unlock_notify
|
||||
|
||||
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR)
|
||||
|
||||
GO_DIRS := cmd tests models modules routers build services tools
|
||||
GO_DIRS := build cmd models modules routers services tests
|
||||
WEB_DIRS := web_src/js web_src/css
|
||||
|
||||
GO_SOURCES := $(wildcard *.go)
|
||||
@@ -196,6 +196,7 @@ help:
|
||||
@echo " - lint lint everything"
|
||||
@echo " - lint-frontend lint frontend files"
|
||||
@echo " - lint-backend lint backend files"
|
||||
@echo " - lint-md lint markdown files"
|
||||
@echo " - checks run various consistency checks"
|
||||
@echo " - checks-frontend check frontend files"
|
||||
@echo " - checks-backend check backend files"
|
||||
@@ -219,7 +220,6 @@ help:
|
||||
@echo " - tidy run go mod tidy"
|
||||
@echo " - test[\#TestSpecificName] run unit test"
|
||||
@echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite"
|
||||
@echo " - pr#<index> build and start gitea from a PR with integration test data loaded"
|
||||
|
||||
.PHONY: go-check
|
||||
go-check:
|
||||
@@ -342,10 +342,13 @@ checks-backend: tidy-check swagger-check fmt-check misspell-check swagger-valida
|
||||
lint: lint-frontend lint-backend
|
||||
|
||||
.PHONY: lint-frontend
|
||||
lint-frontend: node_modules
|
||||
lint-frontend: node_modules lint-md
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e
|
||||
npx stylelint --color --max-warnings=0 web_src/css
|
||||
npx spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||
|
||||
.PHONY: lint-md
|
||||
lint-md: node_modules
|
||||
npx markdownlint docs *.md
|
||||
|
||||
.PHONY: lint-backend
|
||||
@@ -353,7 +356,7 @@ lint-backend: golangci-lint vet editorconfig-checker
|
||||
|
||||
.PHONY: watch
|
||||
watch:
|
||||
bash tools/watch.sh
|
||||
bash build/watch.sh
|
||||
|
||||
.PHONY: watch-frontend
|
||||
watch-frontend: node-check node_modules
|
||||
@@ -748,7 +751,7 @@ generate-go: $(TAGS_PREREQ)
|
||||
|
||||
.PHONY: security-check
|
||||
security-check:
|
||||
go run $(GOVULNCHECK_PACKAGE) -v ./...
|
||||
go run $(GOVULNCHECK_PACKAGE) ./...
|
||||
|
||||
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
||||
@@ -939,10 +942,6 @@ generate-manpage:
|
||||
@gzip -9 man/man1/gitea.1 && echo man/man1/gitea.1.gz created
|
||||
@#TODO A small script that formats config-cheat-sheet.en-us.md nicely for use as a config man page
|
||||
|
||||
.PHONY: pr\#%
|
||||
pr\#%: clean-all
|
||||
$(GO) run contrib/pr/checkout.go $*
|
||||
|
||||
.PHONY: golangci-lint
|
||||
golangci-lint:
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run
|
||||
|
||||
Generated
+22
-12
File diff suppressed because one or more lines are too long
@@ -1,7 +1,6 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
//go:build vendor
|
||||
|
||||
package main
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
@@ -59,6 +62,7 @@ func main() {
|
||||
|
||||
// use old en-US as the base, and copy the new translations to the old locales
|
||||
enUsOld := inisOld["options/locale/locale_en-US.ini"]
|
||||
brokenWarned := map[string]bool{}
|
||||
for path, iniOld := range inisOld {
|
||||
if iniOld == enUsOld {
|
||||
continue
|
||||
@@ -74,10 +78,14 @@ func main() {
|
||||
if secNew.HasKey(keyEnUs.Name()) {
|
||||
oldStr := secOld.Key(keyEnUs.Name()).String()
|
||||
newStr := secNew.Key(keyEnUs.Name()).String()
|
||||
// A bug: many of new translations with ";" are broken in Crowdin (due to last messy restoring)
|
||||
// As the broken strings are gradually fixed, this workaround check could be removed (in a few months?)
|
||||
if strings.Contains(oldStr, ";") && !strings.Contains(newStr, ";") {
|
||||
println("skip potential broken string", path, secEnUS.Name(), keyEnUs.Name())
|
||||
broken := oldStr != "" && strings.Count(oldStr, "%") != strings.Count(newStr, "%")
|
||||
broken = broken || strings.Contains(oldStr, "\n") || strings.Contains(oldStr, "\n")
|
||||
if broken {
|
||||
brokenWarned[secOld.Name()+"."+keyEnUs.Name()] = true
|
||||
fmt.Println("----")
|
||||
fmt.Printf("WARNING: skip broken locale: %s , [%s] %s\n", path, secEnUS.Name(), keyEnUs.Name())
|
||||
fmt.Printf("\told: %s\n", strings.ReplaceAll(oldStr, "\n", "\\n"))
|
||||
fmt.Printf("\tnew: %s\n", strings.ReplaceAll(newStr, "\n", "\\n"))
|
||||
continue
|
||||
}
|
||||
secOld.Key(keyEnUs.Name()).SetValue(newStr)
|
||||
@@ -86,4 +94,25 @@ func main() {
|
||||
}
|
||||
mustNoErr(iniOld.SaveTo(path))
|
||||
}
|
||||
|
||||
fmt.Println("========")
|
||||
|
||||
for path, iniNew := range inisNew {
|
||||
for _, sec := range iniNew.Sections() {
|
||||
for _, key := range sec.Keys() {
|
||||
str := sec.Key(key.Name()).String()
|
||||
broken := strings.Contains(str, "\n")
|
||||
broken = broken || strings.HasPrefix(str, "`") != strings.HasSuffix(str, "`")
|
||||
broken = broken || strings.HasPrefix(str, "\"`")
|
||||
broken = broken || strings.HasPrefix(str, "`\"")
|
||||
broken = broken || strings.Count(str, `"`)%2 == 1
|
||||
broken = broken || strings.Count(str, "`")%2 == 1
|
||||
if broken && !brokenWarned[sec.Name()+"."+key.Name()] {
|
||||
fmt.Printf("WARNING: found broken locale: %s , [%s] %s\n", path, sec.Name(), key.Name())
|
||||
fmt.Printf("\tstr: %s\n", strings.ReplaceAll(str, "\n", "\\n"))
|
||||
fmt.Println("----")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,6 @@ func newFileCollector(fileFilter string, batchSize int) (*fileCollector, error)
|
||||
"modules",
|
||||
"routers",
|
||||
"services",
|
||||
"tools",
|
||||
}
|
||||
co.includePatterns = append(co.includePatterns, regexp.MustCompile(`.*\.go$`))
|
||||
|
||||
|
||||
@@ -60,13 +60,13 @@ func main() {
|
||||
// generate data
|
||||
buf, err := generate()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalf("generate err: %v", err)
|
||||
}
|
||||
|
||||
// write
|
||||
err = os.WriteFile(*flagOut, buf, 0o644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalf("WriteFile err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
goPath "path"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
@@ -27,9 +28,14 @@ type LicenseEntry struct {
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Println("usage: go run generate-go-licenses.go <base-dir> <out-json-file>")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
base, out := os.Args[1], os.Args[2]
|
||||
|
||||
paths := []string{}
|
||||
var paths []string
|
||||
err := filepath.WalkDir(base, func(path string, entry fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -46,28 +52,27 @@ func main() {
|
||||
|
||||
sort.Strings(paths)
|
||||
|
||||
entries := []LicenseEntry{}
|
||||
for _, path := range paths {
|
||||
path := filepath.ToSlash(path)
|
||||
|
||||
licenseText, err := os.ReadFile(path)
|
||||
var entries []LicenseEntry
|
||||
for _, filePath := range paths {
|
||||
licenseText, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
path = strings.Replace(path, base+"/", "", 1)
|
||||
name := goPath.Dir(path)
|
||||
pkgPath := filepath.ToSlash(filePath)
|
||||
pkgPath = strings.TrimPrefix(pkgPath, base+"/")
|
||||
pkgName := path.Dir(pkgPath)
|
||||
|
||||
// There might be a bug somewhere in go-licenses that sometimes interprets the
|
||||
// root package as "." and sometimes as "code.gitea.io/gitea". Workaround by
|
||||
// removing both of them for the sake of stable output.
|
||||
if name == "." || name == "code.gitea.io/gitea" {
|
||||
if pkgName == "." || pkgName == "code.gitea.io/gitea" {
|
||||
continue
|
||||
}
|
||||
|
||||
entries = append(entries, LicenseEntry{
|
||||
Name: name,
|
||||
Path: path,
|
||||
Name: pkgName,
|
||||
Path: pkgPath,
|
||||
LicenseText: string(licenseText),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, err := io.Copy(os.Stdout, os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
+3
-10
@@ -17,17 +17,10 @@ fi
|
||||
|
||||
mv ./options/locale/locale_en-US.ini ./options/
|
||||
|
||||
# the "ini" library for locale has many quirks
|
||||
# * `a="xx"` gets `xx` (no quote)
|
||||
# * `a=x\"y` gets `x\"y` (no unescaping)
|
||||
# * `a="x\"y"` gets `"x\"y"` (no unescaping, the quotes are still there)
|
||||
# * `a='x\"y'` gets `x\"y` (no unescaping, no quote)
|
||||
# * `a="foo` gets `"foo` (although the quote is not closed)
|
||||
# * 'a=`foo`' works like single-quote
|
||||
# crowdin needs the strings to be quoted correctly and doesn't like incomplete quotes
|
||||
# crowdin always outputs quoted strings if there are quotes in the strings.
|
||||
# the "ini" library for locale has many quirks, its behavior is different from Crowdin.
|
||||
# see i18n_test.go for more details
|
||||
|
||||
# this script helps to unquote the crowdin outputs for the quirky ini library
|
||||
# this script helps to unquote the Crowdin outputs for the quirky ini library
|
||||
# * find all `key="...\"..."` lines
|
||||
# * remove the leading quote
|
||||
# * remove the trailing quote
|
||||
|
||||
+17
-1
@@ -112,6 +112,10 @@ It can be used for backup and capture Gitea server image to send to maintainer`,
|
||||
Name: "verbose, V",
|
||||
Usage: "Show process details",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "quiet, q",
|
||||
Usage: "Only display warnings and errors",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tempdir, t",
|
||||
Value: os.TempDir(),
|
||||
@@ -192,12 +196,25 @@ func runDump(ctx *cli.Context) error {
|
||||
if _, err := setting.CfgProvider.Section("log.console").NewKey("STDERR", "true"); err != nil {
|
||||
fatal("Setting console logger to stderr failed: %v", err)
|
||||
}
|
||||
|
||||
// Set loglevel to Warn if quiet-mode is requested
|
||||
if ctx.Bool("quiet") {
|
||||
if _, err := setting.CfgProvider.Section("log.console").NewKey("LEVEL", "Warn"); err != nil {
|
||||
fatal("Setting console log-level failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !setting.InstallLock {
|
||||
log.Error("Is '%s' really the right config path?\n", setting.CustomConf)
|
||||
return fmt.Errorf("gitea is not initialized")
|
||||
}
|
||||
setting.LoadSettings() // cannot access session settings otherwise
|
||||
|
||||
verbose := ctx.Bool("verbose")
|
||||
if verbose && ctx.Bool("quiet") {
|
||||
return fmt.Errorf("--quiet and --verbose cannot both be set")
|
||||
}
|
||||
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
@@ -223,7 +240,6 @@ func runDump(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
verbose := ctx.Bool("verbose")
|
||||
var iface interface{}
|
||||
if fileName == "-" {
|
||||
iface, err = archiver.ByExtension(fmt.Sprintf(".%s", outType))
|
||||
|
||||
+52
-70
@@ -1,8 +1,6 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build bindata
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
@@ -10,9 +8,9 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/assetfs"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/options"
|
||||
"code.gitea.io/gitea/modules/public"
|
||||
@@ -89,24 +87,20 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
sections map[string]*section
|
||||
assets []asset
|
||||
matchedAssetFiles []assetFile
|
||||
)
|
||||
|
||||
type section struct {
|
||||
Path string
|
||||
Names func() []string
|
||||
IsDir func(string) (bool, error)
|
||||
Asset func(string) ([]byte, error)
|
||||
}
|
||||
|
||||
type asset struct {
|
||||
Section *section
|
||||
Name string
|
||||
Path string
|
||||
type assetFile struct {
|
||||
fs *assetfs.LayeredFS
|
||||
name string
|
||||
path string
|
||||
}
|
||||
|
||||
func initEmbeddedExtractor(c *cli.Context) error {
|
||||
// FIXME: there is a bug, if the user runs `gitea embedded` with a different user or root,
|
||||
// The setting.Init (loadRunModeFrom) will fail and do log.Fatal
|
||||
// But the console logger has been deleted, so nothing is printed, the user sees nothing and Gitea just exits.
|
||||
|
||||
// Silence the console logger
|
||||
log.DelNamedLogger("console")
|
||||
log.DelNamedLogger(log.DEFAULT)
|
||||
@@ -115,24 +109,14 @@ func initEmbeddedExtractor(c *cli.Context) error {
|
||||
setting.InitProviderAllowEmpty()
|
||||
setting.LoadCommonSettings()
|
||||
|
||||
pats, err := getPatterns(c.Args())
|
||||
patterns, err := compileCollectPatterns(c.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sections := make(map[string]*section, 3)
|
||||
|
||||
sections["public"] = §ion{Path: "public", Names: public.AssetNames, IsDir: public.AssetIsDir, Asset: public.Asset}
|
||||
sections["options"] = §ion{Path: "options", Names: options.AssetNames, IsDir: options.AssetIsDir, Asset: options.Asset}
|
||||
sections["templates"] = §ion{Path: "templates", Names: templates.BuiltinAssetNames, IsDir: templates.BuiltinAssetIsDir, Asset: templates.BuiltinAsset}
|
||||
|
||||
for _, sec := range sections {
|
||||
assets = append(assets, buildAssetList(sec, pats, c)...)
|
||||
}
|
||||
|
||||
// Sort assets
|
||||
sort.SliceStable(assets, func(i, j int) bool {
|
||||
return assets[i].Path < assets[j].Path
|
||||
})
|
||||
collectAssetFilesByPattern(c, patterns, "options", options.BuiltinAssets())
|
||||
collectAssetFilesByPattern(c, patterns, "public", public.BuiltinAssets())
|
||||
collectAssetFilesByPattern(c, patterns, "templates", templates.BuiltinAssets())
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -166,8 +150,8 @@ func runListDo(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, a := range assets {
|
||||
fmt.Println(a.Path)
|
||||
for _, a := range matchedAssetFiles {
|
||||
fmt.Println(a.path)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -178,19 +162,19 @@ func runViewDo(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(assets) == 0 {
|
||||
return fmt.Errorf("No files matched the given pattern")
|
||||
} else if len(assets) > 1 {
|
||||
return fmt.Errorf("Too many files matched the given pattern; try to be more specific")
|
||||
if len(matchedAssetFiles) == 0 {
|
||||
return fmt.Errorf("no files matched the given pattern")
|
||||
} else if len(matchedAssetFiles) > 1 {
|
||||
return fmt.Errorf("too many files matched the given pattern, try to be more specific")
|
||||
}
|
||||
|
||||
data, err := assets[0].Section.Asset(assets[0].Name)
|
||||
data, err := matchedAssetFiles[0].fs.ReadFile(matchedAssetFiles[0].name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", assets[0].Path, err)
|
||||
return fmt.Errorf("%s: %w", matchedAssetFiles[0].path, err)
|
||||
}
|
||||
|
||||
if _, err = os.Stdout.Write(data); err != nil {
|
||||
return fmt.Errorf("%s: %w", assets[0].Path, err)
|
||||
return fmt.Errorf("%s: %w", matchedAssetFiles[0].path, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -202,7 +186,7 @@ func runExtractDo(c *cli.Context) error {
|
||||
}
|
||||
|
||||
if len(c.Args()) == 0 {
|
||||
return fmt.Errorf("A list of pattern of files to extract is mandatory (e.g. '**' for all)")
|
||||
return fmt.Errorf("a list of pattern of files to extract is mandatory (e.g. '**' for all)")
|
||||
}
|
||||
|
||||
destdir := "."
|
||||
@@ -227,7 +211,7 @@ func runExtractDo(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %s", destdir, err)
|
||||
} else if !fi.IsDir() {
|
||||
return fmt.Errorf("%s is not a directory.", destdir)
|
||||
return fmt.Errorf("destination %q is not a directory", destdir)
|
||||
}
|
||||
|
||||
fmt.Printf("Extracting to %s:\n", destdir)
|
||||
@@ -235,23 +219,23 @@ func runExtractDo(c *cli.Context) error {
|
||||
overwrite := c.Bool("overwrite")
|
||||
rename := c.Bool("rename")
|
||||
|
||||
for _, a := range assets {
|
||||
for _, a := range matchedAssetFiles {
|
||||
if err := extractAsset(destdir, a, overwrite, rename); err != nil {
|
||||
// Non-fatal error
|
||||
fmt.Fprintf(os.Stderr, "%s: %v", a.Path, err)
|
||||
fmt.Fprintf(os.Stderr, "%s: %v", a.path, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractAsset(d string, a asset, overwrite, rename bool) error {
|
||||
dest := filepath.Join(d, filepath.FromSlash(a.Path))
|
||||
func extractAsset(d string, a assetFile, overwrite, rename bool) error {
|
||||
dest := filepath.Join(d, filepath.FromSlash(a.path))
|
||||
dir := filepath.Dir(dest)
|
||||
|
||||
data, err := a.Section.Asset(a.Name)
|
||||
data, err := a.fs.ReadFile(a.name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", a.Path, err)
|
||||
return fmt.Errorf("%s: %w", a.path, err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
@@ -272,7 +256,7 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
||||
return fmt.Errorf("%s already exists, but it's not a regular file", dest)
|
||||
} else if rename {
|
||||
if err := util.Rename(dest, dest+".bak"); err != nil {
|
||||
return fmt.Errorf("Error creating backup for %s: %w", dest, err)
|
||||
return fmt.Errorf("error creating backup for %s: %w", dest, err)
|
||||
}
|
||||
// Attempt to respect file permissions mask (even if user:group will be set anew)
|
||||
perms = fi.Mode()
|
||||
@@ -293,32 +277,30 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildAssetList(sec *section, globs []glob.Glob, c *cli.Context) []asset {
|
||||
results := make([]asset, 0, 64)
|
||||
for _, name := range sec.Names() {
|
||||
if isdir, err := sec.IsDir(name); !isdir && err == nil {
|
||||
if sec.Path == "public" &&
|
||||
strings.HasPrefix(name, "vendor/") &&
|
||||
!c.Bool("include-vendored") {
|
||||
continue
|
||||
}
|
||||
matchName := sec.Path + "/" + name
|
||||
for _, g := range globs {
|
||||
if g.Match(matchName) {
|
||||
results = append(results, asset{
|
||||
Section: sec,
|
||||
Name: name,
|
||||
Path: sec.Path + "/" + name,
|
||||
})
|
||||
break
|
||||
}
|
||||
func collectAssetFilesByPattern(c *cli.Context, globs []glob.Glob, path string, layer *assetfs.Layer) {
|
||||
fs := assetfs.Layered(layer)
|
||||
files, err := fs.ListAllFiles(".", true)
|
||||
if err != nil {
|
||||
log.Error("Error listing files in %q: %v", path, err)
|
||||
return
|
||||
}
|
||||
for _, name := range files {
|
||||
if path == "public" &&
|
||||
strings.HasPrefix(name, "vendor/") &&
|
||||
!c.Bool("include-vendored") {
|
||||
continue
|
||||
}
|
||||
matchName := path + "/" + name
|
||||
for _, g := range globs {
|
||||
if g.Match(matchName) {
|
||||
matchedAssetFiles = append(matchedAssetFiles, assetFile{fs: fs, name: name, path: path + "/" + name})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
func getPatterns(args []string) ([]glob.Glob, error) {
|
||||
func compileCollectPatterns(args []string) ([]glob.Glob, error) {
|
||||
if len(args) == 0 {
|
||||
args = []string{"**"}
|
||||
}
|
||||
@@ -326,7 +308,7 @@ func getPatterns(args []string) ([]glob.Glob, error) {
|
||||
for i := range args {
|
||||
if g, err := glob.Compile(args[i], '/'); err != nil {
|
||||
return nil, fmt.Errorf("'%s': Invalid glob pattern: %w", args[i], err)
|
||||
} else {
|
||||
} else { //nolint:revive
|
||||
pat[i] = g
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !bindata
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Cmdembedded represents the available extract sub-command.
|
||||
var (
|
||||
Cmdembedded = cli.Command{
|
||||
Name: "embedded",
|
||||
Usage: "Extract embedded resources",
|
||||
Description: "A command for extracting embedded resources, like templates and images",
|
||||
Action: extractorNotImplemented,
|
||||
}
|
||||
)
|
||||
|
||||
func extractorNotImplemented(c *cli.Context) error {
|
||||
err := fmt.Errorf("Sorry: the 'embedded' subcommand is not available in builds without bindata")
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
+63
-81
@@ -6,9 +6,9 @@ package cmd
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -167,11 +167,11 @@ func runHookPreReceive(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("hooks/pre-receive.log", c.Bool("debug"))
|
||||
setup(ctx, c.Bool("debug"))
|
||||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||
return fail(`Rejecting changes as Gitea environment not set.
|
||||
return fail(ctx, `Rejecting changes as Gitea environment not set.
|
||||
If you are pushing over SSH you must push with a key managed by
|
||||
Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
@@ -257,14 +257,9 @@ Gitea or set your environment appropriately.`, "")
|
||||
hookOptions.OldCommitIDs = oldCommitIDs
|
||||
hookOptions.NewCommitIDs = newCommitIDs
|
||||
hookOptions.RefFullNames = refFullNames
|
||||
statusCode, msg := private.HookPreReceive(ctx, username, reponame, hookOptions)
|
||||
switch statusCode {
|
||||
case http.StatusOK:
|
||||
// no-op
|
||||
case http.StatusInternalServerError:
|
||||
return fail("Internal Server Error", msg)
|
||||
default:
|
||||
return fail(msg, "")
|
||||
extra := private.HookPreReceive(ctx, username, reponame, hookOptions)
|
||||
if extra.HasError() {
|
||||
return fail(ctx, extra.UserMsg, "HookPreReceive(batch) failed: %v", extra.Error)
|
||||
}
|
||||
count = 0
|
||||
lastline = 0
|
||||
@@ -285,12 +280,9 @@ Gitea or set your environment appropriately.`, "")
|
||||
|
||||
fmt.Fprintf(out, " Checking %d references\n", count)
|
||||
|
||||
statusCode, msg := private.HookPreReceive(ctx, username, reponame, hookOptions)
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("Internal Server Error", msg)
|
||||
case http.StatusForbidden:
|
||||
return fail(msg, "")
|
||||
extra := private.HookPreReceive(ctx, username, reponame, hookOptions)
|
||||
if extra.HasError() {
|
||||
return fail(ctx, extra.UserMsg, "HookPreReceive(last) failed: %v", extra.Error)
|
||||
}
|
||||
} else if lastline > 0 {
|
||||
fmt.Fprintf(out, "\n")
|
||||
@@ -309,7 +301,7 @@ func runHookPostReceive(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("hooks/post-receive.log", c.Bool("debug"))
|
||||
setup(ctx, c.Bool("debug"))
|
||||
|
||||
// First of all run update-server-info no matter what
|
||||
if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil {
|
||||
@@ -323,7 +315,7 @@ func runHookPostReceive(c *cli.Context) error {
|
||||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||
return fail(`Rejecting changes as Gitea environment not set.
|
||||
return fail(ctx, `Rejecting changes as Gitea environment not set.
|
||||
If you are pushing over SSH you must push with a key managed by
|
||||
Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
@@ -394,11 +386,11 @@ Gitea or set your environment appropriately.`, "")
|
||||
hookOptions.OldCommitIDs = oldCommitIDs
|
||||
hookOptions.NewCommitIDs = newCommitIDs
|
||||
hookOptions.RefFullNames = refFullNames
|
||||
resp, err := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
|
||||
if resp == nil {
|
||||
resp, extra := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
|
||||
if extra.HasError() {
|
||||
_ = dWriter.Close()
|
||||
hookPrintResults(results)
|
||||
return fail("Internal Server Error", err)
|
||||
return fail(ctx, extra.UserMsg, "HookPostReceive failed: %v", extra.Error)
|
||||
}
|
||||
wasEmpty = wasEmpty || resp.RepoWasEmpty
|
||||
results = append(results, resp.Results...)
|
||||
@@ -409,9 +401,9 @@ Gitea or set your environment appropriately.`, "")
|
||||
if count == 0 {
|
||||
if wasEmpty && masterPushed {
|
||||
// We need to tell the repo to reset the default branch to master
|
||||
err := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
|
||||
extra := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
|
||||
if extra.HasError() {
|
||||
return fail(ctx, extra.UserMsg, "SetDefaultBranch failed: %v", extra.Error)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(out, "Processed %d references in total\n", total)
|
||||
@@ -427,11 +419,11 @@ Gitea or set your environment appropriately.`, "")
|
||||
|
||||
fmt.Fprintf(out, " Processing %d references\n", count)
|
||||
|
||||
resp, err := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
|
||||
resp, extra := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
|
||||
if resp == nil {
|
||||
_ = dWriter.Close()
|
||||
hookPrintResults(results)
|
||||
return fail("Internal Server Error", err)
|
||||
return fail(ctx, extra.UserMsg, "HookPostReceive failed: %v", extra.Error)
|
||||
}
|
||||
wasEmpty = wasEmpty || resp.RepoWasEmpty
|
||||
results = append(results, resp.Results...)
|
||||
@@ -440,9 +432,9 @@ Gitea or set your environment appropriately.`, "")
|
||||
|
||||
if wasEmpty && masterPushed {
|
||||
// We need to tell the repo to reset the default branch to master
|
||||
err := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
|
||||
extra := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
|
||||
if extra.HasError() {
|
||||
return fail(ctx, extra.UserMsg, "SetDefaultBranch failed: %v", extra.Error)
|
||||
}
|
||||
}
|
||||
_ = dWriter.Close()
|
||||
@@ -485,22 +477,22 @@ func pushOptions() map[string]string {
|
||||
}
|
||||
|
||||
func runHookProcReceive(c *cli.Context) error {
|
||||
setup("hooks/proc-receive.log", c.Bool("debug"))
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup(ctx, c.Bool("debug"))
|
||||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||
return fail(`Rejecting changes as Gitea environment not set.
|
||||
return fail(ctx, `Rejecting changes as Gitea environment not set.
|
||||
If you are pushing over SSH you must push with a key managed by
|
||||
Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if git.CheckGitVersionAtLeast("2.29") != nil {
|
||||
return fail("Internal Server Error", "git not support proc-receive.")
|
||||
return fail(ctx, "No proc-receive support", "current git version doesn't support proc-receive.")
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
@@ -515,7 +507,7 @@ Gitea or set your environment appropriately.`, "")
|
||||
// H: PKT-LINE(version=1\0push-options...)
|
||||
// H: flush-pkt
|
||||
|
||||
rs, err := readPktLine(reader, pktLineTypeData)
|
||||
rs, err := readPktLine(ctx, reader, pktLineTypeData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -530,19 +522,19 @@ Gitea or set your environment appropriately.`, "")
|
||||
|
||||
index := bytes.IndexByte(rs.Data, byte(0))
|
||||
if index >= len(rs.Data) {
|
||||
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
||||
return fail(ctx, "Protocol: format error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
||||
}
|
||||
|
||||
if index < 0 {
|
||||
if len(rs.Data) == 10 && rs.Data[9] == '\n' {
|
||||
index = 9
|
||||
} else {
|
||||
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
||||
return fail(ctx, "Protocol: format error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
||||
}
|
||||
}
|
||||
|
||||
if string(rs.Data[0:index]) != VersionHead {
|
||||
return fail("Internal Server Error", "Received unsupported version: %s", string(rs.Data[0:index]))
|
||||
return fail(ctx, "Protocol: version error", "Received unsupported version: %s", string(rs.Data[0:index]))
|
||||
}
|
||||
requestOptions = strings.Split(string(rs.Data[index+1:]), " ")
|
||||
|
||||
@@ -555,17 +547,17 @@ Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
response = append(response, '\n')
|
||||
|
||||
_, err = readPktLine(reader, pktLineTypeFlush)
|
||||
_, err = readPktLine(ctx, reader, pktLineTypeFlush)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeDataPktLine(os.Stdout, response)
|
||||
err = writeDataPktLine(ctx, os.Stdout, response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeFlushPktLine(os.Stdout)
|
||||
err = writeFlushPktLine(ctx, os.Stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -588,7 +580,7 @@ Gitea or set your environment appropriately.`, "")
|
||||
|
||||
for {
|
||||
// note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed
|
||||
rs, err = readPktLine(reader, pktLineTypeUnknow)
|
||||
rs, err = readPktLine(ctx, reader, pktLineTypeUnknow)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -609,7 +601,7 @@ Gitea or set your environment appropriately.`, "")
|
||||
|
||||
if hasPushOptions {
|
||||
for {
|
||||
rs, err = readPktLine(reader, pktLineTypeUnknow)
|
||||
rs, err = readPktLine(ctx, reader, pktLineTypeUnknow)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -626,9 +618,9 @@ Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
|
||||
// 3. run hook
|
||||
resp, err := private.HookProcReceive(ctx, repoUser, repoName, hookOptions)
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "run proc-receive hook failed :%v", err)
|
||||
resp, extra := private.HookProcReceive(ctx, repoUser, repoName, hookOptions)
|
||||
if extra.HasError() {
|
||||
return fail(ctx, extra.UserMsg, "HookProcReceive failed: %v", extra.Error)
|
||||
}
|
||||
|
||||
// 4. response result to service
|
||||
@@ -649,7 +641,7 @@ Gitea or set your environment appropriately.`, "")
|
||||
|
||||
for _, rs := range resp.Results {
|
||||
if len(rs.Err) > 0 {
|
||||
err = writeDataPktLine(os.Stdout, []byte("ng "+rs.OriginalRef+" "+rs.Err))
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("ng "+rs.OriginalRef+" "+rs.Err))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -657,43 +649,43 @@ Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
|
||||
if rs.IsNotMatched {
|
||||
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = writeDataPktLine(os.Stdout, []byte("option fall-through"))
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("option fall-through"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = writeDataPktLine(os.Stdout, []byte("option refname "+rs.Ref))
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("option refname "+rs.Ref))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rs.OldOID != git.EmptySHA {
|
||||
err = writeDataPktLine(os.Stdout, []byte("option old-oid "+rs.OldOID))
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("option old-oid "+rs.OldOID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = writeDataPktLine(os.Stdout, []byte("option new-oid "+rs.NewOID))
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("option new-oid "+rs.NewOID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rs.IsForcePush {
|
||||
err = writeDataPktLine(os.Stdout, []byte("option forced-update"))
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("option forced-update"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
err = writeFlushPktLine(os.Stdout)
|
||||
err = writeFlushPktLine(ctx, os.Stdout)
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -718,7 +710,7 @@ type gitPktLine struct {
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func readPktLine(in *bufio.Reader, requestType pktLineType) (*gitPktLine, error) {
|
||||
func readPktLine(ctx context.Context, in *bufio.Reader, requestType pktLineType) (*gitPktLine, error) {
|
||||
var (
|
||||
err error
|
||||
r *gitPktLine
|
||||
@@ -729,33 +721,33 @@ func readPktLine(in *bufio.Reader, requestType pktLineType) (*gitPktLine, error)
|
||||
for i := 0; i < 4; i++ {
|
||||
lengthBytes[i], err = in.ReadByte()
|
||||
if err != nil {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
|
||||
return nil, fail(ctx, "Protocol: stdin error", "Pkt-Line: read stdin failed : %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
r = new(gitPktLine)
|
||||
r.Length, err = strconv.ParseUint(string(lengthBytes), 16, 32)
|
||||
if err != nil {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong :%v", err)
|
||||
return nil, fail(ctx, "Protocol: format parse error", "Pkt-Line format is wrong :%v", err)
|
||||
}
|
||||
|
||||
if r.Length == 0 {
|
||||
if requestType == pktLineTypeData {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
|
||||
return nil, fail(ctx, "Protocol: format data error", "Pkt-Line format is wrong")
|
||||
}
|
||||
r.Type = pktLineTypeFlush
|
||||
return r, nil
|
||||
}
|
||||
|
||||
if r.Length <= 4 || r.Length > 65520 || requestType == pktLineTypeFlush {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
|
||||
return nil, fail(ctx, "Protocol: format length error", "Pkt-Line format is wrong")
|
||||
}
|
||||
|
||||
r.Data = make([]byte, r.Length-4)
|
||||
for i := range r.Data {
|
||||
r.Data[i], err = in.ReadByte()
|
||||
if err != nil {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
|
||||
return nil, fail(ctx, "Protocol: data error", "Pkt-Line: read stdin failed : %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -764,19 +756,15 @@ func readPktLine(in *bufio.Reader, requestType pktLineType) (*gitPktLine, error)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func writeFlushPktLine(out io.Writer) error {
|
||||
func writeFlushPktLine(ctx context.Context, out io.Writer) error {
|
||||
l, err := out.Write([]byte("0000"))
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
if err != nil || l != 4 {
|
||||
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
if l != 4 {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeDataPktLine(out io.Writer, data []byte) error {
|
||||
func writeDataPktLine(ctx context.Context, out io.Writer, data []byte) error {
|
||||
hexchar := []byte("0123456789abcdef")
|
||||
hex := func(n uint64) byte {
|
||||
return hexchar[(n)&15]
|
||||
@@ -790,19 +778,13 @@ func writeDataPktLine(out io.Writer, data []byte) error {
|
||||
tmp[3] = hex(length)
|
||||
|
||||
lr, err := out.Write(tmp)
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
if lr != 4 {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
if err != nil || lr != 4 {
|
||||
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
|
||||
lr, err = out.Write(data)
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
if int(length-4) != lr {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
if err != nil || int(length-4) != lr {
|
||||
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
+6
-4
@@ -6,6 +6,7 @@ package cmd
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -14,27 +15,28 @@ import (
|
||||
|
||||
func TestPktLine(t *testing.T) {
|
||||
// test read
|
||||
ctx := context.Background()
|
||||
s := strings.NewReader("0000")
|
||||
r := bufio.NewReader(s)
|
||||
result, err := readPktLine(r, pktLineTypeFlush)
|
||||
result, err := readPktLine(ctx, r, pktLineTypeFlush)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, pktLineTypeFlush, result.Type)
|
||||
|
||||
s = strings.NewReader("0006a\n")
|
||||
r = bufio.NewReader(s)
|
||||
result, err = readPktLine(r, pktLineTypeData)
|
||||
result, err = readPktLine(ctx, r, pktLineTypeData)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, pktLineTypeData, result.Type)
|
||||
assert.Equal(t, []byte("a\n"), result.Data)
|
||||
|
||||
// test write
|
||||
w := bytes.NewBuffer([]byte{})
|
||||
err = writeFlushPktLine(w)
|
||||
err = writeFlushPktLine(ctx, w)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []byte("0000"), w.Bytes())
|
||||
|
||||
w.Reset()
|
||||
err = writeDataPktLine(w, []byte("a\nb"))
|
||||
err = writeDataPktLine(ctx, w, []byte("a\nb"))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []byte("0007a\nb"), w.Bytes())
|
||||
}
|
||||
|
||||
+5
-4
@@ -64,11 +64,12 @@ func runKeys(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("keys.log", false)
|
||||
setup(ctx, false)
|
||||
|
||||
authorizedString, err := private.AuthorizedPublicKeyByContent(ctx, content)
|
||||
if err != nil {
|
||||
return err
|
||||
authorizedString, extra := private.AuthorizedPublicKeyByContent(ctx, content)
|
||||
// do not use handleCliResponseExtra or cli.NewExitError, if it exists immediately, it breaks some tests like Test_CmdKeys
|
||||
if extra.Error != nil {
|
||||
return extra.Error
|
||||
}
|
||||
fmt.Println(strings.TrimSpace(authorizedString))
|
||||
return nil
|
||||
|
||||
+4
-8
@@ -5,7 +5,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@@ -43,13 +42,10 @@ func runSendMail(c *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
status, message := private.SendEmail(ctx, subject, body, nil)
|
||||
if status != http.StatusOK {
|
||||
fmt.Printf("error: %s\n", message)
|
||||
return nil
|
||||
respText, extra := private.SendEmail(ctx, subject, body, nil)
|
||||
if extra.HasError() {
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
fmt.Printf("Success: %s\n", message)
|
||||
|
||||
_, _ = fmt.Printf("Sent %s email(s) to all users\n", respText)
|
||||
return nil
|
||||
}
|
||||
|
||||
+12
-37
@@ -4,8 +4,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -103,57 +101,34 @@ func runShutdown(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("manager", c.Bool("debug"))
|
||||
statusCode, msg := private.Shutdown(ctx)
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
return nil
|
||||
setup(ctx, c.Bool("debug"))
|
||||
extra := private.Shutdown(ctx)
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
func runRestart(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("manager", c.Bool("debug"))
|
||||
statusCode, msg := private.Restart(ctx)
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
return nil
|
||||
setup(ctx, c.Bool("debug"))
|
||||
extra := private.Restart(ctx)
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
func runFlushQueues(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("manager", c.Bool("debug"))
|
||||
statusCode, msg := private.FlushQueues(ctx, c.Duration("timeout"), c.Bool("non-blocking"))
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
return nil
|
||||
setup(ctx, c.Bool("debug"))
|
||||
extra := private.FlushQueues(ctx, c.Duration("timeout"), c.Bool("non-blocking"))
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
func runProcesses(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("manager", c.Bool("debug"))
|
||||
statusCode, msg := private.Processes(ctx, os.Stdout, c.Bool("flat"), c.Bool("no-system"), c.Bool("stacktraces"), c.Bool("json"), c.String("cancel"))
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
return nil
|
||||
setup(ctx, c.Bool("debug"))
|
||||
extra := private.Processes(ctx, os.Stdout, c.Bool("flat"), c.Bool("no-system"), c.Bool("stacktraces"), c.Bool("json"), c.String("cancel"))
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
+36
-57
@@ -5,7 +5,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@@ -191,27 +190,25 @@ var (
|
||||
)
|
||||
|
||||
func runRemoveLogger(c *cli.Context) error {
|
||||
setup("manager", c.Bool("debug"))
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup(ctx, c.Bool("debug"))
|
||||
group := c.String("group")
|
||||
if len(group) == 0 {
|
||||
group = log.DEFAULT
|
||||
}
|
||||
name := c.Args().First()
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
statusCode, msg := private.RemoveLogger(ctx, group, name)
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
return nil
|
||||
extra := private.RemoveLogger(ctx, group, name)
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
func runAddSMTPLogger(c *cli.Context) error {
|
||||
setup("manager", c.Bool("debug"))
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup(ctx, c.Bool("debug"))
|
||||
vals := map[string]interface{}{}
|
||||
mode := "smtp"
|
||||
if c.IsSet("host") {
|
||||
@@ -242,7 +239,10 @@ func runAddSMTPLogger(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func runAddConnLogger(c *cli.Context) error {
|
||||
setup("manager", c.Bool("debug"))
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup(ctx, c.Bool("debug"))
|
||||
vals := map[string]interface{}{}
|
||||
mode := "conn"
|
||||
vals["net"] = "tcp"
|
||||
@@ -269,7 +269,10 @@ func runAddConnLogger(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func runAddFileLogger(c *cli.Context) error {
|
||||
setup("manager", c.Bool("debug"))
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup(ctx, c.Bool("debug"))
|
||||
vals := map[string]interface{}{}
|
||||
mode := "file"
|
||||
if c.IsSet("filename") {
|
||||
@@ -299,7 +302,10 @@ func runAddFileLogger(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func runAddConsoleLogger(c *cli.Context) error {
|
||||
setup("manager", c.Bool("debug"))
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup(ctx, c.Bool("debug"))
|
||||
vals := map[string]interface{}{}
|
||||
mode := "console"
|
||||
if c.IsSet("stderr") && c.Bool("stderr") {
|
||||
@@ -338,28 +344,17 @@ func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) e
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
statusCode, msg := private.AddLogger(ctx, group, name, mode, vals)
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
return nil
|
||||
extra := private.AddLogger(ctx, group, name, mode, vals)
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
func runPauseLogging(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("manager", c.Bool("debug"))
|
||||
statusCode, msg := private.PauseLogging(ctx)
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
setup(ctx, c.Bool("debug"))
|
||||
userMsg := private.PauseLogging(ctx)
|
||||
_, _ = fmt.Fprintln(os.Stdout, userMsg)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -367,14 +362,9 @@ func runResumeLogging(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("manager", c.Bool("debug"))
|
||||
statusCode, msg := private.ResumeLogging(ctx)
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
setup(ctx, c.Bool("debug"))
|
||||
userMsg := private.ResumeLogging(ctx)
|
||||
_, _ = fmt.Fprintln(os.Stdout, userMsg)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -382,28 +372,17 @@ func runReleaseReopenLogging(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setup("manager", c.Bool("debug"))
|
||||
statusCode, msg := private.ReleaseReopenLogging(ctx)
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
setup(ctx, c.Bool("debug"))
|
||||
userMsg := private.ReleaseReopenLogging(ctx)
|
||||
_, _ = fmt.Fprintln(os.Stdout, userMsg)
|
||||
return nil
|
||||
}
|
||||
|
||||
func runSetLogSQL(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
setup("manager", c.Bool("debug"))
|
||||
setup(ctx, c.Bool("debug"))
|
||||
|
||||
statusCode, msg := private.SetLogSQL(ctx, !c.Bool("off"))
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
return fail("InternalServerError", msg)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, msg)
|
||||
return nil
|
||||
extra := private.SetLogSQL(ctx, !c.Bool("off"))
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
+19
-8
@@ -72,12 +72,21 @@ var CmdMigrateStorage = cli.Command{
|
||||
cli.StringFlag{
|
||||
Name: "minio-base-path",
|
||||
Value: "",
|
||||
Usage: "Minio storage basepath on the bucket",
|
||||
Usage: "Minio storage base path on the bucket",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "minio-use-ssl",
|
||||
Usage: "Enable SSL for minio",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "minio-insecure-skip-verify",
|
||||
Usage: "Skip SSL verification",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "minio-checksum-algorithm",
|
||||
Value: "",
|
||||
Usage: "Minio checksum algorithm (default/md5)",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -168,13 +177,15 @@ func runMigrateStorage(ctx *cli.Context) error {
|
||||
dstStorage, err = storage.NewMinioStorage(
|
||||
stdCtx,
|
||||
storage.MinioStorageConfig{
|
||||
Endpoint: ctx.String("minio-endpoint"),
|
||||
AccessKeyID: ctx.String("minio-access-key-id"),
|
||||
SecretAccessKey: ctx.String("minio-secret-access-key"),
|
||||
Bucket: ctx.String("minio-bucket"),
|
||||
Location: ctx.String("minio-location"),
|
||||
BasePath: ctx.String("minio-base-path"),
|
||||
UseSSL: ctx.Bool("minio-use-ssl"),
|
||||
Endpoint: ctx.String("minio-endpoint"),
|
||||
AccessKeyID: ctx.String("minio-access-key-id"),
|
||||
SecretAccessKey: ctx.String("minio-secret-access-key"),
|
||||
Bucket: ctx.String("minio-bucket"),
|
||||
Location: ctx.String("minio-location"),
|
||||
BasePath: ctx.String("minio-base-path"),
|
||||
UseSSL: ctx.Bool("minio-use-ssl"),
|
||||
InsecureSkipVerify: ctx.Bool("minio-insecure-skip-verify"),
|
||||
ChecksumAlgorithm: ctx.String("minio-checksum-algorithm"),
|
||||
})
|
||||
default:
|
||||
return fmt.Errorf("unsupported storage type: %s", ctx.String("storage"))
|
||||
|
||||
+2
-10
@@ -4,11 +4,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
@@ -60,7 +57,7 @@ func runRestoreRepository(c *cli.Context) error {
|
||||
if s := c.String("units"); s != "" {
|
||||
units = strings.Split(s, ",")
|
||||
}
|
||||
statusCode, errStr := private.RestoreRepo(
|
||||
extra := private.RestoreRepo(
|
||||
ctx,
|
||||
c.String("repo_dir"),
|
||||
c.String("owner_name"),
|
||||
@@ -68,10 +65,5 @@ func runRestoreRepository(c *cli.Context) error {
|
||||
units,
|
||||
c.Bool("validation"),
|
||||
)
|
||||
if statusCode == http.StatusOK {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Fatal("Failed to restore repository: %v", errStr)
|
||||
return errors.New(errStr)
|
||||
return handleCliResponseExtra(extra)
|
||||
}
|
||||
|
||||
+57
-42
@@ -7,7 +7,6 @@ package cmd
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -16,6 +15,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
@@ -55,7 +55,7 @@ var CmdServ = cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func setup(logPath string, debug bool) {
|
||||
func setup(ctx context.Context, debug bool) {
|
||||
_ = log.DelLogger("console")
|
||||
if debug {
|
||||
_ = log.NewLogger(1000, "console", "console", `{"level":"trace","stacktracelevel":"NONE","stderr":true}`)
|
||||
@@ -72,15 +72,15 @@ func setup(logPath string, debug bool) {
|
||||
// `[repository]` `ROOT` is a relative path and $GITEA_WORK_DIR isn't passed to the SSH connection.
|
||||
if _, err := os.Stat(setting.RepoRootPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
_ = fail("Incorrect configuration, no repository directory.", "Directory `[repository].ROOT` %q was not found, please check if $GITEA_WORK_DIR is passed to the SSH connection or make `[repository].ROOT` an absolute value.", setting.RepoRootPath)
|
||||
_ = fail(ctx, "Incorrect configuration, no repository directory.", "Directory `[repository].ROOT` %q was not found, please check if $GITEA_WORK_DIR is passed to the SSH connection or make `[repository].ROOT` an absolute value.", setting.RepoRootPath)
|
||||
} else {
|
||||
_ = fail("Incorrect configuration, repository directory is inaccessible", "Directory `[repository].ROOT` %q is inaccessible. err: %v", setting.RepoRootPath, err)
|
||||
_ = fail(ctx, "Incorrect configuration, repository directory is inaccessible", "Directory `[repository].ROOT` %q is inaccessible. err: %v", setting.RepoRootPath, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := git.InitSimple(context.Background()); err != nil {
|
||||
_ = fail("Failed to init git", "Failed to init git, err: %v", err)
|
||||
_ = fail(ctx, "Failed to init git", "Failed to init git, err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,32 +94,54 @@ var (
|
||||
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
|
||||
)
|
||||
|
||||
func fail(userMessage, logMessage string, args ...interface{}) error {
|
||||
// fail prints message to stdout, it's mainly used for git serv and git hook commands.
|
||||
// The output will be passed to git client and shown to user.
|
||||
func fail(ctx context.Context, userMessage, logMsgFmt string, args ...interface{}) error {
|
||||
if userMessage == "" {
|
||||
userMessage = "Internal Server Error (no specific error)"
|
||||
}
|
||||
|
||||
// There appears to be a chance to cause a zombie process and failure to read the Exit status
|
||||
// if nothing is outputted on stdout.
|
||||
_, _ = fmt.Fprintln(os.Stdout, "")
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Gitea:", userMessage)
|
||||
|
||||
if len(logMessage) > 0 {
|
||||
if logMsgFmt != "" {
|
||||
logMsg := fmt.Sprintf(logMsgFmt, args...)
|
||||
if !setting.IsProd {
|
||||
_, _ = fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Gitea:", logMsg)
|
||||
}
|
||||
}
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if len(logMessage) > 0 {
|
||||
_ = private.SSHLog(ctx, true, fmt.Sprintf(logMessage+": ", args...))
|
||||
if userMessage != "" {
|
||||
if unicode.IsPunct(rune(userMessage[len(userMessage)-1])) {
|
||||
logMsg = userMessage + " " + logMsg
|
||||
} else {
|
||||
logMsg = userMessage + ". " + logMsg
|
||||
}
|
||||
}
|
||||
_ = private.SSHLog(ctx, true, logMsg)
|
||||
}
|
||||
return cli.NewExitError("", 1)
|
||||
}
|
||||
|
||||
// handleCliResponseExtra handles the extra response from the cli sub-commands
|
||||
// If there is a user message it will be printed to stdout
|
||||
// If the command failed it will return an error (the error will be printed by cli framework)
|
||||
func handleCliResponseExtra(extra private.ResponseExtra) error {
|
||||
if extra.UserMsg != "" {
|
||||
_, _ = fmt.Fprintln(os.Stdout, extra.UserMsg)
|
||||
}
|
||||
if extra.HasError() {
|
||||
return cli.NewExitError(extra.Error, 1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runServ(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
// FIXME: This needs to internationalised
|
||||
setup("serv.log", c.Bool("debug"))
|
||||
setup(ctx, c.Bool("debug"))
|
||||
|
||||
if setting.SSH.Disabled {
|
||||
println("Gitea: SSH has been disabled")
|
||||
@@ -135,18 +157,18 @@ func runServ(c *cli.Context) error {
|
||||
|
||||
keys := strings.Split(c.Args()[0], "-")
|
||||
if len(keys) != 2 || keys[0] != "key" {
|
||||
return fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
|
||||
return fail(ctx, "Key ID format error", "Invalid key argument: %s", c.Args()[0])
|
||||
}
|
||||
keyID, err := strconv.ParseInt(keys[1], 10, 64)
|
||||
if err != nil {
|
||||
return fail("Key ID format error", "Invalid key argument: %s", c.Args()[1])
|
||||
return fail(ctx, "Key ID parsing error", "Invalid key argument: %s", c.Args()[1])
|
||||
}
|
||||
|
||||
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
|
||||
if len(cmd) == 0 {
|
||||
key, user, err := private.ServNoCommand(ctx, keyID)
|
||||
if err != nil {
|
||||
return fail("Internal error", "Failed to check provided key: %v", err)
|
||||
return fail(ctx, "Key check failed", "Failed to check provided key: %v", err)
|
||||
}
|
||||
switch key.Type {
|
||||
case asymkey_model.KeyTypeDeploy:
|
||||
@@ -164,7 +186,7 @@ func runServ(c *cli.Context) error {
|
||||
|
||||
words, err := shellquote.Split(cmd)
|
||||
if err != nil {
|
||||
return fail("Error parsing arguments", "Failed to parse arguments: %v", err)
|
||||
return fail(ctx, "Error parsing arguments", "Failed to parse arguments: %v", err)
|
||||
}
|
||||
|
||||
if len(words) < 2 {
|
||||
@@ -175,7 +197,7 @@ func runServ(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fail("Too few arguments", "Too few arguments in cmd: %s", cmd)
|
||||
return fail(ctx, "Too few arguments", "Too few arguments in cmd: %s", cmd)
|
||||
}
|
||||
|
||||
verb := words[0]
|
||||
@@ -187,7 +209,7 @@ func runServ(c *cli.Context) error {
|
||||
var lfsVerb string
|
||||
if verb == lfsAuthenticateVerb {
|
||||
if !setting.LFS.StartServer {
|
||||
return fail("Unknown git command", "LFS authentication request over SSH denied, LFS support is disabled")
|
||||
return fail(ctx, "Unknown git command", "LFS authentication request over SSH denied, LFS support is disabled")
|
||||
}
|
||||
|
||||
if len(words) > 2 {
|
||||
@@ -200,37 +222,37 @@ func runServ(c *cli.Context) error {
|
||||
|
||||
rr := strings.SplitN(repoPath, "/", 2)
|
||||
if len(rr) != 2 {
|
||||
return fail("Invalid repository path", "Invalid repository path: %v", repoPath)
|
||||
return fail(ctx, "Invalid repository path", "Invalid repository path: %v", repoPath)
|
||||
}
|
||||
|
||||
username := strings.ToLower(rr[0])
|
||||
reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git"))
|
||||
|
||||
if alphaDashDotPattern.MatchString(reponame) {
|
||||
return fail("Invalid repo name", "Invalid repo name: %s", reponame)
|
||||
return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame)
|
||||
}
|
||||
|
||||
if c.Bool("enable-pprof") {
|
||||
if err := os.MkdirAll(setting.PprofDataPath, os.ModePerm); err != nil {
|
||||
return fail("Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)
|
||||
return fail(ctx, "Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)
|
||||
}
|
||||
|
||||
stopCPUProfiler, err := pprof.DumpCPUProfileForUsername(setting.PprofDataPath, username)
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "Unable to start CPU profile: %v", err)
|
||||
return fail(ctx, "Unable to start CPU profiler", "Unable to start CPU profile: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
stopCPUProfiler()
|
||||
err := pprof.DumpMemProfileForUsername(setting.PprofDataPath, username)
|
||||
if err != nil {
|
||||
_ = fail("Internal Server Error", "Unable to dump Mem Profile: %v", err)
|
||||
_ = fail(ctx, "Unable to dump Mem profile", "Unable to dump Mem Profile: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
requestedMode, has := allowedCommands[verb]
|
||||
if !has {
|
||||
return fail("Unknown git command", "Unknown git command %s", verb)
|
||||
return fail(ctx, "Unknown git command", "Unknown git command %s", verb)
|
||||
}
|
||||
|
||||
if verb == lfsAuthenticateVerb {
|
||||
@@ -239,20 +261,13 @@ func runServ(c *cli.Context) error {
|
||||
} else if lfsVerb == "download" {
|
||||
requestedMode = perm.AccessModeRead
|
||||
} else {
|
||||
return fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb)
|
||||
return fail(ctx, "Unknown LFS verb", "Unknown lfs verb %s", lfsVerb)
|
||||
}
|
||||
}
|
||||
|
||||
results, err := private.ServCommand(ctx, keyID, username, reponame, requestedMode, verb, lfsVerb)
|
||||
if err != nil {
|
||||
if private.IsErrServCommand(err) {
|
||||
errServCommand := err.(private.ErrServCommand)
|
||||
if errServCommand.StatusCode != http.StatusInternalServerError {
|
||||
return fail("Unauthorized", "%s", errServCommand.Error())
|
||||
}
|
||||
return fail("Internal Server Error", "%s", errServCommand.Error())
|
||||
}
|
||||
return fail("Internal Server Error", "%s", err.Error())
|
||||
results, extra := private.ServCommand(ctx, keyID, username, reponame, requestedMode, verb, lfsVerb)
|
||||
if extra.HasError() {
|
||||
return fail(ctx, extra.UserMsg, "ServCommand failed: %s", extra.Error)
|
||||
}
|
||||
|
||||
// LFS token authentication
|
||||
@@ -274,7 +289,7 @@ func runServ(c *cli.Context) error {
|
||||
// Sign and get the complete encoded token as a string using the secret
|
||||
tokenString, err := token.SignedString(setting.LFS.JWTSecretBytes)
|
||||
if err != nil {
|
||||
return fail("Internal error", "Failed to sign JWT token: %v", err)
|
||||
return fail(ctx, "Failed to sign JWT Token", "Failed to sign JWT token: %v", err)
|
||||
}
|
||||
|
||||
tokenAuthentication := &git_model.LFSTokenResponse{
|
||||
@@ -286,7 +301,7 @@ func runServ(c *cli.Context) error {
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
err = enc.Encode(tokenAuthentication)
|
||||
if err != nil {
|
||||
return fail("Internal error", "Failed to encode LFS json response: %v", err)
|
||||
return fail(ctx, "Failed to encode LFS json response", "Failed to encode LFS json response: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -332,13 +347,13 @@ func runServ(c *cli.Context) error {
|
||||
gitcmd.Env = append(gitcmd.Env, git.CommonCmdServEnvs()...)
|
||||
|
||||
if err = gitcmd.Run(); err != nil {
|
||||
return fail("Internal error", "Failed to execute git command: %v", err)
|
||||
return fail(ctx, "Failed to execute git command", "Failed to execute git command: %v", err)
|
||||
}
|
||||
|
||||
// Update user key activity.
|
||||
if results.KeyID > 0 {
|
||||
if err = private.UpdatePublicKeyInRepo(ctx, results.KeyID, results.RepoID); err != nil {
|
||||
return fail("Internal error", "UpdatePublicKeyInRepo: %v", err)
|
||||
return fail(ctx, "Failed to update public key", "UpdatePublicKeyInRepo: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
su git -c "/home/git/gogs/scripts/gogs_supervisord.sh restart"
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/google/go-github/v45/github"
|
||||
"github.com/google/go-github/v51/github"
|
||||
"github.com/urfave/cli"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
DROP DATABASE IF EXISTS gitea;
|
||||
CREATE DATABASE IF NOT EXISTS gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
@@ -1,267 +0,0 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package main
|
||||
|
||||
/*
|
||||
Checkout a PR and load the tests data into sqlite database
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
gitea_git "code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/external"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers"
|
||||
markup_service "code.gitea.io/gitea/services/markup"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/config"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"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.InitProviderAllowEmpty()
|
||||
setting.LoadCommonSettings()
|
||||
|
||||
setting.RepoRootPath, err = os.MkdirTemp(os.TempDir(), "repos")
|
||||
if err != nil {
|
||||
log.Fatalf("TempDir: %v\n", err)
|
||||
}
|
||||
setting.AppDataPath, err = os.MkdirTemp(os.TempDir(), "appdata")
|
||||
if err != nil {
|
||||
log.Fatalf("TempDir: %v\n", err)
|
||||
}
|
||||
setting.AppWorkPath = curDir
|
||||
setting.StaticRootPath = curDir
|
||||
setting.GravatarSource = "https://secure.gravatar.com/avatar/"
|
||||
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")
|
||||
//models.LoadConfigs()
|
||||
/*
|
||||
setting.Database.Type = "sqlite3"
|
||||
setting.Database.Path = ":memory:"
|
||||
setting.Database.Timeout = 500
|
||||
*/
|
||||
dbCfg := setting.CfgProvider.Section("database")
|
||||
dbCfg.NewKey("DB_TYPE", "sqlite3")
|
||||
dbCfg.NewKey("PATH", ":memory:")
|
||||
|
||||
routers.InitGitServices()
|
||||
setting.Database.LogSQL = true
|
||||
// x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
||||
|
||||
db.InitEngineWithMigration(context.Background(), func(_ *xorm.Engine) error {
|
||||
return nil
|
||||
})
|
||||
db.HasEngine = true
|
||||
// x.ShowSQL(true)
|
||||
err = unittest.InitFixtures(
|
||||
unittest.FixturesOptions{
|
||||
Dir: path.Join(curDir, "models/fixtures/"),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Error initializing test database: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
unittest.LoadFixtures()
|
||||
util.RemoveAll(setting.RepoRootPath)
|
||||
util.RemoveAll(repo_module.LocalCopyPath())
|
||||
unittest.CopyDir(path.Join(curDir, "tests/gitea-repositories-meta"), setting.RepoRootPath)
|
||||
|
||||
log.Printf("[PR] Setting up router\n")
|
||||
// routers.GlobalInit()
|
||||
external.RegisterRenderers()
|
||||
markup.Init(markup_service.ProcessorHelper())
|
||||
c := routers.NormalRoutes(graceful.GetManager().HammerContext())
|
||||
|
||||
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", c)
|
||||
|
||||
log.Printf("[PR] Cleaning up ...\n")
|
||||
/*
|
||||
if err = util.RemoveAll(setting.Indexer.IssuePath); err != nil {
|
||||
fmt.Printf("util.RemoveAll: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = util.RemoveAll(setting.Indexer.RepoPath); err != nil {
|
||||
fmt.Printf("Unable to remove repo indexer: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
*/
|
||||
if err = util.RemoveAll(setting.RepoRootPath); err != nil {
|
||||
log.Fatalf("util.RemoveAll: %v\n", err)
|
||||
}
|
||||
if err = util.RemoveAll(setting.AppDataPath); err != nil {
|
||||
log.Fatalf("util.RemoveAll: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
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 := os.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.git" ||
|
||||
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("%s%s/head:%s", gitea_git.PullPrefix, 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), 0o755)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to duplicate this code file in PR : %v", err)
|
||||
}
|
||||
err = os.WriteFile(codeFilePath, dat, 0o644)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to duplicate this code file in PR : %v", err)
|
||||
}
|
||||
}
|
||||
// Force build of js, css, bin, ...
|
||||
runCmd("make", "build")
|
||||
// Start with integration test
|
||||
runCmd("go", "run", "-mod", "vendor", "-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)
|
||||
}
|
||||
}
|
||||
+17
-10
@@ -186,8 +186,8 @@ RUN_MODE = ; prod
|
||||
;; default is the system temporary directory.
|
||||
;SSH_KEY_TEST_PATH =
|
||||
;;
|
||||
;; Path to ssh-keygen, default is 'ssh-keygen' which means the shell is responsible for finding out which one to call.
|
||||
;SSH_KEYGEN_PATH = ssh-keygen
|
||||
;; Use `ssh-keygen` to parse public SSH keys. The value is passed to the shell. By default, Gitea does the parsing itself.
|
||||
;SSH_KEYGEN_PATH =
|
||||
;;
|
||||
;; Enable SSH Authorized Key Backup when rewriting all keys, default is true
|
||||
;SSH_AUTHORIZED_KEYS_BACKUP = true
|
||||
@@ -583,15 +583,15 @@ ROUTER = console
|
||||
;; * In request Header: X-Request-ID: test-id-123
|
||||
;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID
|
||||
;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "test-id-123"
|
||||
;;
|
||||
;; If you configure more than one in the .ini file, it will match in the order of configuration,
|
||||
;;
|
||||
;; If you configure more than one in the .ini file, it will match in the order of configuration,
|
||||
;; and the first match will be finally printed in the log.
|
||||
;; * E.g:
|
||||
;; * In reuqest Header: X-Trace-ID: trace-id-1q2w3e4r
|
||||
;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID, X-Req-ID
|
||||
;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "trace-id-1q2w3e4r"
|
||||
;;
|
||||
;; REQUEST_ID_HEADERS =
|
||||
;; REQUEST_ID_HEADERS =
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
@@ -603,7 +603,7 @@ ROUTER = console
|
||||
;ACCESS = file
|
||||
;;
|
||||
;; Sets the template used to create the access log.
|
||||
;ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"
|
||||
;ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
@@ -947,10 +947,10 @@ ROUTER = console
|
||||
;USE_COMPAT_SSH_URI = false
|
||||
;;
|
||||
;; Close issues as long as a commit on any branch marks it as fixed
|
||||
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects, repo.packages
|
||||
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects, repo.packages, repo.actions.
|
||||
;DISABLED_REPO_UNITS =
|
||||
;;
|
||||
;; Comma separated list of default new repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects, repo.packages.
|
||||
;; Comma separated list of default new repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects, repo.packages, repo.actions.
|
||||
;; Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility.
|
||||
;; External wiki and issue tracker can't be enabled by default as it requires additional settings.
|
||||
;; Disabled repo units will not be added to new repositories regardless if it is in the default list.
|
||||
@@ -1238,6 +1238,10 @@ ROUTER = console
|
||||
;;
|
||||
;; Whether to enable a Service Worker to cache frontend assets
|
||||
;USE_SERVICE_WORKER = false
|
||||
;;
|
||||
;; Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used.
|
||||
;; A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic).
|
||||
;ONLY_SHOW_RELEVANT_REPOS = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1357,13 +1361,13 @@ ROUTER = console
|
||||
;; Issue Indexer settings
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Issue indexer type, currently support: bleve, db or elasticsearch, default is bleve
|
||||
;; Issue indexer type, currently support: bleve, db, elasticsearch or meilisearch default is bleve
|
||||
;ISSUE_INDEXER_TYPE = bleve
|
||||
;;
|
||||
;; Issue indexer storage path, available when ISSUE_INDEXER_TYPE is bleve
|
||||
;ISSUE_INDEXER_PATH = indexers/issues.bleve ; Relative paths will be made absolute against _`AppWorkPath`_.
|
||||
;;
|
||||
;; Issue indexer connection string, available when ISSUE_INDEXER_TYPE is elasticsearch
|
||||
;; Issue indexer connection string, available when ISSUE_INDEXER_TYPE is elasticsearch or meilisearch
|
||||
;ISSUE_INDEXER_CONN_STR = http://elastic:changeme@localhost:9200
|
||||
;;
|
||||
;; Issue indexer name, available when ISSUE_INDEXER_TYPE is elasticsearch
|
||||
@@ -1886,6 +1890,9 @@ ROUTER = console
|
||||
;;
|
||||
;; Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
;MINIO_INSECURE_SKIP_VERIFY = false
|
||||
;;
|
||||
;; Minio checksum algorithm: default (for MinIO or AWS S3) or md5 (for Cloudflare or Backblaze)
|
||||
;MINIO_CHECKSUM_ALGORITHM = default
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ params:
|
||||
description: Git with a cup of tea
|
||||
author: The Gitea Authors
|
||||
website: https://docs.gitea.io
|
||||
version: 1.18.5
|
||||
version: 1.19.0
|
||||
minGoVersion: 1.19
|
||||
goVersion: 1.20
|
||||
minNodeVersion: 16
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2019-12-28"
|
||||
title: "Adding Legal Pages"
|
||||
slug: adding-legal-pages
|
||||
weight: 9
|
||||
weight: 110
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2017-01-01T16:00:00+02:00"
|
||||
title: "Usage: Backup and Restore"
|
||||
title: "Backup and Restore"
|
||||
slug: "backup-and-restore"
|
||||
weight: 11
|
||||
toc: false
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2020-01-25T21:00:00-03:00"
|
||||
title: "Embedded data extraction tool"
|
||||
slug: "cmd-embedded"
|
||||
weight: 40
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
date: "2017-01-01T16:00:00+02:00"
|
||||
title: "Usage: Command Line"
|
||||
title: "Gitea Command Line"
|
||||
slug: "command-line"
|
||||
weight: 10
|
||||
weight: 1
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-26T16:00:00+02:00"
|
||||
title: "Config Cheat Sheet"
|
||||
slug: "config-cheat-sheet"
|
||||
weight: 20
|
||||
weight: 30
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
@@ -103,8 +103,8 @@ In addition there is _`StaticRootPath`_ which can be set as a built-in at build
|
||||
- `DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH`: **false**: Close an issue if a commit on a non default branch marks it as closed.
|
||||
- `ENABLE_PUSH_CREATE_USER`: **false**: Allow users to push local repositories to Gitea and have them automatically created for a user.
|
||||
- `ENABLE_PUSH_CREATE_ORG`: **false**: Allow users to push local repositories to Gitea and have them automatically created for an org.
|
||||
- `DISABLED_REPO_UNITS`: **_empty_**: Comma separated list of globally disabled repo units. Allowed values: \[repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects\]
|
||||
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages**: Comma separated list of default new repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
|
||||
- `DISABLED_REPO_UNITS`: **_empty_**: Comma separated list of globally disabled repo units. Allowed values: \[repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects, repo.packages, repo.actions\]
|
||||
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages**: Comma separated list of default new repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects, repo.packages, repo.actions\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
|
||||
- `DEFAULT_FORK_REPO_UNITS`: **repo.code,repo.pulls**: Comma separated list of default forked repo units. The set of allowed values and rules is the same as `DEFAULT_REPO_UNITS`.
|
||||
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
||||
- `DISABLE_MIGRATIONS`: **false**: Disable migrating feature.
|
||||
@@ -226,11 +226,13 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
Values can be emoji alias (:smile:) or a unicode emoji.
|
||||
For custom reactions, add a tightly cropped square image to public/img/emoji/reaction_name.png
|
||||
- `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: Additional Emojis not defined in the utf8 standard.
|
||||
By default we support Gitea (:gitea:), to add more copy them to public/img/emoji/emoji_name.png and
|
||||
By default, we support Gitea (:gitea:), to add more copy them to public/img/emoji/emoji_name.png and
|
||||
add it to this config.
|
||||
- `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used.
|
||||
- `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page.
|
||||
- `USE_SERVICE_WORKER`: **false**: Whether to enable a Service Worker to cache frontend assets.
|
||||
- `ONLY_SHOW_RELEVANT_REPOS`: **false** Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used.
|
||||
A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic).
|
||||
|
||||
### UI - Admin (`ui.admin`)
|
||||
|
||||
@@ -343,7 +345,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
- `SSH_SERVER_MACS`: **hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect
|
||||
- `SSH_SERVER_HOST_KEYS`: **ssh/gitea.rsa, ssh/gogs.rsa**: For the built-in SSH server, choose the keypairs to offer as the host key. The private key should be at `SSH_SERVER_HOST_KEY` and the public `SSH_SERVER_HOST_KEY.pub`. Relative paths are made absolute relative to the `APP_DATA_PATH`. If no key exists a 4096 bit RSA key will be created for you.
|
||||
- `SSH_KEY_TEST_PATH`: **/tmp**: Directory to create temporary files in when testing public keys using ssh-keygen, default is the system temporary directory.
|
||||
- `SSH_KEYGEN_PATH`: **ssh-keygen**: Path to ssh-keygen, default is 'ssh-keygen' which means the shell is responsible for finding out which one to call.
|
||||
- `SSH_KEYGEN_PATH`: **\<empty\>**: Use `ssh-keygen` to parse public SSH keys. The value is passed to the shell. By default, Gitea does the parsing itself.
|
||||
- `SSH_EXPOSE_ANONYMOUS`: **false**: Enable exposure of SSH clone URL to anonymous visitors, default is false.
|
||||
- `SSH_PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the SSH connections. (Set to
|
||||
-1 to disable all timeouts.)
|
||||
@@ -456,8 +458,8 @@ relation to port exhaustion.
|
||||
|
||||
## Indexer (`indexer`)
|
||||
|
||||
- `ISSUE_INDEXER_TYPE`: **bleve**: Issue indexer type, currently supported: `bleve`, `db` or `elasticsearch`.
|
||||
- `ISSUE_INDEXER_CONN_STR`: ****: Issue indexer connection string, available when ISSUE_INDEXER_TYPE is elasticsearch. i.e. http://elastic:changeme@localhost:9200
|
||||
- `ISSUE_INDEXER_TYPE`: **bleve**: Issue indexer type, currently supported: `bleve`, `db`, `elasticsearch` or `meilisearch`.
|
||||
- `ISSUE_INDEXER_CONN_STR`: ****: Issue indexer connection string, available when ISSUE_INDEXER_TYPE is elasticsearch, or meilisearch. i.e. http://elastic:changeme@localhost:9200
|
||||
- `ISSUE_INDEXER_NAME`: **gitea_issues**: Issue indexer name, available when ISSUE_INDEXER_TYPE is elasticsearch
|
||||
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search; available when ISSUE_INDEXER_TYPE is bleve and elasticsearch. Relative paths will be made absolute against _`AppWorkPath`_.
|
||||
- The next 4 configuration values are deprecated and should be set in `queue.issue_indexer` however are kept for backwards compatibility:
|
||||
@@ -855,6 +857,7 @@ Default templates for project boards:
|
||||
- `MINIO_BASE_PATH`: **attachments/**: Minio base path on the bucket only available when STORAGE_TYPE is `minio`
|
||||
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||
- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
|
||||
- `MINIO_CHECKSUM_ALGORITHM`: **default**: Minio checksum algorithm: `default` (for MinIO or AWS S3) or `md5` (for Cloudflare or Backblaze)
|
||||
|
||||
## Log (`log`)
|
||||
|
||||
@@ -875,7 +878,7 @@ Default templates for project boards:
|
||||
|
||||
- `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.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log.
|
||||
- `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log.
|
||||
- The following variables are available:
|
||||
- `Ctx`: the `context.Context` of the request.
|
||||
- `Identity`: the SignedUserName or `"-"` if not logged in.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-26T16:00:00+02:00"
|
||||
title: "配置说明"
|
||||
slug: "config-cheat-sheet"
|
||||
weight: 20
|
||||
weight: 30
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
@@ -265,7 +265,7 @@ test01.xls: application/vnd.ms-excel; charset=binary
|
||||
- `LEVEL`: 日志级别,默认为 `Trace`。
|
||||
- `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。
|
||||
- `ENABLE_ACCESS_LOG`: 是否开启 Access Log, 默认为 false。
|
||||
- `ACCESS_LOG_TEMPLATE`: `access.log` 输出内容的模板,默认模板:**`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**
|
||||
- `ACCESS_LOG_TEMPLATE`: `access.log` 输出内容的模板,默认模板:**`{{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"`**
|
||||
模板支持以下参数:
|
||||
- `Ctx`: 请求上下文。
|
||||
- `Identity`: 登录用户名,默认: “`-`”。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2017-04-15T14:56:00+02:00"
|
||||
title: "Customizing Gitea"
|
||||
slug: "customizing-gitea"
|
||||
weight: 9
|
||||
weight: 100
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2017-04-15T14:56:00+02:00"
|
||||
title: "自定义 Gitea 配置"
|
||||
slug: "customizing-gitea"
|
||||
weight: 9
|
||||
weight: 100
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2019-10-15T10:10:00+05:00"
|
||||
title: "Usage: Email setup"
|
||||
title: "Email setup"
|
||||
slug: "email-setup"
|
||||
weight: 12
|
||||
toc: false
|
||||
@@ -81,7 +81,7 @@ SMTP_ADDR = smtp.gmail.com
|
||||
SMTP_PORT = 465
|
||||
FROM = example.user@gmail.com
|
||||
USER = example.user
|
||||
PASSWD = ***
|
||||
PASSWD = `***`
|
||||
MAILER_TYPE = smtp
|
||||
IS_TLS_ENABLED = true
|
||||
```
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2017-04-08T11:34:00+02:00"
|
||||
title: "Environment variables"
|
||||
slug: "environment-variables"
|
||||
weight: 20
|
||||
weight: 10
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2017-04-08T11:34:00+02:00"
|
||||
title: "环境变量清单"
|
||||
slug: "environment-variables"
|
||||
weight: 20
|
||||
weight: 10
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2018-11-23:00:00+02:00"
|
||||
title: "External renderers"
|
||||
slug: "external-renderers"
|
||||
weight: 40
|
||||
weight: 60
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2018-05-11T11:00:00+02:00"
|
||||
title: "Usage: Setup fail2ban"
|
||||
title: "Fail2ban Setup "
|
||||
slug: "fail2ban-setup"
|
||||
weight: 16
|
||||
toc: false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2022-08-01T00:00:00+00:00"
|
||||
title: "使用: 设置 Fail2ban"
|
||||
title: "设置 Fail2ban"
|
||||
slug: "fail2ban-setup"
|
||||
weight: 16
|
||||
toc: false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2019-10-06T08:00:00+05:00"
|
||||
title: "Usage: Git LFS setup"
|
||||
title: "Git LFS setup"
|
||||
slug: "git-lfs-setup"
|
||||
weight: 12
|
||||
toc: false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2018-06-02T11:00:00+02:00"
|
||||
title: "Usage: HTTPS setup"
|
||||
title: "HTTPS setup"
|
||||
slug: "https-setup"
|
||||
weight: 12
|
||||
toc: false
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
date: "2023-04-09T11:00:00+02:00"
|
||||
title: "使用: HTTPS配置"
|
||||
slug: "https-setup"
|
||||
weight: 12
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "administration"
|
||||
name: "HTTPS setup"
|
||||
weight: 12
|
||||
identifier: "https-setup"
|
||||
---
|
||||
|
||||
# HTTPS setup to encrypt connections to Gitea
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## 使用内置服务器
|
||||
|
||||
在启用HTTPS之前,确保您拥有有效的SSL/TLS证书。
|
||||
建议在测试和评估情况下使用自签名证书,请运行 `gitea cert --host [HOST]` 以生成自签名证书
|
||||
|
||||
如果您在服务器上使用阿帕奇(Apache)或Nginx,建议参考 [反向代理指南]({{< relref "doc/administration/reverse-proxies.zh-cn.md" >}})。
|
||||
|
||||
要使用Gitea内置HTTPS支持,您必须编辑`app.ini`文件。
|
||||
|
||||
```ini
|
||||
[server]
|
||||
PROTOCOL = https
|
||||
ROOT_URL = https://git.example.com:3000/
|
||||
HTTP_PORT = 3000
|
||||
CERT_FILE = cert.pem
|
||||
KEY_FILE = key.pem
|
||||
```
|
||||
|
||||
请注意,如果您的证书由第三方证书颁发机构签名(即不是自签名的),则 cert.pem 应包含证书链。服务器证书必须是 cert.pem 中的第一个条目,后跟中介(如果有)。不必包含根证书,因为连接客户端必须已经拥有根证书才能建立信任关系。要了解有关配置值的更多信息,请查看 [配置备忘单](../config-cheat-sheet#server-server)。
|
||||
|
||||
对于“CERT_FILE”或“KEY_FILE”字段,当文件路径是相对路径时,文件路径相对于“GITEA_CUSTOM”环境变量。它也可以是绝对路径。
|
||||
|
||||
### 设置HTTP重定向
|
||||
|
||||
Gitea服务器仅支持监听一个端口;要重定向HTTP请求致HTTPS端口,您需要启用HTTP重定向服务:
|
||||
|
||||
```ini
|
||||
[server]
|
||||
REDIRECT_OTHER_PORT = true
|
||||
; Port the redirection service should listen on
|
||||
PORT_TO_REDIRECT = 3080
|
||||
```
|
||||
|
||||
如果您使用Docker,确保端口已配置在 `docker-compose.yml` 文件
|
||||
|
||||
## 使用 ACME (默认: Let's Encrypt)
|
||||
|
||||
[ACME](https://tools.ietf.org/html/rfc8555) 是一种证书颁发机构标准协议,允许您自动请求和续订 SSL/TLS 证书。[Let`s Encrypt](https://letsencrypt.org/) 是使用此标准的免费公开信任的证书颁发机构服务器。仅实施“HTTP-01”和“TLS-ALPN-01”挑战。为了使 ACME 质询通过并验证您的域所有权,“80”端口(“HTTP-01”)或“443”端口(“TLS-ALPN-01”)上 gitea 域的外部流量必须由 gitea 实例提供服务。可能需要设置 [HTTP 重定向](#设置http重定向) 和端口转发才能正确路由外部流量。否则,到端口“80”的正常流量将自动重定向到 HTTPS。**您必须同意**ACME提供商的服务条款(默认为Let's Encrypt的 [服务条款](https://letsencrypt.org/documents/LE-SA-v1.2-2017年11月15日.pdf)。
|
||||
|
||||
实用默认 Let's Encrypt 的最小配置如下:
|
||||
|
||||
```ini
|
||||
[server]
|
||||
PROTOCOL=https
|
||||
DOMAIN=git.example.com
|
||||
ENABLE_ACME=true
|
||||
ACME_ACCEPTTOS=true
|
||||
ACME_DIRECTORY=https
|
||||
;; Email can be omitted here and provided manually at first run, after which it is cached
|
||||
ACME_EMAIL=email@example.com
|
||||
```
|
||||
|
||||
小型配置请使用 [smallstep CA](https://github.com/smallstep/certificates), 点击 [教程](https://smallstep.com/docs/tutorials/acme-challenge) 了解更多信息。
|
||||
|
||||
```ini
|
||||
[server]
|
||||
PROTOCOL=https
|
||||
DOMAIN=git.example.com
|
||||
ENABLE_ACME=true
|
||||
ACME_ACCEPTTOS=true
|
||||
ACME_URL=https://ca.example.com/acme/acme/directory
|
||||
;; Can be omitted if using the system's trust is preferred
|
||||
;ACME_CA_ROOT=/path/to/root_ca.crt
|
||||
ACME_DIRECTORY=https
|
||||
ACME_EMAIL=email@example.com
|
||||
```
|
||||
|
||||
要了解关于配置, 请访问 [配置备忘单](../config-cheat-sheet#server-server)获取更多信息
|
||||
|
||||
## 使用反向代理服务器
|
||||
|
||||
按照 [reverse proxy guide](../reverse-proxies) 的规则设置你的反向代理服务器
|
||||
|
||||
然后,按照下面的想到启用 HTTPS:
|
||||
|
||||
- [nginx](https://nginx.org/en/docs/http/configuring_https_servers.html)
|
||||
- [apache2/httpd](https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html)
|
||||
- [caddy](https://caddyserver.com/docs/tls)
|
||||
|
||||
注意:仅在代理层启用 HTTPS 被称为 [TLS 终止代理](https://en.wikipedia.org/wiki/TLS_termination_proxy)。代理服务器接受传入的 TLS 连接,解密内容,然后将现在未加密的内容传递给 Gitea。只要代理和 Gitea 实例在同一台计算机上或在私有网络中的不同计算机上(代理暴露给外部网络),这通常是可以接受的。如果您的 Gitea 实例与代理隔离在公共网络上,或者如果您想要全端到端的加密,您还可以直接在 Gitea 中 [启用内置服务器的 HTTPS 支持](#使用内置服务器),并将连接转发到 HTTPS 上。
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
date: "2019-04-02T17:06:00+01:00"
|
||||
title: "Advanced: Logging Configuration"
|
||||
title: "Logging Configuration"
|
||||
slug: "logging-configuration"
|
||||
weight: 55
|
||||
weight: 40
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
@@ -304,7 +304,7 @@ log using the value: `ACCESS = ,`
|
||||
|
||||
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.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`
|
||||
`{{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"`
|
||||
|
||||
The template is passed following options:
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ Currently, the following notification events make use of templates:
|
||||
| `approve` | The head comment of a approving review for a pull request. |
|
||||
| `reject` | The head comment of a review requesting changes for a pull request. |
|
||||
| `code` | A single comment on the code of a pull request. |
|
||||
| `assigned` | Used was assigned to an issue or pull request. |
|
||||
| `assigned` | User was assigned to an issue or pull request. |
|
||||
| `default` | Any action not included in the above categories, or when the corresponding category template is not present. |
|
||||
|
||||
The path for the template of a particular message type is:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
date: "2018-05-22T11:00:00+00:00"
|
||||
title: "Usage: Reverse Proxies"
|
||||
title: "Reverse Proxies"
|
||||
slug: "reverse-proxies"
|
||||
weight: 17
|
||||
weight: 16
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2018-05-22T11:00:00+00:00"
|
||||
title: "使用:反向代理"
|
||||
slug: "reverse-proxies"
|
||||
weight: 17
|
||||
weight: 16
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
date: "2019-12-31T13:55:00+05:00"
|
||||
title: "Advanced: Search Engines Indexation"
|
||||
title: "Search Engines Indexation"
|
||||
slug: "search-engines-indexation"
|
||||
weight: 30
|
||||
weight: 60
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2019-08-17T10:20:00+01:00"
|
||||
title: "GPG Commit Signatures"
|
||||
slug: "signing"
|
||||
weight: 20
|
||||
weight: 50
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "本地化"
|
||||
slug: "localization"
|
||||
weight: 10
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "在地化"
|
||||
slug: "localization"
|
||||
weight: 10
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
date: "2021-01-22T00:00:00+02:00"
|
||||
title: "Übersetzungs Richtlinien"
|
||||
weight: 10
|
||||
weight: 70
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
date: "2021-01-22T00:00:00+02:00"
|
||||
title: "Translation Guidelines"
|
||||
weight: 10
|
||||
weight: 70
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2019-04-15T17:29:00+08:00"
|
||||
title: "Integrations"
|
||||
slug: "integrations"
|
||||
weight: 40
|
||||
weight: 65
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2019-04-15T17:29:00+08:00"
|
||||
title: "整合"
|
||||
slug: "integrations"
|
||||
weight: 40
|
||||
weight: 65
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2019-04-15T17:29:00+08:00"
|
||||
title: "Migrations Interfaces"
|
||||
slug: "migrations-interfaces"
|
||||
weight: 30
|
||||
weight: 55
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2019-04-15T17:29:00+08:00"
|
||||
title: "遷移介面"
|
||||
slug: "migrations-interfaces"
|
||||
weight: 30
|
||||
weight: 55
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
---
|
||||
date: "2019-04-19:44:00+01:00"
|
||||
title: "OAuth2 提供者"
|
||||
slug: "oauth2-provider"
|
||||
weight: 41
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "development"
|
||||
name: "OAuth2 提供者"
|
||||
weight: 41
|
||||
identifier: "oauth2-provider"
|
||||
---
|
||||
|
||||
# OAuth2 提供者
|
||||
|
||||
**目录**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
Gitea 支持作为 OAuth2 提供者,允许第三方应用程序在用户同意的情况下访问其资源。此功能自 1.8.0 版起可用。
|
||||
|
||||
## 端点
|
||||
|
||||
| 端点 | URL |
|
||||
| ------------------------ | ----------------------------------- |
|
||||
| OpenID Connect Discovery | `/.well-known/openid-configuration` |
|
||||
| Authorization Endpoint | `/login/oauth/authorize` |
|
||||
| Access Token Endpoint | `/login/oauth/access_token` |
|
||||
| OpenID Connect UserInfo | `/login/oauth/userinfo` |
|
||||
| JSON Web Key Set | `/login/oauth/keys` |
|
||||
|
||||
## 支持的 OAuth2 授权
|
||||
|
||||
目前 Gitea 仅支持 [**Authorization Code Grant**](https://tools.ietf.org/html/rfc6749#section-1.3.1) 标准,并额外支持以下扩展:
|
||||
|
||||
- [Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636)
|
||||
- [OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
|
||||
|
||||
要将 Authorization Code Grant 作为第三方应用程序,您需要通过在设置中添加一个新的 "应用程序" (`/user/settings/applications`)。
|
||||
|
||||
## 范围
|
||||
|
||||
Gitea 支持以下令牌范围:
|
||||
|
||||
| 名称 | 介绍 |
|
||||
| ---- | ----------- |
|
||||
| **(no scope)** | 授予对公共用户配置文件和公共存储库的只读访问权限 |
|
||||
| **repo** | 完全控制所有存储库 |
|
||||
| **repo:status** | 授予对所有存储库中提交状态的读/写访问权限 |
|
||||
| **public_repo** | 仅授予对公共存储库的读/写访问权限 |
|
||||
| **admin:repo_hook** | 授予对所有存储库的 Hooks 访问权限,该权限已包含在 `repo` 范围中 |
|
||||
| **write:repo_hook** | 授予对存储库 Hooks 的读/写访问权限 |
|
||||
| **read:repo_hook** | 授予对存储库 Hooks 的只读访问权限 |
|
||||
| **admin:org** | 授予对组织设置的完全访问权限 |
|
||||
| **write:org** | 授予对组织设置的读/写访问权限 |
|
||||
| **read:org** | 授予对组织设置的只读访问权限 |
|
||||
| **admin:public_key** | 授予公钥管理的完全访问权限 |
|
||||
| **write:public_key** | 授予对公钥的读/写访问权限 |
|
||||
| **read:public_key** | 授予对公钥的只读访问权限 |
|
||||
| **admin:org_hook** | 授予对组织级别 Hooks 的完全访问权限 |
|
||||
| **admin:user_hook** | 授予对用户级别 Hooks 的完全访问权限 |
|
||||
| **notification** | 授予对通知的完全访问权限 |
|
||||
| **user** | 授予对用户个人资料信息的完全访问权限 |
|
||||
| **read:user** | 授予对用户个人资料的读取权限 |
|
||||
| **user:email** | 授予对用户电子邮件地址的读取权限 |
|
||||
| **user:follow** | 授予访问权限以关注/取消关注用户 |
|
||||
| **delete_repo** | 授予删除存储库的权限 |
|
||||
| **package** | 授予对托管包的完全访问权限 |
|
||||
| **write:package** | 授予对包的读/写访问权限 |
|
||||
| **read:package** | 授予对包的读取权限 |
|
||||
| **delete:package** | 授予对包的删除权限 |
|
||||
| **admin:gpg_key** | 授予 GPG 密钥管理的完全访问权限 |
|
||||
| **write:gpg_key** | 授予对 GPG 密钥的读/写访问权限 |
|
||||
| **read:gpg_key** | 授予对 GPG 密钥的只读访问权限 |
|
||||
| **admin:application** | 授予应用程序管理的完全访问权限 |
|
||||
| **write:application** | 授予应用程序管理的读/写访问权限 |
|
||||
| **read:application** | 授予应用程序管理的读取权限 |
|
||||
| **sudo** | 允许以站点管理员身份执行操作 |
|
||||
|
||||
## 客户端类型
|
||||
|
||||
Gitea 支持私密和公共客户端类型,[参见 RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1).
|
||||
|
||||
对于公共客户端, 允许在本地回环地址的重定向 URI 中使用任意端口,例如 `http://127.0.0.1/`。根据 [RFC 8252 的建议](https://datatracker.ietf.org/doc/html/rfc8252#section-8.3),请避免使用 `localhost`。
|
||||
|
||||
## 示例
|
||||
|
||||
**注意:** 该示例中尚未使用 PKCE。
|
||||
|
||||
1. 将用户重定向到授权端点,以获得他们的访问资源授权:
|
||||
|
||||
```curl
|
||||
https://[YOUR-GITEA-URL]/login/oauth/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI& response_type=code&state=STATE
|
||||
```
|
||||
|
||||
在设置中注册应用程序以获得 `CLIENT_ID`。`STATE` 是一个随机字符串,它将在获得用户授权后发送回您的应用程序。`state` 参数是可选的,但您应该使用它来防止 CSRF 攻击。
|
||||
|
||||

|
||||
|
||||
用户将会被询问是否授权给您的应用程序。如果他们同意了授权,用户将会被重定向到 `REDIRECT_URL`,例如:
|
||||
|
||||
```curl
|
||||
https://[REDIRECT_URI]?code=RETURNED_CODE&state=STATE
|
||||
```
|
||||
|
||||
2. 使用重定向提供的 `code`,您可以请求一个新的应用程序和 Refresh Token。Access Token Endpoint 接受 `application/json` 或 `application/x-www-form-urlencoded` 类型的 POST 请求,例如:
|
||||
|
||||
```curl
|
||||
POST https://[YOUR-GITEA-URL]/login/oauth/access_token
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"client_id": "YOUR_CLIENT_ID",
|
||||
"client_secret": "YOUR_CLIENT_SECRET",
|
||||
"code": "RETURNED_CODE",
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "REDIRECT_URI"
|
||||
}
|
||||
```
|
||||
|
||||
返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJnbnQiOjIsInR0IjowLCJleHAiOjE1NTUxNzk5MTIsImlhdCI6MTU1NTE3NjMxMn0.0-iFsAwBtxuckA0sNZ6QpBQmywVPz129u75vOM7wPJecw5wqGyBkmstfJHAjEOqrAf_V5Z-1QYeCh_Cz4RiKug",
|
||||
"token_type": "bearer",
|
||||
"expires_in": 3600,
|
||||
"refresh_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJnbnQiOjIsInR0IjoxLCJjbnQiOjEsImV4cCI6MTU1NzgwNDMxMiwiaWF0IjoxNTU1MTc2MzEyfQ.S_HZQBy4q9r5SEzNGNIoFClT43HPNDbUdHH-GYNYYdkRfft6XptJBkUQscZsGxOW975Yk6RbgtGvq1nkEcklOw"
|
||||
}
|
||||
```
|
||||
|
||||
`CLIENT_SECRET` 是生成给应用程序的唯一密钥。请注意,该密钥只会在您使用 Gitea 创建/注册应用程序后出现一次。如果您丢失了密钥,您必须在应用程序设置中重新生成密钥。
|
||||
|
||||
`access_token` 请求中的 `REDIRECT_URI` 必须与 `authorize` 请求中的 `REDIRECT_URI` 相符。
|
||||
|
||||
3. 使用 `access_token` 来构造 [API 请求](https://docs.gitea.io/en-us/api-usage#oauth2) 以读写用户的资源。
|
||||
@@ -118,6 +118,14 @@ The correct path for the template(s) will be relative to the `CustomPath`
|
||||
2. If you are still unable to find a path, the default can be [calculated above](#where-does-gitea-store-what-file)
|
||||
3. Once you have figured out the correct custom path, you can refer to the [customizing Gitea]({{< relref "doc/administration/customizing-gitea.en-us.md" >}}) page to add your template to the correct location.
|
||||
|
||||
## Does Gitea have a "GitHub/GitLab pages" feature?
|
||||
|
||||
Gitea doesn't provide a built-in Pages server. You need a dedicated domain to serve static pages to avoid CSRF security risks.
|
||||
|
||||
For simple usage, you can use a reverse proxy to rewrite & serve static contents from Gitea's raw file URLs.
|
||||
|
||||
And there are already available third-party services, like a standalone [pages server](https://codeberg.org/Codeberg/pages-server) or a [caddy plugin](https://github.com/42wim/caddy-gitea), that can provide the required functionality.
|
||||
|
||||
## Active user vs login prohibited user
|
||||
|
||||
In Gitea, an "active" user refers to a user that has activated their account via email.
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Search"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
weight: 1
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
priority : 1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Search"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
weight: 1
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
priority : 1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Chercher"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
weight: 1
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
priority : 1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Search"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
weight: 1
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
priority : 1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Search"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
weight: 1
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
priority : 1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "搜索"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
weight: 1
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
priority : 1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "搜尋"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
weight: 1
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
priority : 1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2018-05-21T15:00:00+00:00"
|
||||
title: "Support Options"
|
||||
slug: "seek-help"
|
||||
weight: 10
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2017-01-20T15:00:00+08:00"
|
||||
title: "需要帮助"
|
||||
slug: "seek-help"
|
||||
weight: 10
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2018-05-21T15:00:00+00:00"
|
||||
title: "取得協助"
|
||||
slug: "seek-help"
|
||||
weight: 10
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2018-05-07T13:00:00+02:00"
|
||||
title: "Gitea compared to other Git hosting options"
|
||||
title: "Compared to other Git hosting"
|
||||
slug: "comparison"
|
||||
weight: 5
|
||||
toc: false
|
||||
@@ -31,6 +31,8 @@ _Symbols used in table:_
|
||||
|
||||
- _✘ - unsupported_
|
||||
|
||||
- _⚙️ - supported through third-party software_
|
||||
|
||||
## General Features
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
@@ -51,7 +53,7 @@ _Symbols used in table:_
|
||||
| Custom Theme Support | ✓ | ✓ | ✘ | ✘ | ✘ | ✓ | ✘ |
|
||||
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||
| 'GitHub / GitLab pages' | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 'GitHub / GitLab pages' | [⚙️][gitea-pages-server], [⚙️][gitea-caddy-plugin] | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Repo-specific wiki (as a repo itself) | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
@@ -144,3 +146,6 @@ _Symbols used in table:_
|
||||
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Integration with the most common services | ✓ | / | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
||||
| Incorporate external CI/CD | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
|
||||
[gitea-caddy-plugin]: https://github.com/42wim/caddy-gitea
|
||||
[gitea-pages-server]: https://codeberg.org/Codeberg/pages-server
|
||||
|
||||
@@ -29,6 +29,8 @@ _表格中的符号含义:_
|
||||
|
||||
* _? - 不确定_
|
||||
|
||||
* _⚙️ - 由第三方服务或插件支持_
|
||||
|
||||
#### 主要特性
|
||||
|
||||
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
@@ -42,7 +44,7 @@ _表格中的符号含义:_
|
||||
| 支持 Orgmode | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? |
|
||||
| 支持 CSV | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||
| 支持第三方渲染工具 | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
||||
| Git 驱动的静态 pages | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Git 驱动的静态 pages | [⚙️][gitea-pages-server], [⚙️][gitea-caddy-plugin] | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Git 驱动的集成化 wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
||||
| 部署令牌 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 仓库写权限令牌 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
@@ -129,3 +131,6 @@ _表格中的符号含义:_
|
||||
| 集成 Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 集成 Microsoft Teams | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 显示外部 CI/CD 的状态 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
|
||||
[gitea-caddy-plugin]: https://github.com/42wim/caddy-gitea
|
||||
[gitea-pages-server]: https://codeberg.org/Codeberg/pages-server
|
||||
|
||||
@@ -31,6 +31,8 @@ menu:
|
||||
|
||||
- ✘ - 不支援
|
||||
|
||||
- _⚙️ - 由第三方服務或外掛程式支援_
|
||||
|
||||
## 一般功能
|
||||
|
||||
| 功能 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
@@ -44,7 +46,7 @@ menu:
|
||||
| 支援 Orgmode | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? |
|
||||
| 支援 CSV | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||
| 支援第三方渲染工具 | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
||||
| Git 驅動的靜態頁面 | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Git 驅動的靜態頁面 | [⚙️][gitea-pages-server], [⚙️][gitea-caddy-plugin] | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Git 驅動的整合 wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 部署 Token | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 有寫入權限的儲存庫 Token | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||
@@ -130,3 +132,6 @@ menu:
|
||||
| 整合 Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 整合 Microsoft Teams | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 顯示外部 CI/CD 狀態 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
|
||||
[gitea-caddy-plugin]: https://github.com/42wim/caddy-gitea
|
||||
[gitea-pages-server]: https://codeberg.org/Codeberg/pages-server
|
||||
|
||||
@@ -9,13 +9,13 @@ menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Database preparation"
|
||||
weight: 5
|
||||
weight: 10
|
||||
identifier: "database-prep"
|
||||
---
|
||||
|
||||
# Database Preparation
|
||||
|
||||
You need a database to use Gitea. Gitea supports PostgreSQL (>=10), MySQL (>=5.7), SQLite, and MSSQL (>=2008R2 SP3). This page will guide into preparing database. Only PostgreSQL and MySQL will be covered here since those database engines are widely-used in production.
|
||||
You need a database to use Gitea. Gitea supports PostgreSQL (>=10), MySQL (>=5.7), SQLite, and MSSQL (>=2008R2 SP3). This page will guide into preparing database. Only PostgreSQL and MySQL will be covered here since those database engines are widely-used in production. If you plan to use SQLite, you can ignore this chapter.
|
||||
|
||||
Database instance can be on same machine as Gitea (local database setup), or on different machine (remote database).
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
date: "2017-06-19T12:00:00+02:00"
|
||||
title: "Installation from binary"
|
||||
slug: "install-from-binary"
|
||||
weight: 10
|
||||
weight: 15
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "From binary"
|
||||
weight: 20
|
||||
weight: 15
|
||||
identifier: "install-from-binary"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Installation avec le binaire pré-compilé"
|
||||
slug: "install-from-binary"
|
||||
weight: 10
|
||||
weight: 15
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Binaire pré-compilé"
|
||||
weight: 20
|
||||
weight: 15
|
||||
identifier: "install-from-binary"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "从二进制安装"
|
||||
slug: "install-from-binary"
|
||||
weight: 10
|
||||
weight: 15
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "从二进制安装"
|
||||
weight: 20
|
||||
weight: 15
|
||||
identifier: "install-from-binary"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "執行檔安裝"
|
||||
slug: "install-from-binary"
|
||||
weight: 10
|
||||
weight: 15
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "執行檔"
|
||||
weight: 20
|
||||
weight: 15
|
||||
identifier: "install-from-binary"
|
||||
---
|
||||
|
||||
|
||||
@@ -13,12 +13,25 @@ menu:
|
||||
identifier: "install-from-package"
|
||||
---
|
||||
|
||||
# Installation from package
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
# Official packages
|
||||
|
||||
## macOS
|
||||
|
||||
Currently, the only supported method of installation on MacOS is [Homebrew](http://brew.sh/).
|
||||
Following the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide may work,
|
||||
but is not supported. To install Gitea via `brew`:
|
||||
|
||||
```
|
||||
brew tap gitea/tap https://gitea.com/gitea/homebrew-gitea
|
||||
brew install gitea
|
||||
```
|
||||
|
||||
# Unofficial packages
|
||||
|
||||
## Alpine Linux
|
||||
|
||||
Alpine Linux has [Gitea](https://pkgs.alpinelinux.org/packages?name=gitea&branch=edge) in its community repository which follows the latest stable version.
|
||||
@@ -74,17 +87,6 @@ choco install gitea
|
||||
|
||||
Or follow the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide.
|
||||
|
||||
## macOS
|
||||
|
||||
Currently, the only supported method of installation on MacOS is [Homebrew](http://brew.sh/).
|
||||
Following the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide may work,
|
||||
but is not supported. To install Gitea via `brew`:
|
||||
|
||||
```
|
||||
brew tap gitea/tap https://gitea.com/gitea/homebrew-gitea
|
||||
brew install gitea
|
||||
```
|
||||
|
||||
## FreeBSD
|
||||
|
||||
A FreeBSD port `www/gitea` is available. To install the pre-built binary package:
|
||||
@@ -108,7 +110,7 @@ is in `/usr/local/etc/rc.d/gitea`.
|
||||
|
||||
To enable Gitea to run as a service, run `sysrc gitea_enable=YES` and start it with `service gitea start`.
|
||||
|
||||
## Third-party
|
||||
## Others
|
||||
|
||||
Various other third-party packages of Gitea exist.
|
||||
To see a curated list, head over to [awesome-gitea](https://gitea.com/gitea/awesome-gitea/src/branch/master/README.md#user-content-packages).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "Installation depuis le gestionnaire de paquets"
|
||||
slug: "install-from-package"
|
||||
weight: 10
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "使用包管理器安装"
|
||||
slug: "install-from-package"
|
||||
weight: 10
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
@@ -13,12 +13,23 @@ menu:
|
||||
identifier: "install-from-package"
|
||||
---
|
||||
|
||||
# 使用包管理器安装
|
||||
|
||||
**目录**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
# 官方包管理器
|
||||
|
||||
## macOS
|
||||
|
||||
macOS 平台下当前我们仅支持通过 `brew` 来安装。如果你没有安装 [Homebrew](http://brew.sh/),你也可以查看 [从二进制安装]({{< relref "from-binary.zh-cn.md" >}})。在你安装了 `brew` 之后, 你可以执行以下命令:
|
||||
|
||||
```
|
||||
brew tap gitea/tap https://gitea.com/gitea/homebrew-gitea
|
||||
brew install gitea
|
||||
```
|
||||
|
||||
# 非官方包管理器
|
||||
|
||||
## Alpine Linux
|
||||
|
||||
Gitea 已经包含在 Alpine Linux 的[社区存储库](https://pkgs.alpinelinux.org/packages?name=gitea&branch=edge)中,版本与 Gitea 官方保持同步。
|
||||
@@ -66,15 +77,6 @@ choco install gitea
|
||||
|
||||
你也可以 [从二进制安装]({{< relref "from-binary.zh-cn.md" >}}) 。
|
||||
|
||||
## macOS
|
||||
|
||||
macOS 平台下当前我们仅支持通过 `brew` 来安装。如果你没有安装 [Homebrew](http://brew.sh/),你也可以查看 [从二进制安装]({{< relref "from-binary.zh-cn.md" >}})。在你安装了 `brew` 之后, 你可以执行以下命令:
|
||||
|
||||
```
|
||||
brew tap gitea/tap https://gitea.com/gitea/homebrew-gitea
|
||||
brew install gitea
|
||||
```
|
||||
|
||||
## FreeBSD
|
||||
|
||||
可以使用 Gitea 的 FreeBSD port `www/gitea`。 请安装预构建的二进制包:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "套件安裝"
|
||||
slug: "install-from-package"
|
||||
weight: 10
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "Installation from source"
|
||||
slug: "install-from-source"
|
||||
weight: 10
|
||||
weight: 30
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Installation depuis le code source"
|
||||
slug: "install-from-source"
|
||||
weight: 10
|
||||
weight: 30
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "从源代码安装"
|
||||
slug: "install-from-source"
|
||||
weight: 10
|
||||
weight: 30
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "原始碼安裝"
|
||||
slug: "install-from-source"
|
||||
weight: 10
|
||||
weight: 30
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "Install on Cloud Provider"
|
||||
slug: "install-on-cloud-provider"
|
||||
weight: 20
|
||||
weight: 90
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "On cloud provider"
|
||||
weight: 20
|
||||
weight: 90
|
||||
identifier: "install-on-cloud-provider"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
date: "2020-03-19T19:27:00+02:00"
|
||||
title: "Install on Kubernetes"
|
||||
slug: "install-on-kubernetes"
|
||||
weight: 10
|
||||
weight: 80
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Kubernetes"
|
||||
weight: 50
|
||||
weight: 80
|
||||
identifier: "install-on-kubernetes"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
date: "2020-03-19T19:27:00+02:00"
|
||||
title: "在 Kubernetes 安装 Gitea"
|
||||
slug: "install-on-kubernetes"
|
||||
weight: 10
|
||||
weight: 80
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Kubernetes"
|
||||
weight: 50
|
||||
weight: 80
|
||||
identifier: "install-on-kubernetes"
|
||||
---
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
date: "2020-03-19T19:27:00+02:00"
|
||||
title: "在 Kubernetes 安裝"
|
||||
slug: "install-on-kubernetes"
|
||||
weight: 10
|
||||
weight: 80
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Kubernetes"
|
||||
weight: 50
|
||||
weight: 80
|
||||
identifier: "install-on-kubernetes"
|
||||
---
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user