Compare commits

..

4 Commits

Author SHA1 Message Date
bbb0b8c17c add change log for release v1.2.0-rc1 (#2388) 2017-08-25 16:54:41 +08:00
0938a2dca3 Fix missing collabrative repos (#2367) (#2382)
* fix missing collabrative repos

* fix bug of collabrative

* fix SQL quotes
2017-08-25 10:25:37 +08:00
9df0eafa25 Move 3rd party js/css into public/vendor and document sources (#2383)
This commit cherry picks the following commits (master -> v1.2):
  a915a09
  874f9be
  233bbcf

Ref: https://github.com/go-gitea/gitea/issues/1484
Signed-off-by: Michael Lustfield <michael@lustfield.net>
2017-08-25 10:01:17 +08:00
e13eef8cfe update translation from crowdin (#2368) (#2380) 2017-08-24 21:57:17 +08:00
729 changed files with 14929 additions and 48243 deletions

View File

@ -1,44 +0,0 @@
repo: go-gitea/gitea
groups:
-
name: BREAKING
labels:
- kind/breaking
-
name: FEATURE
labels:
- kind/feature
-
name: BUGFIXES
labels:
- kind/bug
-
name: ENHANCEMENT
labels:
- kind/enhancement
- kind/refactor
- kind/ui
-
name: SECURITY
labels:
- kind/security
-
name: TESTING
labels:
- kind/testing
-
name: TRANSLATION
labels:
- kind/translation
-
name: BUILD
labels:
- kind/build
- kind/lint
-
name: DOCS
labels:
- kind/docs
-
name: MISC
default: true

File diff suppressed because it is too large Load Diff

1
.drone.yml.sig Normal file

File diff suppressed because one or more lines are too long

15
.gitignore vendored
View File

@ -10,9 +10,6 @@ _test
# IntelliJ
.idea
# MS VSCode
.vscode
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
@ -30,7 +27,6 @@ _testmain.go
*.prof
*coverage.out
coverage.all
/modules/options/bindata.go
/modules/public/bindata.go
@ -40,7 +36,6 @@ coverage.all
*.log
/gitea
/debug
/integrations.test
/bin
@ -50,12 +45,4 @@ coverage.all
/indexers
/log
/public/img/avatar
/integrations/gitea-integration-mysql
/integrations/gitea-integration-pgsql
/integrations/gitea-integration-sqlite
/integrations/indexers-mysql
/integrations/indexers-pgsql
/integrations/indexers-sqlite
/integrations/mysql.ini
/integrations/pgsql.ini
/node_modules
/integrations/gitea-integration

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@
- [Discuss your design](#discuss-your-design)
- [Testing redux](#testing-redux)
- [Vendoring](#vendoring)
- [Translation](#translation)
- [Code review](#code-review)
- [Styleguide](#styleguide)
- [Sign your work](#sign-your-work)
@ -20,107 +19,47 @@
## Introduction
This document explains how to contribute changes to the Gitea project.
It assumes you have followed the
[installation instructions](https://docs.gitea.io/en-us/).
Sensitive security-related issues should be reported to
[security@gitea.io](mailto:security@gitea.io).
For configuring IDE or code editor to develop Gitea see [IDE and code editor configuration](contrib/ide/)
This document explains how to contribute changes to the Gitea project. It assumes you have followed the [installation instructions](https://docs.gitea.io/en-us/). Sensitive security-related issues should be reported to [security@gitea.io](mailto:security@gitea.io).
## Bug reports
Please search the issues on the issue tracker with a variety of keywords
to ensure your bug is not already reported.
Please search the issues on the issue tracker with a variety of keywords to ensure your bug is not already reported.
If unique, [open an issue](https://github.com/go-gitea/gitea/issues/new)
and answer the questions so we can understand and reproduce the
problematic behavior.
If unique, [open an issue](https://github.com/go-gitea/gitea/issues/new) and answer the questions so we can understand and reproduce the problematic behavior.
To show us that the issue you are having is in Gitea itself, please
write clear, concise instructions so we can reproduce the behavior—
even if it seems obvious. The more detailed and specific you are,
the faster we can fix the issue. Check out [How to Report Bugs
Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
To show us that the issue you are having is in Gitea itself, please write clear, concise instructions so we can reproduce the behavior (even if it seems obvious). The more detailed and specific you are, the faster we can fix the issue. Check out [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
Please be kind, remember that Gitea comes at no cost to you, and you're
getting free help.
Please be kind, remember that Gitea comes at no cost to you, and you're getting free help.
## Discuss your design
The project welcomes submissions. If you want to change or add something,
please let everyone know what you're working on—[file an issue](https://github.com/go-gitea/gitea/issues/new)!
Significant changes must go through the [change proposal process](https://github.com/go-gitea/proposals)
before they can be accepted.
The project welcomes submissions but please let everyone know what you're working on if you want to change or add something to the Gitea repositories.
This process gives everyone a chance to validate the design, helps
prevent duplication of effort, and ensures that the idea fits inside
the goals for the project and tools. It also checks that the design is
sound before code is written; the code review tool is not the place for
high-level discussions.
Before starting to write something new for the Gitea project, please [file an issue](https://github.com/go-gitea/gitea/issues/new). Significant changes must go through the [change proposal process](https://github.com/go-gitea/proposals) before they can be accepted.
This process gives everyone a chance to validate the design, helps prevent duplication of effort, and ensures that the idea fits inside the goals for the project and tools. It also checks that the design is sound before code is written; the code review tool is not the place for high-level discussions.
## Testing redux
Before sending code out for review, run all the tests for the
whole tree to make sure the changes don't break other usage
and keep the compatibility on upgrade. To make sure you are
running the test suite exactly like we do, you should install
the CLI for [Drone CI](https://github.com/drone/drone), as
we are using the server for continous testing, following [these
instructions](http://readme.drone.io/usage/getting-started-cli). After that,
you can simply call `drone exec` within your working directory and it will try
to run the test suite locally.
Before sending code out for review, run all the tests for the whole tree to make sure the changes don't break other usage and keep the compatibility on upgrade. To make sure you are running the test suite exactly like we do, you should install the CLI for [Drone CI](https://github.com/drone/drone), as we are using the server for continous testing, following [these instructions](http://readme.drone.io/usage/getting-started-cli). After that you can simply call `drone exec` within your working directory and it will try to run the test suite locally.
## Vendoring
We keep a cached copy of dependencies within the `vendor/` directory,
managing updates via [govendor](http://github.com/kardianos/govendor).
We keep a cached copy of dependencies within the `vendor/` directory, managing updates via [govendor](http://github.com/kardianos/govendor).
Pull requests should only include `vendor/` updates if they are part of
the same change, be it a bugfix or a feature addition.
Pull requests should only include `vendor/` updates if they are part of the same change, be it a bugfix or a feature addition.
The `vendor/` update needs to be justified as part of the PR description,
and must be verified by the reviewers and/or merger to always reference
an existing upstream commit.
## Translation
We do all translation work inside [Crowdin](https://crowdin.com/project/gitea).
The only translation that is maintained in this git repository is
[`en_US.ini`](https://github.com/go-gitea/gitea/blob/master/options/locale/locale_en-US.ini)
and is synced regularily to Crowdin. Once a translation has reached
A SATISFACTORY PERCENTAGE it will be synced back into this repo and
included in the next released version.
## Building Gitea
Generally, the go build tools are installed as-needed in the `Makefile`.
An exception are the tools to build the CSS and images.
- To build CSS: Install [Node.js](https://nodejs.org/en/download/package-manager)
with `npm` and then run `npm install` and `make stylesheets`.
- To build Images: ImageMagick, inkscape and zopflipng binaries must be
available in your `PATH` to run `make generate-images`.
The `vendor/` update needs to be justified as part of the PR description, and must be verified by the reviewers and/or merger to always reference an existing upstream commit.
## Code review
Changes to Gitea must be reviewed before they are acceptedno matter who
makes the change, even if they are an owner or a maintainer. We use GitHub's
pull request workflow to do that. And, we also use [LGTM](http://lgtm.co)
to ensure every PR is reviewed by at least 2 maintainers.
Changes to Gitea must be reviewed before they are accepted, no matter who makes the change even if it is an owner or a maintainer. We use GitHub's pull request workflow to do that and we also use [LGTM](http://lgtm.co) to ensure every PR is reviewed by at least 2 maintainers.
Please try to make your pull request easy to review for us. And, please read
the *[How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/devel/faster_reviews.md)* guide;
it has lots of useful tips for any project you may want to contribute.
Some of the key points:
Please try to make your pull request easy to review for us. Please read the "[How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/devel/faster_reviews.md)" guide, it has lots of useful tips for any project you may want to contribute. Some of the key points:
* Make small pull requests. The smaller, the faster to review and the
more likely it will be merged soon.
* Don't make changes unrelated to your PR. Maybe there are typos on
some comments, maybe refactoring would be welcome on a function... but
if that is not related to your PR, please make *another* PR for that.
* Split big pull requests into multiple small ones. An incremental change
will be faster to review than a huge PR.
* Make small pull requests. The smaller, the faster to review and the more likely it will be merged soon.
* Don't make changes unrelated to your PR. Maybe there are typos on some comments, maybe refactoring would be welcome on a function... but if that is not related to your PR, please make *another* PR for that.
* Split big pull requests into multiple small ones. An incremental change will be faster to review than a huge PR.
## Styleguide
@ -141,86 +80,37 @@ import (
)
```
## Sign-off your work
## Sign your work
The sign-off is a simple line at the end of the explanation for the
patch. Your signature certifies that you wrote the patch or otherwise
have the right to pass it on as an open-source patch. The rules are
pretty simple: If you can certify [DCO](DCO), then you just add a line
to every git commit message:
The sign-off is a simple line at the end of the explanation for the patch. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: If you can certify [DCO](DCO), then you just add a line to every git commit message:
```
Signed-off-by: Joe Smith <joe.smith@email.com>
```
Please use your real name; we really dislike pseudonyms or anonymous
contributions. We are in the open-source world without secrets. If you
set your `user.name` and `user.email` git configs, you can sign-off your
commit automatically with `git commit -s`.
Please use your real name, we really dislike pseudonyms or anonymous contributions. We are in the open-source world without secrets. If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with `git commit -s`.
## Release Cycle
We adopted a release schedule to streamline the process of working
on, finishing, and issuing releases. The overall goal is to make a
minor release every two months, which breaks down into one month of
general development followed by one month of testing and polishing
known as the release freeze. All the feature pull requests should be
merged in the first month of one release period. And, during the frozen
period, a corresponding release branch is open for fixes backported from
master. Release candidates are made during this period for user testing to
obtain a final version that is maintained in this branch. A release is
maintained by issuing patch releases to only correct critical problems
such as crashes or security issues.
We adopted a release schedule to streamline the process of working on, finishing, and issuing releases. The overall goal is to make a major release every two months, which breaks down into one month of general development followed by one month of testing and polishing known as the release freeze. A release is maintained by issuing minor releases to only correct critical problems such as crashes or security issues. All the feature pull requests should be merged in the first month of one release period.
Major release cycles are bimonthly. They always begin on the 25th and end on
the 24th (i.e., the 25th of December to February 24th).
During a development cycle, we may also publish any necessary minor releases
for the previous version. For example, if the latest, published release is
v1.2, then minor changes for the previous release—e.g., v1.1.0 -> v1.1.1—are
still possible.
The current release cycle is aligned to start on December 25 to February 24, next is February 25 to April 24, and etc. On this cycle, we also maybe publish the previous release minor version. For example, the current release version is v1.1, but we maybe also publish v1.0.2. When we publish v1.2, then we will stop publish v1.0.3.
## Maintainers
To make sure every PR is checked, we have [team
maintainers](MAINTAINERS). Every PR **MUST** be reviewed by at least
two maintainers (or owners) before it can get merged. A maintainer
should be a contributor of Gitea (or Gogs) and contributed at least
4 accepted PRs. A contributor should apply as a maintainer in the
[Discord](https://discord.gg/NsatcWJ) #develop channel. The owners
or the team maintainers may invite the contributor. A maintainer
should spend some time on code reviews. If a maintainer has no
time to do that, they should apply to leave the maintainers team
and we will give them the honor of being a member of the [advisors
team](https://github.com/orgs/go-gitea/teams/advisors). Of course, if
an advisor has time to code review, we will gladly welcome them back
to the maintainers team. If a maintainer is inactive for more than 3
months and forgets to leave the maintainers team, the owners may move
him or her from the maintainers team to the advisors team.
To make sure every PR is checked, we have [team maintainers](MAINTAINERS). Every PR **MUST** be reviewed by at least two maintainers (or owners) before it can get merged. A maintainer should be a contributor of Gitea (or Gogs) and contributed at least 4 accepted PRs. A contributor should apply as a maintainer in the [Discord](https://discord.gg/NsatcWJ) #develop channel. The owners or the team maintainers may invite the contributor. A maintainer should spend some time on code reviews. If a maintainer has no time to do that, they should apply to leave the maintainers team and we will give them the honor of being a member of the [advisors team](https://github.com/orgs/go-gitea/teams/advisors). Of course, if an advisor has time to code review, we will gladly welcome them back to the maintainers team. If a maintainer is inactive for more than 3 months and forgets to leave the maintainers team, the owners may move him or her from the maintainers team to the advisors team.
## Owners
Since Gitea is a pure community organization without any company support,
to keep the development healthy we will elect three owners every year. All
contributors may vote to elect up to three candidates, one of which will
be the main owner, and the other two the assistant owners. When the new
owners have been elected, the old owners will give up ownership to the
newly elected owners. If an owner is unable to do so, the other owners
will assist in ceding ownership to the newly elected owners.
Since Gitea is a pure community organization without any company support, to keep the development healthy we will elect three owners every year. All contributors may vote to elect up to three candidates, one of which will be the main owner, and the other two the assistant owners. When the new owners have been elected, the old owners will give up ownership to the newly elected owners. If an owner is unable to do so, the other owners will assist in ceding ownership to the newly elected owners.
After the election, the new owners should proactively agree
with our [CONTRIBUTING](CONTRIBUTING.md) requirements in the
[Discord](https://discord.gg/NsatcWJ) #general channel. Below are the
words to speak:
After the election, the new owners should proactively agree with our [CONTRIBUTING](CONTRIBUTING.md) requirements in the [Discord](https://discord.gg/NsatcWJ) #general channel. Below are the words to speak:
```
I'm honored to having been elected an owner of Gitea, I agree with
[CONTRIBUTING](CONTRIBUTING.md). I will spend part of my time on Gitea
and lead the development of Gitea.
I'm honored to having been elected an owner of Gitea, I agree with [CONTRIBUTING](CONTRIBUTING.md). I will spend part of my time on Gitea and lead the development of Gitea.
```
To honor the past owners, here's the history of the owners and the time
they served:
To honor the past owners, here's the history of the owners and the time they served:
* 2016-11-04 ~ 2017-12-31
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
@ -229,16 +119,9 @@ they served:
## Versions
Gitea has the `master` branch as a tip branch and has version branches
such as `release/v0.9`. `release/v0.9` is a release branch and we will
tag `v0.9.0` for binary download. If `v0.9.0` has bugs, we will accept
pull requests on the `release/v0.9` branch and publish a `v0.9.1` tag,
after bringing the bug fix also to the master branch.
Gitea has the `master` branch as a tip branch and has version branches such as `v0.9`. `v0.9` is a release branch and we will tag `v0.9.0` for binary download. If `v0.9.0` has bugs, we will accept pull requests on the `v0.9` branch and publish a `v0.9.1` tag, after bringing the bug fix also to the master branch.
Since the `master` branch is a tip version, if you wish to use Gitea
in production, please download the latest release tag version. All the
branches will be protected via GitHub, all the PRs to every branch must
be reviewed by two maintainers and must pass the automatic tests.
Since the `master` branch is a tip version, if you wish to use Gitea in production, please download the latest release tag version. All the branches will be protected via GitHub, all the PRs to every branch must be reviewed by two maintainers and must pass the automatic tests.
## Copyright
@ -250,6 +133,4 @@ Code that you contribute should use the standard copyright header:
// license that can be found in the LICENSE file.
```
Files in the repository contain copyright from the year they are added
to the year they are last changed. If the copyright author is changed,
just paste the header below the old one.
Files in the repository contain copyright from the year they are added to the year they are last changed. If the copyright author is changed, just paste the header below the old one.

View File

@ -1,6 +1,5 @@
FROM alpine:3.6
LABEL maintainer="The Gitea Authors"
FROM alpine:3.5
MAINTAINER Thomas Boerger <thomas@webhippie.de>
EXPOSE 22 3000
@ -14,7 +13,6 @@ RUN apk --no-cache add \
s6 \
curl \
openssh \
gettext \
tzdata
RUN addgroup \
-S -g 1000 \

View File

@ -1,6 +1,4 @@
FROM multiarch/alpine:aarch64-v3.6
LABEL maintainer="The Gitea Authors"
FROM multiarch/alpine:aarch64-v3.5
EXPOSE 22 3000
@ -14,7 +12,6 @@ RUN apk --no-cache add \
s6 \
curl \
openssh \
gettext \
tzdata
RUN addgroup \
-S -g 1000 \

View File

@ -1,6 +1,5 @@
FROM multiarch/alpine:armhf-v3.6
LABEL maintainer="The Gitea Authors"
FROM multiarch/alpine:armhf-v3.5
MAINTAINER Thomas Boerger <thomas@webhippie.de>
EXPOSE 22 3000
@ -14,7 +13,6 @@ RUN apk --no-cache add \
s6 \
curl \
openssh \
gettext \
tzdata
RUN addgroup \
-S -g 1000 \

View File

@ -16,5 +16,3 @@ Patrick G <geek1011@outlook.com> (@geek1011)
Antoine Girard <sapk@sapk.fr> (@sapk)
Lauris Bukšis-Haberkorns <lauris@nix.lv> (@lafriks)
Jonas Östanbäck <jonas.ostanback@gmail.com> (@cez81)
David Schneiderbauer <dschneiderbauer@gmail.com> (@daviian)
Peter Žeby <morlinest@gmail.com> (@morlinest)

100
Makefile
View File

@ -15,6 +15,7 @@ else
endif
BINDATA := modules/{options,public,templates}/bindata.go
STYLESHEETS := $(wildcard public/less/index.less public/less/_*.less)
DOCKER_TAG := gitea/gitea:latest
GOFILES := $(shell find . -name "*.go" -type f ! -path "./vendor/*" ! -path "*/bindata.go")
GOFMT ?= gofmt -s
@ -31,15 +32,6 @@ TAGS ?=
TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'gitea-temp')
TEST_MYSQL_HOST ?= mysql:3306
TEST_MYSQL_DBNAME ?= testgitea
TEST_MYSQL_USERNAME ?= root
TEST_MYSQL_PASSWORD ?=
TEST_PGSQL_HOST ?= pgsql:5432
TEST_PGSQL_DBNAME ?= testgitea
TEST_PGSQL_USERNAME ?= postgres
TEST_PGSQL_PASSWORD ?= postgres
ifeq ($(OS), Windows_NT)
EXECUTABLE := gitea.exe
else
@ -62,14 +54,13 @@ all: build
.PHONY: clean
clean:
$(GO) clean -i ./...
rm -rf $(EXECUTABLE) $(DIST) $(BINDATA) \
integrations*.test \
integrations/gitea-integration-pgsql/ integrations/gitea-integration-mysql/ integrations/gitea-integration-sqlite/ \
integrations/indexers-mysql/ integrations/indexers-pgsql integrations/indexers-sqlite \
integrations/mysql.ini integrations/pgsql.ini
rm -rf $(EXECUTABLE) $(DIST) $(BINDATA) integrations*.test
required-gofmt-version:
@$(GO) version | grep -q '\(1.7\|1.8\)' || { echo "We require go version 1.7 or 1.8 to format code" >&2 && exit 1; }
.PHONY: fmt
fmt:
fmt: required-gofmt-version
$(GOFMT) -w $(GOFILES)
.PHONY: vet
@ -89,6 +80,8 @@ generate-swagger:
$(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \
fi
swagger generate spec -o ./public/swagger.v1.json
$(SED_INPLACE) "s;\".ref\": \"#/definitions/GPGKey\";\"type\": \"object\";g" ./public/swagger.v1.json
$(SED_INPLACE) "s;^ \".ref\": \"#/definitions/Repository\"; \"type\": \"object\";g" ./public/swagger.v1.json
.PHONY: errcheck
errcheck:
@ -119,7 +112,7 @@ misspell:
misspell -w -i unknwon $(GOFILES)
.PHONY: fmt-check
fmt-check:
fmt-check: required-gofmt-version
# get all go files and run go fmt on them
@diff=$$($(GOFMT) -d $(GOFILES)); \
if [ -n "$$diff" ]; then \
@ -129,21 +122,20 @@ fmt-check:
fi;
.PHONY: test
test:
test: fmt-check
$(GO) test $(PACKAGES)
.PHONY: coverage
coverage:
.PHONY: test-coverage
test-coverage: unit-test-coverage integration-test-coverage
@hash gocovmerge > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/wadey/gocovmerge; \
fi
echo "mode: set" > coverage.all
for PKG in $(PACKAGES); do\
egrep "$$PKG[^/]*\.go" integration.coverage.out > int.coverage.out;\
gocovmerge $$GOPATH/src/$$PKG/coverage.out int.coverage.out > pkg.coverage.out;\
grep -h -v "^mode:" pkg.coverage.out >> coverage.all;\
mv pkg.coverage.out $$GOPATH/src/$$PKG/coverage.out;\
rm int.coverage.out;\
touch $$GOPATH/src/$$PKG/coverage.out;\
egrep "$$PKG[^/]*\.go" integration.coverage.out > int.coverage.out;\
gocovmerge $$GOPATH/src/$$PKG/coverage.out int.coverage.out > pkg.coverage.out;\
mv pkg.coverage.out $$GOPATH/src/$$PKG/coverage.out;\
rm int.coverage.out;\
done;
.PHONY: unit-test-coverage
@ -167,48 +159,34 @@ test-vendor:
test-sqlite: integrations.sqlite.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test
generate-ini:
sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \
-e 's|{{TEST_MYSQL_DBNAME}}|${TEST_MYSQL_DBNAME}|g' \
-e 's|{{TEST_MYSQL_USERNAME}}|${TEST_MYSQL_USERNAME}|g' \
-e 's|{{TEST_MYSQL_PASSWORD}}|${TEST_MYSQL_PASSWORD}|g' \
integrations/mysql.ini.tmpl > integrations/mysql.ini
sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \
-e 's|{{TEST_PGSQL_DBNAME}}|${TEST_PGSQL_DBNAME}|g' \
-e 's|{{TEST_PGSQL_USERNAME}}|${TEST_PGSQL_USERNAME}|g' \
-e 's|{{TEST_PGSQL_PASSWORD}}|${TEST_PGSQL_PASSWORD}|g' \
integrations/pgsql.ini.tmpl > integrations/pgsql.ini
.PHONY: test-mysql
test-mysql: integrations.mysql.test generate-ini
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test
test-mysql: integrations.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.test
.PHONY: test-pgsql
test-pgsql: integrations.pgsql.test generate-ini
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test
test-pgsql: integrations.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.test
.PHONY: bench-sqlite
bench-sqlite: integrations.sqlite.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test -test.bench .
.PHONY: bench-mysql
bench-mysql: integrations.mysql.test generate-ini
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test -test.bench .
bench-mysql: integrations.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.test -test.bench .
.PHONY: bench-pgsql
bench-pgsql: integrations.pgsql.test generate-ini
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test -test.bench .
bench-pgsql: integrations.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/pgsql.ini ./integrations.test -test.bench .
.PHONY: integration-test-coverage
integration-test-coverage: integrations.cover.test generate-ini
integration-test-coverage: integrations.cover.test
GITEA_ROOT=${CURDIR} GITEA_CONF=integrations/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out
integrations.mysql.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations -o integrations.mysql.test
integrations.pgsql.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations -o integrations.pgsql.test
integrations.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations
integrations.sqlite.test: $(SOURCES)
$(GO) test -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags 'sqlite'
@ -287,25 +265,31 @@ public/js/index.js: $(JAVASCRIPTS)
cat $< >| $@
.PHONY: stylesheets-check
stylesheets-check: generate-stylesheets
stylesheets-check: stylesheets
@diff=$$(git diff public/css/index.css); \
if [ -n "$$diff" ]; then \
echo "Please run 'make generate-stylesheets' and commit the result:"; \
echo "Please run 'make stylesheets' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;
.PHONY: generate-stylesheets
generate-stylesheets:
node_modules/.bin/lessc --no-ie-compat --clean-css public/less/index.less public/css/index.css
.PHONY: stylesheets
stylesheets: public/css/index.css
.IGNORE: public/css/index.css
public/css/index.css: $(STYLESHEETS)
@which lessc > /dev/null; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/kib357/less-go/lessc; \
fi
lessc -i $< -o $@
.PHONY: swagger-ui
swagger-ui:
rm -Rf public/vendor/assets/swagger-ui
git clone --depth=10 -b v3.3.2 --single-branch https://github.com/swagger-api/swagger-ui.git $(TMPDIR)/swagger-ui
git clone --depth=10 -b v3.0.7 --single-branch https://github.com/swagger-api/swagger-ui.git $(TMPDIR)/swagger-ui
mv $(TMPDIR)/swagger-ui/dist public/vendor/assets/swagger-ui
rm -Rf $(TMPDIR)/swagger-ui
$(SED_INPLACE) "s;http://petstore.swagger.io/v2/swagger.json;../../../swagger.v1.json;g" public/vendor/assets/swagger-ui/index.html
$(SED_INPLACE) "s;http://petstore.swagger.io/v2/swagger.json;../../swagger.v1.json;g" public/assets/swagger-ui/index.html
.PHONY: update-translations
update-translations:

View File

@ -6,45 +6,30 @@
[![Join the Discord chat at https://discord.gg/NsatcWJ](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/NsatcWJ)
[![Join the Matrix chat at https://matrix.to/#/#gitea:matrix.org](https://img.shields.io/badge/matrix-%23gitea%3Amatrix.org-7bc9a4.svg)](https://matrix.to/#/#gitea:matrix.org)
[![](https://images.microbadger.com/badges/image/gitea/gitea.svg)](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
[![codecov](https://codecov.io/gh/go-gitea/gitea/branch/master/graph/badge.svg)](https://codecov.io/gh/go-gitea/gitea)
[![Coverage Status](https://coverage.gitea.io/badges/go-gitea/gitea/coverage.svg)](https://coverage.gitea.io/go-gitea/gitea)
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea)
[![GoDoc](https://godoc.org/code.gitea.io/gitea?status.svg)](https://godoc.org/code.gitea.io/gitea)
[![Release](https://github-release-version.herokuapp.com/github/go-gitea/gitea/release.svg?style=flat)](https://github.com/go-gitea/gitea/releases/latest)
| | | |
|:---:|:---:|:---:|
|![Dashboard](https://image.ibb.co/dms6DG/1.png)|![Repository](https://image.ibb.co/m6MSLw/2.png)|![Commits History](https://image.ibb.co/cjrSLw/3.png)|
|![Branches](https://image.ibb.co/e6vbDG/4.png)|![Issues](https://image.ibb.co/bJTJSb/5.png)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)|
|![Releases](https://image.ibb.co/cUzgfw/7.png)|![Activity](https://image.ibb.co/eZgGDG/8.png)|![Wiki](https://image.ibb.co/dYV9YG/9.png)|
|![Diff](https://image.ibb.co/ewA9YG/10.png)|![Organization](https://image.ibb.co/ceOwDG/11.png)|![Profile](https://image.ibb.co/c44Q7b/12.png)|
|![Dashboard](https://i.imgur.com/3iEQsux.jpg)|![Repository](https://i.imgur.com/glqFnj8.jpg)|![Commits History](https://i.imgur.com/ad1FEpi.jpg)|
|![Profile](https://i.imgur.com/q81EcGa.jpg)|![Admin Dashboard](https://i.imgur.com/L2CQeN0.jpg)|![Diff](https://i.imgur.com/cNuvMum.jpg)|
|![Issues](https://i.imgur.com/xCYRqaF.jpg)|![Releases](https://i.imgur.com/ILpRBCe.jpg)|![Organization](https://i.imgur.com/0BHnrcL.jpg)|
## Purpose
The goal of this project is to make the easiest, fastest, and most
painless way of setting up a self-hosted Git service.
Using Go, this can be done with an independent binary distribution across
**all platforms** which Go supports, including Linux, macOS, and Windows
on x86, amd64, ARM and PowerPC architectures.
Want to try it before doing anything else?
Do it [with the online demo](https://try.gitea.io/)!
This project has been
[forked](https://blog.gitea.io/2016/12/welcome-to-gitea/) from
[Gogs](https://gogs.io) since 2016.11 but changed a lot.
The goal of this project is to make the easiest, fastest, and most painless way of setting up a self-hosted Git service. Using Go, this can be done with an independent binary distribution across **all platforms** which Go supports, including Linux, macOS, and Windows on x86, amd64, ARM and PowerPC architectures. Want to try it before doing anything else? Do it [with the online demo](https://try.gitea.io/)! This project has been [forked](https://blog.gitea.io/2016/12/welcome-to-gitea/) from [Gogs](https://gogs.io).
## Notes
1. **YOU MUST READ THE [CONTRIBUTORS GUIDE](CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST.**
2. If you have found a vulnerability in the project, please write privately to **security@gitea.io**. Thanks!
2. If you found a vulnerability in the project, please write privately to **security@gitea.io**. Thanks!
3. If you're interested in using our APIs, we have experimental support with [documentation](https://godoc.org/code.gitea.io/sdk/gitea).
## Docs
For more information and instructions about how to install Gitea, please look
at our [documentation](https://docs.gitea.io/en-us/). If you have questions
that are not covered by the documentation, you can get in contact with us on
our [Discord server](https://discord.gg/NsatcWJ),
[Matrix room](https://matrix.to/#/#gitea:matrix.org),
or [forum](https://discourse.gitea.io/)!
For more information and instructions about how to install Gitea please look at our [documentation](https://docs.gitea.io/en-us/). If you cannot find some specific information, then head over to our [Discord server](https://discord.gg/NsatcWJ) or [Matrix room](https://matrix.to/#/#gitea:matrix.org) to chat with us or use the [forum](https://discourse.gitea.io/).
## Contributing
@ -58,6 +43,4 @@ Fork -> Patch -> Push -> Pull Request
## License
This project is licensed under the MIT License.
See the [LICENSE](https://github.com/go-gitea/gitea/blob/master/LICENSE) file
for the full license text.
This project is licensed under the MIT License. See the [LICENSE](https://github.com/go-gitea/gitea/blob/master/LICENSE) file for the full license text.

View File

@ -12,10 +12,9 @@
| | | |
|:---:|:---:|:---:|
|![Dashboard](https://image.ibb.co/dms6DG/1.png)|![Repository](https://image.ibb.co/m6MSLw/2.png)|![Commits History](https://image.ibb.co/cjrSLw/3.png)|
|![Branches](https://image.ibb.co/e6vbDG/4.png)|![Issues](https://image.ibb.co/bJTJSb/5.png)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)|
|![Releases](https://image.ibb.co/cUzgfw/7.png)|![Activity](https://image.ibb.co/eZgGDG/8.png)|![Wiki](https://image.ibb.co/dYV9YG/9.png)|
|![Diff](https://image.ibb.co/ewA9YG/10.png)|![Organization](https://image.ibb.co/ceOwDG/11.png)|![Profile](https://image.ibb.co/c44Q7b/12.png)|
|![Dashboard](https://i.imgur.com/3iEQsux.jpg)|![Repository](https://i.imgur.com/glqFnj8.jpg)|![Commits History](https://i.imgur.com/ad1FEpi.jpg)|
|![Profile](https://i.imgur.com/q81EcGa.jpg)|![Admin Dashboard](https://i.imgur.com/L2CQeN0.jpg)|![Diff](https://i.imgur.com/cNuvMum.jpg)|
|![Issues](https://i.imgur.com/xCYRqaF.jpg)|![Releases](https://i.imgur.com/ILpRBCe.jpg)|![Organization](https://i.imgur.com/0BHnrcL.jpg)|
## 目标

View File

@ -126,7 +126,10 @@ func runDump(ctx *cli.Context) error {
var sessionAbsPath string
if setting.SessionConfig.Provider == "file" {
sessionAbsPath = setting.SessionConfig.ProviderConfig
if len(setting.SessionConfig.ProviderConfig) == 0 {
setting.SessionConfig.ProviderConfig = "data/sessions"
}
sessionAbsPath, _ = filepath.Abs(setting.SessionConfig.ProviderConfig)
}
if err := zipAddDirectoryExclude(z, "data", setting.AppDataPath, sessionAbsPath); err != nil {
log.Fatalf("Failed to include data directory: %v", err)

View File

@ -84,10 +84,9 @@ func runHookPreReceive(c *cli.Context) error {
// the environment setted on serv command
repoID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchRepoID), 10, 64)
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
username := os.Getenv(models.EnvRepoUsername)
reponame := os.Getenv(models.EnvRepoName)
userIDStr := os.Getenv(models.EnvPusherID)
repoPath := models.RepoPath(username, reponame)
//username := os.Getenv(models.EnvRepoUsername)
//reponame := os.Getenv(models.EnvRepoName)
//repoPath := models.RepoPath(username, reponame)
buf := bytes.NewBuffer(nil)
scanner := bufio.NewScanner(os.Stdin)
@ -105,37 +104,36 @@ func runHookPreReceive(c *cli.Context) error {
continue
}
oldCommitID := string(fields[0])
//oldCommitID := string(fields[0])
newCommitID := string(fields[1])
refFullName := string(fields[2])
// FIXME: when we add feature to protected branch to deny force push, then uncomment below
/*var isForce bool
// detect force push
if git.EmptySHA != oldCommitID {
output, err := git.NewCommand("rev-list", oldCommitID, "^"+newCommitID).RunInDir(repoPath)
if err != nil {
fail("Internal error", "Fail to detect force push: %v", err)
} else if len(output) > 0 {
isForce = true
}
}*/
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
protectBranch, err := private.GetProtectedBranchBy(repoID, branchName)
if err != nil {
log.GitLogger.Fatal(2, "retrieve protected branches information failed")
}
if protectBranch != nil && protectBranch.IsProtected() {
// detect force push
if git.EmptySHA != oldCommitID {
output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).RunInDir(repoPath)
if err != nil {
fail("Internal error", "Fail to detect force push: %v", err)
} else if len(output) > 0 {
fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
}
}
// check and deletion
if newCommitID == git.EmptySHA {
fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "")
} else {
userID, _ := strconv.ParseInt(userIDStr, 10, 64)
canPush, err := private.CanUserPush(protectBranch.ID, userID)
if err != nil {
fail("Internal error", "Fail to detect user can push: %v", err)
} else if !canPush {
if protectBranch != nil {
if !protectBranch.CanPush {
// check and deletion
if newCommitID == git.EmptySHA {
fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "")
} else {
fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "")
//fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
}
}
}

View File

@ -50,9 +50,9 @@ func setup(logPath string) error {
models.LoadConfigs()
if setting.UseSQLite3 || setting.UseTiDB {
workPath := setting.AppWorkPath
if err := os.Chdir(workPath); err != nil {
log.GitLogger.Fatal(4, "Failed to change directory %s: %v", workPath, err)
workDir, _ := setting.WorkDir()
if err := os.Chdir(workDir); err != nil {
log.GitLogger.Fatal(4, "Failed to change directory %s: %v", workDir, err)
}
}

View File

@ -14,7 +14,6 @@ import (
"strings"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup/external"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/routes"
@ -60,8 +59,6 @@ func runWeb(ctx *cli.Context) error {
routers.GlobalInit()
external.RegisterParsers()
m := routes.NewMacaron()
routes.RegisterRoutes(m)

53
conf/app.ini vendored
View File

@ -23,8 +23,6 @@ PULL_REQUEST_QUEUE_LENGTH = 1000
PREFERRED_LICENSES = Apache License 2.0,MIT License
; Disable ability to interact with repositories by HTTP protocol
DISABLE_HTTP_GIT = false
; Force ssh:// clone url instead of scp-style uri when default SSH port is used
USE_COMPAT_SSH_URI = false
[repository.editor]
; List of file extensions that should have line wraps in the CodeMirror editor
@ -113,8 +111,6 @@ LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/
DISABLE_SSH = false
; Whether use builtin SSH server or not.
START_SSH_SERVER = false
; Username to use for builtin SSH server. If blank, then it is the value of RUN_USER.
BUILTIN_SSH_SERVER_USER =
; Domain name to be exposed in clone URL
SSH_DOMAIN = %(DOMAIN)s
; Network interface builtin SSH server listens on
@ -125,15 +121,6 @@ SSH_PORT = 22
SSH_LISTEN_PORT = %(SSH_PORT)s
; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
SSH_ROOT_PATH =
; For built-in SSH server only, choose the ciphers to support for SSH connections,
; for system SSH this setting has no effect
SSH_SERVER_CIPHERS = aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128
; For built-in SSH server only, choose the key exchange algorithms to support for SSH connections,
; for system SSH this setting has no effect
SSH_SERVER_KEY_EXCHANGES = diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org
; For built-in SSH server only, choose the MACs to support for SSH connections,
; for system SSH this setting has no effect
SSH_SERVER_MACS = hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96
; Directory to create temporary files when test public key using ssh-keygen,
; default is system temporary directory.
SSH_KEY_TEST_PATH =
@ -193,16 +180,10 @@ SSL_MODE = disable
PATH = data/gitea.db
; For "sqlite3" only. Query timeout
SQLITE_TIMEOUT = 500
; For iterate buffer, default is 50
ITERATE_BUFFER_SIZE = 50
[indexer]
ISSUE_INDEXER_PATH = indexers/issues.bleve
; repo indexer by default disabled, since it uses a lot of disk space
REPO_INDEXER_ENABLED = false
REPO_INDEXER_PATH = indexers/repos.bleve
UPDATE_BUFFER_LEN = 20
MAX_FILE_SIZE = 1048576
[admin]
; Disable regular (non-admin) users to create organizations
@ -223,8 +204,6 @@ REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
MIN_PASSWORD_LENGTH = 6
; True when users are allowed to import local server paths
IMPORT_LOCAL_PATHS = false
; Prevent all users (including admin) from creating custom git hooks
DISABLE_GIT_HOOKS = false
[openid]
;
@ -255,7 +234,7 @@ ENABLE_OPENID_SIGNIN = true
; Example value: trusted.domain.org trusted.domain.net
WHITELISTED_URIS =
; Forbidden URI patterns (POSIX regexp).
; Space separated.
; Space sepaated.
; Only used if WHITELISTED_URIS is blank.
; Example value: loadaverage.org/badguy stackexchange.com/.*spammer
BLACKLISTED_URIS =
@ -284,12 +263,6 @@ DEFAULT_KEEP_EMAIL_PRIVATE = false
; Default value for AllowCreateOrganization
; New user will have rights set to create organizations depending on this setting
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
; Default value for EnableTimetracking
; Repositories will use timetracking by default depending on this setting
DEFAULT_ENABLE_TIMETRACKING = true
; Default value for AllowOnlyContributorsToTrackTime
; Only users with write permissions could track time if this is true
DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME = true
; Default value for the domain part of the user's email address in the git log
; if he has set KeepEmailPrivate true. The user's email replaced with a
; concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
@ -335,10 +308,8 @@ PASSWD =
SEND_AS_PLAIN_TEXT = false
; Enable sendmail (override SMTP)
USE_SENDMAIL = false
; Specify an alternative sendmail binary
; Specifiy an alternative sendmail binary
SENDMAIL_PATH = sendmail
; Specify any extra sendmail arguments
SENDMAIL_ARGS =
[cache]
; Either "memory", "redis", or "memcache", default is "memory"
@ -349,9 +320,6 @@ INTERVAL = 60
; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
; memcache: `127.0.0.1:11211`
HOST =
; Time to keep items in cache if not used, default is 16 hours.
; Setting it to 0 disables caching
ITEM_TTL = 16h
[session]
; Either "memory", "file", or "redis", default is "memory"
@ -382,7 +350,7 @@ GRAVATAR_SOURCE = gravatar
DISABLE_GRAVATAR = false
; Federated avatar lookup uses DNS to discover avatar associated
; with emails, see https://www.libravatar.org
; This value will be forced to be false in offline mode or Gravatar is disabled.
; This value will be forced to be false in offline mode or Gravatar is disbaled.
ENABLE_FEDERATED_AVATAR = false
[attachment]
@ -398,7 +366,7 @@ MAX_SIZE = 4
MAX_FILES = 5
[time]
; Specifies the format for fully outputted dates. Defaults to RFC1123
; Specifies the format for fully outputed dates. Defaults to RFC1123
; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano
; For more information about the format see http://golang.org/pkg/time/#pkg-constants
FORMAT =
@ -496,7 +464,7 @@ OLDER_THAN = 24h
; Synchronize external user data (only LDAP user synchronization is supported)
[cron.sync_external_users]
; Synchronize external user data when starting server (default false)
; Syncronize external user data when starting server (default false)
RUN_AT_START = false
; Interval as a duration between each synchronization (default every 24h)
SCHEDULE = @every 24h
@ -537,7 +505,7 @@ MAX_RESPONSE_ITEMS = 50
[i18n]
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,polski,български,Italiano,Suomalainen,Türkçe,čeština,Српски,Svenska,한국어
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen,Türkçe,čeština,Српски,Svenska,한국어
; Used for datetimepicker
[i18n.datelang]
@ -573,12 +541,3 @@ SHOW_FOOTER_BRANDING = false
SHOW_FOOTER_VERSION = true
; Show time of template execution in the footer
SHOW_FOOTER_TEMPLATE_LOAD_TIME = true
[markup.asciidoc]
ENABLED = false
; List of file extensions that should be rendered by an external command
FILE_EXTENSIONS = .adoc,.asciidoc
; External command to render all matching extensions
RENDER_COMMAND = "asciidoc --out-file=- -"
; Input is not a standard input but a file
IS_INPUT_FILE = false

View File

@ -1,12 +0,0 @@
# IDE and code editor configuration
## Table of Contents
- [IDE and code editor configuration](#ide-and-code-editor-configuration)
- [Microsoft Visual Studio Code](#microsoft-visual-studio-code)
## Microsoft Visual Studio Code
Download Microsoft Visual Studio Code at https://code.visualstudio.com/ and follow instructions at https://code.visualstudio.com/docs/languages/go to setup Go extension for it.
Create new directory `.vscode` in Gitea root folder and copy contents of folder [contrib/ide/vscode](vscode/) to it. You can now use `Ctrl`+`Shift`+`B` to build gitea executable and `F5` to run it in debug mode.
Supported on Debian, Ubuntu, Red Hat, Fedora, SUSE Linux, MacOS and Microsoft Windows.

View File

@ -1,31 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "go",
"request": "launch",
"mode": "debug",
"buildFlags": "",
"port": 2345,
"host": "127.0.0.1",
"program": "${workspaceRoot}/main.go",
"env": {},
"args": ["web"],
"showLog": true
},
{
"name": "Launch (with SQLite3)",
"type": "go",
"request": "launch",
"mode": "debug",
"buildFlags": "-tags=\"sqlite\"",
"port": 2345,
"host": "127.0.0.1",
"program": "${workspaceRoot}/main.go",
"env": {},
"args": ["web"],
"showLog": true
}
]
}

View File

@ -1,51 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"taskName": "Build",
"type": "shell",
"command": "go",
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"args": ["build"],
"linux": {
"args": [ "-o", "gitea", "${workspaceRoot}/main.go" ]
},
"osx": {
"args": [ "-o", "gitea", "${workspaceRoot}/main.go" ]
},
"windows": {
"args": [ "-o", "gitea.exe", "\"${workspaceRoot}\\main.go\""]
},
"problemMatcher": ["$go"]
},
{
"taskName": "Build (with SQLite3)",
"type": "shell",
"command": "go",
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"args": ["build", "-tags=\"sqlite\""],
"linux": {
"args": ["-o", "gitea", "${workspaceRoot}/main.go"]
},
"osx": {
"args": ["-o", "gitea", "${workspaceRoot}/main.go"]
},
"windows": {
"args": ["-o", "gitea.exe", "\"${workspaceRoot}\\main.go\""]
},
"problemMatcher": ["$go"]
}
]
}

View File

@ -0,0 +1,25 @@
@ECHO off
:: This script relies on nssm.exe to work.
:: Please, download it and make it available on the system path,
:: or copy it to the gogs path.
:: https://nssm.cc/download
:: This script itself should run in the gogs path, too.
:: In case of startup failure, please read carefully the log file.
:: Make sure Gitea work running manually with "gitea web" before running
:: this script.
:: And, please, read carefully the installation docs first:
:: https://gogs.io/docs/installation
:: To unistall the service, run "nssm remove gogs" and restart Windows.
:: Set the folder where you extracted Gitea. Omit the last slash.
SET gogspath=C:\gogs
nssm install gogs "%gogspath%\gogs.exe"
nssm set gogs AppParameters "web"
nssm set gogs Description "A painless self-hosted Git service."
nssm set gogs DisplayName "Gitea - Git with a cup of tea"
nssm set gogs Start SERVICE_DELAYED_AUTO_START
nssm set gogs AppStdout "%gogspath%\gogs.log"
nssm start gogs
pause

View File

@ -12,29 +12,7 @@ fi
if [ ! -f /data/gitea/conf/app.ini ]; then
mkdir -p /data/gitea/conf
# Set INSTALL_LOCK to true only if SECRET_KEY is not empty and
# INSTALL_LOCK is empty
if [ -n "$SECRET_KEY" ] && [ -z "$INSTALL_LOCK" ]; then
INSTALL_LOCK=true
fi
# Substitude the environment variables in the template
APP_NAME=${APP_NAME:-"Gitea: Git with a cup of tea"} \
RUN_MODE=${RUN_MODE:-"dev"} \
SSH_DOMAIN=${SSH_DOMAIN:-"localhost"} \
HTTP_PORT=${HTTP_PORT:-"3000"} \
ROOT_URL=${ROOT_URL:-""} \
DISABLE_SSH=${DISABLE_SSH:-"false"} \
SSH_PORT=${SSH_PORT:-"22"} \
DB_TYPE=${DB_TYPE:-"sqlite3"} \
DB_HOST=${DB_HOST:-"localhost:3306"} \
DB_NAME=${DB_NAME:-"gitea"} \
DB_USER=${DB_USER:-"root"} \
DB_PASSWD=${DB_PASSWD:-""} \
INSTALL_LOCK=${INSTALL_LOCK:-"false"} \
SECRET_KEY=${SECRET_KEY:-""} \
envsubst < /etc/templates/app.ini > /data/gitea/conf/app.ini
cp /etc/templates/app.ini /data/gitea/conf/app.ini
fi
chown -R git:git /data/gitea /app/gitea /data/git

View File

@ -1,6 +1,3 @@
APP_NAME = $APP_NAME
RUN_MODE = $RUN_MODE
[repository]
ROOT = /data/git/repositories
@ -9,19 +6,10 @@ TEMP_PATH = /data/gitea/uploads
[server]
APP_DATA_PATH = /data/gitea
SSH_DOMAIN = $SSH_DOMAIN
HTTP_PORT = $HTTP_PORT
ROOT_URL = $ROOT_URL
DISABLE_SSH = $DISABLE_SSH
SSH_PORT = $SSH_PORT
[database]
DB_TYPE = sqlite3
PATH = /data/gitea/gitea.db
DB_TYPE = $DB_TYPE
HOST = $DB_HOST
NAME = $DB_NAME
USER = $DB_USER
PASSWD = $DB_PASSWD
[session]
PROVIDER_CONFIG = /data/gitea/sessions
@ -34,7 +22,3 @@ PATH = /data/gitea/attachments
[log]
ROOT_PATH = /data/gitea/log
[security]
INSTALL_LOCK = $INSTALL_LOCK
SECRET_KEY = $SECRET_KEY

View File

@ -1,16 +1,5 @@
#!/bin/sh
## Change GID for USER?
if [ -n "${USER_GID}" ] && [ "${USER_GID}" != "`id -g ${USER}`" ]; then
sed -i -e "s/^${USER}:\([^:]*\):[0-9]*/${USER}:\1:${USER_GID}/" /etc/group
sed -i -e "s/^${USER}:\([^:]*\):\([0-9]*\):[0-9]*/${USER}:\1:\2:${USER_GID}/" /etc/passwd
fi
## Change UID for USER?
if [ -n "${USER_UID}" ] && [ "${USER_UID}" != "`id -u ${USER}`" ]; then
sed -i -e "s/^${USER}:\([^:]*\):[0-9]*:\([0-9]*\)/${USER}:\1:${USER_UID}:\2/" /etc/passwd
fi
for FOLDER in /data/gitea/conf /data/gitea/log /data/git /data/ssh; do
mkdir -p ${FOLDER}
done

View File

@ -1,260 +0,0 @@
// Copyright 2017 The Gogs 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 (
"net/http"
"strconv"
"testing"
"github.com/stretchr/testify/assert"
api "code.gitea.io/sdk/gitea"
)
func TestGPGKeys(t *testing.T) {
prepareTestEnv(t)
session := loginUser(t, "user2")
tt := []struct {
name string
reqBuilder func(testing.TB, *http.Request, int) *TestResponse
results []int
}{
{name: "NoLogin", reqBuilder: MakeRequest,
results: []int{http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized},
},
{name: "LoggedAsUser2", reqBuilder: session.MakeRequest,
results: []int{http.StatusOK, http.StatusOK, http.StatusNotFound, http.StatusNoContent, http.StatusInternalServerError, http.StatusInternalServerError, http.StatusCreated, http.StatusCreated}},
}
for _, tc := range tt {
//Basic test on result code
t.Run(tc.name, func(t *testing.T) {
t.Run("ViewOwnGPGKeys", func(t *testing.T) {
testViewOwnGPGKeys(t, tc.reqBuilder, tc.results[0])
})
t.Run("ViewGPGKeys", func(t *testing.T) {
testViewGPGKeys(t, tc.reqBuilder, tc.results[1])
})
t.Run("GetGPGKey", func(t *testing.T) {
testGetGPGKey(t, tc.reqBuilder, tc.results[2])
})
t.Run("DeleteGPGKey", func(t *testing.T) {
testDeleteGPGKey(t, tc.reqBuilder, tc.results[3])
})
t.Run("CreateInvalidGPGKey", func(t *testing.T) {
testCreateInvalidGPGKey(t, tc.reqBuilder, tc.results[4])
})
t.Run("CreateNoneRegistredEmailGPGKey", func(t *testing.T) {
testCreateNoneRegistredEmailGPGKey(t, tc.reqBuilder, tc.results[5])
})
t.Run("CreateValidGPGKey", func(t *testing.T) {
testCreateValidGPGKey(t, tc.reqBuilder, tc.results[6])
})
t.Run("CreateValidSecondaryEmailGPGKey", func(t *testing.T) {
testCreateValidSecondaryEmailGPGKey(t, tc.reqBuilder, tc.results[7])
})
})
}
//Check state after basic add
t.Run("CheckState", func(t *testing.T) {
var keys []*api.GPGKey
req := NewRequest(t, "GET", "/api/v1/user/gpg_keys") //GET all keys
resp := session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &keys)
primaryKey1 := keys[0] //Primary key 1
assert.EqualValues(t, "38EA3BCED732982C", primaryKey1.KeyID)
assert.EqualValues(t, 1, len(primaryKey1.Emails))
assert.EqualValues(t, "user2@example.com", primaryKey1.Emails[0].Email)
assert.EqualValues(t, true, primaryKey1.Emails[0].Verified)
subKey := primaryKey1.SubsKey[0] //Subkey of 38EA3BCED732982C
assert.EqualValues(t, "70D7C694D17D03AD", subKey.KeyID)
assert.EqualValues(t, 0, len(subKey.Emails))
primaryKey2 := keys[1] //Primary key 2
assert.EqualValues(t, "FABF39739FE1E927", primaryKey2.KeyID)
assert.EqualValues(t, 1, len(primaryKey2.Emails))
assert.EqualValues(t, "user21@example.com", primaryKey2.Emails[0].Email)
assert.EqualValues(t, false, primaryKey2.Emails[0].Verified)
var key api.GPGKey
req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey1.ID, 10)) //Primary key 1
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &key)
assert.EqualValues(t, "38EA3BCED732982C", key.KeyID)
assert.EqualValues(t, 1, len(key.Emails))
assert.EqualValues(t, "user2@example.com", key.Emails[0].Email)
assert.EqualValues(t, true, key.Emails[0].Verified)
req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(subKey.ID, 10)) //Subkey of 38EA3BCED732982C
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &key)
assert.EqualValues(t, "70D7C694D17D03AD", key.KeyID)
assert.EqualValues(t, 0, len(key.Emails))
req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey2.ID, 10)) //Primary key 2
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &key)
assert.EqualValues(t, "FABF39739FE1E927", key.KeyID)
assert.EqualValues(t, 1, len(key.Emails))
assert.EqualValues(t, "user21@example.com", key.Emails[0].Email)
assert.EqualValues(t, false, key.Emails[0].Verified)
})
//Check state after basic add
t.Run("CheckCommits", func(t *testing.T) {
t.Run("NotSigned", func(t *testing.T) {
var branch api.Branch
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/not-signed")
resp := session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &branch)
assert.EqualValues(t, false, branch.Commit.Verification.Verified)
})
t.Run("SignedWithNotValidatedEmail", func(t *testing.T) {
var branch api.Branch
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign-not-yet-validated")
resp := session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &branch)
assert.EqualValues(t, false, branch.Commit.Verification.Verified)
})
t.Run("SignedWithValidEmail", func(t *testing.T) {
var branch api.Branch
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign")
resp := session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &branch)
assert.EqualValues(t, true, branch.Commit.Verification.Verified)
})
})
}
func testViewOwnGPGKeys(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
req := NewRequest(t, "GET", "/api/v1/user/gpg_keys")
reqBuilder(t, req, expected)
}
func testViewGPGKeys(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
req := NewRequest(t, "GET", "/api/v1/users/user2/gpg_keys")
reqBuilder(t, req, expected)
}
func testGetGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
req := NewRequest(t, "GET", "/api/v1/user/gpg_keys/1")
reqBuilder(t, req, expected)
}
func testDeleteGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
req := NewRequest(t, "DELETE", "/api/v1/user/gpg_keys/1")
reqBuilder(t, req, expected)
}
func testCreateGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int, publicKey string) {
req := NewRequestWithJSON(t, "POST", "/api/v1/user/gpg_keys", api.CreateGPGKeyOption{
ArmoredKey: publicKey,
})
reqBuilder(t, req, expected)
}
func testCreateInvalidGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
testCreateGPGKey(t, reqBuilder, expected, "invalid_key")
}
func testCreateNoneRegistredEmailGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
testCreateGPGKey(t, reqBuilder, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFmGUygBCACjCNbKvMGgp0fd5vyFW9olE1CLCSyyF9gQN2hSuzmZLuAZF2Kh
dCMCG2T1UwzUB/yWUFWJ2BtCwSjuaRv+cGohqEy6bhEBV90peGA33lHfjx7wP25O
7moAphDOTZtDj1AZfCh/PTcJut8Lc0eRDMhNyp/bYtO7SHNT1Hr6rrCV/xEtSAvR
3b148/tmIBiSadaLwc558KU3ucjnW5RVGins3AjBZ+TuT4XXVH/oeLSeXPSJ5rt1
rHwaseslMqZ4AbvwFLx5qn1OC9rEQv/F548QsA8m0IntLjoPon+6wcubA9Gra21c
Fp6aRYl9x7fiqXDLg8i3s2nKdV7+e6as6Tp9ABEBAAG0FG5vdGtub3duQGV4YW1w
bGUuY29tiQEcBBABAgAGBQJZhlMoAAoJEC8+pvYULDtte/wH/2JNrhmHwDY+hMj0
batIK4HICnkKxjIgbha80P2Ao08NkzSge58fsxiKDFYAQjHui+ZAw4dq79Ax9AOO
Iv2GS9+DUfWhrb6RF+vNuJldFzcI0rTW/z2q+XGKrUCwN3khJY5XngHfQQrdBtMK
qsoUXz/5B8g422RTbo/SdPsyYAV6HeLLeV3rdgjI1fpaW0seZKHeTXQb/HvNeuPg
qz+XV1g6Gdqa1RjDOaX7A8elVKxrYq3LBtc93FW+grBde8n7JL0zPM3DY+vJ0IJZ
INx/MmBfmtCq05FqNclvU+sj2R3N1JJOtBOjZrJHQbJhzoILou8AkxeX1A+q9OAz
1geiY5E=
=TkP3
-----END PGP PUBLIC KEY BLOCK-----`)
}
func testCreateValidGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
//User2 <user2@example.com> //primary & activated
testCreateGPGKey(t, reqBuilder, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFmGVsMBCACuxgZ7W7rI9xN08Y4M7B8yx/6/I4Slm94+wXf8YNRvAyqj30dW
VJhyBcnfNRDLKSQp5o/hhfDkCgdqBjLa1PnHlGS3PXJc0hP/FyYPD2BFvNMPpCYS
eu3T1qKSNXm6X0XOWD2LIrdiDC8HaI9FqZVMI/srMK2CF8XCL2m67W1FuoPlWzod
5ORy0IZB7spoF0xihmcgnEGElRmdo5w/vkGH8U7Zyn9Eb57UVFeafgeskf4wqB23
BjbMdW2YaB+yzMRwYgOnD5lnBD4uqSmvjaV9C0kxn7x+oJkkiRV8/z1cNcO+BaeQ
Akh/yTTeTzYGSc/ZOqCX1O+NOPgSeixVlqenABEBAAG0GVVzZXIyIDx1c2VyMkBl
eGFtcGxlLmNvbT6JAVQEEwEIAD4WIQRXgbSh0TtGbgRd7XI46jvO1zKYLAUCWYZW
wwIbAwUJA8JnAAULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRA46jvO1zKYLF/e
B/91wm2KLMIQBZBA9WA2/+9rQWTo9EqgYrXN60rEzX3cYJWXZiE4DrKR1oWDGNLi
KXOCW62snvJldolBqq0ZqaKvPKzl0Y5TRqbYEc9AjUSqgRin1b+G2DevLGT4ibq+
7ocQvz0XkASEUAgHahp0Ubiiib1521WwT/duL+AG8Gg0+DK09RfV3eX5/EOkQCKv
8cutqgsd2Smz40A8wXuJkRcipZBtrB/GkUaZ/eJdwEeSYZjEA9GWF61LJT2stvRN
HCk7C3z3pVEek1PluiFs/4VN8BG8yDzW4c0tLty4Fj3VwPqwIbB5AJbquVfhQCb4
Eep2lm3Lc9b1OwO5N3coPJkouQENBFmGVsMBCADAGba2L6NCOE1i3WIP6CPzbdOo
N3gdTfTgccAx9fNeon9jor+3tgEjlo9/6cXiRoksOV6W4wFab/ZwWgwN6JO4CGvZ
Wi7EQwMMMp1E36YTojKQJrcA9UvMnTHulqQQ88F5E845DhzFQM3erv42QZZMBAX3
kXCgy1GNFocl6tLUvJdEqs+VcJGGANMpmzE4WLa8KhSYnxipwuQ62JBy9R+cHyKT
OARk8znRqSu5bT3LtlrZ/HXu+6Oy4+2uCdNzZIh5J5tPS7CPA6ptl88iGVBte/CJ
7cjgJWSQqeYp2Y5QvsWAivkQ4Ww9plHbbwV0A2eaHsjjWzlUl3HoJ/snMOhBABEB
AAGJATwEGAEIACYWIQRXgbSh0TtGbgRd7XI46jvO1zKYLAUCWYZWwwIbDAUJA8Jn
AAAKCRA46jvO1zKYLBwLCACQOpeRVrwIKVaWcPMYjVHHJsGscaLKpgpARAUgbiG6
Cbc2WI8Sm3fRwrY0VAfN+u9QwrtvxANcyB3vTgTzw7FimfhOimxiTSO8HQCfjDZF
Xly8rq+Fua7+ClWUpy21IekW41VvZYjH2sL6EVP+UcEOaGAyN53XfhaRVZPhNtZN
NKAE9N5EG3rbsZ33LzJj40rEKlzFSseAAPft8qA3IXjzFBx+PQXHMpNCagL79he6
lqockTJ+oPmta4CF/J0U5LUr1tOZXheL3TP6m8d08gDrtn0YuGOPk87i9sJz+jR9
uy6MA3VSB99SK9ducGmE1Jv8mcziREroz2TEGr0zPs6h
=J59D
-----END PGP PUBLIC KEY BLOCK-----`)
}
func testCreateValidSecondaryEmailGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
//User2 <user21@example.com> //secondary and not activated
testCreateGPGKey(t, reqBuilder, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFmGWN4BCAC18V4tVGO65VLCV7p14FuXJlUtZ5CuYMvgEkcOqrvRaBSW9ao4
PGESOhJpfWpnW3QgJniYndLzPpsmdHEclEER6aZjiNgReWPOjHD5tykWocZAJqXD
eY1ym59gvVMLcfbV2yQsyR2hbJlc+dJsl16tigSEe3nwxZSw2IsW92pgEzT9JNUr
Q+mC8dw4dqY0tYmFazYUGNxufUc/twgQT/Or1aNs0az5Q6Jft4rrTRsh/S7We0VB
COKGkdcQyYgAls7HJBuPjQRi6DM9VhgBSHLAgSLyaUcZvhZBJr8Qe/q4PP3/kYDJ
wm4RMnjOLz2pFZPgtRqgcAwpmFtLrACbEB3JABEBAAG0GlVzZXIyIDx1c2VyMjFA
ZXhhbXBsZS5jb20+iQFUBBMBCAA+FiEEPOLHOjPSO42DWM57+r85c5/h6ScFAlmG
WN4CGwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQ+r85c5/h6Sfx
Lgf/dq64NBV8+X9an3seaLxePRviva48e4K67/wV/JxtXNO5Z/DhMGz5kHXCsG9D
CXuWYO8ehlTjEnMZ6qqdDnY+H6bQsb2OS5oPn4RwpPXslAjEKtojPAr0dDsMS2DB
dUuIm1AoOnewOVO0OFRf1EqX1bivxnN0FVMcO0m8AczfnKDaGb0y/qg/Y9JAsKqp
j5pZNMWUkntRtGySeJ4CVJMmkVKJAHsa1Qj6MKdFeid4h4y94cBJ4ZdyBxNdpQOx
ydf0doicovfeqGNO4oWzsGP4RBK2CqGPCUT+EFl20jPvMkKwOjxgqc8p0z3b2UT9
+9bnmCGHgF/fW1HJ3iKmfFPqnLkBDQRZhljeAQgA5AirU/NJGgm19ZJYFOiHftjS
azbrPxGeD3cSqmvDPIMc1DNZGfQV5D4EVumnVbQBtL6xHFoGKz9KisUMbe4a/X2J
S8JmIphQWG0vMJX1DaZIzr2gT71MnPD7JMGsSUCh5dIKpTNTZX4w+oGPGOu0/UlL
x0448AryKwp30J2p6D4GeI0nb03n35S2lTOpnHDn1wj7Jl/8LS2fdFOdNaNHXSZe
twdSwJKhyBEiScgeHBDyKqo8zWkYoSb9eA2HiYlbVaiNtp24KP1mIEpiUdrRjWno
zauYSZGHZlOFMgF4dKWuetPiuH9m7UYZGKyMLfQ9vYFb+xcPh2bLCQHJ1OEmMQAR
AQABiQE8BBgBCAAmFiEEPOLHOjPSO42DWM57+r85c5/h6ScFAlmGWN4CGwwFCQPC
ZwAACgkQ+r85c5/h6Sfjfwf+O4WEjRdvPJLxNy7mfAGoAqDMHIwyH/tVzYgyVhnG
h/+cfRxJbGc3rpjYdr8dmvghzjEAout8uibPWaIqs63RCAPGPqgWLfxNO5c8+y8V
LZMVOTV26l2olkkdBWAuhLqKTNh6TiQva03yhOgHWj4XDvFfxICWPFXVd6t5ELpD
iApGu1OAj8JfhmzbG03Yzx+Ku7bWDxMonx3V/IDEu5LS5zrboHYDKCA53bXXghoi
Aceqql+PKrDwEjoY4bptwMHLmcjGjdCQ//Qx1neho7nZcS7xjTucY8gQuulwCyXF
y6wM+wMz8dunIG9gw4+Re6c4Rz9tX1kzxLrU7Pl21tMqfg==
=0N/9
-----END PGP PUBLIC KEY BLOCK-----`)
}

View File

@ -54,9 +54,8 @@ func TestAPIReplaceIssueLabels(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK)
var apiLabels []*api.Label
DecodeJSON(t, resp, &apiLabels)
if assert.Len(t, apiLabels, 1) {
assert.EqualValues(t, label.ID, apiLabels[0].ID)
}
assert.Len(t, apiLabels, 1)
assert.EqualValues(t, label.ID, apiLabels[0].ID)
models.AssertCount(t, &models.IssueLabel{IssueID: issue.ID}, 1)
models.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: issue.ID, LabelID: label.ID})

View File

@ -1,31 +0,0 @@
// Copyright 2017 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 (
"net/http"
"testing"
"code.gitea.io/gitea/models"
)
func TestAPIReposRaw(t *testing.T) {
prepareTestEnv(t)
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
// Login as User2.
session := loginUser(t, user.Name)
for _, ref := range [...]string{
"master", // Branch
"v1.1", // Tag
"65f1bf27bc3bf70f64657658635e66094edbcb4d", // Commit
} {
req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/%s/README.md", user.Name, ref)
session.MakeRequest(t, req, http.StatusOK)
}
// Test default branch
req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/README.md", user.Name)
session.MakeRequest(t, req, http.StatusOK)
}

View File

@ -5,8 +5,8 @@
package integrations
import (
"fmt"
"net/http"
"strings"
"testing"
"code.gitea.io/gitea/models"
@ -33,166 +33,23 @@ func TestAPIUserReposNotLogin(t *testing.T) {
}
}
func TestAPISearchRepo(t *testing.T) {
type searchResponseBody struct {
ok bool
data []api.Repository
}
func TestAPISearchRepoNotLogin(t *testing.T) {
prepareTestEnv(t)
const keyword = "test"
req := NewRequestf(t, "GET", "/api/v1/repos/search?q=%s", keyword)
resp := MakeRequest(t, req, http.StatusOK)
var body api.SearchResults
var body searchResponseBody
DecodeJSON(t, resp, &body)
assert.NotEmpty(t, body.Data)
for _, repo := range body.Data {
assert.Contains(t, repo.Name, keyword)
assert.False(t, repo.Private)
for _, repo := range body.data {
assert.True(t, strings.Contains(repo.Name, keyword))
}
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 15}).(*models.User)
user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 16}).(*models.User)
user3 := models.AssertExistsAndLoadBean(t, &models.User{ID: 18}).(*models.User)
user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 20}).(*models.User)
orgUser := models.AssertExistsAndLoadBean(t, &models.User{ID: 17}).(*models.User)
// Map of expected results, where key is user for login
type expectedResults map[*models.User]struct {
count int
repoOwnerID int64
repoName string
includesPrivate bool
}
testCases := []struct {
name, requestURL string
expectedResults
}{
{name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50", expectedResults: expectedResults{
nil: {count: 15},
user: {count: 15},
user2: {count: 15}},
},
{name: "RepositoriesMax10", requestURL: "/api/v1/repos/search?limit=10", expectedResults: expectedResults{
nil: {count: 10},
user: {count: 10},
user2: {count: 10}},
},
{name: "RepositoriesDefaultMax10", requestURL: "/api/v1/repos/search", expectedResults: expectedResults{
nil: {count: 10},
user: {count: 10},
user2: {count: 10}},
},
{name: "RepositoriesByName", requestURL: fmt.Sprintf("/api/v1/repos/search?q=%s", "big_test_"), expectedResults: expectedResults{
nil: {count: 7, repoName: "big_test_"},
user: {count: 7, repoName: "big_test_"},
user2: {count: 7, repoName: "big_test_"}},
},
{name: "RepositoriesAccessibleAndRelatedToUser", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user.ID), expectedResults: expectedResults{
nil: {count: 4},
user: {count: 8, includesPrivate: true},
user2: {count: 4}},
},
{name: "RepositoriesAccessibleAndRelatedToUser2", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user2.ID), expectedResults: expectedResults{
nil: {count: 1},
user: {count: 1},
user2: {count: 2, includesPrivate: true}},
},
{name: "RepositoriesAccessibleAndRelatedToUser3", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user3.ID), expectedResults: expectedResults{
nil: {count: 1},
user: {count: 1},
user2: {count: 1},
user3: {count: 4, includesPrivate: true}},
},
{name: "RepositoriesOwnedByOrganization", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", orgUser.ID), expectedResults: expectedResults{
nil: {count: 1, repoOwnerID: orgUser.ID},
user: {count: 2, repoOwnerID: orgUser.ID, includesPrivate: true},
user2: {count: 1, repoOwnerID: orgUser.ID}},
},
{name: "RepositoriesAccessibleAndRelatedToUser4", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user4.ID), expectedResults: expectedResults{
nil: {count: 3},
user: {count: 3},
user4: {count: 6, includesPrivate: true}}},
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeSource", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "source"), expectedResults: expectedResults{
nil: {count: 0},
user: {count: 0},
user4: {count: 0, includesPrivate: true}}},
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeFork", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "fork"), expectedResults: expectedResults{
nil: {count: 1},
user: {count: 1},
user4: {count: 2, includesPrivate: true}}},
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeFork/Exclusive", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s&exclusive=1", user4.ID, "fork"), expectedResults: expectedResults{
nil: {count: 1},
user: {count: 1},
user4: {count: 2, includesPrivate: true}}},
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeMirror", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "mirror"), expectedResults: expectedResults{
nil: {count: 2},
user: {count: 2},
user4: {count: 4, includesPrivate: true}}},
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeMirror/Exclusive", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s&exclusive=1", user4.ID, "mirror"), expectedResults: expectedResults{
nil: {count: 1},
user: {count: 1},
user4: {count: 2, includesPrivate: true}}},
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeCollaborative", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "collaborative"), expectedResults: expectedResults{
nil: {count: 0},
user: {count: 0},
user4: {count: 0, includesPrivate: true}}},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
for userToLogin, expected := range testCase.expectedResults {
var session *TestSession
var testName string
var userID int64
if userToLogin != nil && userToLogin.ID > 0 {
testName = fmt.Sprintf("LoggedUser%d", userToLogin.ID)
session = loginUser(t, userToLogin.Name)
userID = userToLogin.ID
} else {
testName = "AnonymousUser"
session = emptyTestSession(t)
}
t.Run(testName, func(t *testing.T) {
request := NewRequest(t, "GET", testCase.requestURL)
response := session.MakeRequest(t, request, http.StatusOK)
var body api.SearchResults
DecodeJSON(t, response, &body)
assert.Len(t, body.Data, expected.count)
for _, repo := range body.Data {
r := getRepo(t, repo.ID)
hasAccess, err := models.HasAccess(userID, r, models.AccessModeRead)
assert.NoError(t, err)
assert.True(t, hasAccess)
assert.NotEmpty(t, repo.Name)
if len(expected.repoName) > 0 {
assert.Contains(t, repo.Name, expected.repoName)
}
if expected.repoOwnerID > 0 {
assert.Equal(t, expected.repoOwnerID, repo.Owner.ID)
}
if !expected.includesPrivate {
assert.False(t, repo.Private)
}
}
})
}
})
}
}
var repoCache = make(map[int64]*models.Repository)
func getRepo(t *testing.T, repoID int64) *models.Repository {
if _, ok := repoCache[repoID]; !ok {
repoCache[repoID] = models.AssertExistsAndLoadBean(t, &models.Repository{ID: repoID}).(*models.Repository)
}
return repoCache[repoID]
}
func TestAPIViewRepo(t *testing.T) {

View File

@ -1,79 +0,0 @@
// Copyright 2017 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 (
"net/http"
"net/url"
"testing"
"github.com/PuerkitoBio/goquery"
"github.com/Unknwon/i18n"
"github.com/stretchr/testify/assert"
)
func TestViewBranches(t *testing.T) {
prepareTestEnv(t)
req := NewRequest(t, "GET", "/user2/repo1/branches")
resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
_, exists := htmlDoc.doc.Find(".delete-branch-button").Attr("data-url")
assert.False(t, exists, "The template has changed")
}
func TestDeleteBranch(t *testing.T) {
prepareTestEnv(t)
deleteBranch(t)
}
func TestUndoDeleteBranch(t *testing.T) {
prepareTestEnv(t)
deleteBranch(t)
htmlDoc, name := branchAction(t, ".undo-button")
assert.Contains(t,
htmlDoc.doc.Find(".ui.positive.message").Text(),
i18n.Tr("en", "repo.branch.restore_success", name),
)
}
func deleteBranch(t *testing.T) {
htmlDoc, name := branchAction(t, ".delete-branch-button")
assert.Contains(t,
htmlDoc.doc.Find(".ui.positive.message").Text(),
i18n.Tr("en", "repo.branch.deletion_success", name),
)
}
func branchAction(t *testing.T, button string) (*HTMLDoc, string) {
session := loginUser(t, "user2")
req := NewRequest(t, "GET", "/user2/repo1/branches")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
link, exists := htmlDoc.doc.Find(button).Attr("data-url")
assert.True(t, exists, "The template has changed")
htmlDoc = NewHTMLParser(t, resp.Body)
req = NewRequestWithValues(t, "POST", link, map[string]string{
"_csrf": getCsrf(htmlDoc.doc),
})
resp = session.MakeRequest(t, req, http.StatusOK)
url, err := url.Parse(link)
assert.NoError(t, err)
req = NewRequest(t, "GET", "/user2/repo1/branches")
resp = session.MakeRequest(t, req, http.StatusOK)
return NewHTMLParser(t, resp.Body), url.Query()["name"][0]
}
func getCsrf(doc *goquery.Document) string {
csrf, _ := doc.Find("meta[name=\"_csrf\"]").Attr("content")
return csrf
}

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