Compare commits
242 Commits
v1.10.0-rc
...
lunny/refa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a4bb23150 | ||
|
|
58bc380724 | ||
|
|
ac7c78d004 | ||
|
|
0e063de211 | ||
|
|
5067294f32 | ||
|
|
da074675c6 | ||
|
|
7735d70d66 | ||
|
|
0f5de85f9a | ||
|
|
16a43156a8 | ||
|
|
7b75603ffe | ||
|
|
b41f303ae0 | ||
|
|
8282f26250 | ||
|
|
3b0303a4fc | ||
|
|
afe50873a5 | ||
|
|
71395dffd0 | ||
|
|
27ac1d0952 | ||
|
|
be869e8881 | ||
|
|
722a7c902d | ||
|
|
7b97e04555 | ||
|
|
cda8de2004 | ||
|
|
253fdfb7fa | ||
|
|
fd1b2a31f3 | ||
|
|
3ddca774fc | ||
|
|
4b3fc74937 | ||
|
|
e4e6d48e30 | ||
|
|
a0d4014517 | ||
|
|
bb6879d339 | ||
|
|
555b1f6581 | ||
|
|
173da1b5ae | ||
|
|
561044e422 | ||
|
|
74a6add4d9 | ||
|
|
74bb292fe3 | ||
|
|
8d9e625f83 | ||
|
|
273a24f226 | ||
|
|
0e281384b5 | ||
|
|
ee1d64ddd1 | ||
|
|
44ec9b933a | ||
|
|
01a4a7cb14 | ||
|
|
8eeb2877d5 | ||
|
|
31416a5f4e | ||
|
|
daab245167 | ||
|
|
1b7402bd1d | ||
|
|
bb04fb55d7 | ||
|
|
c54145174f | ||
|
|
a647a54a08 | ||
|
|
1f3ba6919d | ||
|
|
f4937879b0 | ||
|
|
c15d371939 | ||
|
|
6e1912c73a | ||
|
|
9ae4c17cb1 | ||
|
|
d2aee2a3e2 | ||
|
|
f02138a148 | ||
|
|
55bdc9aa38 | ||
|
|
016a5d0438 | ||
|
|
fb459f2c2c | ||
|
|
1274ad864e | ||
|
|
d9be82bd00 | ||
|
|
b747501337 | ||
|
|
884acf8295 | ||
|
|
065bbddab9 | ||
|
|
1f90147f39 | ||
|
|
d5b1e6bc51 | ||
|
|
f05cd3e317 | ||
|
|
12170d26a7 | ||
|
|
72aa5a20ec | ||
|
|
0109229928 | ||
|
|
6d42add37f | ||
|
|
8a84d82d53 | ||
|
|
36b8c081f6 | ||
|
|
9395805512 | ||
|
|
45f219239e | ||
|
|
79fd422a92 | ||
|
|
aaeef295bb | ||
|
|
05e7715c4b | ||
|
|
2f4ef84cbf | ||
|
|
c0f4675a68 | ||
|
|
a91679c9e3 | ||
|
|
8d8aecd3cf | ||
|
|
86a44f6b48 | ||
|
|
3fb9e3afe3 | ||
|
|
0471aae348 | ||
|
|
ee5249889d | ||
|
|
2282c659dd | ||
|
|
a966a0298e | ||
|
|
491887d441 | ||
|
|
7971b05d2b | ||
|
|
dce22efbee | ||
|
|
022d2d8beb | ||
|
|
fe7a6d9bfc | ||
|
|
61a3eae923 | ||
|
|
76185edd76 | ||
|
|
729708e878 | ||
|
|
5a187f4bcc | ||
|
|
dd9cb32bff | ||
|
|
21dfe1b256 | ||
|
|
232340f5e3 | ||
|
|
9d663dfde6 | ||
|
|
8f26397928 | ||
|
|
f518fe6662 | ||
|
|
4b8d9e58c5 | ||
|
|
484edb7583 | ||
|
|
0e7f7df3cf | ||
|
|
ba336f6f45 | ||
|
|
9175556da0 | ||
|
|
7cf56a16d2 | ||
|
|
ebcc38188e | ||
|
|
ac0fb36c41 | ||
|
|
4ee986e4c9 | ||
|
|
a2bd8fe8dc | ||
|
|
cb1048d780 | ||
|
|
887a8fe242 | ||
|
|
086a46994a | ||
|
|
690a8ec502 | ||
|
|
7432396514 | ||
|
|
de2f45f95e | ||
|
|
1286473386 | ||
|
|
b48cad6a2a | ||
|
|
bda70b848f | ||
|
|
bc1775b490 | ||
|
|
7d9351779f | ||
|
|
f9944c0e69 | ||
|
|
ac6accef09 | ||
|
|
f694bb45d7 | ||
|
|
56ebc0c003 | ||
|
|
e6706df49d | ||
|
|
7bb817e6d1 | ||
|
|
e7fbc551ab | ||
|
|
559803025d | ||
|
|
9513a6983a | ||
|
|
c0f97f2687 | ||
|
|
c4f9d06855 | ||
|
|
c4bc5abda3 | ||
|
|
d6f6f9db3f | ||
|
|
09b281a6ac | ||
|
|
fd40c9d024 | ||
|
|
5e6a008fba | ||
|
|
af8957bc4c | ||
|
|
e3875ace91 | ||
|
|
c66c9dabc7 | ||
|
|
495d5e4329 | ||
|
|
018b0e8180 | ||
|
|
478f7db68e | ||
|
|
5b33ffe7c5 | ||
|
|
70fa80df11 | ||
|
|
9e85358777 | ||
|
|
d2d5910894 | ||
|
|
8b07823680 | ||
|
|
6aa3f8bc29 | ||
|
|
c34e58fc00 | ||
|
|
560a511a35 | ||
|
|
516fd7d3ae | ||
|
|
fc0580a4b7 | ||
|
|
a520236cb5 | ||
|
|
0a80164bec | ||
|
|
3c63c3ace4 | ||
|
|
bd7709a602 | ||
|
|
ab791fe7bb | ||
|
|
ee7b153dd9 | ||
|
|
c84174b764 | ||
|
|
22272fe1e4 | ||
|
|
ace0346c66 | ||
|
|
3e61a9628c | ||
|
|
dbd9d8dd54 | ||
|
|
637e3219ab | ||
|
|
f067e12859 | ||
|
|
7d1a7c05db | ||
|
|
c2fca23b2c | ||
|
|
b4b0e22f5f | ||
|
|
2f10bfa0f6 | ||
|
|
3fe9646564 | ||
|
|
fe41f71ba1 | ||
|
|
a41a965db2 | ||
|
|
00629fea95 | ||
|
|
d0c7a08d75 | ||
|
|
2f9a66a76c | ||
|
|
d8161ee3fd | ||
|
|
73f8069249 | ||
|
|
b59a905394 | ||
|
|
41c7aa5a3a | ||
|
|
969a540ce2 | ||
|
|
bfdcedfe89 | ||
|
|
0bfe5eb10b | ||
|
|
b1c1e1549b | ||
|
|
b539a6e6e3 | ||
|
|
481c66a91f | ||
|
|
28f60bb5cb | ||
|
|
c8f3146cd5 | ||
|
|
2657e718b6 | ||
|
|
85e4190761 | ||
|
|
bcd96421dd | ||
|
|
3b379691fa | ||
|
|
f37b87f81e | ||
|
|
85609efaad | ||
|
|
b2b9bdaf26 | ||
|
|
5a62ae5cbf | ||
|
|
280f4bebbf | ||
|
|
240f46a422 | ||
|
|
0a004a69cd | ||
|
|
05e437f8fd | ||
|
|
23045c7d53 | ||
|
|
945f121262 | ||
|
|
fecd8f949d | ||
|
|
7c4c01c0fd | ||
|
|
d44053eeda | ||
|
|
17c96ee52b | ||
|
|
37028f0e4e | ||
|
|
115a1cc680 | ||
|
|
d151503d34 | ||
|
|
ae132632a9 | ||
|
|
cf42cb0ae6 | ||
|
|
c43feedb96 | ||
|
|
c748deef33 | ||
|
|
de4f10be86 | ||
|
|
d4cd4ed442 | ||
|
|
fcb535c5c3 | ||
|
|
1b72690cb8 | ||
|
|
8f0e63c80a | ||
|
|
50b66b66e7 | ||
|
|
8edf3d5804 | ||
|
|
1d9a1a0d45 | ||
|
|
0b44f0c465 | ||
|
|
e1505d6250 | ||
|
|
31655aabfc | ||
|
|
66e99d722a | ||
|
|
80655026d2 | ||
|
|
9b9b67cd31 | ||
|
|
167e8f18da | ||
|
|
4a290bd64c | ||
|
|
8c909820a9 | ||
|
|
d7d348ea86 | ||
|
|
1e9b330525 | ||
|
|
6fa14ac3c8 | ||
|
|
20477a69ea | ||
|
|
34fb9d68a5 | ||
|
|
ebe8ff782f | ||
|
|
cea8ea5ae6 | ||
|
|
8ad2697611 | ||
|
|
733c898a90 | ||
|
|
0be992a1e2 | ||
|
|
b6ef539ef4 | ||
|
|
086bfb8b4b | ||
|
|
3083522620 |
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
/public/js/semantic.dropdown.custom.js
|
||||
@@ -10,6 +10,7 @@ env:
|
||||
browser: true
|
||||
jquery: true
|
||||
es6: true
|
||||
node: true
|
||||
|
||||
globals:
|
||||
Clipboard: false
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,6 +12,7 @@ _test
|
||||
|
||||
# MS VSCode
|
||||
.vscode
|
||||
__debug_bin
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
|
||||
@@ -73,6 +73,9 @@ issues:
|
||||
- path: routers/routes/routes.go
|
||||
linters:
|
||||
- dupl
|
||||
- path: routers/api/v1/repo/issue_subscription.go
|
||||
linters:
|
||||
- dupl
|
||||
- path: routers/repo/view.go
|
||||
linters:
|
||||
- dupl
|
||||
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
@@ -289,6 +289,38 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* wiki - editor - add buttons 'inline code', 'empty checkbox', 'checked checkbox' (#7243)
|
||||
* Fix Statuses API only shows first 10 statuses: Add paging and extend API GetCommitStatuses (#7141)
|
||||
|
||||
## [1.9.6](https://github.com/go-gitea/gitea/releases/tag/v1.9.6) - 2019-11-13
|
||||
* BUGFIXES
|
||||
* Allow to merge if file path contains " or \ (#8629) (#8772)
|
||||
* Fix 500 when edit hook (#8782) (#8790)
|
||||
* Fix issue with user.fullname (#8904)
|
||||
* Update Github Migration Test (#8897) (#8946)
|
||||
* Add Close() method to gogitRepository (#8901) (#8958)
|
||||
|
||||
## [1.9.5](https://github.com/go-gitea/gitea/releases/tag/v1.9.5) - 2019-10-30
|
||||
* BREAKING
|
||||
* Hide some user information via API if user doesn't have enough permission (#8655) (#8658)
|
||||
* BUGFIXES
|
||||
* Fix milestone close timestamp (#8728) (#8731)
|
||||
* Fix deadline on update issue or PR via API (#8699)
|
||||
* Fix 'New Issue Missing Milestone Comment' (#8678) (#8682)
|
||||
* Fix 500 when getting user as unauthenticated user (#8653) (#8662)
|
||||
* Use AppSubUrl for more redirections (#8647) (#8652)
|
||||
* Add SubURL to redirect path (#8632) (#8634) (#8640)
|
||||
* Fix #8582 by handling empty repos (#8587) (#8593)
|
||||
* Fix bug on pull requests when transfer head repository (#8571)
|
||||
* Add missed close in ServeBlobLFS (#8527) (#8543)
|
||||
* Return false if provided branch name is empty for IsBranchExist (#8485) (#8492)
|
||||
* Create .ssh dir as necessary (#8369) (#8486) (#8489)
|
||||
* Restore functionality for early gits (#7775) (#8476)
|
||||
* Add check for empty set when dropping indexes during migration (#8475)
|
||||
* Ensure Request Body Readers are closed in LFS server (#8454) (#8459)
|
||||
* Ensure that LFS files are relative to the LFS content path (#8455) (#8458)
|
||||
* SECURITY
|
||||
* Ignore mentions for users with no access (#8395) (#8484)
|
||||
* TESTING
|
||||
* Update heatmap fixtures to restore tests (#8615) (#8617)
|
||||
|
||||
## [1.9.4](https://github.com/go-gitea/gitea/releases/tag/v1.9.4) - 2019-10-08
|
||||
* BUGFIXES
|
||||
* Highlight issue references (#8101) (#8404)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
- [Translation](#translation)
|
||||
- [Code review](#code-review)
|
||||
- [Styleguide](#styleguide)
|
||||
- [Design guideline](#design-guideline)
|
||||
- [Developer Certificate of Origin (DCO)](#developer-certificate-of-origin-dco)
|
||||
- [Release Cycle](#release-cycle)
|
||||
- [Maintainers](#maintainers)
|
||||
@@ -71,13 +72,15 @@ Here's how to run the test suite:
|
||||
|
||||
- Install the correct version of the drone-cli package. As of this
|
||||
writing, the correct drone-cli version is
|
||||
[1.1.0](https://docs.drone.io/cli/install/).
|
||||
[1.2.0](https://docs.drone.io/cli/install/).
|
||||
- Ensure you have enough free disk space. You will need at least
|
||||
15-20 Gb of free disk space to hold all of the containers drone
|
||||
creates (a default AWS or GCE disk size won't work -- see
|
||||
[#6243](https://github.com/go-gitea/gitea/issues/6243)).
|
||||
- Change into the base directory of your copy of the gitea repository,
|
||||
and run `drone exec --event pull_request`.
|
||||
- At the moment `drone exec` doesn't support the Docker Toolbox on Windows 10
|
||||
(see [drone-cli#135](https://github.com/drone/drone-cli/issues/135))
|
||||
|
||||
The drone version, command line, and disk requirements do change over
|
||||
time (see [#4053](https://github.com/go-gitea/gitea/issues/4053) and
|
||||
@@ -118,6 +121,8 @@ An exception are the tools to build the CSS and images.
|
||||
- To build Images: ImageMagick, inkscape and zopflipng binaries must be
|
||||
available in your `PATH` to run `make generate-images`.
|
||||
|
||||
For more details on how to generate files, build and test Gitea, see the [hacking instructions](https://docs.gitea.io/en-us/hacking-on-gitea/)
|
||||
|
||||
## Code review
|
||||
|
||||
Changes to Gitea must be reviewed before they are accepted—no matter who
|
||||
@@ -157,6 +162,22 @@ import (
|
||||
)
|
||||
```
|
||||
|
||||
## Design guideline
|
||||
|
||||
To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The gitea code is divided into the following parts:
|
||||
|
||||
- **integration:** Integrations tests
|
||||
- **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependecies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
|
||||
- **models/fixtures:** Sample model data used in integration tests.
|
||||
- **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step.
|
||||
- **modules:** Different modules to handle specific functionality in Gitea.
|
||||
- **public:** Frontend files (javascript, images, css, etc.)
|
||||
- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers
|
||||
- **services:** Support functions for common routing operations. Uses models and modules to handle the request.
|
||||
- **templates:** Golang templates for generating the html output.
|
||||
- **vendor:** External code that Gitea depends on.
|
||||
|
||||
|
||||
## Developer Certificate of Origin (DCO)
|
||||
|
||||
We consider the act of contributing to the code by submitting a Pull
|
||||
@@ -283,7 +304,7 @@ be reviewed by two maintainers and must pass the automatic tests.
|
||||
* Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`.
|
||||
* And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically created a release and upload all the compiled binary. (But currently it didn't add the release notes automatically. Maybe we should fix that.)
|
||||
* If needed send PR for changelog on branch `master`.
|
||||
* Send PR to [blog repository](https://github.com/go-gitea/blog) announcing the release.
|
||||
* Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release.
|
||||
|
||||
## Copyright
|
||||
|
||||
|
||||
@@ -34,3 +34,4 @@ Gary Kim <gary@garykim.dev> (@gary-kim)
|
||||
Guillermo Prandi <gitea.maint@mailfilter.com.ar> (@guillep2k)
|
||||
Mura Li <typeless@ctli.io> (@typeless)
|
||||
6543 <6543@obermui.de> (@6543)
|
||||
jaqra <jaqra@hotmail.com> (@jaqra)
|
||||
|
||||
15
Makefile
15
Makefile
@@ -168,6 +168,10 @@ fmt-check:
|
||||
test:
|
||||
GO111MODULE=on $(GO) test -mod=vendor -tags='sqlite sqlite_unlock_notify' $(PACKAGES)
|
||||
|
||||
.PHONY: test\#%
|
||||
test\#%:
|
||||
GO111MODULE=on $(GO) test -mod=vendor -tags='sqlite sqlite_unlock_notify' -run $* $(PACKAGES)
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
@hash gocovmerge > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
@@ -430,13 +434,14 @@ npm-update: npm-check
|
||||
|
||||
.PHONY: js
|
||||
js: npm
|
||||
npx eslint public/js
|
||||
npx eslint web_src/js webpack.config.js
|
||||
npx webpack
|
||||
|
||||
.PHONY: css
|
||||
css: npm
|
||||
npx stylelint public/less
|
||||
npx lessc --clean-css="--s0 -b" public/less/index.less public/css/index.css
|
||||
$(foreach file, $(filter-out public/less/themes/_base.less, $(wildcard public/less/themes/*)),npx lessc --clean-css="--s0 -b" public/less/themes/$(notdir $(file)) > public/css/theme-$(notdir $(call strip-suffix,$(file))).css;)
|
||||
npx stylelint web_src/less
|
||||
npx lessc --clean-css="--s0 -b" web_src/less/index.less public/css/index.css
|
||||
$(foreach file, $(filter-out web_src/less/themes/_base.less, $(wildcard web_src/less/themes/*)),npx lessc --clean-css="--s0 -b" web_src/less/themes/$(notdir $(file)) > public/css/theme-$(notdir $(call strip-suffix,$(file))).css;)
|
||||
npx postcss --use autoprefixer --no-map --replace public/css/*
|
||||
|
||||
@diff=$$(git diff public/css/*); \
|
||||
@@ -517,4 +522,4 @@ golangci-lint:
|
||||
export BINARY="golangci-lint"; \
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.20.0; \
|
||||
fi
|
||||
golangci-lint run
|
||||
golangci-lint run --timeout 5m
|
||||
|
||||
13
README.md
13
README.md
@@ -1,6 +1,6 @@
|
||||
[简体中文](https://github.com/go-gitea/gitea/blob/master/README_ZH.md)
|
||||
[简体中文](README_ZH.md)
|
||||
|
||||
# Gitea - Git with a cup of tea
|
||||
<h1> <img src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea-192.png" alt="logo" width="30" height="30"> Gitea - Git with a cup of tea</h1>
|
||||
|
||||
[](https://drone.gitea.io/go-gitea/gitea)
|
||||
[](https://discord.gg/NsatcWJ)
|
||||
@@ -105,9 +105,8 @@ for the full license text.
|
||||
## Screenshots
|
||||
Looking for an overview of the interface? Check it out!
|
||||
|
||||
| | | |
|
||||
||||
|
||||
|:---:|:---:|:---:|
|
||||
||||
|
||||
||||
|
||||
||||
|
||||
||||
|
||||
||||
|
||||
|||
|
||||
|||
|
||||
|
||||
16
README_ZH.md
16
README_ZH.md
@@ -1,14 +1,15 @@
|
||||
[English](https://github.com/go-gitea/gitea/blob/master/README.md)
|
||||
[English](README.md)
|
||||
|
||||
# Gitea - Git with a cup of tea
|
||||
<h1> <img src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea-192.png" alt="logo" width="30" height="30"> Gitea - Git with a cup of tea</h1>
|
||||
|
||||
[](https://drone.gitea.io/go-gitea/gitea)
|
||||
[](https://discord.gg/gitea)
|
||||
[](https://discord.gg/NsatcWJ)
|
||||
[](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
|
||||
[](https://codecov.io/gh/go-gitea/gitea)
|
||||
[](https://goreportcard.com/report/code.gitea.io/gitea)
|
||||
[](https://godoc.org/code.gitea.io/gitea)
|
||||
[](https://github.com/go-gitea/gitea/releases/latest)
|
||||
[](https://www.codetriage.com/go-gitea/gitea)
|
||||
[](https://opencollective.com/gitea)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://crowdin.com/project/gitea)
|
||||
@@ -45,9 +46,8 @@ Fork -> Patch -> Push -> Pull Request
|
||||
|
||||
## 截图
|
||||
|
||||
| | | |
|
||||
||||
|
||||
|:---:|:---:|:---:|
|
||||
||||
|
||||
||||
|
||||
||||
|
||||
||||
|
||||
||||
|
||||
|||
|
||||
|||
|
||||
|
||||
@@ -66,7 +66,7 @@ var (
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "must-change-password",
|
||||
Usage: "Force the user to change his/her password after initial login",
|
||||
Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "random-password-length",
|
||||
@@ -375,17 +375,20 @@ func runRepoSyncReleases(c *cli.Context) error {
|
||||
|
||||
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
|
||||
log.Warn(" SyncReleasesWithTags: %v", err)
|
||||
gitRepo.Close()
|
||||
continue
|
||||
}
|
||||
|
||||
count, err = getReleaseCount(repo.ID)
|
||||
if err != nil {
|
||||
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
||||
gitRepo.Close()
|
||||
continue
|
||||
}
|
||||
|
||||
log.Trace(" repo %s releases synchronized to tags: from %d to %d",
|
||||
repo.FullName(), oldnum, count)
|
||||
gitRepo.Close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ func runHookPreReceive(c *cli.Context) error {
|
||||
reponame := os.Getenv(models.EnvRepoName)
|
||||
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
||||
prID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchPRID), 10, 64)
|
||||
isDeployKey, _ := strconv.ParseBool(os.Getenv(models.EnvIsDeployKey))
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
@@ -98,6 +99,7 @@ func runHookPreReceive(c *cli.Context) error {
|
||||
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
||||
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
|
||||
ProtectedBranchID: prID,
|
||||
IsDeployKey: isDeployKey,
|
||||
})
|
||||
switch statusCode {
|
||||
case http.StatusInternalServerError:
|
||||
|
||||
@@ -191,6 +191,8 @@ func runServ(c *cli.Context) error {
|
||||
os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
|
||||
os.Setenv(models.ProtectedBranchRepoID, strconv.FormatInt(results.RepoID, 10))
|
||||
os.Setenv(models.ProtectedBranchPRID, fmt.Sprintf("%d", 0))
|
||||
os.Setenv(models.EnvIsDeployKey, fmt.Sprintf("%t", results.IsDeployKey))
|
||||
os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID))
|
||||
|
||||
//LFS token authentication
|
||||
if verb == lfsAuthenticateVerb {
|
||||
|
||||
37
cmd/web.go
37
cmd/web.go
@@ -13,6 +13,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/routers"
|
||||
@@ -75,17 +76,13 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
|
||||
}
|
||||
go func() {
|
||||
log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
|
||||
var err = http.ListenAndServe(setting.HTTPAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler))) // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here)
|
||||
// all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here)
|
||||
var err = runHTTP(setting.HTTPAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)))
|
||||
if err != nil {
|
||||
log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err)
|
||||
}
|
||||
}()
|
||||
server := &http.Server{
|
||||
Addr: listenAddr,
|
||||
Handler: m,
|
||||
TLSConfig: certManager.TLSConfig(),
|
||||
}
|
||||
return server.ListenAndServeTLS("", "")
|
||||
return runHTTPSWithTLSConfig(listenAddr, certManager.TLSConfig(), context2.ClearHandler(m))
|
||||
}
|
||||
|
||||
func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -101,12 +98,21 @@ func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func runWeb(ctx *cli.Context) error {
|
||||
if os.Getppid() > 1 && len(os.Getenv("LISTEN_FDS")) > 0 {
|
||||
log.Info("Restarting Gitea on PID: %d from parent PID: %d", os.Getpid(), os.Getppid())
|
||||
} else {
|
||||
log.Info("Starting Gitea on PID: %d", os.Getpid())
|
||||
}
|
||||
|
||||
// Set pid file setting
|
||||
if ctx.IsSet("pid") {
|
||||
setting.CustomPID = ctx.String("pid")
|
||||
}
|
||||
|
||||
// Perform global initialization
|
||||
routers.GlobalInit()
|
||||
|
||||
// Set up Macaron
|
||||
m := routes.NewMacaron()
|
||||
routes.RegisterRoutes(m)
|
||||
|
||||
@@ -164,6 +170,7 @@ func runWeb(ctx *cli.Context) error {
|
||||
var err error
|
||||
switch setting.Protocol {
|
||||
case setting.HTTP:
|
||||
NoHTTPRedirector()
|
||||
err = runHTTP(listenAddr, context2.ClearHandler(m))
|
||||
case setting.HTTPS:
|
||||
if setting.EnableLetsEncrypt {
|
||||
@@ -172,9 +179,15 @@ func runWeb(ctx *cli.Context) error {
|
||||
}
|
||||
if setting.RedirectOtherPort {
|
||||
go runHTTPRedirector()
|
||||
} else {
|
||||
NoHTTPRedirector()
|
||||
}
|
||||
err = runHTTPS(listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
|
||||
case setting.FCGI:
|
||||
NoHTTPRedirector()
|
||||
// FCGI listeners are provided as stdin - this is orthogonal to the LISTEN_FDS approach
|
||||
// in graceful and systemD
|
||||
NoMainListener()
|
||||
var listener net.Listener
|
||||
listener, err = net.Listen("tcp", listenAddr)
|
||||
if err != nil {
|
||||
@@ -187,6 +200,10 @@ func runWeb(ctx *cli.Context) error {
|
||||
}()
|
||||
err = fcgi.Serve(listener, context2.ClearHandler(m))
|
||||
case setting.UnixSocket:
|
||||
// This could potentially be inherited using LISTEN_FDS but currently
|
||||
// these cannot be inherited
|
||||
NoHTTPRedirector()
|
||||
NoMainListener()
|
||||
if err := os.Remove(listenAddr); err != nil && !os.IsNotExist(err) {
|
||||
log.Fatal("Failed to remove unix socket directory %s: %v", listenAddr, err)
|
||||
}
|
||||
@@ -207,8 +224,10 @@ func runWeb(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("Failed to start server: %v", err)
|
||||
log.Critical("Failed to start server: %v", err)
|
||||
}
|
||||
|
||||
log.Info("HTTP Listener: %s Closed", listenAddr)
|
||||
graceful.WaitForServers()
|
||||
log.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,36 +10,28 @@ import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"github.com/facebookgo/grace/gracehttp"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
)
|
||||
|
||||
func runHTTP(listenAddr string, m http.Handler) error {
|
||||
return gracehttp.Serve(&http.Server{
|
||||
Addr: listenAddr,
|
||||
Handler: m,
|
||||
})
|
||||
return graceful.HTTPListenAndServe("tcp", listenAddr, m)
|
||||
}
|
||||
|
||||
func runHTTPS(listenAddr, certFile, keyFile string, m http.Handler) error {
|
||||
config := &tls.Config{
|
||||
MinVersion: tls.VersionTLS10,
|
||||
}
|
||||
if config.NextProtos == nil {
|
||||
config.NextProtos = []string{"http/1.1"}
|
||||
}
|
||||
|
||||
config.Certificates = make([]tls.Certificate, 1)
|
||||
var err error
|
||||
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to load https cert file %s: %v", listenAddr, err)
|
||||
}
|
||||
|
||||
return gracehttp.Serve(&http.Server{
|
||||
Addr: listenAddr,
|
||||
Handler: m,
|
||||
TLSConfig: config,
|
||||
})
|
||||
return graceful.HTTPListenAndServeTLS("tcp", listenAddr, certFile, keyFile, m)
|
||||
}
|
||||
|
||||
func runHTTPSWithTLSConfig(listenAddr string, tlsConfig *tls.Config, m http.Handler) error {
|
||||
return graceful.HTTPListenAndServeTLSConfig("tcp", listenAddr, tlsConfig, m)
|
||||
}
|
||||
|
||||
// NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector
|
||||
func NoHTTPRedirector() {
|
||||
graceful.InformCleanup()
|
||||
}
|
||||
|
||||
// NoMainListener tells our cleanup routine that we will not be using a possibly provided listener
|
||||
// for our main HTTP/HTTPS service
|
||||
func NoMainListener() {
|
||||
graceful.InformCleanup()
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@@ -17,3 +18,20 @@ func runHTTP(listenAddr string, m http.Handler) error {
|
||||
func runHTTPS(listenAddr, certFile, keyFile string, m http.Handler) error {
|
||||
return http.ListenAndServeTLS(listenAddr, certFile, keyFile, m)
|
||||
}
|
||||
|
||||
func runHTTPSWithTLSConfig(listenAddr string, tlsConfig *tls.Config, m http.Handler) error {
|
||||
server := &http.Server{
|
||||
Addr: listenAddr,
|
||||
Handler: m,
|
||||
TLSConfig: tlsConfig,
|
||||
}
|
||||
return server.ListenAndServeTLS("", "")
|
||||
}
|
||||
|
||||
// NoHTTPRedirector is a no-op on Windows
|
||||
func NoHTTPRedirector() {
|
||||
}
|
||||
|
||||
// NoMainListener is a no-op on Windows
|
||||
func NoMainListener() {
|
||||
}
|
||||
|
||||
@@ -27,13 +27,13 @@ import (
|
||||
"code.gitea.io/gitea/routers"
|
||||
"code.gitea.io/gitea/routers/routes"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
context2 "github.com/gorilla/context"
|
||||
"github.com/unknwon/com"
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
"gopkg.in/src-d/go-git.v4/config"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
"gopkg.in/testfixtures.v2"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
var codeFilePath = "contrib/pr/checkout.go"
|
||||
|
||||
@@ -2,11 +2,42 @@
|
||||
Description=Gitea (Git with a cup of tea)
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
###
|
||||
# Don't forget to add the database service requirements
|
||||
###
|
||||
#
|
||||
#Requires=mysql.service
|
||||
#Requires=mariadb.service
|
||||
#Requires=postgresql.service
|
||||
#Requires=memcached.service
|
||||
#Requires=redis.service
|
||||
#
|
||||
###
|
||||
# If using socket activation for main http/s
|
||||
###
|
||||
#
|
||||
#After=gitea.main.socket
|
||||
#Requires=gitea.main.socket
|
||||
#
|
||||
###
|
||||
# (You can also provide gitea an http fallback and/or ssh socket too)
|
||||
#
|
||||
# An example of /etc/systemd/system/gitea.main.socket
|
||||
###
|
||||
##
|
||||
## [Unit]
|
||||
## Description=Gitea Web Socket
|
||||
## PartOf=gitea.service
|
||||
##
|
||||
## [Socket]
|
||||
## Service=gitea.service
|
||||
## ListenStream=<some_port>
|
||||
## NoDelay=true
|
||||
##
|
||||
## [Install]
|
||||
## WantedBy=sockets.target
|
||||
##
|
||||
###
|
||||
|
||||
[Service]
|
||||
# Modify these two values and uncomment them if you have
|
||||
@@ -20,17 +51,18 @@ Type=simple
|
||||
User=git
|
||||
Group=git
|
||||
WorkingDirectory=/var/lib/gitea/
|
||||
# If using unix socket: Tells Systemd to create /run/gitea folder to home gitea.sock
|
||||
# Manual cration would vanish after reboot.
|
||||
# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock file
|
||||
# (manually creating /run/gitea doesn't work, because it would not persist across reboots)
|
||||
#RuntimeDirectory=gitea
|
||||
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
|
||||
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
|
||||
Restart=always
|
||||
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
|
||||
# If you want to bind Gitea to a port below 1024 uncomment
|
||||
# the two values below
|
||||
# If you want to bind Gitea to a port below 1024, uncomment
|
||||
# the two values below, or use socket activation to pass Gitea its ports as above
|
||||
###
|
||||
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
#AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
###
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -69,11 +69,46 @@ MAX_FILES = 5
|
||||
[repository.pull-request]
|
||||
; List of prefixes used in Pull Request title to mark them as Work In Progress
|
||||
WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP]
|
||||
; List of keywords used in Pull Request comments to automatically close a related issue
|
||||
CLOSE_KEYWORDS=close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved
|
||||
; List of keywords used in Pull Request comments to automatically reopen a related issue
|
||||
REOPEN_KEYWORDS=reopen,reopens,reopened
|
||||
|
||||
[repository.issue]
|
||||
; List of reasons why a Pull Request or Issue can be locked
|
||||
LOCK_REASONS=Too heated,Off-topic,Resolved,Spam
|
||||
|
||||
[repository.signing]
|
||||
; GPG key to use to sign commits, Defaults to the default - that is the value of git config --get user.signingkey
|
||||
; run in the context of the RUN_USER
|
||||
; Switch to none to stop signing completely
|
||||
SIGNING_KEY = default
|
||||
; If a SIGNING_KEY ID is provided and is not set to default, use the provided Name and Email address as the signer.
|
||||
; These should match a publicized name and email address for the key. (When SIGNING_KEY is default these are set to
|
||||
; the results of git config --get user.name and git config --get user.email respectively and can only be overrided
|
||||
; by setting the SIGNING_KEY ID to the correct ID.)
|
||||
SIGNING_NAME =
|
||||
SIGNING_EMAIL =
|
||||
; Determines when gitea should sign the initial commit when creating a repository
|
||||
; Either:
|
||||
; - never
|
||||
; - pubkey: only sign if the user has a pubkey
|
||||
; - twofa: only sign if the user has logged in with twofa
|
||||
; - always
|
||||
; options other than none and always can be combined as comma separated list
|
||||
INITIAL_COMMIT = always
|
||||
; Determines when to sign for CRUD actions
|
||||
; - as above
|
||||
; - parentsigned: requires that the parent commit is signed.
|
||||
CRUD_ACTIONS = pubkey, twofa, parentsigned
|
||||
; Determines when to sign Wiki commits
|
||||
; - as above
|
||||
WIKI = never
|
||||
; Determines when to sign on merges
|
||||
; - basesigned: require that the parent of commit on the base repo is signed.
|
||||
; - commitssigned: require that all the commits in the head branch are signed.
|
||||
MERGES = pubkey, twofa, basesigned, commitssigned
|
||||
|
||||
[cors]
|
||||
; More information about CORS can be found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#The_HTTP_response_headers
|
||||
; enable cors headers (disabled by default)
|
||||
@@ -141,8 +176,9 @@ KEYWORDS = go,git,self-hosted,gitea
|
||||
[markdown]
|
||||
; Enable hard line break extension
|
||||
ENABLE_HARD_LINE_BREAK = false
|
||||
; List of custom URL-Schemes that are allowed as links when rendering Markdown
|
||||
; for example git,magnet
|
||||
; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown
|
||||
; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes)
|
||||
; URLs starting with http and https are always displayed, whatever is put in this entry.
|
||||
CUSTOM_URL_SCHEMES =
|
||||
; List of file extensions that should be rendered/edited as Markdown
|
||||
; Separate the extensions with a comma. To render files without any extension as markdown, just put a comma
|
||||
@@ -153,6 +189,8 @@ FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
|
||||
PROTOCOL = http
|
||||
DOMAIN = localhost
|
||||
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
||||
; when STATIC_URL_PREFIX is empty it will follow APP_URL
|
||||
STATIC_URL_PREFIX =
|
||||
; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket.
|
||||
HTTP_ADDR = 0.0.0.0
|
||||
HTTP_PORT = 3000
|
||||
@@ -243,6 +281,14 @@ LFS_CONTENT_PATH = data/lfs
|
||||
LFS_JWT_SECRET =
|
||||
; LFS authentication validity period (in time.Duration), pushes taking longer than this may fail.
|
||||
LFS_HTTP_AUTH_EXPIRY = 20m
|
||||
; Allow graceful restarts using SIGHUP to fork
|
||||
ALLOW_GRACEFUL_RESTARTS = true
|
||||
; After a restart the parent will finish ongoing requests before
|
||||
; shutting down. Force shutdown if this process takes longer than this delay.
|
||||
; set to a negative value to disable
|
||||
GRACEFUL_HAMMER_TIME = 60s
|
||||
; Static resources, includes resources on custom/, public/ and all uploaded avatars web browser cache time, default is 6h
|
||||
STATIC_CACHE_TIME = 6h
|
||||
|
||||
; Define allowed algorithms and their minimum key length (use -1 to disable a type)
|
||||
[ssh.minimum_key_sizes]
|
||||
@@ -298,6 +344,9 @@ ISSUE_INDEXER_QUEUE_DIR = indexers/issues.queue
|
||||
ISSUE_INDEXER_QUEUE_CONN_STR = "addrs=127.0.0.1:6379 db=0"
|
||||
; Batch queue number, default is 20
|
||||
ISSUE_INDEXER_QUEUE_BATCH_NUMBER = 20
|
||||
; Timeout the indexer if it takes longer than this to start.
|
||||
; Set to zero to disable timeout.
|
||||
STARTUP_TIMEOUT=30s
|
||||
|
||||
; repo indexer by default disabled, since it uses a lot of disk space
|
||||
REPO_INDEXER_ENABLED = false
|
||||
@@ -395,6 +444,10 @@ ALLOW_ONLY_EXTERNAL_REGISTRATION = false
|
||||
REQUIRE_SIGNIN_VIEW = false
|
||||
; Mail notification
|
||||
ENABLE_NOTIFY_MAIL = false
|
||||
; This setting enables gitea to be signed in with HTTP BASIC Authentication using the user's password
|
||||
; If you set this to false you will not be able to access the tokens endpoints on the API with your password
|
||||
; Please note that setting this to false will not disable OAuth Basic or Basic authentication using a token
|
||||
ENABLE_BASIC_AUTHENTICATION = true
|
||||
; More detail: https://github.com/gogits/gogs/issues/165
|
||||
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
|
||||
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
|
||||
@@ -426,6 +479,8 @@ DEFAULT_ORG_MEMBER_VISIBLE = false
|
||||
; Default value for EnableDependencies
|
||||
; Repositories will use dependencies by default depending on this setting
|
||||
DEFAULT_ENABLE_DEPENDENCIES = true
|
||||
; Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting.
|
||||
ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true
|
||||
; Enable heatmap on users profiles.
|
||||
ENABLE_USER_HEATMAP = true
|
||||
; Enable Timetracking
|
||||
@@ -446,6 +501,9 @@ SHOW_REGISTRATION_BUTTON = true
|
||||
; When adding a repo to a team or creating a new repo all team members will watch the
|
||||
; repo automatically if enabled
|
||||
AUTO_WATCH_NEW_REPOS = true
|
||||
; Default value for AutoWatchOnChanges
|
||||
; Make the user watch a repository When they commit for the first time
|
||||
AUTO_WATCH_ON_CHANGES = false
|
||||
|
||||
[webhook]
|
||||
; Hook task queue length, increase if webhook shooting starts hanging
|
||||
@@ -456,6 +514,10 @@ DELIVER_TIMEOUT = 5
|
||||
SKIP_TLS_VERIFY = false
|
||||
; Number of history information in each page
|
||||
PAGING_NUM = 10
|
||||
; Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
||||
PROXY_URL =
|
||||
; Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
||||
PROXY_HOSTS =
|
||||
|
||||
[mailer]
|
||||
ENABLED = false
|
||||
|
||||
1
docs/.gitignore
vendored
1
docs/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
public/
|
||||
templates/swagger/v1_json.tmpl
|
||||
themes/
|
||||
resources/
|
||||
|
||||
176
docs/assets/js/search.js
Normal file
176
docs/assets/js/search.js
Normal file
@@ -0,0 +1,176 @@
|
||||
function ready(fn) {
|
||||
if (document.readyState != 'loading') {
|
||||
fn();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fn);
|
||||
}
|
||||
}
|
||||
|
||||
ready(doSearch);
|
||||
|
||||
const summaryInclude = 60;
|
||||
const fuseOptions = {
|
||||
shouldSort: true,
|
||||
includeMatches: true,
|
||||
matchAllTokens: true,
|
||||
threshold: 0.0, // for parsing diacritics
|
||||
tokenize: true,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
maxPatternLength: 32,
|
||||
minMatchCharLength: 1,
|
||||
keys: [{
|
||||
name: "title",
|
||||
weight: 0.8
|
||||
},
|
||||
{
|
||||
name: "contents",
|
||||
weight: 0.5
|
||||
},
|
||||
{
|
||||
name: "tags",
|
||||
weight: 0.3
|
||||
},
|
||||
{
|
||||
name: "categories",
|
||||
weight: 0.3
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
function param(name) {
|
||||
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ');
|
||||
}
|
||||
|
||||
let searchQuery = param("s");
|
||||
|
||||
function doSearch() {
|
||||
if (searchQuery) {
|
||||
document.getElementById("search-query").value = searchQuery;
|
||||
executeSearch(searchQuery);
|
||||
} else {
|
||||
const para = document.createElement("P");
|
||||
para.innerText = "Please enter a word or phrase above";
|
||||
document.getElementById("search-results").appendChild(para);
|
||||
}
|
||||
}
|
||||
|
||||
function getJSON(url, fn) {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.onload = function () {
|
||||
if (request.status >= 200 && request.status < 400) {
|
||||
const data = JSON.parse(request.responseText);
|
||||
fn(data);
|
||||
} else {
|
||||
console.log("Target reached on " + url + " with error " + request.status);
|
||||
}
|
||||
};
|
||||
request.onerror = function () {
|
||||
console.log("Connection error " + request.status);
|
||||
};
|
||||
request.send();
|
||||
}
|
||||
|
||||
function executeSearch(searchQuery) {
|
||||
getJSON("/" + document.LANG + "/index.json", function (data) {
|
||||
const pages = data;
|
||||
const fuse = new Fuse(pages, fuseOptions);
|
||||
const result = fuse.search(searchQuery);
|
||||
console.log({
|
||||
"matches": result
|
||||
});
|
||||
document.getElementById("search-results").innerHTML = "";
|
||||
if (result.length > 0) {
|
||||
populateResults(result);
|
||||
} else {
|
||||
const para = document.createElement("P");
|
||||
para.innerText = "No matches found";
|
||||
document.getElementById("search-results").appendChild(para);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function populateResults(result) {
|
||||
result.forEach(function (value, key) {
|
||||
const content = value.item.contents;
|
||||
let snippet = "";
|
||||
const snippetHighlights = [];
|
||||
if (fuseOptions.tokenize) {
|
||||
snippetHighlights.push(searchQuery);
|
||||
value.matches.forEach(function (mvalue) {
|
||||
if (mvalue.key === "tags" || mvalue.key === "categories") {
|
||||
snippetHighlights.push(mvalue.value);
|
||||
} else if (mvalue.key === "contents") {
|
||||
const ind = content.toLowerCase().indexOf(searchQuery.toLowerCase());
|
||||
const start = ind - summaryInclude > 0 ? ind - summaryInclude : 0;
|
||||
const end = ind + searchQuery.length + summaryInclude < content.length ? ind + searchQuery.length + summaryInclude : content.length;
|
||||
snippet += content.substring(start, end);
|
||||
if (ind > -1) {
|
||||
snippetHighlights.push(content.substring(ind, ind + searchQuery.length))
|
||||
} else {
|
||||
snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (snippet.length < 1) {
|
||||
snippet += content.substring(0, summaryInclude * 2);
|
||||
}
|
||||
//pull template from hugo templarte definition
|
||||
const templateDefinition = document.getElementById("search-result-template").innerHTML;
|
||||
//replace values
|
||||
const output = render(templateDefinition, {
|
||||
key: key,
|
||||
title: value.item.title,
|
||||
link: value.item.permalink,
|
||||
tags: value.item.tags,
|
||||
categories: value.item.categories,
|
||||
snippet: snippet
|
||||
});
|
||||
document.getElementById("search-results").appendChild(htmlToElement(output));
|
||||
|
||||
snippetHighlights.forEach(function (snipvalue) {
|
||||
new Mark(document.getElementById("summary-" + key)).mark(snipvalue);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function render(templateString, data) {
|
||||
let conditionalMatches, copy;
|
||||
const conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g;
|
||||
//since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
|
||||
copy = templateString;
|
||||
while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) {
|
||||
if (data[conditionalMatches[1]]) {
|
||||
//valid key, remove conditionals, leave content.
|
||||
copy = copy.replace(conditionalMatches[0], conditionalMatches[2]);
|
||||
} else {
|
||||
//not valid, remove entire section
|
||||
copy = copy.replace(conditionalMatches[0], '');
|
||||
}
|
||||
}
|
||||
templateString = copy;
|
||||
//now any conditionals removed we can do simple substitution
|
||||
let key, find, re;
|
||||
for (key in data) {
|
||||
find = '\\$\\{\\s*' + key + '\\s*\\}';
|
||||
re = new RegExp(find, 'g');
|
||||
templateString = templateString.replace(re, data[key]);
|
||||
}
|
||||
return templateString;
|
||||
}
|
||||
|
||||
/**
|
||||
* By Mark Amery: https://stackoverflow.com/a/35385518
|
||||
* @param {String} HTML representing a single element
|
||||
* @return {Element}
|
||||
*/
|
||||
function htmlToElement(html) {
|
||||
const template = document.createElement('template');
|
||||
html = html.trim(); // Never return a text node of whitespace as the result
|
||||
template.innerHTML = html;
|
||||
return template.content.firstChild;
|
||||
}
|
||||
@@ -18,7 +18,13 @@ params:
|
||||
description: Git with a cup of tea
|
||||
author: The Gitea Authors
|
||||
website: https://docs.gitea.io
|
||||
version: 1.9.3
|
||||
version: 1.9.5
|
||||
|
||||
outputs:
|
||||
home:
|
||||
- HTML
|
||||
- RSS
|
||||
- JSON
|
||||
|
||||
menu:
|
||||
page:
|
||||
|
||||
@@ -71,11 +71,34 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
|
||||
- `WORK_IN_PROGRESS_PREFIXES`: **WIP:,\[WIP\]**: List of prefixes used in Pull Request
|
||||
title to mark them as Work In Progress
|
||||
- `CLOSE_KEYWORDS`: **close**, **closes**, **closed**, **fix**, **fixes**, **fixed**, **resolve**, **resolves**, **resolved**: List of
|
||||
keywords used in Pull Request comments to automatically close a related issue
|
||||
- `REOPEN_KEYWORDS`: **reopen**, **reopens**, **reopened**: List of keywords used in Pull Request comments to automatically reopen
|
||||
a related issue
|
||||
|
||||
### Repository - Issue (`repository.issue`)
|
||||
|
||||
- `LOCK_REASONS`: **Too heated,Off-topic,Resolved,Spam**: A list of reasons why a Pull Request or Issue can be locked
|
||||
|
||||
### Repository - Signing (`repository.signing`)
|
||||
|
||||
- `SIGNING_KEY`: **default**: \[none, KEYID, default \]: Key to sign with.
|
||||
- `SIGNING_NAME` & `SIGNING_EMAIL`: if a KEYID is provided as the `SIGNING_KEY`, use these as the Name and Email address of the signer. These should match publicized name and email address for the key.
|
||||
- `INITIAL_COMMIT`: **always**: \[never, pubkey, twofa, always\]: Sign initial commit.
|
||||
- `never`: Never sign
|
||||
- `pubkey`: Only sign if the user has a public key
|
||||
- `twofa`: Only sign if the user is logged in with twofa
|
||||
- `always`: Always sign
|
||||
- Options other than `never` and `always` can be combined as a comma separated list.
|
||||
- `WIKI`: **never**: \[never, pubkey, twofa, always, parentsigned\]: Sign commits to wiki.
|
||||
- `CRUD_ACTIONS`: **pubkey, twofa, parentsigned**: \[never, pubkey, twofa, parentsigned, always\]: Sign CRUD actions.
|
||||
- Options as above, with the addition of:
|
||||
- `parentsigned`: Only sign if the parent commit is signed.
|
||||
- `MERGES`: **pubkey, twofa, basesigned, commitssigned**: \[never, pubkey, twofa, basesigned, commitssigned, always\]: Sign merges.
|
||||
- `basesigned`: Only sign if the parent commit in the base repo is signed.
|
||||
- `headsigned`: Only sign if the head commit in the head branch is signed.
|
||||
- `commitssigned`: Only sign if all the commits in the head branch to the merge point are signed.
|
||||
|
||||
## CORS (`cors`)
|
||||
|
||||
- `ENABLED`: **false**: enable cors headers (disabled by default)
|
||||
@@ -108,6 +131,9 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
## Markdown (`markdown`)
|
||||
|
||||
- `ENABLE_HARD_LINE_BREAK`: **false**: Enable Markdown's hard line break extension.
|
||||
- `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional
|
||||
URL hyperlinks to be rendered in Markdown. URLs beginning in http and https are
|
||||
always displayed
|
||||
|
||||
## Server (`server`)
|
||||
|
||||
@@ -116,6 +142,13 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
- `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**:
|
||||
Overwrite the automatically generated public URL.
|
||||
This is useful if the internal and the external URL don't match (e.g. in Docker).
|
||||
- `STATIC_URL_PREFIX`: **\<empty\>**:
|
||||
Overwrite this option to request static resources from a different URL.
|
||||
This includes CSS files, images, JS files and web fonts.
|
||||
Avatar images are dynamic resources and still served by gitea.
|
||||
The option can be just a different path, as in `/static`, or another domain, as in `https://cdn.example.com`.
|
||||
Requests are then made as `%(ROOT_URL)s/static/css/index.css` and `https://cdn.example.com/css/index.css` respective.
|
||||
The static files are located in the `public/` directory of the gitea source repository.
|
||||
- `HTTP_ADDR`: **0.0.0.0**: HTTP listen address.
|
||||
- If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
|
||||
defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
|
||||
@@ -140,6 +173,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
- `CERT_FILE`: **custom/https/cert.pem**: Cert file path used for HTTPS.
|
||||
- `KEY_FILE`: **custom/https/key.pem**: Key file path used for HTTPS.
|
||||
- `STATIC_ROOT_PATH`: **./**: Upper level of template and static files path.
|
||||
- `STATIC_CACHE_TIME`: **6h**: Web browser cache time for static resources on `custom/`, `public/` and all uploaded avatars.
|
||||
- `ENABLE_GZIP`: **false**: Enables application-level GZIP support.
|
||||
- `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore\].
|
||||
- `LFS_START_SERVER`: **false**: Enables git-lfs support.
|
||||
@@ -153,6 +187,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
- `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt.
|
||||
- `LETSENCRYPT_DIRECTORY`: **https**: Directory that Letsencrypt will use to cache information such as certs and private keys.
|
||||
- `LETSENCRYPT_EMAIL`: **email@example.com**: Email used by Letsencrypt to notify about problems with issued certificates. (No default)
|
||||
- `ALLOW_GRACEFUL_RESTARTS`: **true**: Perform a graceful restart on SIGHUP
|
||||
- `GRACEFUL_HAMMER_TIME`: **60s**: After a restart the parent process will stop accepting new connections and will allow requests to finish before stopping. Shutdown will be forced if it takes longer than this time.
|
||||
|
||||
## Database (`database`)
|
||||
|
||||
@@ -189,6 +225,7 @@ relation to port exhaustion.
|
||||
- `REPO_INDEXER_EXCLUDE`: **empty**: A comma separated list of glob patterns (see https://github.com/gobwas/glob) to **exclude** from the index. Files that match this list will not be indexed, even if they match in `REPO_INDEXER_INCLUDE`.
|
||||
- `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request.
|
||||
- `MAX_FILE_SIZE`: **1048576**: Maximum size in bytes of files to be indexed.
|
||||
- `STARTUP_TIMEOUT`: **30s**: If the indexer takes longer than this timeout to start - fail. (This timeout will be added to the hammer time above for child processes - as bleve will not start until the previous parent is shutdown.) Set to zero to never timeout.
|
||||
|
||||
## Admin (`admin`)
|
||||
- `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
|
||||
@@ -243,6 +280,10 @@ relation to port exhaustion.
|
||||
- `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page.
|
||||
- `ENABLE_NOTIFY_MAIL`: **false**: Enable this to send e-mail to watchers of a repository when
|
||||
something happens, like creating issues. Requires `Mailer` to be enabled.
|
||||
- `ENABLE_BASIC_AUTHENTICATION`: **true**: Disable this to disallow authenticaton using HTTP
|
||||
BASIC and the user's password. Please note if you disable this you will not be able to access the
|
||||
tokens API endpoints using a password. Further, this only disables BASIC authentication using the
|
||||
password - not tokens or OAuth Basic.
|
||||
- `ENABLE_REVERSE_PROXY_AUTHENTICATION`: **false**: Enable this to allow reverse proxy authentication.
|
||||
- `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: **false**: Enable this to allow auto-registration
|
||||
for reverse authentication.
|
||||
@@ -256,11 +297,13 @@ relation to port exhaustion.
|
||||
- `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha.
|
||||
- `RECAPTCHA_URL`: **https://www.google.com/recaptcha/**: Set the recaptcha url - allows the use of recaptcha net.
|
||||
- `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default.
|
||||
- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access.
|
||||
- `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles.
|
||||
- `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register
|
||||
on this instance.
|
||||
- `SHOW_REGISTRATION_BUTTON`: **! DISABLE\_REGISTRATION**: Show Registration Button
|
||||
- `AUTO_WATCH_NEW_REPOS`: **true**: Enable this to let all organisation users watch new repos when they are created
|
||||
- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch a repository after their first commit to it
|
||||
- `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private".
|
||||
- `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation.
|
||||
|
||||
@@ -270,6 +313,8 @@ relation to port exhaustion.
|
||||
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
|
||||
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
|
||||
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
|
||||
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
||||
- `PROXY_HOSTS`: ****: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
||||
|
||||
## Mailer (`mailer`)
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ menu:
|
||||
- `CERT_FILE`: 启用HTTPS的证书文件。
|
||||
- `KEY_FILE`: 启用HTTPS的密钥文件。
|
||||
- `STATIC_ROOT_PATH`: 存放模板和静态文件的根目录,默认是 Gitea 的根目录。
|
||||
- `STATIC_CACHE_TIME`: **6h**: 静态资源文件,包括 `custom/`, `public/` 和所有上传的头像的浏览器缓存时间。
|
||||
- `ENABLE_GZIP`: 启用应用级别的 GZIP 压缩。
|
||||
- `LANDING_PAGE`: 未登录用户的默认页面,可选 `home` 或 `explore`。
|
||||
- `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true` 或 `false`, 默认是 `false`。
|
||||
@@ -128,6 +129,8 @@ menu:
|
||||
- `DELIVER_TIMEOUT`: 请求webhooks的超时时间,单位秒。
|
||||
- `SKIP_TLS_VERIFY`: 是否允许不安全的证书。
|
||||
- `PAGING_NUM`: 每页显示的Webhook 历史数量。
|
||||
- `PROXY_URL`: ****: 代理服务器网址,支持 http://, https//, socks://, 为空将使用环境变量中的 http_proxy/https_proxy 设置。
|
||||
- `PROXY_HOSTS`: ****: 逗号分隔的需要代理的域名或IP地址。支持 * 号匹配符,使用 ** 匹配所有域名和IP地址。
|
||||
|
||||
## Mailer (`mailer`)
|
||||
|
||||
@@ -172,6 +175,20 @@ menu:
|
||||
- `MAX_SIZE`: 附件最大限制,单位 MB,比如: `4`。
|
||||
- `MAX_FILES`: 一次最多上传的附件数量,比如: `5`。
|
||||
|
||||
关于 `ALLOWED_TYPES`, 在 (*)unix 系统中可以使用`file -I <filename>` 来快速获得对应的 `MIME type`。
|
||||
|
||||
```shell
|
||||
$ file -I test00.tar.xz
|
||||
test00.tar.xz: application/x-xz; charset=binary
|
||||
|
||||
$ file --mime test00.xlsx
|
||||
test00.xlsx: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=binary
|
||||
|
||||
file -I test01.xls
|
||||
test01.xls: application/vnd.ms-excel; charset=binary
|
||||
```
|
||||
|
||||
|
||||
## Log (`log`)
|
||||
|
||||
- `ROOT_PATH`: 日志文件根目录。
|
||||
|
||||
@@ -72,6 +72,12 @@ matching source.
|
||||
Any statement contained inside `{{` and `}}` are Gitea's template syntax and
|
||||
shouldn't be touched without fully understanding these components.
|
||||
|
||||
### Customizing startpage / homepage
|
||||
|
||||
Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/master/templates/home.tmpl) for your version of Gitea from `templates` to `custom/templates`.
|
||||
Edit as you wish.
|
||||
Dont forget to restart your gitea to apply the changes.
|
||||
|
||||
### Adding links and tabs
|
||||
|
||||
If all you want is to add extra links to the top navigation bar, or extra tabs to the repository view, you can put them in `extra_links.tmpl` and `extra_tabs.tmpl` inside your `custom/templates/custom/` directory.
|
||||
@@ -140,7 +146,7 @@ To add a custom license, add a file with the license text to `custom/options/lic
|
||||
Locales are managed via our [crowdin](https://crowdin.com/project/gitea).
|
||||
You can override a locale by placing an altered locale file in `custom/options/locale`.
|
||||
Gitea's default locale files can be found in the [`options/locale`](https://github.com/go-gitea/gitea/tree/master/options/locale) source folder and these should be used as examples for your changes.
|
||||
|
||||
|
||||
To add a completely new locale, as well as placing the file in the above location, you will need to add the new lang and name to the `[i18n]` section in your `app.ini`. Keep in mind that Gitea will use those settings as **overrides**, so if you want to keep the other languages as well you will need to copy/paste the default values and add your own to them.
|
||||
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ add one `[markup.XXXXX]` section per external renderer on your custom `app.ini`:
|
||||
[markup.asciidoc]
|
||||
ENABLED = true
|
||||
FILE_EXTENSIONS = .adoc,.asciidoc
|
||||
RENDER_COMMAND = "asciidoctor --out-file=- -"
|
||||
RENDER_COMMAND = "asciidoctor -e -a leveloffset=-1 --out-file=- -"
|
||||
; Input is not a standard input but a file
|
||||
IS_INPUT_FILE = false
|
||||
|
||||
|
||||
272
docs/content/doc/advanced/mail-templates-us.md
Normal file
272
docs/content/doc/advanced/mail-templates-us.md
Normal file
@@ -0,0 +1,272 @@
|
||||
---
|
||||
date: "2019-10-23T17:00:00-03:00"
|
||||
title: "Mail templates"
|
||||
slug: "mail-templates"
|
||||
weight: 45
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "advanced"
|
||||
name: "Mail templates"
|
||||
weight: 45
|
||||
identifier: "mail-templates"
|
||||
---
|
||||
|
||||
# Mail templates
|
||||
|
||||
To craft the e-mail subject and contents for certain operations, Gitea can be customized by using templates. The templates
|
||||
for these functions are located under the [`custom` directory](https://docs.gitea.io/en-us/customizing-gitea/).
|
||||
Gitea has an internal template that serves as default in case there's no custom alternative.
|
||||
|
||||
Custom templates are loaded when Gitea starts. Changes made to them are not recognized until Gitea is restarted again.
|
||||
|
||||
## Mail notifications supporting templates
|
||||
|
||||
Currently, the following notification events make use of templates:
|
||||
|
||||
| Action name | Usage |
|
||||
|---------------|--------------------------------------------------------------------------------------------------------------|
|
||||
| `new` | A new issue or pull request was created. |
|
||||
| `comment` | A new comment was created in an existing issue or pull request. |
|
||||
| `close` | An issue or pull request was closed. |
|
||||
| `reopen` | An issue or pull request was reopened. |
|
||||
| `review` | The head comment of a review in a pull request. |
|
||||
| `code` | A single comment on the code of a pull request. |
|
||||
| `assigned` | Used 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:
|
||||
|
||||
```
|
||||
custom/templates/mail/{action type}/{action name}.tmpl
|
||||
```
|
||||
|
||||
Where `{action type}` is one of `issue` or `pull` (for pull requests), and `{action name}` is one of the names listed above.
|
||||
|
||||
For example, the specific template for a mail regarding a comment in a pull request is:
|
||||
```
|
||||
custom/templates/mail/pull/comment.tmpl
|
||||
```
|
||||
|
||||
However, creating templates for each and every action type/name combination is not required.
|
||||
A fallback system is used to choose the appropriate template for an event. The _first existing_
|
||||
template on this list is used:
|
||||
|
||||
* The specific template for the desired **action type** and **action name**.
|
||||
* The template for action type `issue` and the desired **action name**.
|
||||
* The template for the desired **action type**, action name `default`.
|
||||
* The template for action type `issue`, action name `default`.
|
||||
|
||||
The only mandatory template is action type `issue`, action name `default`, which is already embedded in Gitea
|
||||
unless it's overridden by the user in the `custom` directory.
|
||||
|
||||
## Template syntax
|
||||
|
||||
Mail templates are UTF-8 encoded text files that need to follow one of the following formats:
|
||||
|
||||
```
|
||||
Text and macros for the subject line
|
||||
------------
|
||||
Text and macros for the mail body
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
Text and macros for the mail body
|
||||
```
|
||||
|
||||
Specifying a _subject_ section is optional (and therefore also the dash line separator). When used, the separator between
|
||||
_subject_ and _mail body_ templates requires at least three dashes; no other characters are allowed in the separator line.
|
||||
|
||||
|
||||
_Subject_ and _mail body_ are parsed by [Golang's template engine](https://golang.org/pkg/text/template/) and
|
||||
are provided with a _metadata context_ assembled for each notification. The context contains the following elements:
|
||||
|
||||
| Name | Type | Available | Usage |
|
||||
|--------------------|----------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `.FallbackSubject` | string | Always | A default subject line. See Below. |
|
||||
| `.Subject` | string | Only in body | The _subject_, once resolved. |
|
||||
| `.Body` | string | Always | The message of the issue, pull request or comment, parsed from Markdown into HTML and sanitized. Do not confuse with the _mail body_ |
|
||||
| `.Link` | string | Always | The address of the originating issue, pull request or comment. |
|
||||
| `.Issue` | models.Issue | Always | The issue (or pull request) originating the notification. To get data specific to a pull request (e.g. `HasMerged`), `.Issue.PullRequest` can be used, but care should be taken as this field will be `nil` if the issue is *not* a pull request. |
|
||||
| `.Comment` | models.Comment | If applicable | If the notification is from a comment added to an issue or pull request, this will contain the information about the comment. |
|
||||
| `.IsPull` | bool | Always | `true` if the mail notification is associated with a pull request (i.e. `.Issue.PullRequest` is not `nil`). |
|
||||
| `.Repo` | string | Always | Name of the repository, including owner name (e.g. `mike/stuff`) |
|
||||
| `.User` | models.User | Always | Owner of the repository from which the event originated. To get the user name (e.g. `mike`),`.User.Name` can be used. |
|
||||
| `.Doer` | models.User | Always | User that executed the action triggering the notification event. To get the user name (e.g. `rhonda`), `.Doer.Name` can be used. |
|
||||
| `.IsMention` | bool | Always | `true` if this notification was only generated because the user was mentioned in the comment, while not being subscribed to the source. It will be `false` if the recipient was subscribed to the issue or repository. |
|
||||
| `.SubjectPrefix` | string | Always | `Re: ` if the notification is about other than issue or pull request creation; otherwise an empty string. |
|
||||
| `.ActionType` | string | Always | `"issue"` or `"pull"`. Will correspond to the actual _action type_ independently of which template was selected. |
|
||||
| `.ActionName` | string | Always | It will be one of the action types described above (`new`, `comment`, etc.), and will correspond to the actual _action name_ independently of which template was selected. |
|
||||
|
||||
All names are case sensitive.
|
||||
|
||||
### The _subject_ part of the template
|
||||
|
||||
The template engine used for the mail _subject_ is golang's [`text/template`](https://golang.org/pkg/text/template/).
|
||||
Please refer to the linked documentation for details about its syntax.
|
||||
|
||||
The _subject_ is built using the following steps:
|
||||
|
||||
* A template is selected according to the type of notification and to what templates are present.
|
||||
* The template is parsed and resolved (e.g. `{{.Issue.Index}}` is converted to the number of the issue
|
||||
or pull request).
|
||||
* All space-like characters (e.g. `TAB`, `LF`, etc.) are converted to normal spaces.
|
||||
* All leading, trailing and redundant spaces are removed.
|
||||
* The string is truncated to its first 256 runes (characters).
|
||||
|
||||
If the end result is an empty string, **or** no subject template was available (i.e. the selected template
|
||||
did not include a subject part), Gitea's **internal default** will be used.
|
||||
|
||||
The internal default (fallback) subject is the equivalent of:
|
||||
|
||||
```
|
||||
{{.SubjectPrefix}}[{{.Repo}}] {{.Issue.Title}} (#.Issue.Index)
|
||||
```
|
||||
|
||||
For example: `Re: [mike/stuff] New color palette (#38)`
|
||||
|
||||
Gitea's default subject can also be found in the template _metadata_ as `.FallbackSubject` from any of
|
||||
the two templates, even if a valid subject template is present.
|
||||
|
||||
### The _mail body_ part of the template
|
||||
|
||||
The template engine used for the _mail body_ is golang's [`html/template`](https://golang.org/pkg/html/template/).
|
||||
Please refer to the linked documentation for details about its syntax.
|
||||
|
||||
The _mail body_ is parsed after the mail subject, so there is an additional _metadata_ field which is
|
||||
the actual rendered subject, after all considerations.
|
||||
|
||||
The expected result is HTML (including structural elements like`<html>`, `<body>`, etc.). Styling
|
||||
through `<style>` blocks, `class` and `style` attributes is possible. However, `html/template`
|
||||
does some [automatic escaping](https://golang.org/pkg/html/template/#hdr-Contexts) that should be considered.
|
||||
|
||||
Attachments (such as images or external style sheets) are not supported. However, other templates can
|
||||
be referenced too, for example to provide the contents of a `<style>` element in a centralized fashion.
|
||||
The external template must be placed under `custom/mail` and referenced relative to that directory.
|
||||
For example, `custom/mail/styles/base.tmpl` can be included using `{{template styles/base}}`.
|
||||
|
||||
The mail is sent with `Content-Type: multipart/alternative`, so the body is sent in both HTML
|
||||
and text formats. The latter is obtained by stripping the HTML markup.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
How a mail is rendered is directly dependent on the capabilities of the mail application. Many mail
|
||||
clients don't even support HTML, so they show the text version included in the generated mail.
|
||||
|
||||
If the template fails to render, it will be noticed only at the moment the mail is sent.
|
||||
A default subject is used if the subject template fails, and whatever was rendered successfully
|
||||
from the the _mail body_ is used, disregarding the rest.
|
||||
|
||||
Please check [Gitea's logs](https://docs.gitea.io/en-us/logging-configuration/) for error messages in case of trouble.
|
||||
|
||||
## Example
|
||||
|
||||
`custom/templates/mail/issue/default.tmpl`:
|
||||
|
||||
```
|
||||
[{{.Repo}}] @{{.Doer.Name}}
|
||||
{{if eq .ActionName "new"}}
|
||||
created
|
||||
{{else if eq .ActionName "comment"}}
|
||||
commented on
|
||||
{{else if eq .ActionName "close"}}
|
||||
closed
|
||||
{{else if eq .ActionName "reopen"}}
|
||||
reopened
|
||||
{{else}}
|
||||
updated
|
||||
{{end}}
|
||||
{{if eq .ActionType "issue"}}
|
||||
issue
|
||||
{{else}}
|
||||
pull request
|
||||
{{end}}
|
||||
#{{.Issue.Index}}: {{.Issue.Title}}
|
||||
------------
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.Subject}}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{if .IsMention}}
|
||||
<p>
|
||||
You are receiving this because @{{.Doer.Name}} mentioned you.
|
||||
</p>
|
||||
{{end}}
|
||||
<p>
|
||||
<p>
|
||||
<a href="{{AppURL}}/{{.Doer.LowerName}}">@{{.Doer.Name}}</a>
|
||||
{{if not (eq .Doer.FullName "")}}
|
||||
({{.Doer.FullName}})
|
||||
{{end}}
|
||||
{{if eq .ActionName "new"}}
|
||||
created
|
||||
{{else if eq .ActionName "close"}}
|
||||
closed
|
||||
{{else if eq .ActionName "reopen"}}
|
||||
reopened
|
||||
{{else}}
|
||||
updated
|
||||
{{end}}
|
||||
<a href="{{.Link}}">{{.Repo}}#{{.Issue.Index}}</a>.
|
||||
</p>
|
||||
{{if not (eq .Body "")}}
|
||||
<h3>Message content:</h3>
|
||||
<hr>
|
||||
{{.Body | Str2html}}
|
||||
{{end}}
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
<a href="{{.Link}}">View it on Gitea</a>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
This template produces something along these lines:
|
||||
|
||||
#### Subject
|
||||
|
||||
> [mike/stuff] @rhonda commented on pull request #38: New color palette
|
||||
|
||||
#### Mail body
|
||||
|
||||
> [@rhonda](#) (Rhonda Myers) updated [mike/stuff#38](#).
|
||||
>
|
||||
> #### Message content:
|
||||
>
|
||||
> \__________________________________________________________________
|
||||
>
|
||||
> Mike, I think we should tone down the blues a little.
|
||||
> \__________________________________________________________________
|
||||
>
|
||||
> [View it on Gitea](#).
|
||||
|
||||
## Advanced
|
||||
|
||||
The template system contains several functions that can be used to further process and format
|
||||
the messages. Here's a list of some of them:
|
||||
|
||||
| Name | Parameters | Available | Usage |
|
||||
|----------------------|-------------|-----------|---------------------------------------------------------------------|
|
||||
| `AppUrl` | - | Any | Gitea's URL |
|
||||
| `AppName` | - | Any | Set from `app.ini`, usually "Gitea" |
|
||||
| `AppDomain` | - | Any | Gitea's host name |
|
||||
| `EllipsisString` | string, int | Any | Truncates a string to the specified length; adds ellipsis as needed |
|
||||
| `Str2html` | string | Body only | Sanitizes text by removing any HTML tags from it. |
|
||||
|
||||
These are _functions_, not metadata, so they have to be used:
|
||||
|
||||
```
|
||||
Like this: {{Str2html "Escape<my>text"}}
|
||||
Or this: {{"Escape<my>text" | Str2html}}
|
||||
Or this: {{AppUrl}}
|
||||
But not like this: {{.AppUrl}}
|
||||
```
|
||||
@@ -68,6 +68,7 @@ type Uploader interface {
|
||||
CreateComment(issueNumber int64, comment *Comment) error
|
||||
CreatePullRequest(pr *PullRequest) error
|
||||
Rollback() error
|
||||
Close()
|
||||
}
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
162
docs/content/doc/advanced/signing.en-us.md
Normal file
162
docs/content/doc/advanced/signing.en-us.md
Normal file
@@ -0,0 +1,162 @@
|
||||
---
|
||||
date: "2019-08-17T10:20:00+01:00"
|
||||
title: "GPG Commit Signatures"
|
||||
slug: "signing"
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "advanced"
|
||||
name: "GPG Commit Signatures"
|
||||
weight: 20
|
||||
identifier: "signing"
|
||||
---
|
||||
|
||||
# GPG Commit Signatures
|
||||
|
||||
Gitea will verify GPG commit signatures in the provided tree by
|
||||
checking if the commits are signed by a key within the gitea database,
|
||||
or if the commit matches the default key for git.
|
||||
|
||||
Keys are not checked to determine if they have expired or revoked.
|
||||
Keys are also not checked with keyservers.
|
||||
|
||||
A commit will be marked with a grey unlocked icon if no key can be
|
||||
found to verify it. If a commit is marked with a red unlocked icon,
|
||||
it is reported to be signed with a key with an id.
|
||||
|
||||
Please note: The signer of a commit does not have to be an author or
|
||||
committer of a commit.
|
||||
|
||||
This functionality requires git >= 1.7.9 but for full functionality
|
||||
this requires git >= 2.0.0.
|
||||
|
||||
## Automatic Signing
|
||||
|
||||
There are a number of places where Gitea will generate commits itself:
|
||||
|
||||
* Repository Initialisation
|
||||
* Wiki Changes
|
||||
* CRUD actions using the editor or the API
|
||||
* Merges from Pull Requests
|
||||
|
||||
Depending on configuration and server trust you may want Gitea to
|
||||
sign these commits.
|
||||
|
||||
## General Configuration
|
||||
|
||||
Gitea's configuration for signing can be found with the
|
||||
`[repository.signing]` section of `app.ini`:
|
||||
|
||||
```ini
|
||||
...
|
||||
[repository.signing]
|
||||
SIGNING_KEY = default
|
||||
SIGNING_NAME =
|
||||
SIGNING_EMAIL =
|
||||
INITIAL_COMMIT = always
|
||||
CRUD_ACTIONS = pubkey, twofa, parentsigned
|
||||
WIKI = never
|
||||
MERGES = pubkey, twofa, basesigned, commitssigned
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### `SIGNING_KEY`
|
||||
|
||||
The first option to discuss is the `SIGNING_KEY`. There are three main
|
||||
options:
|
||||
|
||||
* `none` - this prevents Gitea from signing any commits
|
||||
* `default` - Gitea will default to the key configured within
|
||||
`git config`
|
||||
* `KEYID` - Gitea will sign commits with the gpg key with the ID
|
||||
`KEYID`. In this case you should provide a `SIGNING_NAME` and
|
||||
`SIGNING_EMAIL` to be displayed for this key.
|
||||
|
||||
The `default` option will interrogate `git config` for
|
||||
`commit.gpgsign` option - if this is set, then it will use the results
|
||||
of the `user.signingkey`, `user.name` and `user.email` as appropriate.
|
||||
|
||||
Please note: by adjusting git's `config` file within Gitea's
|
||||
repositories, `SIGNING_KEY=default` could be used to provide different
|
||||
signing keys on a per-repository basis. However, this is cleary not an
|
||||
ideal UI and therefore subject to change.
|
||||
|
||||
### `INITIAL_COMMIT`
|
||||
|
||||
This option determines whether Gitea should sign the initial commit
|
||||
when creating a repository. The possible values are:
|
||||
|
||||
* `never`: Never sign
|
||||
* `pubkey`: Only sign if the user has a public key
|
||||
* `twofa`: Only sign if the user logs in with two factor authentication
|
||||
* `always`: Always sign
|
||||
|
||||
Options other than `never` and `always` can be combined as a comma
|
||||
separated list.
|
||||
|
||||
### `WIKI`
|
||||
|
||||
This options determines if Gitea should sign commits to the Wiki.
|
||||
The possible values are:
|
||||
|
||||
* `never`: Never sign
|
||||
* `pubkey`: Only sign if the user has a public key
|
||||
* `twofa`: Only sign if the user logs in with two factor authentication
|
||||
* `parentsigned`: Only sign if the parent commit is signed.
|
||||
* `always`: Always sign
|
||||
|
||||
Options other than `never` and `always` can be combined as a comma
|
||||
separated list.
|
||||
|
||||
### `CRUD_ACTIONS`
|
||||
|
||||
This option determines if Gitea should sign commits from the web
|
||||
editor or API CRUD actions. The possible values are:
|
||||
|
||||
* `never`: Never sign
|
||||
* `pubkey`: Only sign if the user has a public key
|
||||
* `twofa`: Only sign if the user logs in with two factor authentication
|
||||
* `parentsigned`: Only sign if the parent commit is signed.
|
||||
* `always`: Always sign
|
||||
|
||||
Options other than `never` and `always` can be combined as a comma
|
||||
separated list.
|
||||
|
||||
### `MERGES`
|
||||
|
||||
This option determines if Gitea should sign merge commits from PRs.
|
||||
The possible options are:
|
||||
|
||||
* `never`: Never sign
|
||||
* `pubkey`: Only sign if the user has a public key
|
||||
* `twofa`: Only sign if the user logs in with two factor authentication
|
||||
* `basesigned`: Only sign if the parent commit in the base repo is signed.
|
||||
* `headsigned`: Only sign if the head commit in the head branch is signed.
|
||||
* `commitssigned`: Only sign if all the commits in the head branch to the merge point are signed.
|
||||
* `always`: Always sign
|
||||
|
||||
Options other than `never` and `always` can be combined as a comma
|
||||
separated list.
|
||||
|
||||
## Installing and generating a GPG key for Gitea
|
||||
|
||||
It is up to a server administrator to determine how best to install
|
||||
a signing key. Gitea generates all its commits using the server `git`
|
||||
command at present - and therefore the server `gpg` will be used for
|
||||
signing (if configured.) Administrators should review best-practices
|
||||
for gpg - in particular it is probably advisable to only install a
|
||||
signing secret subkey without the master signing and certifying secret
|
||||
key.
|
||||
|
||||
## Obtaining the Public Key of the Signing Key
|
||||
|
||||
The public key used to sign Gitea's commits can be obtained from the API at:
|
||||
|
||||
```/api/v1/signing-key.gpg```
|
||||
|
||||
In cases where there is a repository specific key this can be obtained from:
|
||||
|
||||
```/api/v1/repos/:username/:reponame/signing-key.gpg```
|
||||
36
docs/content/doc/advanced/third-party-tools.zh-cn.md
Normal file
36
docs/content/doc/advanced/third-party-tools.zh-cn.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
date: "2019-03-11T21:45:00+00:00"
|
||||
title: "高级: 第三方工具"
|
||||
slug: "third-party-tools"
|
||||
weight: 50
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "advanced"
|
||||
name: "第三方工具"
|
||||
weight: 50
|
||||
identifier: "third-party-tools"
|
||||
---
|
||||
|
||||
# 第三方工具列表
|
||||
**注意:** 这些工具并没有经过Gitea的检验,在这里列出它们只是为了便捷.
|
||||
|
||||
*此列表并不是完整的列表,可以随时咨询如何添加!*
|
||||
|
||||
### 持续集成
|
||||
[BuildKite 连接器](https://github.com/techknowlogick/gitea-buildkite-connector)
|
||||
[Jenkins 插件](https://github.com/jenkinsci/gitea-plugin)
|
||||
[Gitea搭配Drone](https://docs.drone.io/installation/gitea)
|
||||
|
||||
|
||||
### 迁移
|
||||
[Gitea安装脚本](https://git.coolaj86.com/coolaj86/gitea-installer.sh)
|
||||
[GitHub迁移](https://gitea.com/gitea/migrator)
|
||||
|
||||
|
||||
### 移动端
|
||||
[安卓客户端GitNex](https://gitlab.com/mmarif4u/gitnex)
|
||||
|
||||
### 编辑器扩展
|
||||
- [Gitea的Visual Studio扩展](https://github.com/maikebing/Gitea.VisualStudio) 从 [Visual Studio 扩展市场](https://marketplace.visualstudio.com/items?itemName=MysticBoy.GiteaExtensionforVisualStudio) 下载
|
||||
@@ -105,6 +105,7 @@ _Symbols used in table:_
|
||||
| Revert specific commits or a merge request | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Cherry-picking changes | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | [/](https://jira.atlassian.com/plugins/servlet/mobile#issue/BCLOUD-8323) | ✘ |
|
||||
|
||||
|
||||
#### 3rd-party integrations
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
date: "2017-01-20T15:00:00+08:00"
|
||||
title: "Help"
|
||||
slug: "help"
|
||||
weight: 50
|
||||
weight: 5
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
name: "Help"
|
||||
weight: 50
|
||||
weight: 5
|
||||
identifier: "help"
|
||||
---
|
||||
|
||||
13
docs/content/doc/help.fr-fr.md
Normal file
13
docs/content/doc/help.fr-fr.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
date: "2017-01-20T15:00:00+08:00"
|
||||
title: "Aide"
|
||||
slug: "help"
|
||||
weight: 5
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
name: "Aide"
|
||||
weight: 5
|
||||
identifier: "help"
|
||||
---
|
||||
@@ -2,12 +2,12 @@
|
||||
date: "2017-01-20T15:00:00+08:00"
|
||||
title: "帮助"
|
||||
slug: "help"
|
||||
weight: 50
|
||||
weight: 5
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
name: "帮助"
|
||||
weight: 50
|
||||
weight: 5
|
||||
identifier: "help"
|
||||
---
|
||||
|
||||
13
docs/content/doc/help.zh-tw.md
Normal file
13
docs/content/doc/help.zh-tw.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
date: "2017-01-20T15:00:00+08:00"
|
||||
title: "救命"
|
||||
slug: "help"
|
||||
weight: 5
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
name: "救命"
|
||||
weight: 5
|
||||
identifier: "help"
|
||||
---
|
||||
@@ -42,6 +42,9 @@ Also see [Support Options]({{< relref "doc/help/seek-help.en-us.md" >}})
|
||||
* [SSH Common Errors](#ssh-common-errors)
|
||||
* [Missing releases after migration repository with tags](#missing-releases-after-migrating-repository-with-tags)
|
||||
* [LFS Issues](#lfs-issues)
|
||||
* [How can I create users before starting Gitea](#how-can-i-create-users-before-starting-gitea)
|
||||
* [How can I enable password reset](#how-can-i-enable-password-reset)
|
||||
* [How can a user's password be changed](#how-can-a-user-s-password-be-changed)
|
||||
|
||||
|
||||
## Difference between 1.x and 1.x.x downloads
|
||||
@@ -272,3 +275,19 @@ Check the value of `LFS_HTTP_AUTH_EXPIRY` in your `app.ini` file.
|
||||
By default, your LFS token will expire after 20 minutes. If you have a slow connection or a large file (or both), it may not finish uploading within the time limit.
|
||||
|
||||
You may want to set this value to `60m` or `120m`.
|
||||
|
||||
## How can I create users before starting Gitea
|
||||
Gitea provides a sub-command `gitea migrate` to initialize the database, after which you can use the [admin CLI commands]({{< relref "doc/usage/command-line.en-us.md#admin" >}}) to add users like normal.
|
||||
|
||||
## How can I enable password reset
|
||||
There is no setting for password resets. It is enabled when a [mail service]({{< relref "doc/usage/email-setup.en-us.md" >}}) is configured, and disabled otherwise.
|
||||
|
||||
## How can a user's password be changed
|
||||
- As an **admin**, you can change any user's password (and optionally force them to change it on next login)...
|
||||
- By navigating to your `Site Administration -> User Accounts` page and editing a user.
|
||||
- By using the [admin CLI commands]({{< relref "doc/usage/command-line.en-us.md#admin" >}}).
|
||||
Keep in mind most commands will also need a [global flag]({{< relref "doc/usage/command-line.en-us.md#global-options" >}}) to point the CLI at the correct configuration.
|
||||
- As a **user** you can change it...
|
||||
- In your account `Settings -> Account` page (this method **requires** you to know your current password).
|
||||
- By using the `Forgot Password` link.
|
||||
If the `Forgot Password/Account Recovery` page is disabled, please contact your administrator to configure a [mail service]({{< relref "doc/usage/email-setup.en-us.md" >}}).
|
||||
|
||||
25
docs/content/doc/help/search.en-us.md
Normal file
25
docs/content/doc/help/search.en-us.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Search"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "help"
|
||||
name: "Search"
|
||||
weight: 4
|
||||
identifier: "search"
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||
|
||||
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||
|
||||
Setting a very low sitemap priority will tell search engines this is not important content.
|
||||
|
||||
25
docs/content/doc/help/search.fr-fr.md
Normal file
25
docs/content/doc/help/search.fr-fr.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Chercher"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "help"
|
||||
name: "Chercher"
|
||||
weight: 4
|
||||
identifier: "search"
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||
|
||||
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||
|
||||
Setting a very low sitemap priority will tell search engines this is not important content.
|
||||
|
||||
25
docs/content/doc/help/search.zh-cn.md
Normal file
25
docs/content/doc/help/search.zh-cn.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "搜索"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "help"
|
||||
name: "搜索"
|
||||
weight: 4
|
||||
identifier: "search"
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||
|
||||
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||
|
||||
Setting a very low sitemap priority will tell search engines this is not important content.
|
||||
|
||||
25
docs/content/doc/help/search.zh-tw.md
Normal file
25
docs/content/doc/help/search.zh-tw.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "搜索"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "help"
|
||||
name: "搜索"
|
||||
weight: 4
|
||||
identifier: "search"
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||
|
||||
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||
|
||||
Setting a very low sitemap priority will tell search engines this is not important content.
|
||||
|
||||
@@ -118,12 +118,12 @@ launched manually from command line, it can be killed by pressing `Ctrl + C`.
|
||||
./gitea web
|
||||
```
|
||||
|
||||
## Changing the default CustomPath, CustomConf and AppWorkDir
|
||||
## Changing the default CustomPath, CustomConf and AppWorkPath
|
||||
|
||||
Gitea will search for a number of things from the `CustomPath`. By default this is
|
||||
the `custom/` directory in the current working directory when running Gitea. It will also
|
||||
look for its configuration file `CustomConf` in `$CustomPath/conf/app.ini`, and will use the
|
||||
current working directory as the relative base path `AppWorkDir` for a number configurable
|
||||
current working directory as the relative base path `AppWorkPath` for a number configurable
|
||||
values.
|
||||
|
||||
These values, although useful when developing, may conflict with downstream users preferences.
|
||||
@@ -134,7 +134,7 @@ using the `LDFLAGS` environment variable for `make`. The appropriate settings ar
|
||||
|
||||
* To set the `CustomPath` use `LDFLAGS="-X \"code.gitea.io/gitea/modules/setting.CustomPath=custom-path\""`
|
||||
* For `CustomConf` you should use `-X \"code.gitea.io/gitea/modules/setting.CustomConf=conf.ini\"`
|
||||
* For `AppWorkDir` you should use `-X \"code.gitea.io/gitea/modules/setting.AppWorkDir=working-directory\"`
|
||||
* For `AppWorkPath` you should use `-X \"code.gitea.io/gitea/modules/setting.AppWorkPath=working-path\"`
|
||||
|
||||
Add as many of the strings with their preceding `-X` to the `LDFLAGS` variable and run `make build`
|
||||
with the appropriate `TAGS` as above.
|
||||
|
||||
@@ -51,6 +51,8 @@ services:
|
||||
- gitea
|
||||
volumes:
|
||||
- ./gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "222:22"
|
||||
@@ -80,6 +82,8 @@ services:
|
||||
- gitea
|
||||
volumes:
|
||||
- ./gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- - "3000:3000"
|
||||
- - "222:22"
|
||||
@@ -115,6 +119,8 @@ services:
|
||||
- gitea
|
||||
volumes:
|
||||
- ./gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "222:22"
|
||||
@@ -163,6 +169,8 @@ services:
|
||||
- gitea
|
||||
volumes:
|
||||
- ./gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "222:22"
|
||||
@@ -209,6 +217,8 @@ services:
|
||||
volumes:
|
||||
- - ./gitea:/data
|
||||
+ - gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "222:22"
|
||||
@@ -306,6 +316,8 @@ UID/GID as the container values `USER_UID`/`USER_GID`. You should also create th
|
||||
- gitea
|
||||
volumes:
|
||||
- /var/lib/gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "127.0.0.1:2222:22"
|
||||
|
||||
@@ -74,6 +74,11 @@ After successful migration from `gogs` to `gitea 1.0.x`, it is possible to upgra
|
||||
Simply download the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea)
|
||||
and replace the binary.
|
||||
|
||||
## Upgrading from a more recent version of Gogs
|
||||
|
||||
Upgrading from a more recent version of Gogs is also possible, but requires a bit more work.
|
||||
See [#4286](https://github.com/go-gitea/gitea/issues/4286).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* If errors are encountered relating to custom templates in the `gitea/custom/templates`
|
||||
|
||||
@@ -281,3 +281,10 @@ provided key. You should also set the value
|
||||
NB: opensshd requires the gitea program to be owned by root and not
|
||||
writable by group or others. The program must be specified by an absolute
|
||||
path.
|
||||
|
||||
#### migrate
|
||||
Migrates the database. This command can be used to run other commands before starting the server for the first time.
|
||||
This command is idempotent.
|
||||
|
||||
#### convert
|
||||
Converts an existing MySQL database from utf8 to utf8mb4.
|
||||
|
||||
33
docs/content/doc/usage/email-setup.en-us.md
Normal file
33
docs/content/doc/usage/email-setup.en-us.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
date: "2019-10-15T10:10:00+05:00"
|
||||
title: "Usage: Email setup"
|
||||
slug: "email-setup"
|
||||
weight: 12
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "usage"
|
||||
name: "Email setup"
|
||||
weight: 12
|
||||
identifier: "email-setup"
|
||||
---
|
||||
|
||||
# Email setup
|
||||
|
||||
- To use Gitea's built-in Email support, update the `app.ini` config file [mailer] section:
|
||||
|
||||
```ini
|
||||
[mailer]
|
||||
ENABLED = true
|
||||
HOST = mail.mydomain.com:587
|
||||
FROM = gitea@mydomain.com
|
||||
USER = gitea@mydomain.com
|
||||
PASSWD = `password`
|
||||
```
|
||||
|
||||
- Restart Gitea for the configuration changes to take effect.
|
||||
|
||||
- To send a test email to validate the settings, go to Gitea > Site Administration > Configuration > SMTP Mailer Configuration.
|
||||
|
||||
For the full list of options check the [Config Cheat Sheet]({{< relref "doc/advanced/config-cheat-sheet.en-us.md" >}})
|
||||
@@ -13,7 +13,7 @@ menu:
|
||||
identifier: "fail2ban-setup"
|
||||
---
|
||||
|
||||
# Fail2ban setup to block users after failed login attemts
|
||||
# Fail2ban setup to block users after failed login attempts
|
||||
|
||||
**Remember that fail2ban is powerful and can cause lots of issues if you do it incorrectly, so make
|
||||
sure to test this before relying on it so you don't lock yourself out.**
|
||||
@@ -26,7 +26,7 @@ on a bad authentication:
|
||||
2018/04/26 18:15:54 [I] Failed authentication attempt for user from xxx.xxx.xxx.xxx
|
||||
```
|
||||
|
||||
So we set our filter in `/etc/fail2ban/filter.d/gitea.conf`:
|
||||
Add our filter in `/etc/fail2ban/filter.d/gitea.conf`:
|
||||
|
||||
```ini
|
||||
# gitea.conf
|
||||
@@ -35,12 +35,11 @@ failregex = .*Failed authentication attempt for .* from <HOST>
|
||||
ignoreregex =
|
||||
```
|
||||
|
||||
And configure it in `/etc/fail2ban/jail.d/jail.local`:
|
||||
Add our jail in `/etc/fail2ban/jail.d/gitea.conf`:
|
||||
|
||||
```ini
|
||||
[gitea]
|
||||
enabled = true
|
||||
port = http,https
|
||||
filter = gitea
|
||||
logpath = /home/git/gitea/log/gitea.log
|
||||
maxretry = 10
|
||||
@@ -49,6 +48,23 @@ bantime = 900
|
||||
action = iptables-allports
|
||||
```
|
||||
|
||||
If you're using Docker, you'll also need to add an additional jail to handle the **FORWARD**
|
||||
chain in **iptables**. Configure it in `/etc/fail2ban/jail.d/gitea-docker.conf`:
|
||||
|
||||
```ini
|
||||
[gitea-docker]
|
||||
enabled = true
|
||||
filter = gitea
|
||||
logpath = /home/git/gitea/log/gitea.log
|
||||
maxretry = 10
|
||||
findtime = 3600
|
||||
bantime = 900
|
||||
action = iptables-allports[chain="FORWARD"]
|
||||
```
|
||||
|
||||
Then simply run `service fail2ban restart` to apply your changes. You can check to see if
|
||||
fail2ban has accepted your configuration using `service fail2ban status`.
|
||||
|
||||
Make sure and read up on fail2ban and configure it to your needs, this bans someone
|
||||
for **15 minutes** (from all ports) when they fail authentication 10 times in an hour.
|
||||
|
||||
|
||||
@@ -44,6 +44,74 @@ server {
|
||||
|
||||
Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.
|
||||
|
||||
## Using Nginx as a reverse proxy and serve static resources directly
|
||||
We can tune the performance in splitting requests into categories static and dynamic.
|
||||
|
||||
CSS files, JavaScript files, images and web fonts are static content.
|
||||
The front page, a repository view or issue list is dynamic content.
|
||||
|
||||
Nginx can serve static resources directly and proxy only the dynamic requests to gitea.
|
||||
Nginx is optimized for serving static content, while the proxying of large responses might be the opposite of that
|
||||
(see https://serverfault.com/q/587386).
|
||||
|
||||
Download a snap shot of the gitea source repository to `/path/to/gitea/`.
|
||||
|
||||
We are only interested in the `public/` directory and you can delete the rest.
|
||||
|
||||
Depending on the scale of your user base, you might want to split the traffic to two distinct servers,
|
||||
or use a cdn for the static files.
|
||||
|
||||
### using a single node and a single domain
|
||||
|
||||
Set `[server] STATIC_URL_PREFIX = /_/static` in your configuration.
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
server_name git.example.com;
|
||||
|
||||
location /_/static {
|
||||
alias /path/to/gitea/public;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:3000;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### using two nodes and two domains
|
||||
|
||||
Set `[server] STATIC_URL_PREFIX = http://cdn.example.com/gitea` in your configuration.
|
||||
|
||||
```
|
||||
# application server running gitea
|
||||
server {
|
||||
listen 80;
|
||||
server_name git.example.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:3000;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
# static content delivery server
|
||||
server {
|
||||
listen 80;
|
||||
server_name cdn.example.com;
|
||||
|
||||
location /gitea {
|
||||
alias /path/to/gitea/public;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 404;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Using Apache HTTPD as a reverse proxy
|
||||
|
||||
If you want Apache HTTPD to serve your Gitea instance, you can add the following to your Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu):
|
||||
|
||||
5
docs/layouts/_default/index.json
Normal file
5
docs/layouts/_default/index.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{{- $.Scratch.Add "index" slice -}}
|
||||
{{- range .Site.RegularPages -}}
|
||||
{{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}}
|
||||
{{- end -}}
|
||||
{{- $.Scratch.Get "index" | jsonify -}}
|
||||
44
docs/layouts/doc/search.html
Normal file
44
docs/layouts/doc/search.html
Normal file
@@ -0,0 +1,44 @@
|
||||
{{ partial "header.html" . }}
|
||||
{{ partial "navbar.html" . }}
|
||||
|
||||
<section class="section">
|
||||
<div class="container is-centered page">
|
||||
<div class="columns">
|
||||
<div class="column is-one-quarter">
|
||||
{{ partial "menu" . }}
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class=" content">
|
||||
<section class="resume-section p-3 p-lg-5 d-flex flex-column">
|
||||
<div class="my-auto" >
|
||||
<form action="{{ "search" | absLangURL }}">
|
||||
<label>Search:
|
||||
<input id="search-query" name="s"/>
|
||||
</label>
|
||||
</form>
|
||||
<br/>
|
||||
<div id="search-results"></div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- this template is sucked in by search.js and appended to the search-results div above. So editing here will adjust style -->
|
||||
<script id="search-result-template" type="text/x-js-template">
|
||||
<div id="summary-${key}">
|
||||
<h4><a href="${link}">${title}</a></h4>
|
||||
<p>${snippet}</p>
|
||||
${ isset tags }<p>Tags: ${tags}</p>${ end }
|
||||
${ isset categories }<p>Categories: ${categories}</p>${ end }
|
||||
<hr/>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.4.5/fuse.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js"></script>
|
||||
<script>document.LANG = "{{ .Language.Lang }}";</script>
|
||||
{{ $script := resources.Get "js/search.js" | minify | fingerprint -}}
|
||||
<script src="{{ $script.Permalink }}" {{ printf "integrity=%q" $script.Data.Integrity | safeHTMLAttr }}></script>
|
||||
{{ partial "footer.html" . }}
|
||||
2
docs/static/_headers
vendored
2
docs/static/_headers
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; style-src 'self' https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com
|
||||
X-Frame-Options: DENY
|
||||
X-Xss-Protection: 1; mode=block
|
||||
X-Content-Type-Options: nosniff
|
||||
|
||||
23
go.mod
23
go.mod
@@ -22,23 +22,18 @@ require (
|
||||
github.com/blevesearch/go-porterstemmer v0.0.0-20141230013033-23a2c8e5cf1f // indirect
|
||||
github.com/blevesearch/segment v0.0.0-20160105220820-db70c57796cc // indirect
|
||||
github.com/boombuler/barcode v0.0.0-20161226211916-fe0f26ff6d26 // indirect
|
||||
github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f
|
||||
github.com/couchbase/vellum v0.0.0-20190111184608-e91b68ff3efe // indirect
|
||||
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d // indirect
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
|
||||
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.1.1
|
||||
github.com/emirpasic/gods v1.12.0
|
||||
github.com/etcd-io/bbolt v1.3.2 // indirect
|
||||
github.com/ethantkoenig/rupture v0.0.0-20180203182544-0a76f03a811a
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 // indirect
|
||||
github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 // indirect
|
||||
github.com/facebookgo/grace v0.0.0-20160926231715-5729e484473f
|
||||
github.com/facebookgo/httpdown v0.0.0-20160323221027-a3b1354551a2 // indirect
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
||||
github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4 // indirect
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
|
||||
github.com/gliderlabs/ssh v0.2.2
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd // indirect
|
||||
@@ -48,7 +43,6 @@ require (
|
||||
github.com/go-redis/redis v6.15.2+incompatible
|
||||
github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/go-swagger/go-swagger v0.20.1
|
||||
github.com/go-xorm/xorm v0.7.9
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
|
||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||
@@ -64,7 +58,7 @@ require (
|
||||
github.com/klauspost/compress v0.0.0-20161025140425-8df558b6cb6f
|
||||
github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc // indirect
|
||||
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 // indirect
|
||||
github.com/lafriks/xormstore v1.3.1
|
||||
github.com/lafriks/xormstore v1.3.2
|
||||
github.com/lib/pq v1.2.0
|
||||
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
|
||||
github.com/lunny/levelqueue v0.0.0-20190217115915-02b525a4418e
|
||||
@@ -78,6 +72,7 @@ require (
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae // indirect
|
||||
github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc
|
||||
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5
|
||||
github.com/niklasfasching/go-org v0.1.8
|
||||
github.com/oliamb/cutter v0.2.2
|
||||
github.com/philhofer/fwd v1.0.0 // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
@@ -85,12 +80,13 @@ require (
|
||||
github.com/prometheus/client_golang v1.1.0
|
||||
github.com/prometheus/procfs v0.0.4 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
|
||||
github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff
|
||||
github.com/russross/blackfriday v2.0.0+incompatible // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/sergi/go-diff v1.0.0
|
||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||
github.com/steveyen/gtreap v0.0.0-20150807155958-0abe01ef9be2 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
@@ -105,23 +101,22 @@ require (
|
||||
github.com/willf/bitset v0.0.0-20180426185212-8ce1146b8621 // indirect
|
||||
github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
|
||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad
|
||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b
|
||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b
|
||||
golang.org/x/text v0.3.2
|
||||
golang.org/x/tools v0.0.0-20190910221609-7f5965fd7709 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect
|
||||
gopkg.in/editorconfig/editorconfig-core-go.v1 v1.3.0
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/ini.v1 v1.46.0
|
||||
gopkg.in/ini.v1 v1.48.0
|
||||
gopkg.in/ldap.v3 v3.0.2
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2 // indirect
|
||||
gopkg.in/testfixtures.v2 v2.5.0
|
||||
mvdan.cc/xurls/v2 v2.1.0
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
xorm.io/builder v0.3.6
|
||||
xorm.io/core v0.7.2
|
||||
xorm.io/xorm v0.8.0
|
||||
)
|
||||
|
||||
58
go.sum
58
go.sum
@@ -86,11 +86,7 @@ github.com/boombuler/barcode v0.0.0-20161226211916-fe0f26ff6d26/go.mod h1:paBWMc
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f h1:REH9VH5ubNR0skLaOxK7TRJeRbE2dDfvaouQo8FsRcA=
|
||||
github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f/go.mod h1:6QaC0vFoKWYDth94dHFNgRT2YkT5FHdQp/Yx15aAAi0=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/corbym/gocrest v1.0.3 h1:gwEdq6RkTmq+09CTuM29DfKOCtZ7G7bcyxs3IZ6EVdU=
|
||||
github.com/corbym/gocrest v1.0.3/go.mod h1:maVFL5lbdS2PgfOQgGRWDYTeunSWQeiEgoNdTABShCs=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
@@ -134,6 +130,8 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.1.1 h1:mhPg/0hGebcpiiQLqJD2PWWyoHRLEdZ3sXKaEvT1EQU=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.1.1/go.mod h1:/LuhWJiQ9Gvo1DhVpa4ssm5qeg8rrztdtI7j/iCie2k=
|
||||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
@@ -142,20 +140,10 @@ github.com/etcd-io/bbolt v1.3.2 h1:RLRQ0TKLX7DlBRXAJHvbmXL17Q3KNnTBtZ9B6Qo+/Y0=
|
||||
github.com/etcd-io/bbolt v1.3.2/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||
github.com/ethantkoenig/rupture v0.0.0-20180203182544-0a76f03a811a h1:M1bRpaZAn4GSsqu3hdK2R8H0AH9O6vqCTCbm2oAFGfE=
|
||||
github.com/ethantkoenig/rupture v0.0.0-20180203182544-0a76f03a811a/go.mod h1:MkKY/CB98aVE4VxO63X5vTQKUgcn+3XP15LMASe3lYs=
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw=
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
||||
github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 h1:wWke/RUCl7VRjQhwPlR/v0glZXNYzBHdNUzf/Am2Nmg=
|
||||
github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9/go.mod h1:uPmAp6Sws4L7+Q/OokbWDAK1ibXYhB3PXFP1kol5hPg=
|
||||
github.com/facebookgo/grace v0.0.0-20160926231715-5729e484473f h1:0mlfEUWnUDVZnqWEVHGerL5bKYDKMEmT/Qk/W/3nGuo=
|
||||
github.com/facebookgo/grace v0.0.0-20160926231715-5729e484473f/go.mod h1:KigFdumBXUPSwzLDbeuzyt0elrL7+CP7TKuhrhT4bcU=
|
||||
github.com/facebookgo/httpdown v0.0.0-20160323221027-a3b1354551a2 h1:3Zvf9wRhl1cOhckN1oRGWPOkIhOketmEcrQ4TeFAoR4=
|
||||
github.com/facebookgo/httpdown v0.0.0-20160323221027-a3b1354551a2/go.mod h1:TUV/fX3XrTtBQb5+ttSUJzcFgLNpILONFTKmBuk5RSw=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
||||
github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4 h1:0YtRCqIZs2+Tz49QuH6cJVw/IFqzo39gEqZ0iYLxD2M=
|
||||
github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4/go.mod h1:vsJz7uE339KUCpBXx3JAJzSRH7Uk4iGGyJzR529qDIA=
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
@@ -249,11 +237,8 @@ github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l
|
||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
||||
github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0=
|
||||
github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561 h1:deE7ritpK04PgtpyVOS2TYcQEld9qLCD5b5EbVNOuLA=
|
||||
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:YgYOrVn3Nj9Tq0EvjmFbphRytDj7JNRoWSStJZWDJTQ=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@@ -337,9 +322,6 @@ github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=
|
||||
github.com/issue9/assert v1.3.2/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
||||
github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c h1:A/PDn117UYld5mlxe58EpMguqpkeTMw5/FCo0ZPS/Ko=
|
||||
github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c/go.mod h1:5mTb/PQNkqmq2x3IxlQZE0aSnTksJg7fg/oWmJ5SKXQ=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||
github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4=
|
||||
github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d h1:ig/iUfDDg06RVW8OMby+GrmW6K2nPO3AFHlEIdvJSd4=
|
||||
github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
||||
@@ -384,8 +366,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lafriks/xormstore v1.3.1 h1:KpzRUamSV3zmA85Kzw+PZOU9wgMbYsNzuDzLuBMbxpA=
|
||||
github.com/lafriks/xormstore v1.3.1/go.mod h1:qALRD4Vto2Ic7/A5eplMpu5V62mugtSqFysRwz8FETs=
|
||||
github.com/lafriks/xormstore v1.3.2 h1:hqi3F8s/B4rz8GuEZZDuHuOxRjeuOpEI/cC7vcnWwH4=
|
||||
github.com/lafriks/xormstore v1.3.2/go.mod h1:mVNIwIa25QIr8rfR7YlVjrqN/apswHkVdtLCyVYBzXw=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@@ -441,6 +423,12 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY=
|
||||
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/niklasfasching/go-org v0.1.6 h1:F521WcqRNl8OJumlgAnekZgERaTA2HpfOYYfVEKOeI8=
|
||||
github.com/niklasfasching/go-org v0.1.6/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
||||
github.com/niklasfasching/go-org v0.1.7 h1:t3V+3XnS/7BhKv/7SlMUa8FvAiq577/a1T3D7mLIRXE=
|
||||
github.com/niklasfasching/go-org v0.1.7/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
||||
github.com/niklasfasching/go-org v0.1.8 h1:Kjvs6lP+LIILHhc9zIJ4Gu90a/pVY483if2Qmu8v4Fg=
|
||||
github.com/niklasfasching/go-org v0.1.8/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
|
||||
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
|
||||
@@ -503,20 +491,22 @@ github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qq
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff h1:g9ZlAHmkc/h5So+OjNCkZWh+FjuKEOOOoyRkqlGA8+c=
|
||||
github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk=
|
||||
github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc h1:3wIrJvFb3Pf6B/2mDBnN1G5IfUVev4X5apadQlWOczE=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
@@ -532,6 +522,7 @@ github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1
|
||||
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
|
||||
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
@@ -667,6 +658,10 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc=
|
||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss=
|
||||
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 h1:DPz9iiH3YoKiKhX/ijjoZvT0VFwK2c6CWYWQ7Zyr8TU=
|
||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
|
||||
@@ -773,17 +768,18 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/editorconfig/editorconfig-core-go.v1 v1.3.0 h1:oxOEwvhxLMpWpN+0pb2r9TWrM0DCFBHxbuIlS27tmFg=
|
||||
gopkg.in/editorconfig/editorconfig-core-go.v1 v1.3.0/go.mod h1:s2mQFI9McjArkyCwyEwU//+luQENTnD/Lfb/7Sj3/kQ=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg=
|
||||
gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag=
|
||||
gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.48.0 h1:URjZc+8ugRY5mL5uUeQH/a63JcHwdX9xZaWvmNWD7z8=
|
||||
gopkg.in/ini.v1 v1.48.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ldap.v3 v3.0.2 h1:R6RBtabK6e1GO0eQKtkyOFbAHO73QesLzI2w2DZ6b9w=
|
||||
gopkg.in/ldap.v3 v3.0.2/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
@@ -794,8 +790,6 @@ gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOA
|
||||
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE=
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M=
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFYN9JcR6TxU=
|
||||
gopkg.in/testfixtures.v2 v2.5.0 h1:N08B7l2GzFQenyYbzqthDnKAA+cmb17iAZhhFxr7JHw=
|
||||
gopkg.in/testfixtures.v2 v2.5.0/go.mod h1:vyAq+MYCgNpR29qitQdLZhdbLFf4mR/2MFJRFoQZZ2M=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
@@ -819,7 +813,7 @@ strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 h1:mUcz5b3
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY=
|
||||
xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8=
|
||||
xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU=
|
||||
xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb h1:msX3zG3BPl8Ti+LDzP33/9K7BzO/WqFXk610K1kYKfo=
|
||||
xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
||||
xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=
|
||||
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
||||
xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM=
|
||||
xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY=
|
||||
|
||||
@@ -231,3 +231,38 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64)
|
||||
ctx.Session.MakeRequest(t, req, 200)
|
||||
}
|
||||
}
|
||||
|
||||
func doAPIGetBranch(ctx APITestContext, branch string, callback ...func(*testing.T, api.Branch)) func(*testing.T) {
|
||||
return func(t *testing.T) {
|
||||
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/branches/%s?token=%s", ctx.Username, ctx.Reponame, branch, ctx.Token)
|
||||
if ctx.ExpectedCode != 0 {
|
||||
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
|
||||
return
|
||||
}
|
||||
resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var branch api.Branch
|
||||
DecodeJSON(t, resp, &branch)
|
||||
if len(callback) > 0 {
|
||||
callback[0](t, branch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func doAPICreateFile(ctx APITestContext, treepath string, options *api.CreateFileOptions, callback ...func(*testing.T, api.FileResponse)) func(*testing.T) {
|
||||
return func(t *testing.T) {
|
||||
url := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", ctx.Username, ctx.Reponame, treepath, ctx.Token)
|
||||
req := NewRequestWithJSON(t, "POST", url, &options)
|
||||
if ctx.ExpectedCode != 0 {
|
||||
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
|
||||
return
|
||||
}
|
||||
resp := ctx.Session.MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
var contents api.FileResponse
|
||||
DecodeJSON(t, resp, &contents)
|
||||
if len(callback) > 0 {
|
||||
callback[0](t, contents)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ func TestAPICreateAndUpdateRelease(t *testing.T) {
|
||||
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
assert.NoError(t, err)
|
||||
defer gitRepo.Close()
|
||||
|
||||
err = gitRepo.CreateTag("v0.0.1", "master")
|
||||
assert.NoError(t, err)
|
||||
@@ -112,6 +113,7 @@ func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) {
|
||||
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
assert.NoError(t, err)
|
||||
defer gitRepo.Close()
|
||||
|
||||
err = gitRepo.CreateTag("v0.0.1", "master")
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -91,7 +91,7 @@ func getExpectedFileResponseForCreate(commitID, treePath string) *api.FileRespon
|
||||
},
|
||||
Verification: &api.PayloadCommitVerification{
|
||||
Verified: false,
|
||||
Reason: "unsigned",
|
||||
Reason: "gpg.error.not_signed_commit",
|
||||
Signature: "",
|
||||
Payload: "",
|
||||
},
|
||||
@@ -139,6 +139,7 @@ func TestAPICreateFile(t *testing.T) {
|
||||
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
|
||||
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
|
||||
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
|
||||
gitRepo.Close()
|
||||
}
|
||||
|
||||
// Test creating a file in a new branch
|
||||
|
||||
@@ -94,7 +94,7 @@ func getExpectedFileResponseForUpdate(commitID, treePath string) *api.FileRespon
|
||||
},
|
||||
Verification: &api.PayloadCommitVerification{
|
||||
Verified: false,
|
||||
Reason: "unsigned",
|
||||
Reason: "gpg.error.not_signed_commit",
|
||||
Signature: "",
|
||||
Payload: "",
|
||||
},
|
||||
@@ -143,6 +143,7 @@ func TestAPIUpdateFile(t *testing.T) {
|
||||
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
|
||||
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
|
||||
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
|
||||
gitRepo.Close()
|
||||
}
|
||||
|
||||
// Test updating a file in a new branch
|
||||
|
||||
@@ -74,6 +74,8 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) {
|
||||
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
|
||||
// Get the commit ID of the default branch
|
||||
gitRepo, _ := git.OpenRepository(repo1.RepoPath())
|
||||
defer gitRepo.Close()
|
||||
|
||||
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
|
||||
// Make a new tag in repo1
|
||||
newTag := "test_tag"
|
||||
|
||||
@@ -75,6 +75,8 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
|
||||
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
|
||||
// Get the commit ID of the default branch
|
||||
gitRepo, _ := git.OpenRepository(repo1.RepoPath())
|
||||
defer gitRepo.Close()
|
||||
|
||||
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
|
||||
// Make a new tag in repo1
|
||||
newTag := "test_tag"
|
||||
|
||||
@@ -29,6 +29,8 @@ func TestAPIGitTags(t *testing.T) {
|
||||
git.NewCommand("config", "user.email", user.Email).RunInDir(repo.RepoPath())
|
||||
|
||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||
defer gitRepo.Close()
|
||||
|
||||
commit, _ := gitRepo.GetBranchCommit("master")
|
||||
lTagName := "lightweightTag"
|
||||
gitRepo.CreateTag(lTagName, commit.ID.String())
|
||||
|
||||
@@ -70,9 +70,9 @@ func TestAPISearchRepo(t *testing.T) {
|
||||
expectedResults
|
||||
}{
|
||||
{name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50&private=false", expectedResults: expectedResults{
|
||||
nil: {count: 22},
|
||||
user: {count: 22},
|
||||
user2: {count: 22}},
|
||||
nil: {count: 24},
|
||||
user: {count: 24},
|
||||
user2: {count: 24}},
|
||||
},
|
||||
{name: "RepositoriesMax10", requestURL: "/api/v1/repos/search?limit=10&private=false", expectedResults: expectedResults{
|
||||
nil: {count: 10},
|
||||
@@ -92,7 +92,7 @@ func TestAPISearchRepo(t *testing.T) {
|
||||
{name: "RepositoriesAccessibleAndRelatedToUser", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user.ID), expectedResults: expectedResults{
|
||||
nil: {count: 5},
|
||||
user: {count: 9, includesPrivate: true},
|
||||
user2: {count: 5, includesPrivate: true}},
|
||||
user2: {count: 6, includesPrivate: true}},
|
||||
},
|
||||
{name: "RepositoriesAccessibleAndRelatedToUser2", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user2.ID), expectedResults: expectedResults{
|
||||
nil: {count: 1},
|
||||
@@ -103,7 +103,7 @@ func TestAPISearchRepo(t *testing.T) {
|
||||
{name: "RepositoriesAccessibleAndRelatedToUser3", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user3.ID), expectedResults: expectedResults{
|
||||
nil: {count: 1},
|
||||
user: {count: 4, includesPrivate: true},
|
||||
user2: {count: 2, includesPrivate: true},
|
||||
user2: {count: 3, includesPrivate: true},
|
||||
user3: {count: 4, includesPrivate: true}},
|
||||
},
|
||||
{name: "RepositoriesOwnedByOrganization", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", orgUser.ID), expectedResults: expectedResults{
|
||||
@@ -334,7 +334,7 @@ func testAPIRepoMigrateConflict(t *testing.T, u *url.URL) {
|
||||
resp := httpContext.Session.MakeRequest(t, req, http.StatusConflict)
|
||||
respJSON := map[string]string{}
|
||||
DecodeJSON(t, resp, &respJSON)
|
||||
assert.Equal(t, respJSON["message"], "The repository with the same name already exists.")
|
||||
assert.Equal(t, "The repository with the same name already exists.", respJSON["message"])
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@@ -55,37 +55,44 @@ func TestAPITeam(t *testing.T) {
|
||||
|
||||
// Create team.
|
||||
teamToCreate := &api.CreateTeamOption{
|
||||
Name: "team1",
|
||||
Description: "team one",
|
||||
Permission: "write",
|
||||
Units: []string{"repo.code", "repo.issues"},
|
||||
Name: "team1",
|
||||
Description: "team one",
|
||||
IncludesAllRepositories: true,
|
||||
Permission: "write",
|
||||
Units: []string{"repo.code", "repo.issues"},
|
||||
}
|
||||
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams?token=%s", org.Name, token), teamToCreate)
|
||||
resp = session.MakeRequest(t, req, http.StatusCreated)
|
||||
DecodeJSON(t, resp, &apiTeam)
|
||||
checkTeamResponse(t, &apiTeam, teamToCreate.Name, teamToCreate.Description, teamToCreate.Permission, teamToCreate.Units)
|
||||
checkTeamBean(t, apiTeam.ID, teamToCreate.Name, teamToCreate.Description, teamToCreate.Permission, teamToCreate.Units)
|
||||
checkTeamResponse(t, &apiTeam, teamToCreate.Name, teamToCreate.Description, teamToCreate.IncludesAllRepositories,
|
||||
teamToCreate.Permission, teamToCreate.Units)
|
||||
checkTeamBean(t, apiTeam.ID, teamToCreate.Name, teamToCreate.Description, teamToCreate.IncludesAllRepositories,
|
||||
teamToCreate.Permission, teamToCreate.Units)
|
||||
teamID := apiTeam.ID
|
||||
|
||||
// Edit team.
|
||||
teamToEdit := &api.EditTeamOption{
|
||||
Name: "teamone",
|
||||
Description: "team 1",
|
||||
Permission: "admin",
|
||||
Units: []string{"repo.code", "repo.pulls", "repo.releases"},
|
||||
Name: "teamone",
|
||||
Description: "team 1",
|
||||
IncludesAllRepositories: false,
|
||||
Permission: "admin",
|
||||
Units: []string{"repo.code", "repo.pulls", "repo.releases"},
|
||||
}
|
||||
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d?token=%s", teamID, token), teamToEdit)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiTeam)
|
||||
checkTeamResponse(t, &apiTeam, teamToEdit.Name, teamToEdit.Description, teamToEdit.Permission, teamToEdit.Units)
|
||||
checkTeamBean(t, apiTeam.ID, teamToEdit.Name, teamToEdit.Description, teamToEdit.Permission, teamToEdit.Units)
|
||||
checkTeamResponse(t, &apiTeam, teamToEdit.Name, teamToEdit.Description, teamToEdit.IncludesAllRepositories,
|
||||
teamToEdit.Permission, teamToEdit.Units)
|
||||
checkTeamBean(t, apiTeam.ID, teamToEdit.Name, teamToEdit.Description, teamToEdit.IncludesAllRepositories,
|
||||
teamToEdit.Permission, teamToEdit.Units)
|
||||
|
||||
// Read team.
|
||||
teamRead := models.AssertExistsAndLoadBean(t, &models.Team{ID: teamID}).(*models.Team)
|
||||
req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamID)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiTeam)
|
||||
checkTeamResponse(t, &apiTeam, teamRead.Name, teamRead.Description, teamRead.Authorize.String(), teamRead.GetUnitNames())
|
||||
checkTeamResponse(t, &apiTeam, teamRead.Name, teamRead.Description, teamRead.IncludesAllRepositories,
|
||||
teamRead.Authorize.String(), teamRead.GetUnitNames())
|
||||
|
||||
// Delete team.
|
||||
req = NewRequestf(t, "DELETE", "/api/v1/teams/%d?token="+token, teamID)
|
||||
@@ -93,19 +100,20 @@ func TestAPITeam(t *testing.T) {
|
||||
models.AssertNotExistsBean(t, &models.Team{ID: teamID})
|
||||
}
|
||||
|
||||
func checkTeamResponse(t *testing.T, apiTeam *api.Team, name, description string, permission string, units []string) {
|
||||
func checkTeamResponse(t *testing.T, apiTeam *api.Team, name, description string, includesAllRepositories bool, permission string, units []string) {
|
||||
assert.Equal(t, name, apiTeam.Name, "name")
|
||||
assert.Equal(t, description, apiTeam.Description, "description")
|
||||
assert.Equal(t, includesAllRepositories, apiTeam.IncludesAllRepositories, "includesAllRepositories")
|
||||
assert.Equal(t, permission, apiTeam.Permission, "permission")
|
||||
sort.StringSlice(units).Sort()
|
||||
sort.StringSlice(apiTeam.Units).Sort()
|
||||
assert.EqualValues(t, units, apiTeam.Units, "units")
|
||||
}
|
||||
|
||||
func checkTeamBean(t *testing.T, id int64, name, description string, permission string, units []string) {
|
||||
func checkTeamBean(t *testing.T, id int64, name, description string, includesAllRepositories bool, permission string, units []string) {
|
||||
team := models.AssertExistsAndLoadBean(t, &models.Team{ID: id}).(*models.Team)
|
||||
assert.NoError(t, team.GetUnits(), "GetUnits")
|
||||
checkTeamResponse(t, convert.ToTeam(team), name, description, permission, units)
|
||||
checkTeamResponse(t, convert.ToTeam(team), name, description, includesAllRepositories, permission, units)
|
||||
}
|
||||
|
||||
type TeamSearchResults struct {
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
||||
@@ -79,8 +79,10 @@ func allowLFSFilters() []string {
|
||||
return globalArgs
|
||||
}
|
||||
|
||||
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) {
|
||||
prepareTestEnv(t, 1)
|
||||
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL), prepare ...bool) {
|
||||
if len(prepare) == 0 || prepare[0] {
|
||||
prepareTestEnv(t, 1)
|
||||
}
|
||||
s := http.Server{
|
||||
Handler: mac,
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ref: refs/heads/master
|
||||
@@ -0,0 +1,6 @@
|
||||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = false
|
||||
bare = true
|
||||
symlinks = false
|
||||
ignorecase = true
|
||||
@@ -0,0 +1 @@
|
||||
Unnamed repository; edit this file 'description' to name the repository.
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message taken by
|
||||
# applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit. The hook is
|
||||
# allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "applypatch-msg".
|
||||
|
||||
. git-sh-setup
|
||||
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
|
||||
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
|
||||
:
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message.
|
||||
# Called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero
|
||||
# status after issuing an appropriate message if it wants to stop the
|
||||
# commit. The hook is allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "commit-msg".
|
||||
|
||||
# Uncomment the below to add a Signed-off-by line to the message.
|
||||
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
||||
# hook is more suited to it.
|
||||
#
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
||||
|
||||
# This example catches duplicate Signed-off-by lines.
|
||||
|
||||
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
||||
echo >&2 Duplicate Signed-off-by lines.
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IPC::Open2;
|
||||
|
||||
# An example hook script to integrate Watchman
|
||||
# (https://facebook.github.io/watchman/) with git to speed up detecting
|
||||
# new and modified files.
|
||||
#
|
||||
# The hook is passed a version (currently 1) and a time in nanoseconds
|
||||
# formatted as a string and outputs to stdout all files that have been
|
||||
# modified since the given time. Paths must be relative to the root of
|
||||
# the working tree and separated by a single NUL.
|
||||
#
|
||||
# To enable this hook, rename this file to "query-watchman" and set
|
||||
# 'git config core.fsmonitor .git/hooks/query-watchman'
|
||||
#
|
||||
my ($version, $time) = @ARGV;
|
||||
|
||||
# Check the hook interface version
|
||||
|
||||
if ($version == 1) {
|
||||
# convert nanoseconds to seconds
|
||||
$time = int $time / 1000000000;
|
||||
} else {
|
||||
die "Unsupported query-fsmonitor hook version '$version'.\n" .
|
||||
"Falling back to scanning...\n";
|
||||
}
|
||||
|
||||
my $git_work_tree;
|
||||
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
|
||||
$git_work_tree = Win32::GetCwd();
|
||||
$git_work_tree =~ tr/\\/\//;
|
||||
} else {
|
||||
require Cwd;
|
||||
$git_work_tree = Cwd::cwd();
|
||||
}
|
||||
|
||||
my $retry = 1;
|
||||
|
||||
launch_watchman();
|
||||
|
||||
sub launch_watchman {
|
||||
|
||||
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
|
||||
or die "open2() failed: $!\n" .
|
||||
"Falling back to scanning...\n";
|
||||
|
||||
# In the query expression below we're asking for names of files that
|
||||
# changed since $time but were not transient (ie created after
|
||||
# $time but no longer exist).
|
||||
#
|
||||
# To accomplish this, we're using the "since" generator to use the
|
||||
# recency index to select candidate nodes and "fields" to limit the
|
||||
# output to file names only. Then we're using the "expression" term to
|
||||
# further constrain the results.
|
||||
#
|
||||
# The category of transient files that we want to ignore will have a
|
||||
# creation clock (cclock) newer than $time_t value and will also not
|
||||
# currently exist.
|
||||
|
||||
my $query = <<" END";
|
||||
["query", "$git_work_tree", {
|
||||
"since": $time,
|
||||
"fields": ["name"],
|
||||
"expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]]
|
||||
}]
|
||||
END
|
||||
|
||||
print CHLD_IN $query;
|
||||
close CHLD_IN;
|
||||
my $response = do {local $/; <CHLD_OUT>};
|
||||
|
||||
die "Watchman: command returned no output.\n" .
|
||||
"Falling back to scanning...\n" if $response eq "";
|
||||
die "Watchman: command returned invalid output: $response\n" .
|
||||
"Falling back to scanning...\n" unless $response =~ /^\{/;
|
||||
|
||||
my $json_pkg;
|
||||
eval {
|
||||
require JSON::XS;
|
||||
$json_pkg = "JSON::XS";
|
||||
1;
|
||||
} or do {
|
||||
require JSON::PP;
|
||||
$json_pkg = "JSON::PP";
|
||||
};
|
||||
|
||||
my $o = $json_pkg->new->utf8->decode($response);
|
||||
|
||||
if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {
|
||||
print STDERR "Adding '$git_work_tree' to watchman's watch list.\n";
|
||||
$retry--;
|
||||
qx/watchman watch "$git_work_tree"/;
|
||||
die "Failed to make watchman watch '$git_work_tree'.\n" .
|
||||
"Falling back to scanning...\n" if $? != 0;
|
||||
|
||||
# Watchman will always return all files on the first query so
|
||||
# return the fast "everything is dirty" flag to git and do the
|
||||
# Watchman query just to get it over with now so we won't pay
|
||||
# the cost in git to look up each individual file.
|
||||
print "/\0";
|
||||
eval { launch_watchman() };
|
||||
exit 0;
|
||||
}
|
||||
|
||||
die "Watchman: $o->{error}.\n" .
|
||||
"Falling back to scanning...\n" if $o->{error};
|
||||
|
||||
binmode STDOUT, ":utf8";
|
||||
local $, = "\0";
|
||||
print @{$o->{files}};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
data=$(cat)
|
||||
exitcodes=""
|
||||
hookname=$(basename $0)
|
||||
GIT_DIR=${GIT_DIR:-$(dirname $0)}
|
||||
|
||||
for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do
|
||||
test -x "${hook}" || continue
|
||||
echo "${data}" | "${hook}"
|
||||
exitcodes="${exitcodes} $?"
|
||||
done
|
||||
|
||||
for i in ${exitcodes}; do
|
||||
[ ${i} -eq 0 ] || exit ${i}
|
||||
done
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" post-receive
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare a packed repository for use over
|
||||
# dumb transports.
|
||||
#
|
||||
# To enable this hook, rename this file to "post-update".
|
||||
|
||||
exec git update-server-info
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed
|
||||
# by applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-applypatch".
|
||||
|
||||
. git-sh-setup
|
||||
precommit="$(git rev-parse --git-path hooks/pre-commit)"
|
||||
test -x "$precommit" && exec "$precommit" ${1+"$@"}
|
||||
:
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git commit" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message if
|
||||
# it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-commit".
|
||||
|
||||
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||
then
|
||||
against=HEAD
|
||||
else
|
||||
# Initial commit: diff against an empty tree object
|
||||
against=$(git hash-object -t tree /dev/null)
|
||||
fi
|
||||
|
||||
# If you want to allow non-ASCII filenames set this variable to true.
|
||||
allownonascii=$(git config --bool hooks.allownonascii)
|
||||
|
||||
# Redirect output to stderr.
|
||||
exec 1>&2
|
||||
|
||||
# Cross platform projects tend to avoid non-ASCII filenames; prevent
|
||||
# them from being added to the repository. We exploit the fact that the
|
||||
# printable range starts at the space character and ends with tilde.
|
||||
if [ "$allownonascii" != "true" ] &&
|
||||
# Note that the use of brackets around a tr range is ok here, (it's
|
||||
# even required, for portability to Solaris 10's /usr/bin/tr), since
|
||||
# the square bracket bytes happen to fall in the designated range.
|
||||
test $(git diff --cached --name-only --diff-filter=A -z $against |
|
||||
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
|
||||
then
|
||||
cat <<\EOF
|
||||
Error: Attempt to add a non-ASCII file name.
|
||||
|
||||
This can cause problems if you want to work with people on other platforms.
|
||||
|
||||
To be portable it is advisable to rename the file.
|
||||
|
||||
If you know what you are doing you can disable this check using:
|
||||
|
||||
git config hooks.allownonascii true
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If there are whitespace errors, print the offending file names and fail.
|
||||
exec git diff-index --check --cached $against --
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
|
||||
# An example hook script to verify what is about to be pushed. Called by "git
|
||||
# push" after it has checked the remote status, but before anything has been
|
||||
# pushed. If this script exits with a non-zero status nothing will be pushed.
|
||||
#
|
||||
# This hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- Name of the remote to which the push is being done
|
||||
# $2 -- URL to which the push is being done
|
||||
#
|
||||
# If pushing without using a named remote those arguments will be equal.
|
||||
#
|
||||
# Information about the commits which are being pushed is supplied as lines to
|
||||
# the standard input in the form:
|
||||
#
|
||||
# <local ref> <local sha1> <remote ref> <remote sha1>
|
||||
#
|
||||
# This sample shows how to prevent push of commits where the log message starts
|
||||
# with "WIP" (work in progress).
|
||||
|
||||
remote="$1"
|
||||
url="$2"
|
||||
|
||||
z40=0000000000000000000000000000000000000000
|
||||
|
||||
while read local_ref local_sha remote_ref remote_sha
|
||||
do
|
||||
if [ "$local_sha" = $z40 ]
|
||||
then
|
||||
# Handle delete
|
||||
:
|
||||
else
|
||||
if [ "$remote_sha" = $z40 ]
|
||||
then
|
||||
# New branch, examine all commits
|
||||
range="$local_sha"
|
||||
else
|
||||
# Update to existing branch, examine new commits
|
||||
range="$remote_sha..$local_sha"
|
||||
fi
|
||||
|
||||
# Check for WIP commit
|
||||
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
|
||||
if [ -n "$commit" ]
|
||||
then
|
||||
echo >&2 "Found WIP commit in $local_ref, not pushing"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,169 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2006, 2008 Junio C Hamano
|
||||
#
|
||||
# The "pre-rebase" hook is run just before "git rebase" starts doing
|
||||
# its job, and can prevent the command from running by exiting with
|
||||
# non-zero status.
|
||||
#
|
||||
# The hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- the upstream the series was forked from.
|
||||
# $2 -- the branch being rebased (or empty when rebasing the current branch).
|
||||
#
|
||||
# This sample shows how to prevent topic branches that are already
|
||||
# merged to 'next' branch from getting rebased, because allowing it
|
||||
# would result in rebasing already published history.
|
||||
|
||||
publish=next
|
||||
basebranch="$1"
|
||||
if test "$#" = 2
|
||||
then
|
||||
topic="refs/heads/$2"
|
||||
else
|
||||
topic=`git symbolic-ref HEAD` ||
|
||||
exit 0 ;# we do not interrupt rebasing detached HEAD
|
||||
fi
|
||||
|
||||
case "$topic" in
|
||||
refs/heads/??/*)
|
||||
;;
|
||||
*)
|
||||
exit 0 ;# we do not interrupt others.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Now we are dealing with a topic branch being rebased
|
||||
# on top of master. Is it OK to rebase it?
|
||||
|
||||
# Does the topic really exist?
|
||||
git show-ref -q "$topic" || {
|
||||
echo >&2 "No such branch $topic"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is topic fully merged to master?
|
||||
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
|
||||
if test -z "$not_in_master"
|
||||
then
|
||||
echo >&2 "$topic is fully merged to master; better remove it."
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
fi
|
||||
|
||||
# Is topic ever merged to next? If so you should not be rebasing it.
|
||||
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
|
||||
only_next_2=`git rev-list ^master ${publish} | sort`
|
||||
if test "$only_next_1" = "$only_next_2"
|
||||
then
|
||||
not_in_topic=`git rev-list "^$topic" master`
|
||||
if test -z "$not_in_topic"
|
||||
then
|
||||
echo >&2 "$topic is already up to date with master"
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
|
||||
/usr/bin/perl -e '
|
||||
my $topic = $ARGV[0];
|
||||
my $msg = "* $topic has commits already merged to public branch:\n";
|
||||
my (%not_in_next) = map {
|
||||
/^([0-9a-f]+) /;
|
||||
($1 => 1);
|
||||
} split(/\n/, $ARGV[1]);
|
||||
for my $elem (map {
|
||||
/^([0-9a-f]+) (.*)$/;
|
||||
[$1 => $2];
|
||||
} split(/\n/, $ARGV[2])) {
|
||||
if (!exists $not_in_next{$elem->[0]}) {
|
||||
if ($msg) {
|
||||
print STDERR $msg;
|
||||
undef $msg;
|
||||
}
|
||||
print STDERR " $elem->[1]\n";
|
||||
}
|
||||
}
|
||||
' "$topic" "$not_in_next" "$not_in_master"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
<<\DOC_END
|
||||
|
||||
This sample hook safeguards topic branches that have been
|
||||
published from being rewound.
|
||||
|
||||
The workflow assumed here is:
|
||||
|
||||
* Once a topic branch forks from "master", "master" is never
|
||||
merged into it again (either directly or indirectly).
|
||||
|
||||
* Once a topic branch is fully cooked and merged into "master",
|
||||
it is deleted. If you need to build on top of it to correct
|
||||
earlier mistakes, a new topic branch is created by forking at
|
||||
the tip of the "master". This is not strictly necessary, but
|
||||
it makes it easier to keep your history simple.
|
||||
|
||||
* Whenever you need to test or publish your changes to topic
|
||||
branches, merge them into "next" branch.
|
||||
|
||||
The script, being an example, hardcodes the publish branch name
|
||||
to be "next", but it is trivial to make it configurable via
|
||||
$GIT_DIR/config mechanism.
|
||||
|
||||
With this workflow, you would want to know:
|
||||
|
||||
(1) ... if a topic branch has ever been merged to "next". Young
|
||||
topic branches can have stupid mistakes you would rather
|
||||
clean up before publishing, and things that have not been
|
||||
merged into other branches can be easily rebased without
|
||||
affecting other people. But once it is published, you would
|
||||
not want to rewind it.
|
||||
|
||||
(2) ... if a topic branch has been fully merged to "master".
|
||||
Then you can delete it. More importantly, you should not
|
||||
build on top of it -- other people may already want to
|
||||
change things related to the topic as patches against your
|
||||
"master", so if you need further changes, it is better to
|
||||
fork the topic (perhaps with the same name) afresh from the
|
||||
tip of "master".
|
||||
|
||||
Let's look at this example:
|
||||
|
||||
o---o---o---o---o---o---o---o---o---o "next"
|
||||
/ / / /
|
||||
/ a---a---b A / /
|
||||
/ / / /
|
||||
/ / c---c---c---c B /
|
||||
/ / / \ /
|
||||
/ / / b---b C \ /
|
||||
/ / / / \ /
|
||||
---o---o---o---o---o---o---o---o---o---o---o "master"
|
||||
|
||||
|
||||
A, B and C are topic branches.
|
||||
|
||||
* A has one fix since it was merged up to "next".
|
||||
|
||||
* B has finished. It has been fully merged up to "master" and "next",
|
||||
and is ready to be deleted.
|
||||
|
||||
* C has not merged to "next" at all.
|
||||
|
||||
We would want to allow C to be rebased, refuse A, and encourage
|
||||
B to be deleted.
|
||||
|
||||
To compute (1):
|
||||
|
||||
git rev-list ^master ^topic next
|
||||
git rev-list ^master next
|
||||
|
||||
if these match, topic has not merged in next at all.
|
||||
|
||||
To compute (2):
|
||||
|
||||
git rev-list master..topic
|
||||
|
||||
if this is empty, it is fully merged to "master".
|
||||
|
||||
DOC_END
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
data=$(cat)
|
||||
exitcodes=""
|
||||
hookname=$(basename $0)
|
||||
GIT_DIR=${GIT_DIR:-$(dirname $0)}
|
||||
|
||||
for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do
|
||||
test -x "${hook}" || continue
|
||||
echo "${data}" | "${hook}"
|
||||
exitcodes="${exitcodes} $?"
|
||||
done
|
||||
|
||||
for i in ${exitcodes}; do
|
||||
[ ${i} -eq 0 ] || exit ${i}
|
||||
done
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" pre-receive
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to make use of push options.
|
||||
# The example simply echoes all push options that start with 'echoback='
|
||||
# and rejects all pushes when the "reject" push option is used.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-receive".
|
||||
|
||||
if test -n "$GIT_PUSH_OPTION_COUNT"
|
||||
then
|
||||
i=0
|
||||
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
|
||||
do
|
||||
eval "value=\$GIT_PUSH_OPTION_$i"
|
||||
case "$value" in
|
||||
echoback=*)
|
||||
echo "echo from the pre-receive-hook: ${value#*=}" >&2
|
||||
;;
|
||||
reject)
|
||||
exit 1
|
||||
esac
|
||||
i=$((i + 1))
|
||||
done
|
||||
fi
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare the commit log message.
|
||||
# Called by "git commit" with the name of the file that has the
|
||||
# commit message, followed by the description of the commit
|
||||
# message's source. The hook's purpose is to edit the commit
|
||||
# message file. If the hook fails with a non-zero status,
|
||||
# the commit is aborted.
|
||||
#
|
||||
# To enable this hook, rename this file to "prepare-commit-msg".
|
||||
|
||||
# This hook includes three examples. The first one removes the
|
||||
# "# Please enter the commit message..." help message.
|
||||
#
|
||||
# The second includes the output of "git diff --name-status -r"
|
||||
# into the message, just before the "git status" output. It is
|
||||
# commented because it doesn't cope with --amend or with squashed
|
||||
# commits.
|
||||
#
|
||||
# The third example adds a Signed-off-by line to the message, that can
|
||||
# still be edited. This is rarely a good idea.
|
||||
|
||||
COMMIT_MSG_FILE=$1
|
||||
COMMIT_SOURCE=$2
|
||||
SHA1=$3
|
||||
|
||||
/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
|
||||
|
||||
# case "$COMMIT_SOURCE,$SHA1" in
|
||||
# ,|template,)
|
||||
# /usr/bin/perl -i.bak -pe '
|
||||
# print "\n" . `git diff --cached --name-status -r`
|
||||
# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
|
||||
# *) ;;
|
||||
# esac
|
||||
|
||||
# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
|
||||
# if test -z "$COMMIT_SOURCE"
|
||||
# then
|
||||
# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
|
||||
# fi
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
exitcodes=""
|
||||
hookname=$(basename $0)
|
||||
GIT_DIR=${GIT_DIR:-$(dirname $0)}
|
||||
|
||||
for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do
|
||||
test -x "${hook}" || continue
|
||||
"${hook}" $1 $2 $3
|
||||
exitcodes="${exitcodes} $?"
|
||||
done
|
||||
|
||||
for i in ${exitcodes}; do
|
||||
[ ${i} -eq 0 ] || exit ${i}
|
||||
done
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" update $1 $2 $3
|
||||
@@ -0,0 +1,128 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to block unannotated tags from entering.
|
||||
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
|
||||
#
|
||||
# To enable this hook, rename this file to "update".
|
||||
#
|
||||
# Config
|
||||
# ------
|
||||
# hooks.allowunannotated
|
||||
# This boolean sets whether unannotated tags will be allowed into the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowdeletetag
|
||||
# This boolean sets whether deleting tags will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowmodifytag
|
||||
# This boolean sets whether a tag may be modified after creation. By default
|
||||
# it won't be.
|
||||
# hooks.allowdeletebranch
|
||||
# This boolean sets whether deleting branches will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.denycreatebranch
|
||||
# This boolean sets whether remotely creating branches will be denied
|
||||
# in the repository. By default this is allowed.
|
||||
#
|
||||
|
||||
# --- Command line
|
||||
refname="$1"
|
||||
oldrev="$2"
|
||||
newrev="$3"
|
||||
|
||||
# --- Safety check
|
||||
if [ -z "$GIT_DIR" ]; then
|
||||
echo "Don't run this script from the command line." >&2
|
||||
echo " (if you want, you could supply GIT_DIR then run" >&2
|
||||
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
||||
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Config
|
||||
allowunannotated=$(git config --bool hooks.allowunannotated)
|
||||
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
|
||||
denycreatebranch=$(git config --bool hooks.denycreatebranch)
|
||||
allowdeletetag=$(git config --bool hooks.allowdeletetag)
|
||||
allowmodifytag=$(git config --bool hooks.allowmodifytag)
|
||||
|
||||
# check for no description
|
||||
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
|
||||
case "$projectdesc" in
|
||||
"Unnamed repository"* | "")
|
||||
echo "*** Project description file hasn't been set" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Check types
|
||||
# if $newrev is 0000...0000, it's a commit to delete a ref.
|
||||
zero="0000000000000000000000000000000000000000"
|
||||
if [ "$newrev" = "$zero" ]; then
|
||||
newrev_type=delete
|
||||
else
|
||||
newrev_type=$(git cat-file -t $newrev)
|
||||
fi
|
||||
|
||||
case "$refname","$newrev_type" in
|
||||
refs/tags/*,commit)
|
||||
# un-annotated tag
|
||||
short_refname=${refname##refs/tags/}
|
||||
if [ "$allowunannotated" != "true" ]; then
|
||||
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
|
||||
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,delete)
|
||||
# delete tag
|
||||
if [ "$allowdeletetag" != "true" ]; then
|
||||
echo "*** Deleting a tag is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,tag)
|
||||
# annotated tag
|
||||
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
|
||||
then
|
||||
echo "*** Tag '$refname' already exists." >&2
|
||||
echo "*** Modifying a tag is not allowed in this repository." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,commit)
|
||||
# branch
|
||||
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
|
||||
echo "*** Creating a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,delete)
|
||||
# delete branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/remotes/*,commit)
|
||||
# tracking branch
|
||||
;;
|
||||
refs/remotes/*,delete)
|
||||
# delete tracking branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# Anything else (is there anything else?)
|
||||
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Finished
|
||||
exit 0
|
||||
@@ -0,0 +1,6 @@
|
||||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
||||
@@ -0,0 +1 @@
|
||||
aacbdfe9e1c4b47f60abe81849045fa4e96f1d75 refs/heads/master
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
aacbdfe9e1c4b47f60abe81849045fa4e96f1d75
|
||||
333
integrations/gpg_git_test.go
Normal file
333
integrations/gpg_git_test.go
Normal file
@@ -0,0 +1,333 @@
|
||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package integrations
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/process"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"golang.org/x/crypto/openpgp/armor"
|
||||
)
|
||||
|
||||
func TestGPGGit(t *testing.T) {
|
||||
username := "user2"
|
||||
|
||||
// OK Set a new GPG home
|
||||
tmpDir, err := ioutil.TempDir("", "temp-gpg")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
err = os.Chmod(tmpDir, 0700)
|
||||
assert.NoError(t, err)
|
||||
|
||||
oldGNUPGHome := os.Getenv("GNUPGHOME")
|
||||
err = os.Setenv("GNUPGHOME", tmpDir)
|
||||
assert.NoError(t, err)
|
||||
defer os.Setenv("GNUPGHOME", oldGNUPGHome)
|
||||
|
||||
// Need to create a root key
|
||||
rootKeyPair, err := createGPGKey(tmpDir, "gitea", "gitea@fake.local")
|
||||
assert.NoError(t, err)
|
||||
|
||||
rootKeyID := rootKeyPair.PrimaryKey.KeyIdShortString()
|
||||
|
||||
oldKeyID := setting.Repository.Signing.SigningKey
|
||||
oldName := setting.Repository.Signing.SigningName
|
||||
oldEmail := setting.Repository.Signing.SigningEmail
|
||||
defer func() {
|
||||
setting.Repository.Signing.SigningKey = oldKeyID
|
||||
setting.Repository.Signing.SigningName = oldName
|
||||
setting.Repository.Signing.SigningEmail = oldEmail
|
||||
}()
|
||||
|
||||
setting.Repository.Signing.SigningKey = rootKeyID
|
||||
setting.Repository.Signing.SigningName = "gitea"
|
||||
setting.Repository.Signing.SigningEmail = "gitea@fake.local"
|
||||
user := models.AssertExistsAndLoadBean(t, &models.User{Name: username}).(*models.User)
|
||||
|
||||
setting.Repository.Signing.InitialCommit = []string{"never"}
|
||||
setting.Repository.Signing.CRUDActions = []string{"never"}
|
||||
|
||||
baseAPITestContext := NewAPITestContext(t, username, "repo1")
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("Unsigned-Initial", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
|
||||
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||
assert.NotNil(t, branch.Commit)
|
||||
assert.NotNil(t, branch.Commit.Verification)
|
||||
assert.False(t, branch.Commit.Verification.Verified)
|
||||
assert.Empty(t, branch.Commit.Verification.Signature)
|
||||
}))
|
||||
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
||||
t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.False(t, response.Verification.Verified)
|
||||
}))
|
||||
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
||||
t, testCtx, user, "never", "never2", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.False(t, response.Verification.Verified)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("Unsigned-Initial-CRUD-ParentSigned", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
||||
t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.False(t, response.Verification.Verified)
|
||||
}))
|
||||
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
||||
t, testCtx, user, "parentsigned", "parentsigned2", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.False(t, response.Verification.Verified)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.CRUDActions = []string{"never"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("Unsigned-Initial-CRUD-Never", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
||||
t, testCtx, user, "parentsigned", "parentsigned-never", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.False(t, response.Verification.Verified)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.CRUDActions = []string{"always"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("Unsigned-Initial-CRUD-Always", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||
t.Run("CreateCRUDFile-Always", crudActionCreateFile(
|
||||
t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.True(t, response.Verification.Verified)
|
||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||
}))
|
||||
t.Run("CreateCRUDFile-ParentSigned-always", crudActionCreateFile(
|
||||
t, testCtx, user, "parentsigned", "parentsigned-always", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.True(t, response.Verification.Verified)
|
||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("Unsigned-Initial-CRUD-ParentSigned", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||
t.Run("CreateCRUDFile-Always-ParentSigned", crudActionCreateFile(
|
||||
t, testCtx, user, "always", "always-parentsigned", "signed-always-parentsigned.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.True(t, response.Verification.Verified)
|
||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.InitialCommit = []string{"always"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("AlwaysSign-Initial", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-always")
|
||||
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
|
||||
t.Run("CheckMasterBranchSigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||
assert.NotNil(t, branch.Commit)
|
||||
assert.NotNil(t, branch.Commit.Verification)
|
||||
assert.True(t, branch.Commit.Verification.Verified)
|
||||
assert.Equal(t, "gitea@fake.local", branch.Commit.Verification.Signer.Email)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.CRUDActions = []string{"never"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("AlwaysSign-Initial-CRUD-Never", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-always")
|
||||
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
||||
t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.False(t, response.Verification.Verified)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("AlwaysSign-Initial-CRUD-ParentSigned-On-Always", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-always")
|
||||
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
||||
t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.True(t, response.Verification.Verified)
|
||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.CRUDActions = []string{"always"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("AlwaysSign-Initial-CRUD-Always", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-always")
|
||||
t.Run("CreateCRUDFile-Always", crudActionCreateFile(
|
||||
t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) {
|
||||
assert.True(t, response.Verification.Verified)
|
||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||
}))
|
||||
|
||||
})
|
||||
}, false)
|
||||
var pr api.PullRequest
|
||||
setting.Repository.Signing.Merges = []string{"commitssigned"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("UnsignedMerging", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||
var err error
|
||||
t.Run("CreatePullRequest", func(t *testing.T) {
|
||||
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "never2")(t)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
||||
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||
assert.NotNil(t, branch.Commit)
|
||||
assert.NotNil(t, branch.Commit.Verification)
|
||||
assert.False(t, branch.Commit.Verification.Verified)
|
||||
assert.Empty(t, branch.Commit.Verification.Signature)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.Merges = []string{"basesigned"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("BaseSignedMerging", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||
var err error
|
||||
t.Run("CreatePullRequest", func(t *testing.T) {
|
||||
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "parentsigned2")(t)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
||||
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||
assert.NotNil(t, branch.Commit)
|
||||
assert.NotNil(t, branch.Commit.Verification)
|
||||
assert.False(t, branch.Commit.Verification.Verified)
|
||||
assert.Empty(t, branch.Commit.Verification.Signature)
|
||||
}))
|
||||
})
|
||||
}, false)
|
||||
setting.Repository.Signing.Merges = []string{"commitssigned"}
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
|
||||
t.Run("CommitsSignedMerging", func(t *testing.T) {
|
||||
PrintCurrentTest(t)
|
||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||
var err error
|
||||
t.Run("CreatePullRequest", func(t *testing.T) {
|
||||
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "always-parentsigned")(t)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
||||
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||
assert.NotNil(t, branch.Commit)
|
||||
assert.NotNil(t, branch.Commit.Verification)
|
||||
assert.True(t, branch.Commit.Verification.Verified)
|
||||
}))
|
||||
|
||||
})
|
||||
}, false)
|
||||
}
|
||||
|
||||
func crudActionCreateFile(t *testing.T, ctx APITestContext, user *models.User, from, to, path string, callback ...func(*testing.T, api.FileResponse)) func(*testing.T) {
|
||||
return doAPICreateFile(ctx, path, &api.CreateFileOptions{
|
||||
FileOptions: api.FileOptions{
|
||||
BranchName: from,
|
||||
NewBranchName: to,
|
||||
Message: fmt.Sprintf("from:%s to:%s path:%s", from, to, path),
|
||||
Author: api.Identity{
|
||||
Name: user.FullName,
|
||||
Email: user.Email,
|
||||
},
|
||||
Committer: api.Identity{
|
||||
Name: user.FullName,
|
||||
Email: user.Email,
|
||||
},
|
||||
},
|
||||
Content: base64.StdEncoding.EncodeToString([]byte("This is new text")),
|
||||
}, callback...)
|
||||
}
|
||||
|
||||
func createGPGKey(tmpDir, name, email string) (*openpgp.Entity, error) {
|
||||
keyPair, err := openpgp.NewEntity(name, "test", email, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, id := range keyPair.Identities {
|
||||
err := id.SelfSignature.SignUserId(id.UserId.Id, keyPair.PrimaryKey, keyPair.PrivateKey, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
keyFile := filepath.Join(tmpDir, "temporary.key")
|
||||
keyWriter, err := os.Create(keyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer keyWriter.Close()
|
||||
defer os.Remove(keyFile)
|
||||
|
||||
w, err := armor.Encode(keyWriter, openpgp.PrivateKeyType, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
keyPair.SerializePrivate(w, nil)
|
||||
if err := w.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := keyWriter.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, _, err := process.GetManager().Exec("gpg --import temporary.key", "gpg", "--import", keyFile); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return keyPair, nil
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -102,7 +103,11 @@ func initIntegrationTest() {
|
||||
fmt.Println("Environment variable $GITEA_ROOT not set")
|
||||
os.Exit(1)
|
||||
}
|
||||
setting.AppPath = path.Join(giteaRoot, "gitea")
|
||||
giteaBinary := "gitea"
|
||||
if runtime.GOOS == "windows" {
|
||||
giteaBinary += ".exe"
|
||||
}
|
||||
setting.AppPath = path.Join(giteaRoot, giteaBinary)
|
||||
if _, err := os.Stat(setting.AppPath); err != nil {
|
||||
fmt.Printf("Could not find gitea binary at %s\n", setting.AppPath)
|
||||
os.Exit(1)
|
||||
|
||||
@@ -23,8 +23,8 @@ import (
|
||||
"code.gitea.io/gitea/modules/charset"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
var currentEngine *xorm.Engine
|
||||
|
||||
@@ -21,6 +21,9 @@ ROOT = integrations/gitea-integration-mssql/gitea-repositories
|
||||
LOCAL_COPY_PATH = tmp/local-repo-mssql
|
||||
LOCAL_WIKI_PATH = tmp/local-wiki-mssql
|
||||
|
||||
[repository.signing]
|
||||
SIGNING_KEY = none
|
||||
|
||||
[server]
|
||||
SSH_DOMAIN = localhost
|
||||
HTTP_PORT = 3003
|
||||
|
||||
@@ -21,6 +21,9 @@ ROOT = integrations/gitea-integration-mysql/gitea-repositories
|
||||
LOCAL_COPY_PATH = tmp/local-repo-mysql
|
||||
LOCAL_WIKI_PATH = tmp/local-wiki-mysql
|
||||
|
||||
[repository.signing]
|
||||
SIGNING_KEY = none
|
||||
|
||||
[server]
|
||||
SSH_DOMAIN = localhost
|
||||
HTTP_PORT = 3001
|
||||
|
||||
@@ -21,6 +21,9 @@ ROOT = integrations/gitea-integration-mysql8/gitea-repositories
|
||||
LOCAL_COPY_PATH = tmp/local-repo-mysql8
|
||||
LOCAL_WIKI_PATH = tmp/local-wiki-mysql8
|
||||
|
||||
[repository.signing]
|
||||
SIGNING_KEY = none
|
||||
|
||||
[server]
|
||||
SSH_DOMAIN = localhost
|
||||
HTTP_PORT = 3004
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user