Compare commits

..

80 Commits

Author SHA1 Message Date
zeripath
67ceb61fe3 Changelog 1.15.2 (#16940)
## [1.15.2](https://github.com/go-gitea/gitea/releases/tag/v1.15.2) - 2021-09-03

* BUGFIXES
  * Add unique constraint back into issue_index (#16938)
  * Close storage objects before cleaning (#16934) (#16942)

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-09-03 12:50:32 +01:00
zeripath
5cb5101720 Close storage objects before cleaning (#16934) (#16942)
Backport #16934

Storage.Iterate provides the path and an open object. On windows using
local storage means that the objects will be locked thus preventing clean
from deleting them.

This PR simply closes the objects early.

Fix #16932

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-09-03 12:17:07 +01:00
zeripath
6f261fdf47 Add unique constraint back into issue_index (#16938)
There is a flaw in #16820 where it was missed that although xorm will
not add a primary key to a table during syncing, it will remove an
unique constraint.

Users upgrading from 1.15.0 to 1.15.1 will therefore lose the unique
constraint that makes this table work unless they run `gitea doctor
recreate-table issue_index`.  Postgres helpfully warns about this
situation but MySQL does not.

Main/1.16-dev is not affected by this issue as there is a migration that
does the above recreation by default. Users moving directly to 1.15.1
from 1.14.x or lower are also not affected.

Whilst we could force all users who ran 1.15.0 to do the above
recreate-table call, this PR proposes an alternative: Just add the
unique constraint back in for 1.15.x. This won't have any long term
effects - just some wasted space for the unnecessary index.

Fix #16936

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-09-03 17:35:18 +08:00
zeripath
3365611f06 Changelog 1.15.1 (#16925)
## [1.15.1](https://github.com/go-gitea/gitea/releases/tag/v1.15.1) - 2021-09-02

* BUGFIXES
  * Allow BASIC authentication access to /:owner/:repo/releases/download/* (#16916) (#16923)
  * Prevent leave changes dialogs due to autofill fields (#16912) (#16920)
  * Ignore review comment when ref commit is missed (#16905) (#16919)
  * Fix wrong attachment removal (#16915) (#16917)
  * Gitlab Migrator: dont ignore reactions of last request (#16903) (#16913)
  * Correctly return the number of Repositories for Organizations (#16807) (#16911)
  * Test if LFS object is accessible (#16865) (#16904)
  * Fix git.Blob.DataAsync(): close pipe since we return a NopCloser (#16899) (#16900)
  * Fix dump and restore respository (#16698) (#16898)
  * Repare and Improve GetDiffRangeWithWhitespaceBehavior (#16894) (#16895)
  * Fix wiki raw commit diff/patch view (#16891) (#16892)
  * Ensure wiki repos are all closed (#16886) (#16888)
  * List limited and private orgs if authenticated on API (#16866) (#16879)
  * Simplify split diff view generation and remove JS dependency (#16775) (#16863)
  * Ensure that the default visibility is set on the user create page (#16845) (#16862)
  * In Render tolerate not being passed a context (#16842) (#16858)
  * Upgrade xorm to v1.2.2 (#16663) & Add test to ensure that dumping of login sources remains correct (#16847) (#16848)
  * Report the correct number of pushes on the feeds (#16811) (#16822)
  * Add primary_key to issue_index (#16813) (#16820)
  * Prevent NPE on empty commit (#16812) (#16819)
  * Fix branch pagination error (#16805) (#16816)
  * Add missing return to handleSettingRemoteAddrError (#16794) (#16795)
  * Remove spurious / from issues.opened_by (#16793)
  * Ensure that template compilation panics are sent to the logs (#16788) (#16792)
  * Update caddyserver/certmagic (#16789) (#16790)

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-09-02 18:23:40 +01:00
zeripath
ceae89c8c7 Allow BASIC authentication access to /:owner/:repo/releases/download/* (#16916) (#16923)
Backport #16916

Duplicate #15987 to allow access to releases download through BASIC authentication.

Fix #16914

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-09-02 12:34:49 -04:00
zeripath
8f300781ad Prevent leave changes dialogs due to autofill fields (#16912) (#16920)
Backport #16912

Add ignore-dirty to /user/settings/account
Add autocomplete="off" to push_mirror_address form on /:owner/:repo/settings

Fix #16861

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-09-02 17:00:20 +01:00
Lunny Xiao
8b132bdec6 Ignore review comment when ref commit is missed (#16905) (#16919)
backport #16905
2021-09-02 11:51:32 +01:00
wxiaoguang
e70b679d21 Fix wrong attachment removal (#16915) (#16917)
Backport #16917
2021-09-02 06:50:11 +01:00
zeripath
02de43236a Gitlab Migrator: dont ignore reactions of last request (#16903) (#16913)
Backport #16903

Fix bug related to early breaking when migrating reactions.

Co-authored-by: 6543 <6543@obermui.de>
2021-09-01 17:52:38 -04:00
zeripath
f949f9e9c5 Correctly return the number of Repositories for Organizations (#16807) (#16911)
Backport #16807

Calculate and return the number of Repositories on the dashboard
Organization list.

This PR restores some of the logic that was removed in #14032 to
calculate the number of repos on the dashboard orgs list.

Fix #16648
Replaces #16799

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-09-01 19:20:35 +02:00
6543
cbe3ca5d0b Test if LFS object is accessible (#16865) (#16904)
* Test if object is accessible.

* Added more logging.

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
2021-08-31 17:58:39 +02:00
6543
3ac1f35349 List limited and private orgs if authenticated on API (#16866) (#16879) 2021-08-31 12:49:02 +02:00
Lunny Xiao
af1fd56d8a Fix dump and restore respository (#16698) (#16898)
* Fix dump and restore
* return different error message for get commit
* Fix missing delete release attachment when deleting repository
* Fix ci and add some comments

back port #16698

Co-authored-by: zeripath <art27@cantab.net>
2021-08-31 10:44:14 +01:00
6543
0274933c22 Fix git.Blob.DataAsync(): close pipe since we return a NopCloser (#16899) (#16900)
* make sure headGitRepo is closed on err too
* refactor
* Fix git.Blob.DataAsync(): exec cancel since we already read all bytes (close pipe since we return a NopCloser)

Co-authored-by: zeripath <art27@cantab.net>
2021-08-31 16:06:01 +08:00
6543
67776372d6 Fix wiki raw commit diff/patch view (#16891) (#16892) 2021-08-31 14:13:08 +08:00
6543
c54639b8ee Repare and Improve GetDiffRangeWithWhitespaceBehavior (#16894) (#16895)
fix pipe leak
2021-08-31 05:02:27 +02:00
6543
49a71a6461 Ensure wiki repos are all closed (#16886) (#16888)
There are multiple places where wiki git repositories are not properly closed.

This PR ensures they are closed.

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: Andrew Thornton <art27@cantab.net>
2021-08-30 23:00:45 +02:00
zeripath
58f4a4114e Simplify split diff view generation and remove JS dependency (#16775) (#16863)
Backport #16775

Gitea has relied on some slow JS code to match up added and deleted lines on the
diff pages. This can cause a considerable slow down on large diff pages.

This PR makes a small change meaning that the matching up can occur much more simply.

Partial fix #1351

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-30 16:43:06 +01:00
zeripath
b31307c41c Ensure that the default visibility is set on the user create page (#16845) (#16862)
Backport #16845

Set the default visibility on the user create page.

Fix #16840

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-29 17:33:13 +02:00
6543
c5193a8481 In Render tolerate not being passed a context (#16842) (#16858)
* In Render tolerate not being passed a context

It is possible for RenderString to be passed to an external renderer if markdown
is set to be rendered by an external renderer. No context is currently sent to these
meaning that this will error out.

Fix #16835

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Add Context to Repo calls for RenderString

All calls from routers can easily add the context - so add it.

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: zeripath <art27@cantab.net>
2021-08-29 15:25:45 +01:00
zeripath
1790f01dd9 Upgrade xorm to v1.2.2 (#16663) & Add test to ensure that dumping of login sources remains correct (#16847) (#16848)
* Upgrade xorm to v1.2.2 (#16663)

Backport #16663

Fix #16683

* Add test to ensure that dumping of login sources remains correct (#16847)

#16831 has occurred because of a missed regression. This PR adds a simple test to
try to prevent this occuring again.

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2021-08-28 13:16:19 +02:00
techknowlogick
0c7927fe48 Report the correct number of pushes on the feeds (#16811) (#16822)
* Report the correct number of pushes on the feeds

Since the number of commits in the Action table has been limited to 5
the number of commits reported on the feeds page is now incorrectly also
limited to 5. The correct number is available as the Len and this PR
changes this to report this.

Fix #16804

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Update templates/user/dashboard/feeds.tmpl

Co-authored-by: techknowlogick <techknowlogick@gitea.io>

Co-authored-by: zeripath <art27@cantab.net>
2021-08-26 02:30:13 -04:00
zeripath
695e8ae81d Add primary_key to issue_index (#16813) (#16820)
Backport #16813

Make the group_id a primary key in issue_index. This already has an
unique index and therefore is a good candidate for becoming a primary
key.

This PR also changes all other uses of this table to add the group_id as
the primary key.

The migration v192 from #16813 has not been backported but Xorm will
work fine with non-primary keyed tables. If a user on 1.15 wishes to
have the correct schema sooner than 1.16 - they can use gitea doctor
recreate-table issue_index and gitea will recreate the table with the
primary key.

Fix #16802

Signed-off-by: Andrew Thornton art27@cantab.net
2021-08-25 18:10:15 -04:00
zeripath
2148b27bfa Prevent NPE on empty commit (#16812) (#16819)
Backport #16812

Handle completely empty commit as the first commit to a repository.

Fix #16668

Signed-off-by: Andrew Thornton art27@cantab.net
2021-08-25 13:22:48 +01:00
Lunny Xiao
ab7e36e3a5 Fix branch pagination error (#16805) (#16816)
Backport #16805

Fix #16801

Even if default branch is removed from the current page, but the total branches number should be still kept. So that the pagination calculation will be correct.
2021-08-25 11:11:54 +01:00
zeripath
63178b5654 Ensure that template compilation panics are sent to the logs (#16788) (#16792)
Backport #16788

Although panics within the rendering pipeline are caught and dealt with,
panics that occur before that starts are unprotected and will kill Gitea
without being sent to the logs.

This PR adds a basic recovery handler to catch panics that occur after
the logger is initialised and ensure that they're sent to the logger.

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-23 19:50:04 -04:00
zeripath
2d15126de6 Remove spurious / from issues.opened_by (#16793)
Fix #16713

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-23 18:24:30 -04:00
zeripath
31e4e8205a Add missing return to handleSettingRemoteAddrError (#16794) (#16795)
Backport #16794

There is a missing return in handleSettingRemoteAddrError which means
that the error page for repo settings is duplicately rendered.

Fix #16771

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-23 18:09:28 -04:00
zeripath
37e4cdbbe6 Update only certmagic (#16790)
Signed-off-by: jolheiser <john.olheiser@gmail.com>

Co-authored-by: jolheiser <john.olheiser@gmail.com>
2021-08-23 18:07:44 -04:00
techknowlogick
f7e7477c45 changelog for 1.15.0 (#16760)
* changelog for 1.15.0

* Slight rename of GPG feature

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Apply suggestions from code review

Co-authored-by: zeripath <art27@cantab.net>

Co-authored-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
2021-08-21 20:38:22 -04:00
KN4CK3R
0840a508b4 Keep attachments on tasklist update (#16750) (#16757)
* Send attachments too.

* Use tasklist flag.

* use action="ignoreAttachments" instead of "tasklist"

* Use boolean parameter.

* when the update request doesn't intend to update attachments (eg: change checkbox state), ignore attachment updates (#16762)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2021-08-21 20:10:04 +01:00
zeripath
5ceff8fda2 Recreate Tables should Recreate indexes on MySQL (#16718) (#16739)
The MySQL indexes are not being renamed at the same time as RENAME table despite the
CASCADE. Therefore it is probably better to just recreate the indexes instead.

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-20 22:47:37 -04:00
Steven
778a0bf758 Fix dependency translations (#16755)
Signed-off-by: Steven Kriegler <61625851+justusbunsi@users.noreply.github.com>
2021-08-20 13:11:26 -04:00
Elouan Martinet
f19ccd8f6a Do not use thin scrollbars on Firefox (#16738) (#16745)
In #7269, thin scrollbars were added in Arc Green theme. It got moved
in base theme in #13361.

This PR removes the use of thin scrollbars which causes an
accessibility issue. The scrollbars become too thin to be dragged.

Signed-off-by: Elouan Martinet <exa@elou.world>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-20 06:19:22 +01:00
KN4CK3R
b6e4688874 Fix wrong user in OpenID response (#16736) (#16741)
* Fix wrong user in OpenID response (#16736)

* Fixed usage of wrong user.

* Added tests.

* Fixed wrong import.

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-20 00:26:44 +03:00
zeripath
25437672bf Restore functionality for pushing non-standard refs (Partial #16705) (#16706)
Partial Backport #16705

There was an inadvertent breaking change in #15629 meaning that notes refs and other
git extension refs will be automatically rejected.

This PR removes this incorrect forced rejection of non-standard refs.

Fix #16688

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-17 10:24:47 +02:00
techknowlogick
0dc808212b release/v1.15: set min go version to min upstream supported go1.16 (#16710)
* release/v1.15: set min go version to min upstream supported 1.16

* update drone
2021-08-17 10:09:44 +03:00
Lunny Xiao
b6508b872b Upgrade levelqueue 0.4.1 (#16696) (#16700) 2021-08-16 10:37:27 +03:00
zeripath
d89029ebac Ensure empty lines are copiable and final new line too (#16678) (#16692)
Backport #16678

When files are highlighted the newline character needs to be added in a whitespace
compliant mode. Also ensure the final empty newline is rendered.

Fix #16434

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-15 05:39:23 +02:00
6543
62315ea731 If PatchURL is empty, skip pull patch download when migrating (Partial #16356) (#16681)
Partial backport #16356

Whilst looking at adding migration support for onedev it has become apparent that gitea would attempt to pull patches on other migration targets even if that PatchURL was empty.
2021-08-13 18:26:19 +02:00
6543
86861ee135 Update issue_index to finish migration (#16685) (#16687)
* update issue_index to finish migration

* One Func to RecalculateIssueIndexForRepo
2021-08-13 15:13:03 +01:00
6543
d2d99a25b7 Fix NPE in fuzzer (#16680) (#16682)
The fuzzer found an issue with the issue pattern processor where there is a spurious
path.Clean which does not need to be there. This PR also sets the default AppURL for
the fuzzer too.

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: zeripath <art27@cantab.net>
2021-08-13 08:51:13 +03:00
nitul1991
e483ec8b0d Change the implementation of the go-git version of GetNote to mirror the non go-git version when passed a non-existent commit (#16658) (#16659)
Backport #16658

Fixes #16657
2021-08-09 20:24:31 +01:00
zeripath
46d62ad896 Fix direct creation of external users on admin page (#16613)
From #16612 it was noticed that when creating new external users directly it was not
possible to set their username correctly. This PR restores this ability.

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-09 14:18:40 +02:00
zeripath
428d58f8da Restore compatibility with SQLServer 2008 R2 in migrations (#16638)
This fixes two problems with MSSQL:

* `ALTER TABLE DROP ... IF EXISTS ...` is only supported in SQL Server >16.

The `IF EXISTS` here is a belt-and-braces and does not need to be present. Therefore
can be dropped. Also stop attempting to drop the indexes as constraints as they're indexes!

* System tables like: `sys.indexes` should be lowercase not uppercase because of collation issues.

Fix #13615

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2021-08-08 13:32:07 +03:00
zeripath
1a2256bf44 Changelog for 1.15.0-rc3 (#16621)
* Changelog for 1.15.0-rc3

 ## [1.15.0-rc3](https://github.com/go-gitea/gitea/releases/tag/v1.15.0-rc3) - 2021-08-04

* BREAKING
  * Upgrade to the latest version of golang-jwt and increase minimum go to 1.15 (#16590) (#16606)
* SECURITY
  * Upgrade to the latest version of golang-jwt and increase minimum go to 1.15 (#16590) (#16606)
  * Switch to maintained jwt lib (#16532) (#16533)
  * Correctly create of git-daemon-export-ok files (#16508) (#16514)
  * Don't show private user's repo in explore view (#16550) (#16554)
* API
  * Swagger AccessToken fixes (#16574) (#16597)
  * Set AllowedHeaders on API CORS handler (#16524) (#16618)
* BUGFIXES
  * Restore Accessibility for Dropdown (#16576) (#16617)
  * Pass down SignedUserName down to AccessLogger context (#16605) (#16616)
  * Fix table alignment in markdown (#16596) (#16602)
  * Fix 500 on first wiki page (#16586) (#16598)
  * Lock goth/gothic and Re-attempt OAuth2 registration on login if registration failed at startup (#16564) (#16570)
  * Upgrade levelqueue to v0.4.0 (#16560) (#16561)
  * Handle too long PR titles correctly (#16517) (#16549)
  * Fix data race in bleve indexer (#16474) (#16509)
  * Restore CORS on git smart http protocol (#16496) (#16506)
  * Fix race in log (#16490) (#16505)
  * Fix prepareWikiFileName to respect existing unescaped files (#16487) (#16498)
  * Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16480)
  * Update notification table with only latest data (#16445) (#16469)
  * Revert to use alpine 3.13 (#16451) (#16452)
  * Fix crash following ldap authentication update (#16447) (#16448)
  * Fix direct creation of external users on admin page (partial #16612) (#16613)

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Update CHANGELOG.md

Co-authored-by: techknowlogick <techknowlogick@gitea.io>

* Update CHANGELOG.md

Co-authored-by: zeripath <art27@cantab.net>

* Update CHANGELOG.md

* Update CHANGELOG.md

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: Lauris BH <lauris@nix.lv>
2021-08-06 16:08:13 -04:00
techknowlogick
20601f8463 Prevent 500 on draft releases without tag (#16634) (#16636)
It is possible to create draft releases prior to creating a tag. This will cause a
500 on the releases page due to compare page failing.

This PR only shows the compare button if there is a SHA1 present.

Fix #16610

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>

Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Lauris BH <lauris@nix.lv>
2021-08-06 11:09:33 +03:00
zeripath
619e6d6400 Frontport changelog for v1.14.6 (#16633)
* Frontport changelog for v1.14.6

Frontport #16619

Changelog frontported to below v1.15.0-rc1.

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Update config.yaml

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-06 01:17:44 +03:00
zeripath
f438b6f33b Update node tar dependency to 6.1.6 (#16622) (#16623)
Backport #16622

Forcibly update dev dependency on tar to 6.1.6

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-05 00:40:25 -04:00
zeripath
c47065cc29 Set AllowedHeaders on API CORS handler (#16524) (#16618)
Backport #16524

Set AllowedHeaders on API CORS handler and add missing Access-Control-Expose-Headers
to pull API.

Fix #16100

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-04 21:57:59 +02:00
zeripath
719e2f26d5 Pass down SignedUserName down to AccessLogger context (#16605) (#16616)
Backport #16605

Unfortunately when the AccessLogger was moved back before the contexters the
SignedUserName reporting was lost. This is due to Request.WithContext leading to a
shallow copy of the Request and the modules/context/Context being within that request.

This PR adds a new context variable of a string pointer which is set and handled
in the contexters.

Fix #16600

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2021-08-04 13:26:35 -04:00
zeripath
40687a2160 Restore #10096/#8638 and re-fix #15172 (#16576) (#16617)
Backport #16576

This PR restores the vendored and patched dropdow from #8638. It
however, it partially abandons the call to `click()` using instead the
default dropdown click calls instead. This prevents the issue of the
dropdown grabbing focus permanently however, this may have negative
effects on the effect of focus on the dropdowns.

Of note, the behaviour of the template selector dropdown on the repo
creation page is slightly odd - I don't believe that this odd behaviour
is caused by this PR but rather by the feed source for this. I suspect
that the dropdown should be adding a delete button to its selection.

Fix #15172
References: #7057

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-04 13:31:10 +01:00
zeripath
f9120092c1 Fix table alignment in markdown (#16596) (#16602)
Backport #16596

Set the TableOptions in markdown to allow alignment of the tables to work correctly

Fix #15959

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-04 00:16:00 +01:00
zeripath
a17edf446f Fix 500 on first wiki page (#16586) (#16598)
Backport #16586

There is a mistake in #16319 and #16487 which means that the first time
a wiki page is created a 500 is reported because the `master` branch is
not in existence in that wiki yet.

This PR simply checks for this error and returns not found.

Fix #16584

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-03 23:46:08 +01:00
zeripath
ff8fadd2be Upgrade to the latest version of golang-jwt (#16590) (#16606)
* Upgrade to the latest version of golang-jwt.

Backport #16590

* Forcibly update the vendored versions too
* Update our minimal go lang version to 1.15 (differs from 1.16 in #16590)

Signed-off-by: Andrew Thornton <art27@cantab.net>

 ### ⚠️ BREAKING ⚠️

This PR raises the minimal version of go supported to 1.15 which will mean the end of support of 32-bit Mac and Mac OS versions before Sierra.

Signed-off-by: Andrew Thornton <art27@cantab.net>

* update minimal go required

Signed-off-by: Andrew Thornton <art27@cantab.net>

* update config.yaml

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-08-03 22:22:52 +01:00
zeripath
5fe7c0ed7b Swagger AccessToken fixes (#16574) (#16597)
Backport #16574

There is a subtle problem with the Swagger definition for AccessTokens which causes
autogeneration of APIs for these endpoints to fail.

This PR corrects these errors.

Ref: https://github.com/zeripath/java-gitea-api/issues/4
Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-08-02 20:24:47 +02:00
6543
763e4196ba [CI] Use node v14 instead of node v16 until it will pass again (#16595) (#16599)
* for CI release: use node 14 (lts) to build until 16 do fail

* all in for node v14.x
2021-08-02 07:41:58 +01:00
zeripath
903bdefb58 Lock goth/gothic and Re-attempt OAuth2 registration on login if registration failed at startup (#16570)
Backport #16564

This PR has two parts:

* Add locking to goth and gothic calls with a RWMutex

The goth and gothic calls are currently unlocked and thus are a cause of multiple potential races

* Reattempt OAuth2 registration on login if registration failed

If OAuth2 registration fails at startup we currently disable the login_source however an alternative approach could be to reattempt registration on login attempt.
    
Fix #16096

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-29 18:52:38 +01:00
Lunny Xiao
840d240a61 Upgrade levelqueue to v0.4.0 (#16560) (#16561)
Fix #16546
2021-07-27 18:59:06 +02:00
a1012112796
7365b4e757 not show private user's repo in explore view (#16550) (#16554)
after #16069, visibility is also usefull for user,
so this limit is not usefull.

fix #16545
2021-07-27 07:34:25 +01:00
6543
e10cd3da1e Fix session bugs (#16552) (#16553)
* Fix session bugs (#16552)

* fix deadlog bug

* Fix models/issue_stopwatch.go

* Update models/issue_stopwatch.go

Co-authored-by: zeripath <art27@cantab.net>

* fix getLatestCommitStatus

Co-authored-by: zeripath <art27@cantab.net>
2021-07-27 09:44:44 +08:00
zeripath
693275455e Handle too long PR titles correctly (#16517) (#16549)
Backport #16517

The CompareAndPullRequestPost handler for POST to /compare
incorrectly handles returning errors to the user. For a start
it does not set the necessary markers to switch SimpleMDE
but it also does not immediately return to the form.

This PR fixes this by setting the appropriate values, fixing
the templates and preventing the suggestion of a too long
title.

Fix #16507

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-26 17:49:48 +02:00
6543
91527434d0 upgraded github.com/markbates/goth v1.67.1 => v1.68.0 (#16539) 2021-07-24 18:17:50 +01:00
Lunny Xiao
89f680aa04 Fix issue pasted image missing if no release permission (#16520) (#16527)
* Fix issue pasted image missing if no release permission


Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
2021-07-24 18:34:57 +02:00
zeripath
67942ac1a9 Switch to maintained jwt lib (#16532) (#16533)
Backport #16532

Co-authored-by: Matti R <matti@mdranta.net>
2021-07-24 11:13:50 -04:00
zeripath
0b06b2019f Add basic edit ldap auth test & actually fix #16252 (#16465) (#16494)
Backport #16465

One of the reasons why #16447 was needed and why #16268 was needed in
the first place was because it appears that editing ldap configuration
doesn't get tested.

This PR therefore adds a basic test that will run the edit pipeline.

In doing so it's now clear that #16447 and #16268 aren't actually
solving #16252. It turns out that what actually happens is that is that
the bytes are actually double encoded.

This PR now changes the json unmarshal wrapper to handle this double
encode.

Fix #16252

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: 6543 <6543@obermui.de>
2021-07-22 17:24:21 +03:00
zeripath
057205a4b7 Restore creation of git-daemon-export-ok files (#16508) (#16514)
Backport #16508

Somewhere along the line the creation of git-daemon-export-ok
files disappeared but the updating of these files when
repo visibility changes remained. The problem is that the
current state will create files even when the org or user
is private.

This PR restores creation correctly.

Fix #15521

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-22 15:52:02 +02:00
zeripath
1b6c0c6bdc Changelog for 1.15.0-rc2 (#16511)
* Changelog for 1.15.0-rc2

Results of `~/go/bin/changelog -m 1.15.0 --after 16422 generate`

We need to release RC2 as there are mulitple problems with alpine 3.14 related to
the seccomp issues on Docker <20.

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Update CHANGELOG.md

Co-authored-by: zeripath <art27@cantab.net>

Co-authored-by: 6543 <6543@obermui.de>
2021-07-22 15:47:38 +03:00
6543
c4f3f5bdf2 Fix data race in bleve indexer (#16474) (#16509)
* Fix data race in bleve indexer

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2021-07-22 11:42:32 +08:00
zeripath
1f5011dff7 Restore CORS on git smart http protocol (#16496) (#16506)
Backport #16496

Unfortunately the chi changes have resulted in the CORS headers for the
git smart http protocol going missing.

This is mostly because the OPTIONS method is not being handled by
httpBase anymore.

This PR adds a GetOptions, PostOptions and Options methods to web
handler to allow OPTIONS method requests to still reach the httpBase
function.

Fix #16350
Close #16491

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-21 15:03:02 +01:00
zeripath
cf9aeca508 Fix race in log (#16490) (#16505)
Backport #16490

A race has been detected in #1441 relating to getting log levels.

This PR protects the GetLevel and GetStacktraceLevel calls with a RW mutex.

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-21 20:19:36 +08:00
6543
09a4364b21 Add TestPrepareWikiFileName (#16487) (#16498)
* Add TestPrepareWikiFileName

* use LsTree as LsFiles is index only

* ajust other tests

Co-authored-by: Andrew Thornton <art27@cantab.net>
2021-07-21 03:37:00 +01:00
zeripath
0c3467ffb7 Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16480)
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479)

Fix #16427 (again!)

* handle sharing violation error code

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-20 23:52:19 +02:00
Gary Wang
d268c9d6e1 fix: support delete non-urlencoded wiki page (#16482) (#16486)
* fix: support delete non-urlencoded wiki page

* fix: check error
2021-07-19 19:39:50 +02:00
zeripath
7f6019e492 Update notification table with only latest data (#16445) (#16469)
When marking notifications read the results may be returned out of order
or be delayed.  This PR sends a sequence number to gitea so that the
browser can ensure that only the results of the latest notification
change are shown.

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-17 19:05:59 +02:00
zeripath
0f11c5f592 Retry rename on lock induced failures (re-fix) (#16461) (#16462)
Backport #16461

Unfortunately #16435 asserts the wrong error and should use
os.LinkError not os.PathError.

Fix #16439

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-16 13:22:44 -04:00
zeripath
bae0e1d773 Frontport v1.14.5 (#16453)
Frontport the changelog from v1.14.5

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Lauris BH <lauris@nix.lv>
2021-07-16 11:17:16 -04:00
techknowlogick
0877d497f3 revert to use alpine 3.13 (#16452)
Co-authored-by: zeripath <art27@cantab.net>
2021-07-16 09:55:14 +08:00
zeripath
e5fde7ef00 Fix crash following ldap authentication update (#16447) (#16448)
Backport #16447

Unfortunately #16268 contained a terrible error, whereby there was a double
indirection taken when unmarshalling the source data. This fatally breaks
authentication configuration reading.

Fix #16342

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-15 20:17:44 -04:00
zeripath
6243638c11 Update documentation to reflect #15219 (#16442) (#16444)
Backport #16442

The move to render custom/public as within /assets in #15219 missed updating
several documentation pages.

This PR updates this documentation.

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-15 22:28:07 +02:00
8286 changed files with 2610634 additions and 107956 deletions

9
.air.conf Normal file
View File

@@ -0,0 +1,9 @@
root = "."
tmp_dir = ".air"
[build]
cmd = "make backend"
bin = "gitea"
include_ext = ["go", "tmpl"]
exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata"]
include_dir = ["cmd", "models", "modules", "options", "routers", "services", "templates"]

View File

@@ -1,10 +0,0 @@
root = "."
tmp_dir = ".air"
[build]
cmd = "make backend"
bin = "gitea"
include_ext = ["go", "tmpl"]
exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata"]
include_dir = ["cmd", "models", "modules", "options", "routers", "services", "templates"]
exclude_regex = ["_test.go$"]

File diff suppressed because it is too large Load Diff

View File

@@ -3,10 +3,13 @@ reportUnusedDisableDirectives: true
ignorePatterns: ignorePatterns:
- /web_src/js/vendor - /web_src/js/vendor
- /templates/base/head.tmpl
- /templates/repo/activity.tmpl
- /templates/repo/view_file.tmpl
parserOptions: parserOptions:
sourceType: module sourceType: module
ecmaVersion: latest ecmaVersion: 2021
plugins: plugins:
- eslint-plugin-unicorn - eslint-plugin-unicorn
@@ -26,6 +29,7 @@ globals:
CodeMirror: false CodeMirror: false
Dropzone: false Dropzone: false
SimpleMDE: false SimpleMDE: false
u2fApi: false
settings: settings:
html/html-extensions: [".tmpl"] html/html-extensions: [".tmpl"]
@@ -116,12 +120,11 @@ rules:
import/no-amd: [0] import/no-amd: [0]
import/no-anonymous-default-export: [0] import/no-anonymous-default-export: [0]
import/no-commonjs: [0] import/no-commonjs: [0]
import/no-cycle: [2, {ignoreExternal: true, maxDepth: 1}] import/no-cycle: [2, {ignoreExternal: true}]
import/no-default-export: [0] import/no-default-export: [0]
import/no-deprecated: [0] import/no-deprecated: [0]
import/no-dynamic-require: [0] import/no-dynamic-require: [0]
import/no-extraneous-dependencies: [2] import/no-extraneous-dependencies: [2]
import/no-import-module-exports: [0]
import/no-internal-modules: [0] import/no-internal-modules: [0]
import/no-mutable-exports: [2] import/no-mutable-exports: [2]
import/no-named-as-default-member: [0] import/no-named-as-default-member: [0]
@@ -130,7 +133,6 @@ rules:
import/no-named-export: [0] import/no-named-export: [0]
import/no-namespace: [0] import/no-namespace: [0]
import/no-nodejs-modules: [0] import/no-nodejs-modules: [0]
import/no-relative-packages: [0]
import/no-relative-parent-imports: [0] import/no-relative-parent-imports: [0]
import/no-restricted-paths: [0] import/no-restricted-paths: [0]
import/no-self-import: [2] import/no-self-import: [2]
@@ -283,7 +285,6 @@ rules:
no-unsafe-negation: [2] no-unsafe-negation: [2]
no-unused-expressions: [2] no-unused-expressions: [2]
no-unused-labels: [2] no-unused-labels: [2]
no-unused-private-class-members: [2]
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, ignoreRestSiblings: false}] no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, ignoreRestSiblings: false}]
no-use-before-define: [2, nofunc] no-use-before-define: [2, nofunc]
no-useless-backreference: [0] no-useless-backreference: [0]
@@ -316,7 +317,6 @@ rules:
prefer-exponentiation-operator: [2] prefer-exponentiation-operator: [2]
prefer-named-capture-group: [0] prefer-named-capture-group: [0]
prefer-numeric-literals: [2] prefer-numeric-literals: [2]
prefer-object-has-own: [0]
prefer-object-spread: [0] prefer-object-spread: [0]
prefer-promise-reject-errors: [2, {allowEmptyReject: false}] prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
prefer-regex-literals: [2] prefer-regex-literals: [2]
@@ -363,18 +363,14 @@ rules:
unicorn/import-style: [0] unicorn/import-style: [0]
unicorn/new-for-builtins: [2] unicorn/new-for-builtins: [2]
unicorn/no-abusive-eslint-disable: [0] unicorn/no-abusive-eslint-disable: [0]
unicorn/no-array-for-each: [2] unicorn/no-array-for-each: [0]
unicorn/no-array-instanceof: [0] unicorn/no-array-instanceof: [0]
unicorn/no-array-method-this-argument: [2]
unicorn/no-array-push-push: [2] unicorn/no-array-push-push: [2]
unicorn/no-await-expression-member: [0]
unicorn/no-console-spaces: [0] unicorn/no-console-spaces: [0]
unicorn/no-document-cookie: [2] unicorn/no-document-cookie: [2]
unicorn/no-empty-file: [2]
unicorn/no-fn-reference-in-iterator: [0] unicorn/no-fn-reference-in-iterator: [0]
unicorn/no-for-loop: [0] unicorn/no-for-loop: [0]
unicorn/no-hex-escape: [0] unicorn/no-hex-escape: [0]
unicorn/no-invalid-remove-event-listener: [2]
unicorn/no-keyword-prefix: [0] unicorn/no-keyword-prefix: [0]
unicorn/no-lonely-if: [2] unicorn/no-lonely-if: [2]
unicorn/no-nested-ternary: [0] unicorn/no-nested-ternary: [0]
@@ -385,15 +381,10 @@ rules:
unicorn/no-process-exit: [0] unicorn/no-process-exit: [0]
unicorn/no-reduce: [2] unicorn/no-reduce: [2]
unicorn/no-static-only-class: [2] unicorn/no-static-only-class: [2]
unicorn/no-thenable: [2]
unicorn/no-this-assignment: [2] unicorn/no-this-assignment: [2]
unicorn/no-unreadable-array-destructuring: [0] unicorn/no-unreadable-array-destructuring: [0]
unicorn/no-unsafe-regex: [0] unicorn/no-unsafe-regex: [0]
unicorn/no-unused-properties: [2] unicorn/no-unused-properties: [2]
unicorn/no-useless-fallback-in-spread: [2]
unicorn/no-useless-length-check: [2]
unicorn/no-useless-promise-resolve-reject: [2]
unicorn/no-useless-spread: [2]
unicorn/no-useless-undefined: [0] unicorn/no-useless-undefined: [0]
unicorn/no-zero-fractions: [2] unicorn/no-zero-fractions: [2]
unicorn/number-literal-case: [0] unicorn/number-literal-case: [0]
@@ -404,15 +395,11 @@ rules:
unicorn/prefer-array-flat: [2] unicorn/prefer-array-flat: [2]
unicorn/prefer-array-index-of: [2] unicorn/prefer-array-index-of: [2]
unicorn/prefer-array-some: [2] unicorn/prefer-array-some: [2]
unicorn/prefer-at: [0]
unicorn/prefer-code-point: [2]
unicorn/prefer-dataset: [2] unicorn/prefer-dataset: [2]
unicorn/prefer-date-now: [2] unicorn/prefer-date-now: [2]
unicorn/prefer-default-parameters: [0] unicorn/prefer-default-parameters: [0]
unicorn/prefer-event-key: [2] unicorn/prefer-event-key: [2]
unicorn/prefer-export-from: [2]
unicorn/prefer-includes: [2] unicorn/prefer-includes: [2]
unicorn/prefer-json-parse-buffer: [0]
unicorn/prefer-math-trunc: [2] unicorn/prefer-math-trunc: [2]
unicorn/prefer-modern-dom-apis: [0] unicorn/prefer-modern-dom-apis: [0]
unicorn/prefer-module: [2] unicorn/prefer-module: [2]
@@ -421,10 +408,7 @@ rules:
unicorn/prefer-node-protocol: [0] unicorn/prefer-node-protocol: [0]
unicorn/prefer-node-remove: [0] unicorn/prefer-node-remove: [0]
unicorn/prefer-number-properties: [0] unicorn/prefer-number-properties: [0]
unicorn/prefer-object-from-entries: [2]
unicorn/prefer-object-has-own: [0]
unicorn/prefer-optional-catch-binding: [2] unicorn/prefer-optional-catch-binding: [2]
unicorn/prefer-prototype-methods: [0]
unicorn/prefer-query-selector: [0] unicorn/prefer-query-selector: [0]
unicorn/prefer-reflect-apply: [0] unicorn/prefer-reflect-apply: [0]
unicorn/prefer-regexp-test: [2] unicorn/prefer-regexp-test: [2]
@@ -436,16 +420,10 @@ rules:
unicorn/prefer-switch: [0] unicorn/prefer-switch: [0]
unicorn/prefer-ternary: [0] unicorn/prefer-ternary: [0]
unicorn/prefer-text-content: [2] unicorn/prefer-text-content: [2]
unicorn/prefer-top-level-await: [0]
unicorn/prefer-trim-start-end: [2] unicorn/prefer-trim-start-end: [2]
unicorn/prefer-type-error: [0] unicorn/prefer-type-error: [0]
unicorn/prevent-abbreviations: [0] unicorn/prevent-abbreviations: [0]
unicorn/relative-url-style: [2]
unicorn/require-array-join-separator: [2]
unicorn/require-number-to-fixed-digits-argument: [2]
unicorn/require-post-message-target-origin: [0]
unicorn/string-content: [0] unicorn/string-content: [0]
unicorn/template-indent: [2]
unicorn/throw-new-error: [2] unicorn/throw-new-error: [2]
use-isnan: [2] use-isnan: [2]
valid-typeof: [2, {requireStringLiterals: true}] valid-typeof: [2, {requireStringLiterals: true}]

2
.gitattributes vendored
View File

@@ -4,5 +4,3 @@
/templates/**/*.tmpl linguist-language=Handlebars /templates/**/*.tmpl linguist-language=Handlebars
/.eslintrc linguist-language=YAML /.eslintrc linguist-language=YAML
/.stylelintrc linguist-language=YAML /.stylelintrc linguist-language=YAML
/web_src/fomantic/build/** linguist-generated
Dockerfile.* linguist-language=Dockerfile

View File

@@ -1,90 +0,0 @@
name: Bug Report
description: Found something you weren't expecting? Report it here!
body:
- type: markdown
attributes:
value: |
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Make sure you are using the latest release and
take a moment to check that your issue hasn't been reported before.
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.io/en-us/faq)
5. Please give all relevant information below for bug reports, because
incomplete details will be handled as an invalid report.
- type: input
id: gitea-ver
attributes:
label: Gitea Version
description: Gitea version (or commit reference) of your instance
validations:
required: true
- type: input
id: git-ver
attributes:
label: Git Version
description: The version of git running on the server
- type: input
id: os-ver
attributes:
label: Operating System
description: The operating system you are using to run Gitea
- type: textarea
id: run-info
attributes:
label: How are you running Gitea?
description: |
Please include information on whether you built Gitea yourself, used one of our downloads, are using https://try.gitea.io or are using some other package
Please also tell us how you are running Gitea, e.g. if it is being run from docker, a command-line, systemd etc.
If you are using a package or systemd tell us what distribution you are using
validations:
required: true
- type: dropdown
id: database
attributes:
label: Database
description: What database system are you running?
options:
- PostgreSQL
- MySQL
- MSSQL
- SQLite
- type: dropdown
id: can-reproduce
attributes:
label: Can you reproduce the bug on the Gitea demo site?
description: |
If so, please provide a URL in the Description field
URL of Gitea demo: https://try.gitea.io
options:
- "Yes"
- "No"
validations:
required: true
- type: markdown
attributes:
value: |
It's really important to provide pertinent logs
Please read https://docs.gitea.io/en-us/logging-configuration/#debugging-problems
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini
- type: input
id: logs
attributes:
label: Log Gist
description: Please provide a gist URL of your logs, with any sensitive information (e.g. API keys) removed/hidden
- type: textarea
id: description
attributes:
label: Description
description: |
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see above)
If you are using a proxy or a CDN (e.g. Cloudflare) in front of Gitea, please disable the proxy/CDN fully and access Gitea directly to confirm the issue still persists without those services.
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If this issue involves the Web Interface, please provide one or more screenshots

View File

@@ -1,17 +0,0 @@
blank_issues_enabled: true
contact_links:
- name: Security Concern
url: https://tinyurl.com/security-gitea
about: For security concerns, please send a mail to security@gitea.io instead of opening a public issue.
- name: Discord Server
url: https://discord.gg/gitea
about: Please ask questions and discuss configuration or deployment problems here.
- name: Discourse Forum
url: https://discourse.gitea.io
about: Questions and configuration or deployment problems can also be discussed on our forum.
- name: Frequently Asked Questions
url: https://docs.gitea.io/en-us/faq
about: Please check if your question isn't mentioned here.
- name: Crowdin Translations
url: https://crowdin.com/project/gitea
about: Translations are managed here.

View File

@@ -1,23 +0,0 @@
name: Feature Request
description: Got an idea for a feature that Gitea doesn't have currently? Submit your idea here!
body:
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Please take a moment to check that your feature hasn't already been suggested.
- type: textarea
id: description
attributes:
label: Feature Description
placeholder: |
I think it would be great if Gitea had...
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If you can, provide screenshots of an implementation on another site e.g. GitHub

View File

@@ -1,62 +0,0 @@
name: Web Interface Bug Report
description: Something doesn't look quite as it should? Report it here!
body:
- type: markdown
attributes:
value: |
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Please take a moment to check that your issue doesn't already exist.
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.io/en-us/faq)
5. Please give all relevant information below for bug reports, because
incomplete details will be handled as an invalid report.
- type: input
id: gitea-ver
attributes:
label: Gitea Version
description: Gitea version (or commit reference) your instance is running
validations:
required: true
- type: input
id: os-ver
attributes:
label: Operating System
description: The operating system you are using to access Gitea
- type: input
id: browser-ver
attributes:
label: Browser Version
description: The browser and version that you are using to access Gitea
validations:
required: true
- type: dropdown
id: can-reproduce
attributes:
label: Can you reproduce the bug on the Gitea demo site?
description: |
If so, please provide a URL in the Description field
URL of Gitea demo: https://try.gitea.io
options:
- "Yes"
- "No"
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: |
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see above)
If using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please disable the proxy/CDN fully and connect to gitea directly to confirm the issue still persists without those services.
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: Please provide at least 1 screenshot showing the issue.
validations:
required: true

View File

@@ -1,9 +1,7 @@
<!--
Please check the following: Please check the following:
1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for bug fixes. 1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for bug fixes.
2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md 2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md
3. Describe what your pull request does and which issue you're targeting (if any) 3. Describe what your pull request does and which issue you're targeting (if any)
--> **You MUST delete the content above including this line before posting, otherwise your pull request will be invalid.**

5
.gitignore vendored
View File

@@ -9,8 +9,6 @@ _test
# IntelliJ # IntelliJ
.idea .idea
# Goland's output filename can not be set manually
/go_build_*
# MS VSCode # MS VSCode
.vscode .vscode
@@ -36,8 +34,6 @@ _testmain.go
coverage.all coverage.all
cpu.out cpu.out
/modules/migration/bindata.go
/modules/migration/bindata.go.hash
/modules/options/bindata.go /modules/options/bindata.go
/modules/options/bindata.go.hash /modules/options/bindata.go.hash
/modules/public/bindata.go /modules/public/bindata.go
@@ -87,7 +83,6 @@ cpu.out
/public/css /public/css
/public/fonts /public/fonts
/public/img/webpack /public/img/webpack
/vendor
/web_src/fomantic/node_modules /web_src/fomantic/node_modules
/web_src/fomantic/build/* /web_src/fomantic/build/*
!/web_src/fomantic/build/semantic.js !/web_src/fomantic/build/semantic.js

View File

@@ -9,61 +9,24 @@ linters:
- unused - unused
- structcheck - structcheck
- varcheck - varcheck
- golint
- dupl - dupl
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time. #- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
- gofmt - gofmt
- misspell - misspell
#- gocritic # TODO: disabled until fixed with go 1.18 - gocritic
- bidichk
- ineffassign
- revive
enable-all: false enable-all: false
disable-all: true disable-all: true
fast: false fast: false
run: run:
timeout: 10m timeout: 3m
skip-dirs:
- node_modules
- public
- web_src
linters-settings: linters-settings:
gocritic: gocritic:
disabled-checks: disabled-checks:
- ifElseChain - ifElseChain
- singleCaseSwitch # Every time this occurred in the code, there was no other way. - singleCaseSwitch # Every time this occurred in the code, there was no other way.
revive:
ignore-generated-header: false
severity: warning
confidence: 0.8
errorCode: 1
warningCode: 1
rules:
- name: blank-imports
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: exported
- name: if-return
- name: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: duplicated-imports
- name: modifies-value-receiver
gofumpt:
extra-rules: true
lang-version: 1.18
issues: issues:
exclude-rules: exclude-rules:
@@ -148,14 +111,4 @@ issues:
linters: linters:
- staticcheck - staticcheck
text: "svc.IsAnInteractiveSession is deprecated: Use IsWindowsService instead." text: "svc.IsAnInteractiveSession is deprecated: Use IsWindowsService instead."
- path: models/user/openid.go
linters:
- golint
- linters: staticcheck
text: "strings.Title is deprecated: The rule Title uses for word boundaries does not handle Unicode punctuation properly. Use golang.org/x/text/cases instead."
- linters: staticcheck
text: "util.FindClosure is deprecated: This function can not handle newlines. Many elements can be existed over multiple lines(e.g. link labels). Use text.Reader.FindClosure."
- linters: staticcheck
text: "gossh.SigAlgoRSASHA2256 is deprecated: use KeyAlgoRSASHA256."
- linters: staticcheck
text: "gossh.SigAlgoRSASHA2512 is deprecated: use KeyAlgoRSASHA512."

View File

@@ -1,8 +1,5 @@
*.min.css /vendor
*.min.js /public/vendor/plugins
/modules/options/bindata.go /modules/options/bindata.go
/modules/public/bindata.go /modules/public/bindata.go
/modules/templates/bindata.go /modules/templates/bindata.go
/public/vendor/plugins
/vendor
node_modules

25
.revive.toml Normal file
View File

@@ -0,0 +1,25 @@
ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 1
warningCode = 1
[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.dot-imports]
[rule.error-return]
[rule.error-strings]
[rule.error-naming]
[rule.exported]
[rule.if-return]
[rule.increment-decrement]
[rule.var-naming]
[rule.var-declaration]
[rule.package-comments]
[rule.range]
[rule.receiver-naming]
[rule.time-naming]
[rule.unexported-return]
[rule.indent-error-flow]
[rule.errorf]

View File

@@ -1,31 +1,15 @@
extends: stylelint-config-standard extends: stylelint-config-standard
overrides:
- files: ["**/*.less"]
customSyntax: postcss-less
rules: rules:
alpha-value-notation: null
at-rule-empty-line-before: null at-rule-empty-line-before: null
block-closing-brace-empty-line-before: null block-closing-brace-empty-line-before: null
color-function-notation: null
color-hex-length: null color-hex-length: null
comment-empty-line-before: null comment-empty-line-before: null
declaration-block-no-redundant-longhand-properties: null
declaration-block-single-line-max-declarations: null declaration-block-single-line-max-declarations: null
declaration-empty-line-before: null declaration-empty-line-before: null
hue-degree-notation: null
indentation: 2 indentation: 2
max-line-length: null
no-descending-specificity: null no-descending-specificity: null
no-invalid-position-at-import-rule: null
number-leading-zero: never number-leading-zero: never
number-max-precision: null
property-no-vendor-prefix: null
rule-empty-line-before: null rule-empty-line-before: null
selector-class-pattern: null
selector-id-pattern: null
selector-pseudo-element-colon-notation: double selector-pseudo-element-colon-notation: double
shorthand-property-no-redundant-values: true shorthand-property-no-redundant-values: true
string-quotes: null
value-no-vendor-prefix: null

View File

@@ -4,672 +4,6 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.16.6](https://github.com/go-gitea/gitea/releases/tag/v1.16.6) - 2022-04-20
* ENHANCEMENTS
* Only request write when necessary (#18657) (#19422)
* Disable service worker by default (#18914) (#19342)
* BUGFIXES
* When dumping trim the standard suffices instead of a random suffix (#19440) (#19447)
* Fix DELETE request for non-existent public key (#19443) (#19444)
* Don't panic on ErrEmailInvalid (#19441) (#19442)
* Add uploadpack.allowAnySHA1InWant to allow --filter=blob:none with older git clients (#19430) (#19438)
* Warn on SSH connection for incorrect configuration (#19317) (#19437)
* Search Issues via API, dont show 500 if filter result in empty list (#19244) (#19436)
* When updating mirror repo intervals by API reschedule next update too (#19429) (#19433)
* Fix nil error when some pages are rendered outside request context (#19427) (#19428)
* Fix double blob-hunk on diff page (#19404) (#19405)
* Don't allow merging PR's which are being conflict checked (#19357) (#19358)
* Fix middleware function's placements (#19377) (#19378)
* Fix invalid CSRF token bug, make sure CSRF tokens can be up-to-date (#19338)
* Restore user autoregistration with email addresses (#19261) (#19312)
* Move checks for pulls before merge into own function (#19271) (#19277)
* Granular webhook events in editHook (#19251) (#19257)
* Only send webhook events to active system webhooks and only deliver to active hooks (#19234) (#19248)
* Use full output of git show-ref --tags to get tags for PushUpdateAddTag (#19235) (#19236)
* Touch mirrors on even on fail to update (#19217) (#19233)
* Hide sensitive content on admin panel progress monitor (#19218 & #19226) (#19231)
* Fix clone url JS error for the empty repo page (#19209)
* Bump goldmark to v1.4.11 (#19201) (#19203)
* TESTING
* Prevent intermittent failures in RepoIndexerTest (#19225 #19229) (#19228)
* BUILD
* Revert the minimal golang version requirement from 1.17 to 1.16 and add a warning in Makefile (#19319)
* MISC
* Performance improvement for add team user when org has more than 1000 repositories (#19227) (#19289)
* Check go and nodejs version by go.mod and package.json (#19197) (#19254)
## [1.16.5](https://github.com/go-gitea/gitea/releases/tag/v1.16.5) - 2022-03-23
* BREAKING
* Bump to build with go1.18 (#19120 et al) (#19127)
* SECURITY
* Prevent redirect to Host (2) (#19175) (#19186)
* Try to prevent autolinking of displaynames by email readers (#19169) (#19183)
* Clean paths when looking in Storage (#19124) (#19179)
* Do not send notification emails to inactive users (#19131) (#19139)
* Do not send activation email if manual confirm is set (#19119) (#19122)
* ENHANCEMENTS
* Use the new/choose link for New Issue on project page (#19172) (#19176)
* BUGFIXES
* Fix showing issues in your repositories (#18916) (#19191)
* Fix compare link in active feeds for new branch (#19149) (#19185)
* Redirect .wiki/* ui link to /wiki (#18831) (#19184)
* Ensure deploy keys with write access can push (#19010) (#19182)
* Ensure that setting.LocalURL always has a trailing slash (#19171) (#19177)
* Cleanup protected branches when deleting users & teams (#19158) (#19174)
* Use IterateBufferSize whilst querying repositories during adoption check (#19140) (#19160)
* Fix NPE /repos/issues/search when not signed in (#19154) (#19155)
* Use custom favicon when viewing static files if it exists (#19130) (#19152)
* Fix the editor height in review box (#19003) (#19147)
* Ensure isSSH is set whenever DISABLE_HTTP_GIT is set (#19028) (#19146)
* Fix wrong scopes caused by empty scope input (#19029) (#19145)
* Make migrations SKIP_TLS_VERIFY apply to git too (#19132) (#19141)
* Handle email address not exist (#19089) (#19121)
* MISC
* Update json-iterator to allow compilation with go1.18 (#18644) (#19100)
* Update golang.org/x/crypto (#19097) (#19098)
## [1.16.4](https://github.com/go-gitea/gitea/releases/tag/v1.16.4) - 2022-03-14
* SECURITY
* Restrict email address validation (#17688) (#19085)
* Fix lfs bug (#19072) (#19080)
* ENHANCEMENTS
* Improve SyncMirrors logging (#19045) (#19050)
* BUGFIXES
* Refactor mirror code & fix `StartToMirror` (#18904) (#19075)
* Update the webauthn_credential_id_sequence in Postgres (#19048) (#19060)
* Prevent 500 when there is an error during new auth source post (#19041) (#19059)
* If rendering has failed due to a net.OpError stop rendering (attempt 2) (#19049) (#19056)
* Fix flag validation (#19046) (#19051)
* Add pam account authorization check (#19040) (#19047)
* Ignore missing comment for user notifications (#18954) (#19043)
* Set `rel="nofollow noindex"` on new issue links (#19023) (#19042)
* Upgrading binding package (#19034) (#19035)
* Don't show context cancelled errors in attribute reader (#19006) (#19027)
* Fix update hint bug (#18996) (#19002)
* MISC
* Fix potential assignee query for repo (#18994) (#18999)
## [1.16.3](https://github.com/go-gitea/gitea/releases/tag/v1.16.3) - 2022-03-02
* SECURITY
* Git backend ignore replace objects (#18979) (#18980)
* ENHANCEMENTS
* Adjust error for already locked db and prevent level db lock on malformed connstr (#18923) (#18938)
* BUGFIXES
* Set max text height to prevent overflow (#18862) (#18977)
* Fix newAttachmentPaths deletion for DeleteRepository() (#18973) (#18974)
* Accounts with WebAuthn only (no TOTP) now exist ... fix code to handle that case (#18897) (#18964)
* Send 404 on `/{org}.gpg` (#18959) (#18962)
* Fix admin user list pagination (#18957) (#18960)
* Fix lfs management setting (#18947) (#18946)
* Fix login with email panic when email is not exist (#18942)
* Update go-org to v1.6.1 (#18932) (#18933)
* Fix `<strong>` html in translation (#18929) (#18931)
* Fix page and missing return on unadopted repos API (#18848) (#18927)
* Allow adminstrator teams members to see other teams (#18918) (#18919)
* Don't treat BOM escape sequence as hidden character. (#18909) (#18910)
* Correctly link URLs to users/repos with dashes, dots or underscores (… (#18908)
* Fix redirect when using lowercase repo name (#18775) (#18902)
* Fix migration v210 (#18893) (#18892)
* Fix team management UI (#18887) (18886)
* BeforeSourcePath should point to base commit (#18880) (#18799)
* TRANSLATION
* Backport locales from master (#18944)
* MISC
* Don't update email for organisation (#18905) (#18906)
## [1.16.2](https://github.com/go-gitea/gitea/releases/tag/v1.16.2) - 2022-02-24
* ENHANCEMENTS
* Show fullname on issue edits and gpg/ssh signing info (#18828)
* Immediately Hammer if second kill is sent (#18823) (#18826)
* Allow mermaid render error to wrap (#18791)
* BUGFIXES
* Fix ldap user sync missed email in email_address table (#18786) (#18876)
* Update assignees check to include any writing team and change org sidebar (#18680) (#18873)
* Don't report signal: killed errors in serviceRPC (#18850) (#18865)
* Fix bug where certain LDAP settings were reverted (#18859)
* Update go-org to 1.6.0 (#18824) (#18839)
* Fix login with email for ldap users (#18800) (#18836)
* Fix bug for get user by email (#18834)
* Fix panic in EscapeReader (#18820) (#18821)
* Fix ldap loginname (#18789) (#18804)
* Remove redundant call to UpdateRepoStats during migration (#18591) (#18794)
* In disk_channel queues synchronously push to disk on shutdown (#18415) (#18788)
* Fix template bug of LFS lock (#18784) (#18787)
* Attempt to fix the webauthn migration again - part 3 (#18770) (#18771)
* Send mail to issue/pr assignee/reviewer also when OnMention is set (#18707) (#18765)
* Fix a broken link in commits_list_small.tmpl (#18763) (#18764)
* Increase the size of the webauthn_credential credential_id field (#18739) (#18756)
* Prevent dangling GetAttribute calls (#18754) (#18755)
* Fix isempty detection of git repository (#18746) (#18750)
* Fix source code line highlighting on external tracker (#18729) (#18740)
* Prevent double encoding of branch names in delete branch (#18714) (#18738)
* Always set PullRequestWorkInProgressPrefixes in PrepareViewPullInfo (#18713) (#18737)
* Fix forked repositories missed tags (#18719) (#18735)
* Fix release typo (#18728) (#18731)
* Separate the details links of commit-statuses in headers (#18661) (#18730)
* Update object repo with the migrated repository (#18684) (#18726)
* Fix bug for version update hint (#18701) (#18705)
* Fix issue with docker-rootless shimming script (#18690) (#18699)
* Let `MinUnitAccessMode` return correct perm (#18675) (#18689)
* Prevent security failure due to bad APP_ID (#18678) (#18682)
* Restart zero worker if there is still work to do (#18658) (#18672)
* If rendering has failed due to a net.OpError stop rendering (#18642) (#18645)
* TESTING
* Ensure git tag tests and others create test repos in tmpdir (#18447) (#18767)
* BUILD
* Reduce CI go module downloads, add make targets (#18708, #18475, #18443) (#18741)
* MISC
* Put buttons back in org dashboard (#18817) (#18825)
* Various Mermaid improvements (#18776) (#18780)
* C preprocessor colors improvement (#18671) (#18696)
* Fix the missing i18n key for update checker (#18646) (#18665)
## [1.16.1](https://github.com/go-gitea/gitea/releases/tag/v1.16.1) - 2022-02-06
* SECURITY
* Update JS dependencies, fix lint (#18389) (#18540)
* ENHANCEMENTS
* Add dropdown icon to label set template dropdown (#18564) (#18571)
* BUGFIXES
* Comments on migrated issues/prs must link to the comment ID (#18630) (#18637)
* Stop logging an error when notes are not found (#18626) (#18635)
* Ensure that blob-excerpt links work for wiki (#18587) (#18624)
* Only attempt to flush queue if the underlying worker pool is not finished (#18593) (#18620)
* Ensure commit-statuses box is sized correctly in headers (#18538) (#18606)
* Prevent merge messages from being sorted to the top of email chains (#18566) (#18588)
* Prevent panic on prohibited user login with oauth2 (#18562) (#18563)
* Collaborator trust model should trust collaborators (#18539) (#18557)
* Detect conflicts with 3way merge (#18536) (#18537)
* In docker rootless use $GITEA_APP_INI if provided (#18524) (#18535)
* Add `GetUserTeams` (#18499) (#18531)
* Fix review excerpt (#18502) (#18530)
* Fix for AvatarURL database type (#18487) (#18529)
* Use `ImagedProvider` for gplus oauth2 provider (#18504) (#18505)
* Fix OAuth Source Edit Page (#18495) (#18503)
* Use "read" value for General Access (#18496) (#18500)
* Prevent NPE on partial match of compare URL and allow short SHA1 compare URLs (#18472) (#18473)
* BUILD
* Make docker gitea/gitea:v1.16-dev etc refer to the latest build on that branch (#18551) (#18569)
* DOCS
* Update 1.16.0 changelog to set #17846 as breaking (#18533) (#18534)
## [1.16.0](https://github.com/go-gitea/gitea/releases/tag/v1.16.0) - 2022-01-30
* BREAKING
* Remove golang vendored directory (#18277)
* Paginate releases page & set default page size to 10 (#16857)
* Use shadowing script for docker (#17846)
* Only allow webhook to send requests to allowed hosts (#17482)
* SECURITY
* Disable content sniffing on `PlainTextBytes` (#18359) (#18365)
* Only view milestones from current repo (#18414) (#18417)
* Sanitize user-input on file name (#17666)
* Use `hostmatcher` to replace `matchlist` to improve blocking of bad hosts in Webhooks (#17605)
* FEATURES
* Add/update SMTP auth providers via cli (#18197)
* Support webauthn (#17957)
* Team permission allow different unit has different permission (#17811)
* Implement Well-Known URL for password change (#17777)
* Add support for ssh commit signing (#17743)
* Allow Loading of Diffs that are too large (#17739)
* Add copy button to markdown code blocks (#17638)
* Add .gitattribute assisted language detection to blame, diff and render (#17590)
* Add `PULL_LIMIT` and `PUSH_LIMIT` to cron.update_mirror task (#17568)
* Add Reindex buttons to repository settings page (#17494)
* Make SSL cipher suite configurable (#17440)
* Add groups scope/claim to OIDC/OAuth2 Provider (#17367)
* Add simple update checker to Gitea (#17212)
* Migrated Repository will show modifications when possible (#17191)
* Create pub/priv keypair for federation (#17071)
* Make LDAP be able to skip local 2FA (#16954)
* Add nodeinfo endpoint for federation purposes (#16953)
* Save and view issue/comment content history (#16909)
* Use git attributes to determine generated and vendored status for language stats and diffs (#16773)
* Add migrate from Codebase (#16768)
* Add migration from GitBucket (#16767)
* Add OAuth2 introspection endpoint (#16752)
* Add proxy settings and support for migration and webhook (#16704)
* Add microsoft oauth2 providers (#16544)
* Send registration email on user autoregistration (#16523)
* Defer Last Commit Info (#16467)
* Support unprotected file patterns (#16395)
* Add migrate from OneDev (#16356)
* Add option to update pull request by `rebase` (#16125)
* Add RSS/Atom feed support for user actions (#16002)
* Add support for corporate WeChat webhooks (#15910)
* Add a simple way to rename branch like gh (#15870)
* Add bundle download for repository (#14538)
* Add agit flow support in gitea (#14295)
* API
* Add MirrorUpdated field to Repository API type (#18267)
* Adjust Fork API to allow setting a custom repository name (#18066)
* Add API to manage repo tranfers (#17963)
* Add API to get file commit history (#17652)
* Add API to get issue/pull comments and events (timeline) (#17403)
* Add API to get/edit wiki (#17278)
* Add API for get user org permissions (#17232)
* Add HTML urls to notification API (#17178)
* Add API to get commit diff/patch (#17095)
* Respond with updated notifications in API (#17064)
* Add API to fetch git notes (#16649)
* Generalize list header for API (#16551)
* Add API Token Cache (#16547)
* Allow Token API calls be authorized using the reverse-proxy header (#15119)
* ENHANCEMENTS
* Make the height of the editor in Review Box smaller (4 lines as GitHub) (#18319)
* Return nicer error if trying to pull from non-existent user (#18288)
* Show pull link for agit pull request also (#18235)
* Enable partial clone by default (#18195)
* Added replay of webhooks (#18191)
* Show OAuth callback error message (#18185)
* Increase Salt randomness (#18179)
* Add MP4 as default allowed attachment type (#18170)
* Include folders into size cost (#18158)
* Remove `/email2user` endpoint (#18127)
* Handle invalid issues (#18111)
* Load EasyMDE/CodeMirror dynamically, remove RequireEasyMDE (#18069)
* Support open compare page directly (#17975)
* Prefer "Hiragino Kaku Gothic ProN" in system-ui-ja (#17954)
* Clean legacy SimpleMDE code (#17926)
* Refactor install page (db type) (#17919)
* Improve interface when comparing a branch which has created a pull request (#17911)
* Allow default branch to be inferred on compare page (#17908)
* Display issue/comment role even if repo archived (#17907)
* Always set a message-id on mails (#17900)
* Change `<a>` elements to underline on hover (#17898)
* Render issue references in file table (#17897)
* Handle relative unix socket paths (#17836)
* Move accessmode into models/perm (#17828)
* Fix some org style problems (#17807)
* Add List-Unsubscribe header (#17804)
* Create menus for organization pages (#17802)
* Switch archive URL code back to href attributes (#17796)
* Refactor "refs/*" string usage by using constants (#17784)
* Allow forks to org if you can create repos (#17783)
* Improve install code to avoid low-level mistakes. (#17779)
* Improve ellipsis buttons (#17773)
* Add restrict and no-user-rc to authorized_keys (#17772)
* Add copy Commit ID button in commits list (#17759)
* Make `bind` error more readable (#17750)
* Fix navbar on project view (#17749)
* More pleasantly handle broken or missing git repositories (#17747)
* Use `*PushUpdateOptions` as receiver (#17724)
* Remove unused `user` paramater (#17723)
* Better builtin avatar generator (#17707)
* Cleanup and use global style on popups (#17674)
* Move user/org deletion to services (#17673)
* Added comment for changing issue ref (#17672)
* Allow admins to change user avatars (#17661)
* Only set `data-path` once for each file in diff pages (#17657)
* Add icon to vscode clone link (#17641)
* Add download button for file viewer (#17640)
* Add pagination to fork list (#17639)
* Use a standalone struct name for Organization (#17632)
* Minor readability patch. (#17627)
* Add context support for GetUserByID (#17602)
* Move merge-section to `> .content` (#17582)
* Remove NewSession method from db.Engine interface (#17577)
* Move unit into models/unit/ (#17576)
* Restrict GetDeletedBranchByID to the repositories deleted branches (#17570)
* Refactor commentTags functionality (#17558)
* Make Repo Code Indexer an Unique Queue (#17515)
* Simplify Gothic to use our session store instead of creating a different store (#17507)
* Add settings to allow different SMTP envelope from address (#17479)
* Properly determine CSV delimiter (#17459)
* Hide label comments if labels were added and removed immediately (#17455)
* Tune UI alignment for nav bar notification icon, avatar image, issue label (#17438)
* Add appearance section in settings (#17433)
* Move key forms before list and add cancel button (#17432)
* When copying executables to the docker chmod them (#17423)
* Remove deprecated `extendDefaultPlugins` method of svgo (#17399)
* Fix the click behavior for <tr> and <td> with [data-href] (#17388)
* Refactor update checker to use AppState (#17387)
* Improve async/await usage, and sort init calls in `index.js` (#17386)
* Use a variable but a function for IsProd because of a slight performance increment (#17368)
* Frontend refactor, PascalCase to camelCase, remove unused code (#17365)
* Hide command line merge instructions when user can't push (#17339)
* Move session to models/login (#17338)
* Sync gitea app path for git hooks and authorized keys when starting (#17335)
* Make the Mirror Queue a queue (#17326)
* Add "Copy branch name" button to pull request page (#17323)
* Fix repository summary on mobile (#17322)
* Split `index.js` to separate files (#17315)
* Show direct match on top for user search (#17303)
* Frontend refactor: move Vue related code from `index.js` to `components` dir, and remove unused codes. (#17301)
* Upgrade chi to v5 (#17298)
* Disable form autofill (#17291)
* Improve behavior of "Fork" button (#17288)
* Open markdown image links in new window (#17287)
* Add hints for special Wiki pages (#17283)
* Move add deploy key form before the list and add a cancel button (#17228)
* Allow adding multiple issues to a project (#17226)
* Add metrics to get issues by repository (#17225)
* Add specific event type to header (#17222)
* Redirect on project after issue created (#17211)
* Reference in new issue modal: dont pre-populate issue title (#17208)
* Always set a unique Message-ID header (#17206)
* Add projects and project boards in exposed metrics (#17202)
* Add metrics to get issues by label (#17201)
* Add protection to disable Gitea when run as root (#17168)
* Don't return binary file changes in raw PR diffs by default (#17158)
* Support sorting for project board issuses (#17152)
* Force color-adjust for markdown checkboxes (#17146)
* Add option to copy line permalink (#17145)
* Move twofactor to models/login (#17143)
* Multiple tokens support for migrating from github (#17134)
* Unify issue and PR subtitles (#17133)
* Make Requests Processes and create process hierarchy. Associate OpenRepository with context. (#17125)
* Fix problem when database id is not increment as expected (#17124)
* Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
* Re-allow clipboard copy on non-https sites (#17118)
* DBContext is just a Context (#17100)
* Move login related structs and functions to models/login (#17093)
* Add SkipLocal2FA option to pam and smtp sources (#17078)
* Move db related basic functions to models/db (#17075)
* Fixes username tagging in "Reference in new issue" (#17074)
* Use light/dark theme based on system preference (#17051)
* Always emit the configuration path (#17036)
* Add `AbsoluteListOptions` (#17028)
* Use common sessioner for API and Web (#17027)
* Fix overflow label in small view (#17020)
* Report the associated filter if there is an error in LDAP (#17014)
* Add "new issue" btn on project (#17001)
* Add doctor dbconsistency check for release and attachment (#16978)
* Disable Fomantic's CSS tooltips (#16974)
* Add Cache-Control to avatar redirects (#16973)
* Make mirror feature more configurable (#16957)
* Add skip and limit to git.GetTags (#16897)
* Remove ParseQueueConnStr as it is unused (#16878)
* Remove unused Fomantic sidebar module (#16853)
* Allow LDAP Sources to provide Avatars (#16851)
* Remove Dashboard/Home button from the navbar (#16844)
* Use conditions but not repo ids as query condition (#16839)
* Add user settings key/value DB table (#16834)
* Add buttons to allow loading of incomplete diffs (#16829)
* Add information for migrate failure (#16803)
* Add EdDSA JWT signing algorithm (#16786)
* Add user status filter to admin user management page (#16770)
* Add Option to synchronize Admin & Restricted states from OIDC/OAuth2 along with Setting Scopes (#16766)
* Do not use thin scrollbars on Firefox (#16738)
* Download LFS in git and web workflow from minio/s3 directly (SERVE_DIRECT) (#16731)
* Compute proper foreground color for labels (#16729)
* Add edit button to wiki sidebar and footer (#16719)
* Fix migration svg color (#16715)
* Add link to vscode to repo header (#16664)
* Add filter by owner and team to issue/pulls search endpoint (#16662)
* Kanban colored boards (#16647)
* Allow setting X-FRAME-OPTIONS (#16643)
* Separate open and closed issue in metrics (#16637)
* Support direct comparison (git diff a..b) as well merge comparison (a…b) (#16635)
* Add setting to OAuth handlers to skip local 2FA authentication (#16594)
* Make PR merge options more intuitive (#16582)
* Show correct text when comparing commits on empty pull request (#16569)
* Pre-fill suggested New File 'name' and 'content' with Query Params (#16556)
* Add an abstract json layout to make it's easier to change json library (#16528)
* Make Mermaid.js limit configurable (#16519)
* Improve 2FA autofill (#16473)
* Add modals to Organization and Team remove/leave (#16471)
* Show tag name on dashboard items list (#16466)
* Change default cron schedules from @every 24h to @midnight (#16431)
* Prevent double sanitize (#16386)
* Replace `list.List` with slices (#16311)
* Add configuration option to restrict users by default (#16256)
* Move login out of models (#16199)
* Support pagination of organizations on user settings pages (#16083)
* Switch migration icon to svg (#15954)
* Add left padding for chunk header of split diff view (#13397)
* Allow U2F 2FA without TOTP (#11573)
* BUGFIXES
* GitLab reviews may not have the updated_at field set (#18450) (#18461)
* Fix detection of no commits when the default branch is not master (#18422) (#18423)
* Fix broken oauth2 authentication source edit page (#18412) (#18419)
* Place inline diff comment dialogs on split diff in 4th and 8th columns (#18403) (#18404)
* Fix restore without topic failure (#18387) (#18400)
* Fix commit's time (#18375) (#18392)
* Fix partial cloning a repo (#18373) (#18377)
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
* Prevent showing webauthn error for every time visiting `/user/settings/security` (#18386)
* Fix mime-type detection for HTTP server (#18370) (#18371)
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
* Restore propagation of ErrDependenciesLeft (#18325)
* Fix PR comments UI (#18323)
* Use indirect comparison when showing pull requests (#18313)
* Replace satori/go.uuid with gofrs/uuid (#18311)
* Fix commit links on compare page (#18310)
* Don't show double error response in git hook (#18292)
* Handle missing default branch better in owner/repo/branches page (#18290)
* Fix CheckRepoStats and reuse it during migration (#18264)
* Prevent underline hover on cards (#18259)
* Don't delete branch if other PRs with this branch are open (#18164)
* Require codereview to have content (#18156)
* Allow admin to associate missing LFS objects for repositories (#18143)
* When attempting to subscribe other user to issue report why access denied (#18091)
* Add option to convert CRLF to LF line endings for sendmail (#18075)
* Only create pprof files for gitea serv if explicitly asked for (#18068)
* Abort merge if head has been updated before pressing merge (#18032)
* Improve TestPatch to use git read-tree -m and implement git-merge-one-file functionality (#18004)
* Use JSON module instead of stdlib json (#18003)
* Fixed issue merged/closed wording (#17973)
* Return nicer error for ForcePrivate (#17971)
* Fix overflow in commit graph (#17947)
* Prevent services/mailer/mailer_test.go tests from deleteing data directory (#17941)
* Use disable_form_autofill on Codebase and Gitbucket (#17936)
* Fix a panic in NotifyCreateIssueComment (caused by string truncation) (#17928)
* Fix markdown URL parsing (#17924)
* Apply CSS Variables to all message elements (#17920)
* Improve checkBranchName (#17901)
* Update chi/middleware to chi/v5/middleware (#17888)
* Fix position of label color picker colors (#17866)
* Fix ListUnadoptedRepositories incorrect total count (#17865)
* Remove whitespace inside rendered code `<td>` (#17859)
* Make Co-committed-by and co-authored-by trailers optional (#17848)
* Fix value of User.IsRestricted when oauth2 user registration (#17839)
* Use new OneDev /milestones endpoint (#17782)
* Prevent deadlock in TestPersistableChannelQueue (#17717)
* Simplify code for writing SHA to name-rev (#17696)
* Fix database deadlock when update issue labels (#17649)
* Add warning for BIDI characters in page renders and in diffs (#17562)
* Fix ipv6 parsing for builtin ssh server (#17561)
* Multiple Escaping Improvements (#17551)
* Fixes #16559 - Do not trim leading spaces for tab delimited (#17442)
* Show client-side error if wiki page is empty (#17415)
* Fix context popup error (#17398)
* Stop sanitizing full name in API (#17396)
* Fix issue close/comment buttons on mobile (#17317)
* Fix navbar UI (#17235)
* Fix problem when database id is not increment as expected (#17229)
* Open the DingTalk link in browser (#17084)
* Remove heads pointing to missing old refs (#17076)
* Fix commit status index problem (#17061)
* Handle broken references in mirror sync (#17013)
* Fix for create repo page layout (#17012)
* Improve LDAP synchronization efficiency (#16994)
* Add repo_id for attachment (#16958)
* Clean-up HookPreReceive and restore functionality for pushing non-standard refs (#16705)
* Remove duplicate csv import in modules/csv/csv.go (#16631)
* Improve SMTP authentication and Fix user creation bugs (#16612)
* Fixed emoji alias not parsed in links (#16221)
* Calculate label URL on API (#16186)
* TRANSLATION
* Fix mispelling of starred as stared (#17465)
* Re-separate the color translation strings (#17390)
* Enable Malayalam, Greek, Persian, Hungarian & Indonesian by default (#16998)
* BUILD
* Add lockfile-check (#18285)
* Don't store assets modified time into generated files (#18193)
* MISC
* Update JS dependencies (#17611)
## [1.15.11](https://github.com/go-gitea/gitea/releases/tag/v1.15.11) - 2022-01-29
* SECURITY
* Only view milestones from current repo (#18414) (#18418)
* BUGFIXES
* Fix broken when no commits and default branch is not master (#18422) (#18424)
* Fix commit's time (#18375) (#18409)
* Fix restore without topic failure (#18387) (#18401)
* Fix mermaid import in 1.15 (it uses ESModule now) (#18382)
* Update to go/text 0.3.7 (#18336)
* MISC
* Upgrade EasyMDE to 2.16.1 (#18278) (#18279)
## [1.15.10](https://github.com/go-gitea/gitea/releases/tag/v1.15.10) - 2022-01-14
* BUGFIXES
* Fix inconsistent PR comment counts (#18260) (#18261)
* Fix release link broken (#18252) (#18253)
* Fix update user from site administration page bug (#18250) (#18251)
* Set HeadCommit when creating tags (#18116) (#18173)
* Use correct translation key for error messages due to max repo limits (#18135 & #18153) (#18152)
* Fix purple color in suggested label colors (#18241) (#18242)
* SECURITY
* Bump mermaid from 8.10.1 to 8.13.8 (#18198) (#18206)
## [1.15.9](https://github.com/go-gitea/gitea/releases/tag/v1.15.9) - 2021-12-30
* BUGFIXES
* Fix wrong redirect on org labels (#18128) (#18134)
* Fix: unstable sort skips/duplicates issues across pages (#18094) (#18095)
* Revert "Fix delete u2f keys bug (#18042)" (#18107)
* Migrating wiki don't require token, so we should move it out of the require form (#17645) (#18104)
* Prevent NPE if gitea uploader fails to open url (#18080) (#18101)
* Reset locale on login (#17734) (#18100)
* Correctly handle failed migrations (#17575) (#18099)
* Instead of using routerCtx just escape the url before routing (#18086) (#18098)
* Quote references to the user table in consistency checks (#18072) (#18073)
* Add NotFound handler (#18062) (#18067)
* Ensure that git repository is closed before transfer (#18049) (#18057)
* Use common sessioner for API and web routes (#18114)
* TRANSLATION
* Fix code search result hint on zh-CN (#18053)
## [1.15.8](https://github.com/go-gitea/gitea/releases/tag/v1.15.8) - 2021-12-20
* BUGFIXES
* Move POST /{username}/action/{action} to simply POST /{username} (#18045) (#18046)
* Fix delete u2f keys bug (#18040) (#18042)
* Reset Session ID on login (#18018) (#18041)
* Prevent off-by-one error on comments on newly appended lines (#18029) (#18035)
* Stop printing 03d after escaped characters in logs (#18030) (#18034)
* Reset locale on login (#18023) (#18025)
* Fix reset password email template (#17025) (#18022)
* Fix outType on gitea dump (#18000) (#18016)
* Ensure complexity, minlength and isPwned are checked on password setting (#18005) (#18015)
* Fix rename notification bug (#18011)
* Prevent double decoding of % in url params (#17997) (#18001)
* Prevent hang in git cat-file if the repository is not a valid repository (Partial #17991) (#17992)
* Prevent deadlock in create issue (#17970) (#17982)
* TESTING
* Use non-expiring key. (#17984) (#17985)
## [1.15.7](https://github.com/go-gitea/gitea/releases/tag/v1.15.7) - 2021-12-01
* ENHANCEMENTS
* Only allow webhook to send requests to allowed hosts (#17482) (#17510)
* Fix login redirection links (#17451) (#17473)
* BUGFIXES
* Fix database inconsistent when admin change user email (#17549) (#17840)
* Use correct user on releases (#17806) (#17818)
* Fix commit count in tag view (#17698) (#17790)
* Fix close issue but time watcher still running (#17643) (#17761)
* Fix Migrate Description (#17692) (#17727)
* Fix bug when project board get open issue number (#17703) (#17726)
* Return 400 but not 500 when request archive with wrong format (#17691) (#17700)
* Fix bug when read mysql database max lifetime (#17682) (#17690)
* Fix database deadlock when update issue labels (#17649) (#17665)
* Fix bug on detect issue/comment writer (#17592)
* Remove appSubUrl from pasted images (#17572) (#17588)
* Make `ParsePatch` more robust (#17573) (#17580)
* Fix stats upon searching issues (#17566) (#17578)
* Escape issue titles in comments list (#17555) (#17556)
* Fix zero created time bug on commit api (#17546) (#17547)
* Fix database keyword quote problem on migration v161 (#17522) (#17523)
* Fix email with + when active (#17518) (#17520)
* Stop double encoding blame commit messages (#17498) (#17500)
* Quote the table name in CountOrphanedObjects (#17487) (#17488)
* Run Migrate in Install rather than just SyncTables (#17475) (#17486)
* BUILD
* Fix golangci-lint warnings (#17598 et al) (#17668)
* MISC
* Preserve color when inverting emojis (#17797) (#17799)
## [1.15.6](https://github.com/go-gitea/gitea/releases/tag/v1.15.6) - 2021-10-28
* BUGFIXES
* Prevent panic in serv.go with Deploy Keys (#17434) (#17435)
* Fix CSV render error (#17406) (#17431)
* Read expected buffer size (#17409) (#17430)
* Ensure that restricted users can access repos for which they are members (#17460) (#17464)
* Make commit-statuses popup show correctly (#17447) (#17466)
* TESTING
* Add integration tests for private.NoServCommand and private.ServCommand (#17456) (#17463)
## [1.15.5](https://github.com/go-gitea/gitea/releases/tag/v1.15.5) - 2021-10-21
* SECURITY
* Upgrade Bluemonday to v1.0.16 (#17372) (#17374)
* Ensure correct SSH permissions check for private and restricted users (#17370) (#17373)
* BUGFIXES
* Prevent NPE in CSV diff rendering when column removed (#17018) (#17377)
* Offer rsa-sha2-512 and rsa-sha2-256 algorithms in internal SSH (#17281) (#17376)
* Don't panic if we fail to parse U2FRegistration data (#17304) (#17371)
* Ensure popup text is aligned left (backport for 1.15) (#17343)
* Ensure that git daemon export ok is created for mirrors (#17243) (#17306)
* Disable core.protectNTFS (#17300) (#17302)
* Use pointer for wrappedConn methods (#17295) (#17296)
* AutoRegistration is supposed to be working with disabled registration (backport) (#17292)
* Handle duplicate keys on GPG key ring (#17242) (#17284)
* Fix SVG side by side comparison link (#17375) (#17391)
## [1.15.4](https://github.com/go-gitea/gitea/releases/tag/v1.15.4) - 2021-10-08
* BUGFIXES
* Raw file API: don't try to interpret 40char filenames as commit SHA (#17185) (#17272)
* Don't allow merged PRs to be reopened (#17192) (#17271)
* Fix incorrect repository count on organization tab of dashboard (#17256) (#17266)
* Fix unwanted team review request deletion (#17257) (#17264)
* Fix broken Activities link in team dashboard (#17255) (#17258)
* API pull's head/base have correct permission(#17214) (#17245)
* Fix strange behavior of DownloadPullDiffOrPatch in incorrect index (#17223) (#17227)
* Upgrade xorm to v1.2.5 (#17177) (#17188)
* Fix missing repo link in issue/pull assigned emails (#17183) (#17184)
* Fix bug of get context user (#17169) (#17172)
* Nicely handle missing user in collaborations (#17049) (#17166)
* Add Horizontal scrollbar to inner menu on Chrome (#17086) (#17164)
* Fix wrong i18n keys (#17150) (#17153)
* Fix Archive Creation: correct transaction ending (#17151)
* Prevent panic in Org mode HighlightCodeBlock (#17140) (#17141)
* Create doctor command to fix repo_units broken by dumps from 1.14.3-1.14.6 (#17136) (#17137)
* ENHANCEMENT
* Check user instead of organization when creating a repo from a template via API (#16346) (#17195)
* TRANSLATION
* v1.15 fix Sprintf format 'verbs' in locale files (#17187)
## [1.15.3](https://github.com/go-gitea/gitea/releases/tag/v1.15.3) - 2021-09-19
* ENHANCEMENTS
* Add fluid to ui container class to remove margin (#16396) (#16976)
* Add caller to cat-file batch calls (#17082) (#17089)
* BUGFIXES
* Render full plain readme. (#17083) (#17090)
* Upgrade xorm to v1.2.4 (#17059)
* Fix bug of migrate comments which only fetch one page (#17055) (#17058)
* Do not show issue context popup on external issues (#17050) (#17054)
* Decrement Fork Num when converting from Fork (#17035) (#17046)
* Correctly rollback in ForkRepository (#17034) (#17045)
* Fix missing close in WalkGitLog (#17008) (#17009)
* Add prefix to SVG id/class attributes (#16997) (#17000)
* Fix bug of migrated repository not index (#16991) (#16996)
* Skip AllowedUserVisibilityModes validation on update user if it is an organisation (#16988) (#16990)
* Fix storage Iterate bug and Add storage doctor to delete garbage attachments (#16971) (#16977)
* Fix issue with issue default mail template (#16956) (#16975)
* Ensure that rebase conflicts are handled in updates (#16952) (#16960)
* Prevent panic on diff generation (#16950) (#16951)
## [1.15.2](https://github.com/go-gitea/gitea/releases/tag/v1.15.2) - 2021-09-03 ## [1.15.2](https://github.com/go-gitea/gitea/releases/tag/v1.15.2) - 2021-09-03
* BUGFIXES * BUGFIXES
@@ -959,15 +293,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Remove utf8 option from installation page (#16126) * Remove utf8 option from installation page (#16126)
* Use Wants= over Requires= in systemd file (#15897) * Use Wants= over Requires= in systemd file (#15897)
## [1.14.7](https://github.com/go-gitea/gitea/releases/tag/v1.14.7) - 2021-09-02
* BUGFIXES
* Add missing gitRepo close at GetDiffRangeWithWhitespaceBehavior (Partial #16894) (#16896)
* Fix wiki raw commit diff/patch view (#16891) (#16893)
* Ensure wiki repos are all closed (#16886) (#16889)
* Upgrade xorm to v1.2.2 (#16663) & Add test to ensure that dumping of login sources remains correct (#16847) (#16849)
* Recreate Tables should Recreate indexes on MySQL (#16718) (#16740)
## [1.14.6](https://github.com/go-gitea/gitea/releases/tag/v1.14.6) - 2021-08-04 ## [1.14.6](https://github.com/go-gitea/gitea/releases/tag/v1.14.6) - 2021-08-04
* SECURITY * SECURITY

View File

@@ -81,22 +81,23 @@ Here's how to run the test suite:
|``make lint-frontend`` | lint frontend files | |``make lint-frontend`` | lint frontend files |
|``make lint-backend`` | lint backend files | |``make lint-backend`` | lint backend files |
- run test code (Suggest run in Linux) - run test code (Suggest run in linux)
| | | | | |
| :------------------------------------- | :----------------------------------------------- | | :------------------------------------- | :----------------------------------------------- |
|``make test[\#TestSpecificName]`` | run unit test | |``make test[\#TestSpecificName]`` | run unit test |
|``make test-sqlite[\#TestSpecificName]``| run [integration](integrations) test for SQLite | |``make test-sqlite[\#TestSpecificName]``| run [integration](integrations) test for sqlite |
|[More details about integrations](integrations/README.md) | |[More detail message about integrations](integrations/README.md) |
## Vendoring ## Vendoring
We manage dependencies via [Go Modules](https://golang.org/cmd/go/#hdr-Module_maintenance), more details: [go mod](https://go.dev/ref/mod). We keep a cached copy of dependencies within the `vendor/` directory,
managing updates via [Modules](https://golang.org/cmd/go/#hdr-Module_maintenance).
Pull requests should only include `go.mod`, `go.sum` updates if they are part of Pull requests should only include `vendor/` updates if they are part of
the same change, be it a bugfix or a feature addition. the same change, be it a bugfix or a feature addition.
The `go.mod`, `go.sum` update needs to be justified as part of the PR description, The `vendor/` update needs to be justified as part of the PR description,
and must be verified by the reviewers and/or merger to always reference and must be verified by the reviewers and/or merger to always reference
an existing upstream commit. an existing upstream commit.
@@ -105,7 +106,7 @@ You can find more information on how to get started with it on the [Modules Wiki
## Translation ## Translation
We do all translation work inside [Crowdin](https://crowdin.com/project/gitea). We do all translation work inside [Crowdin](https://crowdin.com/project/gitea).
The only translation that is maintained in this Git repository is 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) [`en_US.ini`](https://github.com/go-gitea/gitea/blob/master/options/locale/locale_en-US.ini)
and is synced regularly to Crowdin. Once a translation has reached and is synced regularly to Crowdin. Once a translation has reached
A SATISFACTORY PERCENTAGE it will be synced back into this repo and A SATISFACTORY PERCENTAGE it will be synced back into this repo and
@@ -156,7 +157,7 @@ import (
## Design guideline ## 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: 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 - **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. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging). - **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
@@ -206,10 +207,6 @@ In general, HTTP methods are chosen as follows:
An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required). An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required).
### Endpoints returning lists should
* support pagination (`page` & `limit` options in query)
* set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
## Developer Certificate of Origin (DCO) ## Developer Certificate of Origin (DCO)
@@ -222,7 +219,7 @@ Additionally you could add a line at the end of your commit message.
Signed-off-by: Joe Smith <joe.smith@email.com> Signed-off-by: Joe Smith <joe.smith@email.com>
``` ```
If you set your `user.name` and `user.email` Git configs, you can add the If you set your `user.name` and `user.email` git configs, you can add the
line to the end of your commit automatically with `git commit -s`. line to the end of your commit automatically with `git commit -s`.
We assume in good faith that the information you provide is legally binding. We assume in good faith that the information you provide is legally binding.
@@ -267,7 +264,7 @@ 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 months and forgets to leave the maintainers team, the owners may move
him or her from the maintainers team to the advisors team. him or her from the maintainers team to the advisors team.
For security reasons, Maintainers should use 2FA for their accounts and For security reasons, Maintainers should use 2FA for their accounts and
if possible provide GPG signed commits. if possible provide gpg signed commits.
https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/ https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/
https://help.github.com/articles/signing-commits-with-gpg/ https://help.github.com/articles/signing-commits-with-gpg/
@@ -298,11 +295,6 @@ and lead the development of Gitea.
To honor the past owners, here's the history of the owners and the time To honor the past owners, here's the history of the owners and the time
they served: they served:
* 2022-01-01 ~ 2022-12-31 - https://github.com/go-gitea/gitea/issues/17872
* [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
* [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.io>
* [Andrew Thornton](https://gitea.com/zeripath) <art27@cantab.net>
* 2021-01-01 ~ 2021-12-31 - https://github.com/go-gitea/gitea/issues/13801 * 2021-01-01 ~ 2021-12-31 - https://github.com/go-gitea/gitea/issues/13801
* [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com> * [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
* [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) <lauris@nix.lv> * [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) <lauris@nix.lv>
@@ -330,13 +322,13 @@ they served:
## Versions ## Versions
Gitea has the `main` branch as a tip branch and has version branches 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 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 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, pull requests on the `release/v0.9` branch and publish a `v0.9.1` tag,
after bringing the bug fix also to the main branch. after bringing the bug fix also to the master branch.
Since the `main` branch is a tip version, if you wish to use Gitea 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 in production, please download the latest release tag version. All the
branches will be protected via GitHub, all the PRs to every branch must branches will be protected via GitHub, all the PRs to every branch must
be reviewed by two maintainers and must pass the automatic tests. be reviewed by two maintainers and must pass the automatic tests.
@@ -344,14 +336,14 @@ be reviewed by two maintainers and must pass the automatic tests.
## Releasing Gitea ## Releasing Gitea
* Let $vmaj, $vmin and $vpat be Major, Minor and Patch version numbers, $vpat should be rc1, rc2, 0, 1, ...... $vmaj.$vmin will be kept the same as milestones on github or gitea in future. * Let $vmaj, $vmin and $vpat be Major, Minor and Patch version numbers, $vpat should be rc1, rc2, 0, 1, ...... $vmaj.$vmin will be kept the same as milestones on github or gitea in future.
* Before releasing, confirm all the version's milestone issues or PRs has been resolved. Then discuss the release on Discord channel #maintainers and get agreed with almost all the owners and mergers. Or you can declare the version and if nobody against in about serval hours. * Before releasing, confirm all the version's milestone issues or PRs has been resolved. Then discuss the release on discord channel #maintainers and get agreed with almost all the owners and mergers. Or you can declare the version and if nobody against in about serval hours.
* If this is a big version first you have to create PR for changelog on branch `main` with PRs with label `changelog` and after it has been merged do following steps: * If this is a big version first you have to create PR for changelog on branch `master` with PRs with label `changelog` and after it has been merged do following steps:
* Create `-dev` tag as `git tag -s -F release.notes v$vmaj.$vmin.0-dev` and push the tag as `git push origin v$vmaj.$vmin.0-dev`. * Create `-dev` tag as `git tag -s -F release.notes v$vmaj.$vmin.0-dev` and push the tag as `git push origin v$vmaj.$vmin.0-dev`.
* When CI has finished building tag then you have to create a new branch named `release/v$vmaj.$vmin` * When CI has finished building tag then you have to create a new branch named `release/v$vmaj.$vmin`
* If it is bugfix version create PR for changelog on branch `release/v$vmaj.$vmin` and wait till it is reviewed and merged. * If it is bugfix version create PR for changelog on branch `release/v$vmaj.$vmin` and wait till it is reviewed and merged.
* Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`. * Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`.
* And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically create a release and upload all the compiled binary. (But currently it doesn't add the release notes automatically. Maybe we should fix that.) * And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically created a release and upload all the compiled binary. (But currently it didn't add the release notes automatically. Maybe we should fix that.)
* If needed send PR for changelog on branch `main`. * If needed send PR for changelog on branch `master`.
* Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release. * Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release.
## Copyright ## Copyright

View File

@@ -1,5 +1,7 @@
###################################
#Build stage #Build stage
FROM golang:1.18-alpine3.15 AS build-env FROM golang:1.16-alpine3.13 AS build-env
ARG GOPROXY ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct} ENV GOPROXY ${GOPROXY:-direct}
@@ -64,5 +66,4 @@ CMD ["/bin/s6-svscan", "/etc/s6"]
COPY docker/root / COPY docker/root /
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
RUN chmod 755 /usr/bin/entrypoint /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini RUN ln -s /app/gitea/gitea /usr/local/bin/gitea
RUN chmod 755 /etc/s6/gitea/* /etc/s6/openssh/* /etc/s6/.s6-svscan/*

View File

@@ -1,5 +1,7 @@
###################################
#Build stage #Build stage
FROM golang:1.18-alpine3.15 AS build-env FROM golang:1.16-alpine3.13 AS build-env
ARG GOPROXY ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct} ENV GOPROXY ${GOPROXY:-direct}
@@ -51,9 +53,8 @@ RUN mkdir -p /var/lib/gitea /etc/gitea
RUN chown git:git /var/lib/gitea /etc/gitea RUN chown git:git /var/lib/gitea /etc/gitea
COPY docker/rootless / COPY docker/rootless /
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /usr/local/bin/gitea
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh /usr/local/bin/docker-setup.sh /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini
#git:git #git:git
USER 1000:1000 USER 1000:1000

View File

@@ -1,4 +1,5 @@
Alexey Makhov <amakhov@avito.ru> (@makhov) Alexey Makhov <amakhov@avito.ru> (@makhov)
Andrey Nering <andrey.nering@gmail.com> (@andreynering)
Bo-Yi Wu <appleboy.tw@gmail.com> (@appleboy) Bo-Yi Wu <appleboy.tw@gmail.com> (@appleboy)
Ethan Koenig <ethantkoenig@gmail.com> (@ethantkoenig) Ethan Koenig <ethantkoenig@gmail.com> (@ethantkoenig)
Kees de Vries <bouwko@gmail.com> (@Bwko) Kees de Vries <bouwko@gmail.com> (@Bwko)
@@ -43,6 +44,3 @@ Patrick Schratz <patrick.schratz@gmail.com> (@pat-s)
Janis Estelmann <admin@oldschoolhack.me> (@KN4CK3R) Janis Estelmann <admin@oldschoolhack.me> (@KN4CK3R)
Steven Kriegler <sk.bunsenbrenner@gmail.com> (@justusbunsi) Steven Kriegler <sk.bunsenbrenner@gmail.com> (@justusbunsi)
Jimmy Praet <jimmy.praet@telenet.be> (@jpraet) Jimmy Praet <jimmy.praet@telenet.be> (@jpraet)
Leon Hofmeister <dev.lh@web.de> (@delvh)
Gusted <williamzijl7@hotmail.com) (@Gusted)
singuliere <singuliere@autistici.org> (@singuliere)

215
Makefile
View File

@@ -24,17 +24,9 @@ SHASUM ?= shasum -a 256
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" ) HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
COMMA := , COMMA := ,
XGO_VERSION := go-1.18.x XGO_VERSION := go-1.16.x
MIN_GO_VERSION := 001016000
AIR_PACKAGE ?= github.com/cosmtrek/air@v1.29.0 MIN_NODE_VERSION := 012017000
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.4.0
ERRCHECK_PACKAGE ?= github.com/kisielk/errcheck@v1.6.0
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.3.0
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.44.2
GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.10
MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.29.0
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
DOCKER_IMAGE ?= gitea/gitea DOCKER_IMAGE ?= gitea/gitea
DOCKER_TAG ?= latest DOCKER_TAG ?= latest
@@ -65,6 +57,8 @@ else
SED_INPLACE := sed -i '' SED_INPLACE := sed -i ''
endif endif
GOFMT ?= gofmt -s
EXTRA_GOFLAGS ?= EXTRA_GOFLAGS ?=
MAKE_VERSION := $(shell $(MAKE) -v | head -n 1) MAKE_VERSION := $(shell $(MAKE) -v | head -n 1)
@@ -99,7 +93,7 @@ LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(G
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64 LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/models/migrations code.gitea.io/gitea/integrations/migration-test code.gitea.io/gitea/integrations,$(shell $(GO) list ./... | grep -v /vendor/)) GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/models/migrations code.gitea.io/gitea/integrations/migration-test code.gitea.io/gitea/integrations,$(shell $(GO) list -mod=vendor ./... | grep -v /vendor/))
FOMANTIC_WORK_DIR := web_src/fomantic FOMANTIC_WORK_DIR := web_src/fomantic
@@ -123,7 +117,7 @@ TEST_TAGS ?= sqlite sqlite_unlock_notify
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR)
GO_DIRS := cmd integrations models modules routers build services tools GO_DIRS := cmd integrations models modules routers build services vendor tools
GO_SOURCES := $(wildcard *.go) GO_SOURCES := $(wildcard *.go)
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go) GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go)
@@ -132,6 +126,10 @@ ifeq ($(filter $(TAGS_SPLIT),bindata),bindata)
GO_SOURCES += $(BINDATA_DEST) GO_SOURCES += $(BINDATA_DEST)
endif endif
GO_SOURCES_OWN := $(filter-out vendor/% %/bindata.go, $(GO_SOURCES))
#To update swagger use: GO111MODULE=on go get -u github.com/go-swagger/go-swagger/cmd/swagger
SWAGGER := $(GO) run -mod=vendor github.com/go-swagger/go-swagger/cmd/swagger
SWAGGER_SPEC := templates/swagger/v1_json.tmpl SWAGGER_SPEC := templates/swagger/v1_json.tmpl
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
@@ -171,9 +169,6 @@ help:
@echo " - watch-backend watch backend files and continuously rebuild" @echo " - watch-backend watch backend files and continuously rebuild"
@echo " - clean delete backend and integration files" @echo " - clean delete backend and integration files"
@echo " - clean-all delete backend, frontend and integration files" @echo " - clean-all delete backend, frontend and integration files"
@echo " - deps install dependencies"
@echo " - deps-frontend install frontend dependencies"
@echo " - deps-backend install backend dependencies"
@echo " - lint lint everything" @echo " - lint lint everything"
@echo " - lint-frontend lint frontend files" @echo " - lint-frontend lint frontend files"
@echo " - lint-backend lint backend files" @echo " - lint-backend lint backend files"
@@ -194,6 +189,8 @@ help:
@echo " - generate-swagger generate the swagger spec from code comments" @echo " - generate-swagger generate the swagger spec from code comments"
@echo " - swagger-validate check if the swagger spec is valid" @echo " - swagger-validate check if the swagger spec is valid"
@echo " - golangci-lint run golangci-lint linter" @echo " - golangci-lint run golangci-lint linter"
@echo " - revive run revive linter"
@echo " - misspell check for misspellings"
@echo " - vet examines Go source code and reports suspicious constructs" @echo " - vet examines Go source code and reports suspicious constructs"
@echo " - test[\#TestSpecificName] run unit test" @echo " - test[\#TestSpecificName] run unit test"
@echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite" @echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite"
@@ -201,15 +198,10 @@ help:
.PHONY: go-check .PHONY: go-check
go-check: go-check:
$(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2)) $(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+' | tr '.' ' ');))
$(eval MIN_GO_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' ')))
$(eval GO_VERSION_STR := $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+'))
$(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(GO_VERSION_STR)' | tr '.' ' ')))
@if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \ @if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \
echo "Gitea requires Go $(MIN_GO_VERSION_STR) or greater to build, but $(GO_VERSION) was found. You can get an updated version at https://go.dev/dl/"; \ echo "Gitea requires Go 1.16 or greater to build. You can get it at https://golang.org/dl/"; \
exit 1; \ exit 1; \
else \
echo "WARNING: Please ensure Go $(GO_VERSION_STR) is still maintained to avoid possible security problems. You can check it at https://go.dev/dl/"; \
fi fi
.PHONY: git-check .PHONY: git-check
@@ -221,12 +213,11 @@ git-check:
.PHONY: node-check .PHONY: node-check
node-check: node-check:
$(eval MIN_NODE_VERSION_STR := $(shell grep -Eo '"node":.*[0-9.]+"' package.json | sed -n 's/.*[^0-9.]\([0-9.]*\)"/\1/p'))
$(eval MIN_NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_NODE_VERSION_STR)' | tr '.' ' ')))
$(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');)) $(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');))
$(eval MIN_NODE_VER_FMT := $(shell printf "%g.%g.%g" $(shell echo $(MIN_NODE_VERSION) | grep -o ...)))
$(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1)) $(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1))
@if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \ @if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \
echo "Gitea requires Node.js $(MIN_NODE_VERSION_STR) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \ echo "Gitea requires Node.js $(MIN_NODE_VER_FMT) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \
exit 1; \ exit 1; \
fi fi
@@ -245,13 +236,14 @@ clean:
.PHONY: fmt .PHONY: fmt
fmt: fmt:
@echo "Running gitea-fmt (with gofumpt)..." @echo "Running go fmt..."
@MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}' @$(GOFMT) -w $(GO_SOURCES_OWN)
.PHONY: vet .PHONY: vet
vet: vet:
@echo "Running go vet..." @echo "Running go vet..."
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet @$(GO) vet $(GO_PACKAGES)
@GOOS= GOARCH= $(GO) build -mod=vendor code.gitea.io/gitea-vet
@$(GO) vet -vettool=gitea-vet $(GO_PACKAGES) @$(GO) vet -vettool=gitea-vet $(GO_PACKAGES)
.PHONY: $(TAGS_EVIDENCE) .PHONY: $(TAGS_EVIDENCE)
@@ -265,7 +257,7 @@ endif
.PHONY: generate-swagger .PHONY: generate-swagger
generate-swagger: generate-swagger:
$(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)' $(SWAGGER) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
$(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)' $(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)'
@@ -281,18 +273,44 @@ swagger-check: generate-swagger
.PHONY: swagger-validate .PHONY: swagger-validate
swagger-validate: swagger-validate:
$(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)'
$(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)' $(SWAGGER) validate './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
.PHONY: errcheck .PHONY: errcheck
errcheck: errcheck:
@hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
GO111MODULE=off $(GO) get -u github.com/kisielk/errcheck; \
fi
@echo "Running errcheck..." @echo "Running errcheck..."
$(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES) @errcheck $(GO_PACKAGES)
.PHONY: revive
revive:
@hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
GO111MODULE=off $(GO) get -u github.com/mgechev/revive; \
fi
@revive -config .revive.toml -exclude=./vendor/... ./...
.PHONY: misspell-check
misspell-check:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi
@echo "Running misspell-check..."
@misspell -error -i unknwon $(GO_SOURCES_OWN)
.PHONY: misspell
misspell:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi
@echo "Running go misspell..."
@misspell -w -i unknwon $(GO_SOURCES_OWN)
.PHONY: fmt-check .PHONY: fmt-check
fmt-check: fmt-check:
# get all go files and run gitea-fmt (with gofmt) on them # get all go files and run go fmt on them
@diff=$$(MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -l '{file-list}'); \ @diff=$$($(GOFMT) -d $(GO_SOURCES_OWN)); \
if [ -n "$$diff" ]; then \ if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \ echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \ echo "$${diff}"; \
@@ -303,22 +321,22 @@ fmt-check:
checks: checks-frontend checks-backend checks: checks-frontend checks-backend
.PHONY: checks-frontend .PHONY: checks-frontend
checks-frontend: lockfile-check svg-check checks-frontend: svg-check
.PHONY: checks-backend .PHONY: checks-backend
checks-backend: gomod-check swagger-check swagger-validate checks-backend: misspell-check test-vendor swagger-check swagger-validate
.PHONY: lint .PHONY: lint
lint: lint-frontend lint-backend lint: lint-frontend lint-backend
.PHONY: lint-frontend .PHONY: lint-frontend
lint-frontend: node_modules lint-frontend: node_modules
npx eslint --color --max-warnings=0 web_src/js build templates *.config.js docs/assets/js npx eslint --color --max-warnings=0 web_src/js build templates *.config.js
npx stylelint --color --max-warnings=0 web_src/less npx stylelint --color --max-warnings=0 web_src/less
npx editorconfig-checker templates npx editorconfig-checker templates
.PHONY: lint-backend .PHONY: lint-backend
lint-backend: golangci-lint vet lint-backend: golangci-lint revive vet
.PHONY: watch .PHONY: watch
watch: watch:
@@ -331,15 +349,18 @@ watch-frontend: node-check node_modules
.PHONY: watch-backend .PHONY: watch-backend
watch-backend: go-check watch-backend: go-check
$(GO) run $(AIR_PACKAGE) -c .air.toml @hash air > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
GO111MODULE=off $(GO) get -u github.com/cosmtrek/air; \
fi
air -c .air.conf
.PHONY: test .PHONY: test
test: test-frontend test-backend test: test-frontend test-backend
.PHONY: test-backend .PHONY: test-backend
test-backend: test-backend:
@echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." @echo "Running go test with -tags '$(TEST_TAGS)'..."
@$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_PACKAGES) @$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='$(TEST_TAGS)' $(GO_PACKAGES)
.PHONY: test-frontend .PHONY: test-frontend
test-frontend: node_modules test-frontend: node_modules
@@ -360,29 +381,26 @@ test-check:
.PHONY: test\#% .PHONY: test\#%
test\#%: test\#%:
@echo "Running go test with -tags '$(TEST_TAGS)'..." @echo "Running go test with -tags '$(TEST_TAGS)'..."
@$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_PACKAGES) @$(GO) test -mod=vendor $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_PACKAGES)
.PHONY: coverage .PHONY: coverage
coverage: coverage:
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' coverage.out > coverage-bodged.out GO111MODULE=on $(GO) run -mod=vendor build/gocovmerge.go integration.coverage.out $(shell find . -type f -name "coverage.out") > coverage.all
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' integration.coverage.out > integration.coverage-bodged.out
GO111MODULE=on $(GO) run build/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all || (echo "gocovmerge failed"; echo "integration.coverage.out"; cat integration.coverage.out; echo "coverage.out"; cat coverage.out; exit 1)
.PHONY: unit-test-coverage .PHONY: unit-test-coverage
unit-test-coverage: unit-test-coverage:
@echo "Running unit-test-coverage $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." @echo "Running unit-test-coverage -tags '$(TEST_TAGS)'..."
@$(GO) test $(GOTESTFLAGS) -timeout=20m -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1 @$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
.PHONY: vendor .PHONY: vendor
vendor: vendor:
$(GO) mod tidy && $(GO) mod vendor $(GO) mod tidy && $(GO) mod vendor
.PHONY: gomod-check .PHONY: test-vendor
gomod-check: test-vendor: vendor
@$(GO) mod tidy @diff=$$(git diff vendor/); \
@diff=$$(git diff go.sum); \
if [ -n "$$diff" ]; then \ if [ -n "$$diff" ]; then \
echo "Please run '$(GO) mod tidy' and commit the result:"; \ echo "Please run 'make vendor' and commit the result:"; \
echo "$${diff}"; \ echo "$${diff}"; \
exit 1; \ exit 1; \
fi fi
@@ -404,11 +422,6 @@ test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.sqlite.test GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.sqlite.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.individual.sqlite.test GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.individual.sqlite.test
.PHONY: test-sqlite-migration\#%
test-sqlite-migration\#%: migrations.sqlite.test migrations.individual.sqlite.test generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.individual.sqlite.test -test.run $(subst .,/,$*)
generate-ini-mysql: generate-ini-mysql:
sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \ sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \
-e 's|{{TEST_MYSQL_DBNAME}}|${TEST_MYSQL_DBNAME}|g' \ -e 's|{{TEST_MYSQL_DBNAME}}|${TEST_MYSQL_DBNAME}|g' \
@@ -515,22 +528,22 @@ integration-test-coverage: integrations.cover.test generate-ini-mysql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out
integrations.mysql.test: git-check $(GO_SOURCES) integrations.mysql.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mysql.test $(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mysql.test
integrations.mysql8.test: git-check $(GO_SOURCES) integrations.mysql8.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mysql8.test $(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mysql8.test
integrations.pgsql.test: git-check $(GO_SOURCES) integrations.pgsql.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.pgsql.test $(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.pgsql.test
integrations.mssql.test: git-check $(GO_SOURCES) integrations.mssql.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mssql.test $(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mssql.test
integrations.sqlite.test: git-check $(GO_SOURCES) integrations.sqlite.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags '$(TEST_TAGS)' $(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags '$(TEST_TAGS)'
integrations.cover.test: git-check $(GO_SOURCES) integrations.cover.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.test $(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.test
.PHONY: migrations.mysql.test .PHONY: migrations.mysql.test
migrations.mysql.test: $(GO_SOURCES) migrations.mysql.test: $(GO_SOURCES)
@@ -591,22 +604,25 @@ backend: go-check generate $(EXECUTABLE)
.PHONY: generate .PHONY: generate
generate: $(TAGS_PREREQ) generate: $(TAGS_PREREQ)
@echo "Running go generate..." @echo "Running go generate..."
@CC= GOOS= GOARCH= $(GO) generate -tags '$(TAGS)' $(GO_PACKAGES) @CC= GOOS= GOARCH= $(GO) generate -mod=vendor -tags '$(TAGS)' $(GO_PACKAGES)
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ) $(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@ CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build -mod=vendor $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
.PHONY: release .PHONY: release
release: frontend generate release-windows release-linux release-darwin release-copy release-compress vendor release-sources release-docs release-check release: frontend generate release-windows release-linux release-darwin release-copy release-compress release-sources release-docs release-check
$(DIST_DIRS): $(DIST_DIRS):
mkdir -p $(DIST_DIRS) mkdir -p $(DIST_DIRS)
.PHONY: release-windows .PHONY: release-windows
release-windows: | $(DIST_DIRS) release-windows: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) . @hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install src.techknowlogick.com/xgo@latest; \
fi
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
ifeq (,$(findstring gogit,$(TAGS))) ifeq (,$(findstring gogit,$(TAGS)))
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit . CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
endif endif
ifeq ($(CI),drone) ifeq ($(CI),drone)
cp /build/* $(DIST)/binaries cp /build/* $(DIST)/binaries
@@ -614,14 +630,20 @@ endif
.PHONY: release-linux .PHONY: release-linux
release-linux: | $(DIST_DIRS) release-linux: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) . @hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install src.techknowlogick.com/xgo@latest; \
fi
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) .
ifeq ($(CI),drone) ifeq ($(CI),drone)
cp /build/* $(DIST)/binaries cp /build/* $(DIST)/binaries
endif endif
.PHONY: release-darwin .PHONY: release-darwin
release-darwin: | $(DIST_DIRS) release-darwin: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) . @hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install src.techknowlogick.com/xgo@latest; \
fi
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
ifeq ($(CI),drone) ifeq ($(CI),drone)
cp /build/* $(DIST)/binaries cp /build/* $(DIST)/binaries
endif endif
@@ -636,7 +658,10 @@ release-check: | $(DIST_DIRS)
.PHONY: release-compress .PHONY: release-compress
release-compress: | $(DIST_DIRS) release-compress: | $(DIST_DIRS)
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && $(GO) run $(GXZ_PAGAGE) -k -9 $${file}; done; @hash gxz > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
GO111MODULE=off $(GO) get -u github.com/ulikunitz/xz/cmd/gxz; \
fi
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done;
.PHONY: release-sources .PHONY: release-sources
release-sources: | $(DIST_DIRS) release-sources: | $(DIST_DIRS)
@@ -657,25 +682,6 @@ docs:
fi fi
cd docs; make trans-copy clean build-offline; cd docs; make trans-copy clean build-offline;
.PHONY: deps
deps: deps-frontend deps-backend
.PHONY: deps-frontend
deps-frontend: node_modules
.PHONY: deps-backend
deps-backend:
$(GO) mod download
$(GO) install $(AIR_PACKAGE)
$(GO) install $(EDITORCONFIG_CHECKER_PACKAGE)
$(GO) install $(ERRCHECK_PACKAGE)
$(GO) install $(GOFUMPT_PACKAGE)
$(GO) install $(GOLANGCI_LINT_PACKAGE)
$(GO) install $(GXZ_PAGAGE)
$(GO) install $(MISSPELL_PACKAGE)
$(GO) install $(SWAGGER_PACKAGE)
$(GO) install $(XGO_PACKAGE)
node_modules: package-lock.json node_modules: package-lock.json
npm install --no-save npm install --no-save
@touch node_modules @touch node_modules
@@ -695,7 +701,6 @@ fomantic:
cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/ cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/
cp -f web_src/js/vendor/dropdown.js $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/definitions/modules cp -f web_src/js/vendor/dropdown.js $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/definitions/modules
cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build
rm -f $(FOMANTIC_WORK_DIR)/build/*.min.*
.PHONY: webpack .PHONY: webpack
webpack: $(WEBPACK_DEST) webpack: $(WEBPACK_DEST)
@@ -721,17 +726,6 @@ svg-check: svg
exit 1; \ exit 1; \
fi fi
.PHONY: lockfile-check
lockfile-check:
npm install --package-lock-only
@diff=$$(git diff package-lock.json); \
if [ -n "$$diff" ]; then \
echo "package-lock.json is inconsistent with package.json"; \
echo "Please run 'npm install --package-lock-only' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi
.PHONY: update-translations .PHONY: update-translations
update-translations: update-translations:
mkdir -p ./translations mkdir -p ./translations
@@ -769,18 +763,11 @@ pr\#%: clean-all
.PHONY: golangci-lint .PHONY: golangci-lint
golangci-lint: golangci-lint:
$(GO) run $(GOLANGCI_LINT_PACKAGE) run @hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
export BINARY="golangci-lint"; \
# workaround step for the lint-backend-windows CI task because 'go run' can not curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.37.0; \
# have distinct GOOS/GOARCH for its build and run steps fi
.PHONY: golangci-lint-windows golangci-lint run --timeout 10m
golangci-lint-windows:
@GOOS= GOARCH= $(GO) install $(GOLANGCI_LINT_PACKAGE)
golangci-lint run
.PHONY: editorconfig-checker
editorconfig-checker:
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates
.PHONY: docker .PHONY: docker
docker: docker:

View File

@@ -12,10 +12,13 @@
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea"> <a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
<img src="https://img.shields.io/discord/322538954119184384.svg"> <img src="https://img.shields.io/discord/322538954119184384.svg">
</a> </a>
<a href="https://microbadger.com/images/gitea/gitea" title="Get your own image badge on microbadger.com">
<img src="https://images.microbadger.com/badges/image/gitea/gitea.svg">
</a>
<a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov"> <a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov">
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg"> <img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
</a> </a>
<a href="https://goreportcard.com/report/code.gitea.io/gitea" title="Go Report Card"> <a href="https://godoc.org/code.gitea.io/gitea" title="Go Report Card">
<img src="https://goreportcard.com/badge/code.gitea.io/gitea"> <img src="https://goreportcard.com/badge/code.gitea.io/gitea">
</a> </a>
<a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc"> <a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc">
@@ -36,8 +39,8 @@
<a href="https://crowdin.com/project/gitea" title="Crowdin"> <a href="https://crowdin.com/project/gitea" title="Crowdin">
<img src="https://badges.crowdin.net/gitea/localized.svg"> <img src="https://badges.crowdin.net/gitea/localized.svg">
</a> </a>
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main" title="TODOs"> <a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea" title="TODOs">
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main"> <img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea">
</a> </a>
<a href="https://www.bountysource.com/teams/gitea" title="Bountysource"> <a href="https://www.bountysource.com/teams/gitea" title="Bountysource">
<img src="https://img.shields.io/bountysource/team/gitea/activity"> <img src="https://img.shields.io/bountysource/team/gitea/activity">
@@ -67,14 +70,14 @@ From the root of the source tree, run:
TAGS="bindata" make build TAGS="bindata" make build
or if SQLite support is required: or if sqlite support is required:
TAGS="bindata sqlite sqlite_unlock_notify" make build TAGS="bindata sqlite sqlite_unlock_notify" make build
The `build` target is split into two sub-targets: The `build` target is split into two sub-targets:
- `make backend` which requires [Go 1.17](https://go.dev/dl/) or greater. - `make backend` which requires [Go 1.13](https://golang.org/dl/) or greater.
- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater and Internet connectivity to download npm dependencies. - `make frontend` which requires [Node.js 12.17](https://nodejs.org/en/download/) or greater and Internet connectivity to download npm dependencies.
When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js and Internet connectivity. When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js and Internet connectivity.

View File

@@ -12,10 +12,13 @@
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea"> <a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
<img src="https://img.shields.io/discord/322538954119184384.svg"> <img src="https://img.shields.io/discord/322538954119184384.svg">
</a> </a>
<a href="https://microbadger.com/images/gitea/gitea" title="Get your own image badge on microbadger.com">
<img src="https://images.microbadger.com/badges/image/gitea/gitea.svg">
</a>
<a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov"> <a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov">
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg"> <img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
</a> </a>
<a href="https://goreportcard.com/report/code.gitea.io/gitea" title="Go Report Card"> <a href="https://godoc.org/code.gitea.io/gitea" title="Go Report Card">
<img src="https://goreportcard.com/badge/code.gitea.io/gitea"> <img src="https://goreportcard.com/badge/code.gitea.io/gitea">
</a> </a>
<a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc"> <a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc">
@@ -36,8 +39,8 @@
<a href="https://crowdin.com/project/gitea" title="Crowdin"> <a href="https://crowdin.com/project/gitea" title="Crowdin">
<img src="https://badges.crowdin.net/gitea/localized.svg"> <img src="https://badges.crowdin.net/gitea/localized.svg">
</a> </a>
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main" title="TODOs"> <a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea" title="TODOs">
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main"> <img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea">
</a> </a>
<a href="https://img.shields.io/bountysource/team/gitea" title="Bountysource"> <a href="https://img.shields.io/bountysource/team/gitea" title="Bountysource">
<img src="https://img.shields.io/bountysource/team/gitea/activity"> <img src="https://img.shields.io/bountysource/team/gitea/activity">

View File

@@ -2,8 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build vendor //+build vendor
// +build vendor
package main package main

View File

@@ -1,285 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"code.gitea.io/gitea/build/codeformat"
)
// Windows has a limitation for command line arguments, the size can not exceed 32KB.
// So we have to feed the files to some tools (like gofmt/misspell) batch by batch
// We also introduce a `gitea-fmt` command, it does better import formatting than gofmt/goimports. `gitea-fmt` calls `gofmt` internally.
var optionLogVerbose bool
func logVerbose(msg string, args ...interface{}) {
if optionLogVerbose {
log.Printf(msg, args...)
}
}
func passThroughCmd(cmd string, args []string) error {
foundCmd, err := exec.LookPath(cmd)
if err != nil {
log.Fatalf("can not find cmd: %s", cmd)
}
c := exec.Cmd{
Path: foundCmd,
Args: append([]string{cmd}, args...),
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
return c.Run()
}
type fileCollector struct {
dirs []string
includePatterns []*regexp.Regexp
excludePatterns []*regexp.Regexp
batchSize int
}
func newFileCollector(fileFilter string, batchSize int) (*fileCollector, error) {
co := &fileCollector{batchSize: batchSize}
if fileFilter == "go-own" {
co.dirs = []string{
"build",
"cmd",
"contrib",
"integrations",
"models",
"modules",
"routers",
"services",
"tools",
}
co.includePatterns = append(co.includePatterns, regexp.MustCompile(`.*\.go$`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`.*\bbindata\.go$`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`integrations/gitea-repositories-meta`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`integrations/migration-test`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`modules/git/tests`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`models/fixtures`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`models/migrations/fixtures`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`services/gitdiff/testdata`))
}
if co.dirs == nil {
return nil, fmt.Errorf("unknown file-filter: %s", fileFilter)
}
return co, nil
}
func (fc *fileCollector) matchPatterns(path string, regexps []*regexp.Regexp) bool {
path = strings.ReplaceAll(path, "\\", "/")
for _, re := range regexps {
if re.MatchString(path) {
return true
}
}
return false
}
func (fc *fileCollector) collectFiles() (res [][]string, err error) {
var batch []string
for _, dir := range fc.dirs {
err = filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error {
include := len(fc.includePatterns) == 0 || fc.matchPatterns(path, fc.includePatterns)
exclude := fc.matchPatterns(path, fc.excludePatterns)
process := include && !exclude
if !process {
if d.IsDir() {
if exclude {
logVerbose("exclude dir %s", path)
return filepath.SkipDir
}
// for a directory, if it is not excluded explicitly, we should walk into
return nil
}
// for a file, we skip it if it shouldn't be processed
logVerbose("skip process %s", path)
return nil
}
if d.IsDir() {
// skip dir, we don't add dirs to the file list now
return nil
}
if len(batch) >= fc.batchSize {
res = append(res, batch)
batch = nil
}
batch = append(batch, path)
return nil
})
if err != nil {
return nil, err
}
}
res = append(res, batch)
return res, nil
}
// substArgFiles expands the {file-list} to a real file list for commands
func substArgFiles(args []string, files []string) []string {
for i, s := range args {
if s == "{file-list}" {
newArgs := append(args[:i], files...)
newArgs = append(newArgs, args[i+1:]...)
return newArgs
}
}
return args
}
func exitWithCmdErrors(subCmd string, subArgs []string, cmdErrors []error) {
for _, err := range cmdErrors {
if err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
exitCode := exitError.ExitCode()
log.Printf("run command failed (code=%d): %s %v", exitCode, subCmd, subArgs)
os.Exit(exitCode)
} else {
log.Fatalf("run command failed (err=%s) %s %v", err, subCmd, subArgs)
}
}
}
}
func parseArgs() (mainOptions map[string]string, subCmd string, subArgs []string) {
mainOptions = map[string]string{}
for i := 1; i < len(os.Args); i++ {
arg := os.Args[i]
if arg == "" {
break
}
if arg[0] == '-' {
arg = strings.TrimPrefix(arg, "-")
arg = strings.TrimPrefix(arg, "-")
fields := strings.SplitN(arg, "=", 2)
if len(fields) == 1 {
mainOptions[fields[0]] = "1"
} else {
mainOptions[fields[0]] = fields[1]
}
} else {
subCmd = arg
subArgs = os.Args[i+1:]
break
}
}
return
}
func showUsage() {
fmt.Printf(`Usage: %[1]s [options] {command} [arguments]
Options:
--verbose
--file-filter=go-own
--batch-size=100
Commands:
%[1]s gofmt ...
%[1]s misspell ...
Arguments:
{file-list} the file list
Example:
%[1]s gofmt -s -d {file-list}
`, "file-batch-exec")
}
func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) {
fileFilter := mainOptions["file-filter"]
if fileFilter == "" {
fileFilter = "go-own"
}
batchSize, _ := strconv.Atoi(mainOptions["batch-size"])
if batchSize == 0 {
batchSize = 100
}
return newFileCollector(fileFilter, batchSize)
}
func containsString(a []string, s string) bool {
for _, v := range a {
if v == s {
return true
}
}
return false
}
func giteaFormatGoImports(files []string) error {
for _, file := range files {
if err := codeformat.FormatGoImports(file); err != nil {
log.Printf("failed to format go imports: %s, err=%v", file, err)
return err
}
}
return nil
}
func main() {
mainOptions, subCmd, subArgs := parseArgs()
if subCmd == "" {
showUsage()
os.Exit(1)
}
optionLogVerbose = mainOptions["verbose"] != ""
fc, err := newFileCollectorFromMainOptions(mainOptions)
if err != nil {
log.Fatalf("can not create file collector: %s", err.Error())
}
fileBatches, err := fc.collectFiles()
if err != nil {
log.Fatalf("can not collect files: %s", err.Error())
}
processed := 0
var cmdErrors []error
for _, files := range fileBatches {
if len(files) == 0 {
break
}
substArgs := substArgFiles(subArgs, files)
logVerbose("batch cmd: %s %v", subCmd, substArgs)
switch subCmd {
case "gitea-fmt":
if containsString(subArgs, "-w") {
cmdErrors = append(cmdErrors, giteaFormatGoImports(files))
}
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-l"), containsString(subArgs, "-w")))
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", "1.17"}, substArgs...)))
case "misspell":
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("MISSPELL_PACKAGE")}, substArgs...)))
default:
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
}
processed += len(files)
}
logVerbose("processed %d files", processed)
exitWithCmdErrors(subCmd, subArgs, cmdErrors)
}

View File

@@ -1,187 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package codeformat
import (
"bytes"
"errors"
"io"
"os"
"sort"
"strings"
)
var importPackageGroupOrders = map[string]int{
"": 1, // internal
"code.gitea.io/gitea/": 2,
}
var errInvalidCommentBetweenImports = errors.New("comments between imported packages are invalid, please move comments to the end of the package line")
var importBlockBegin = []byte("\nimport (\n")
var importBlockEnd = []byte("\n)")
type importLineParsed struct {
group string
pkg string
content string
}
func parseImportLine(line string) (*importLineParsed, error) {
il := &importLineParsed{content: line}
p1 := strings.IndexRune(line, '"')
if p1 == -1 {
return nil, errors.New("invalid import line: " + line)
}
p1++
p := strings.IndexRune(line[p1:], '"')
if p == -1 {
return nil, errors.New("invalid import line: " + line)
}
p2 := p1 + p
il.pkg = line[p1:p2]
pDot := strings.IndexRune(il.pkg, '.')
pSlash := strings.IndexRune(il.pkg, '/')
if pDot != -1 && pDot < pSlash {
il.group = "domain-package"
}
for groupName := range importPackageGroupOrders {
if groupName == "" {
continue // skip internal
}
if strings.HasPrefix(il.pkg, groupName) {
il.group = groupName
}
}
return il, nil
}
type importLineGroup []*importLineParsed
type importLineGroupMap map[string]importLineGroup
func formatGoImports(contentBytes []byte) ([]byte, error) {
p1 := bytes.Index(contentBytes, importBlockBegin)
if p1 == -1 {
return nil, nil
}
p1 += len(importBlockBegin)
p := bytes.Index(contentBytes[p1:], importBlockEnd)
if p == -1 {
return nil, nil
}
p2 := p1 + p
importGroups := importLineGroupMap{}
r := bytes.NewBuffer(contentBytes[p1:p2])
eof := false
for !eof {
line, err := r.ReadString('\n')
eof = err == io.EOF
if err != nil && !eof {
return nil, err
}
line = strings.TrimSpace(line)
if line != "" {
if strings.HasPrefix(line, "//") || strings.HasPrefix(line, "/*") {
return nil, errInvalidCommentBetweenImports
}
importLine, err := parseImportLine(line)
if err != nil {
return nil, err
}
importGroups[importLine.group] = append(importGroups[importLine.group], importLine)
}
}
var groupNames []string
for groupName, importLines := range importGroups {
groupNames = append(groupNames, groupName)
sort.Slice(importLines, func(i, j int) bool {
return strings.Compare(importLines[i].pkg, importLines[j].pkg) < 0
})
}
sort.Slice(groupNames, func(i, j int) bool {
n1 := groupNames[i]
n2 := groupNames[j]
o1 := importPackageGroupOrders[n1]
o2 := importPackageGroupOrders[n2]
if o1 != 0 && o2 != 0 {
return o1 < o2
}
if o1 == 0 && o2 == 0 {
return strings.Compare(n1, n2) < 0
}
return o1 != 0
})
formattedBlock := bytes.Buffer{}
for _, groupName := range groupNames {
hasNormalImports := false
hasDummyImports := false
// non-dummy import comes first
for _, importLine := range importGroups[groupName] {
if strings.HasPrefix(importLine.content, "_") {
hasDummyImports = true
} else {
formattedBlock.WriteString("\t" + importLine.content + "\n")
hasNormalImports = true
}
}
// dummy (_ "pkg") comes later
if hasDummyImports {
if hasNormalImports {
formattedBlock.WriteString("\n")
}
for _, importLine := range importGroups[groupName] {
if strings.HasPrefix(importLine.content, "_") {
formattedBlock.WriteString("\t" + importLine.content + "\n")
}
}
}
formattedBlock.WriteString("\n")
}
formattedBlockBytes := bytes.TrimRight(formattedBlock.Bytes(), "\n")
var formattedBytes []byte
formattedBytes = append(formattedBytes, contentBytes[:p1]...)
formattedBytes = append(formattedBytes, formattedBlockBytes...)
formattedBytes = append(formattedBytes, contentBytes[p2:]...)
return formattedBytes, nil
}
//FormatGoImports format the imports by our rules (see unit tests)
func FormatGoImports(file string) error {
f, err := os.Open(file)
if err != nil {
return err
}
var contentBytes []byte
{
defer f.Close()
contentBytes, err = io.ReadAll(f)
if err != nil {
return err
}
}
formattedBytes, err := formatGoImports(contentBytes)
if err != nil {
return err
}
if formattedBytes == nil {
return nil
}
if bytes.Equal(contentBytes, formattedBytes) {
return nil
}
f, err = os.OpenFile(file, os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close()
_, err = f.Write(formattedBytes)
return err
}

View File

@@ -1,125 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package codeformat
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestFormatImportsSimple(t *testing.T) {
formatted, err := formatGoImports([]byte(`
package codeformat
import (
"github.com/stretchr/testify/assert"
"testing"
)
`))
expected := `
package codeformat
import (
"testing"
"github.com/stretchr/testify/assert"
)
`
assert.NoError(t, err)
assert.Equal(t, expected, string(formatted))
}
func TestFormatImportsGroup(t *testing.T) {
// gofmt/goimports won't group the packages, for example, they produce such code:
// "bytes"
// "image"
// (a blank line)
// "fmt"
// "image/color/palette"
// our formatter does better, and these packages are grouped into one.
formatted, err := formatGoImports([]byte(`
package test
import (
"bytes"
"fmt"
"image"
"image/color"
_ "image/gif" // for processing gif images
_ "image/jpeg" // for processing jpeg images
_ "image/png" // for processing png images
"code.gitea.io/other/package"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"xorm.io/the/package"
"github.com/issue9/identicon"
"github.com/nfnt/resize"
"github.com/oliamb/cutter"
)
`))
expected := `
package test
import (
"bytes"
"fmt"
"image"
"image/color"
_ "image/gif" // for processing gif images
_ "image/jpeg" // for processing jpeg images
_ "image/png" // for processing png images
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/other/package"
"github.com/issue9/identicon"
"github.com/nfnt/resize"
"github.com/oliamb/cutter"
"xorm.io/the/package"
)
`
assert.NoError(t, err)
assert.Equal(t, expected, string(formatted))
}
func TestFormatImportsInvalidComment(t *testing.T) {
// why we shouldn't write comments between imports: it breaks the grouping of imports
// for example:
// "pkg1"
// "pkg2"
// // a comment
// "pkgA"
// "pkgB"
// the comment splits the packages into two groups, pkg1/2 are sorted separately, pkgA/B are sorted separately
// we don't want such code, so the code should be:
// "pkg1"
// "pkg2"
// "pkgA" // a comment
// "pkgB"
_, err := formatGoImports([]byte(`
package test
import (
"image/jpeg"
// for processing gif images
"image/gif"
)
`))
assert.ErrorIs(t, err, errInvalidCommentBetweenImports)
}

View File

@@ -2,7 +2,6 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build ignore
// +build ignore // +build ignore
package main package main
@@ -11,6 +10,7 @@ import (
"bytes" "bytes"
"crypto/sha1" "crypto/sha1"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"net/http" "net/http"
"os" "os"
@@ -27,7 +27,7 @@ func needsUpdate(dir string, filename string) (bool, []byte) {
needRegen = true needRegen = true
} }
oldHash, err := os.ReadFile(filename + ".hash") oldHash, err := ioutil.ReadFile(filename + ".hash")
if err != nil { if err != nil {
oldHash = []byte{} oldHash = []byte{}
} }
@@ -58,15 +58,11 @@ func needsUpdate(dir string, filename string) (bool, []byte) {
} }
func main() { func main() {
if len(os.Args) < 4 { if len(os.Args) != 4 {
log.Fatal("Insufficient number of arguments. Need: directory packageName filename") log.Fatal("Insufficient number of arguments. Need: directory packageName filename")
} }
dir, packageName, filename := os.Args[1], os.Args[2], os.Args[3] dir, packageName, filename := os.Args[1], os.Args[2], os.Args[3]
var useGlobalModTime bool
if len(os.Args) == 5 {
useGlobalModTime, _ = strconv.ParseBool(os.Args[4])
}
update, newHash := needsUpdate(dir, filename) update, newHash := needsUpdate(dir, filename)
@@ -82,10 +78,9 @@ func main() {
BuildTags: "bindata", BuildTags: "bindata",
VariableName: "Assets", VariableName: "Assets",
Filename: filename, Filename: filename,
UseGlobalModTime: useGlobalModTime,
}) })
if err != nil { if err != nil {
log.Fatalf("%v\n", err) log.Fatalf("%v\n", err)
} }
_ = os.WriteFile(filename+".hash", newHash, 0666) _ = ioutil.WriteFile(filename+".hash", newHash, 0666)
} }

View File

@@ -3,7 +3,6 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build ignore
// +build ignore // +build ignore
package main package main
@@ -12,17 +11,16 @@ import (
"flag" "flag"
"fmt" "fmt"
"go/format" "go/format"
"io" "io/ioutil"
"log" "log"
"net/http" "net/http"
"os"
"regexp" "regexp"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"unicode/utf8" "unicode/utf8"
"code.gitea.io/gitea/modules/json" jsoniter "github.com/json-iterator/go"
) )
const ( const (
@@ -53,6 +51,7 @@ func (e Emoji) MarshalJSON() ([]byte, error) {
x.UnicodeVersion = "" x.UnicodeVersion = ""
x.Description = "" x.Description = ""
x.SkinTones = false x.SkinTones = false
json := jsoniter.ConfigCompatibleWithStandardLibrary
return json.Marshal(x) return json.Marshal(x)
} }
@@ -68,7 +67,7 @@ func main() {
} }
// write // write
err = os.WriteFile(*flagOut, buf, 0644) err = ioutil.WriteFile(*flagOut, buf, 0644)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@@ -97,13 +96,14 @@ func generate() ([]byte, error) {
defer res.Body.Close() defer res.Body.Close()
// read all // read all
body, err := io.ReadAll(res.Body) body, err := ioutil.ReadAll(res.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// unmarshal // unmarshal
var data Gemoji var data Gemoji
json := jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal(body, &data) err = json.Unmarshal(body, &data)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -158,7 +158,7 @@ func generate() ([]byte, error) {
// write a JSON file to use with tribute (write before adding skin tones since we can't support them there yet) // write a JSON file to use with tribute (write before adding skin tones since we can't support them there yet)
file, _ := json.Marshal(data) file, _ := json.Marshal(data)
_ = os.WriteFile("assets/emoji.json", file, 0644) _ = ioutil.WriteFile("assets/emoji.json", file, 0644)
// Add skin tones to emoji that support it // Add skin tones to emoji that support it
var ( var (

View File

@@ -1,4 +1,3 @@
//go:build ignore
// +build ignore // +build ignore
package main package main
@@ -9,6 +8,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"net/http" "net/http"
"os" "os"
@@ -33,7 +33,7 @@ func main() {
flag.StringVar(&githubApiToken, "token", "", "github api token") flag.StringVar(&githubApiToken, "token", "", "github api token")
flag.Parse() flag.Parse()
file, err := os.CreateTemp(os.TempDir(), prefix) file, err := ioutil.TempFile(os.TempDir(), prefix)
if err != nil { if err != nil {
log.Fatalf("Failed to create temp file. %s", err) log.Fatalf("Failed to create temp file. %s", err)
@@ -113,13 +113,13 @@ func main() {
for dst, src := range filesToCopy { for dst, src := range filesToCopy {
// Read all content of src to data // Read all content of src to data
src = path.Join(destination, src) src = path.Join(destination, src)
data, err := os.ReadFile(src) data, err := ioutil.ReadFile(src)
if err != nil { if err != nil {
log.Fatalf("Failed to read src file. %s", err) log.Fatalf("Failed to read src file. %s", err)
} }
// Write data to dst // Write data to dst
dst = path.Join(destination, dst) dst = path.Join(destination, dst)
err = os.WriteFile(dst, data, 0644) err = ioutil.WriteFile(dst, data, 0644)
if err != nil { if err != nil {
log.Fatalf("Failed to write new file. %s", err) log.Fatalf("Failed to write new file. %s", err)
} }

View File

@@ -1,5 +1,5 @@
import imageminZopfli from 'imagemin-zopfli'; import imageminZopfli from 'imagemin-zopfli';
import {optimize} from 'svgo'; import {optimize, extendDefaultPlugins} from 'svgo';
import {fabric} from 'fabric'; import {fabric} from 'fabric';
import fs from 'fs'; import fs from 'fs';
import {resolve, dirname} from 'path'; import {resolve, dirname} from 'path';
@@ -25,14 +25,13 @@ function loadSvg(svg) {
async function generate(svg, outputFile, {size, bg}) { async function generate(svg, outputFile, {size, bg}) {
if (outputFile.endsWith('.svg')) { if (outputFile.endsWith('.svg')) {
const {data} = optimize(svg, { const {data} = optimize(svg, {
plugins: [ plugins: extendDefaultPlugins([
'preset-default',
'removeDimensions', 'removeDimensions',
{ {
name: 'addAttributesToSVGElement', name: 'addAttributesToSVGElement',
params: {attributes: [{width: size}, {height: size}]} params: {attributes: [{width: size}, {height: size}]}
}, },
], ]),
}); });
await writeFile(outputFile, data); await writeFile(outputFile, data);
return; return;

View File

@@ -1,4 +1,3 @@
//go:build ignore
// +build ignore // +build ignore
package main package main
@@ -9,6 +8,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"net/http" "net/http"
"os" "os"
@@ -33,7 +33,7 @@ func main() {
flag.StringVar(&githubApiToken, "token", "", "github api token") flag.StringVar(&githubApiToken, "token", "", "github api token")
flag.Parse() flag.Parse()
file, err := os.CreateTemp(os.TempDir(), prefix) file, err := ioutil.TempFile(os.TempDir(), prefix)
if err != nil { if err != nil {
log.Fatalf("Failed to create temp file. %s", err) log.Fatalf("Failed to create temp file. %s", err)

View File

@@ -1,5 +1,5 @@
import fastGlob from 'fast-glob'; import fastGlob from 'fast-glob';
import {optimize} from 'svgo'; import {optimize, extendDefaultPlugins} from 'svgo';
import {resolve, parse, dirname} from 'path'; import {resolve, parse, dirname} from 'path';
import fs from 'fs'; import fs from 'fs';
import {fileURLToPath} from 'url'; import {fileURLToPath} from 'url';
@@ -26,14 +26,18 @@ async function processFile(file, {prefix, fullName} = {}) {
} }
const {data} = optimize(await readFile(file, 'utf8'), { const {data} = optimize(await readFile(file, 'utf8'), {
plugins: [ plugins: extendDefaultPlugins([
{name: 'preset-default'}, 'removeXMLNS',
{name: 'removeXMLNS'}, 'removeDimensions',
{name: 'removeDimensions'}, {
{name: 'prefixIds', params: {prefix: () => name}}, name: 'addClassesToSVGElement',
{name: 'addClassesToSVGElement', params: {classNames: ['svg', name]}}, params: {classNames: ['svg', name]},
{name: 'addAttributesToSVGElement', params: {attributes: [{'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}]}}, },
], {
name: 'addAttributesToSVGElement',
params: {attributes: [{'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}]},
},
]),
}); });
await writeFile(resolve(outputDir, `${name}.svg`), data); await writeFile(resolve(outputDir, `${name}.svg`), data);
} }

View File

@@ -1,27 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
import (
"log"
"os"
"code.gitea.io/gitea/build/codeformat"
)
func main() {
if len(os.Args) <= 1 {
log.Fatalf("Usage: gitea-format-imports [files...]")
}
for _, file := range os.Args[1:] {
if err := codeformat.FormatGoImports(file); err != nil {
log.Fatalf("can not format file %s, err=%v", file, err)
}
}
}

View File

@@ -6,7 +6,6 @@
// gocovmerge takes the results from multiple `go test -coverprofile` runs and // gocovmerge takes the results from multiple `go test -coverprofile` runs and
// merges them into one profile // merges them into one profile
//go:build ignore
// +build ignore // +build ignore
package main package main
@@ -109,7 +108,7 @@ func main() {
for _, file := range flag.Args() { for _, file := range flag.Args() {
profiles, err := cover.ParseProfiles(file) profiles, err := cover.ParseProfiles(file)
if err != nil { if err != nil {
log.Fatalf("failed to parse profile '%s': %v", file, err) log.Fatalf("failed to parse profiles: %v", err)
} }
for _, p := range profiles { for _, p := range profiles {
merged = addProfile(merged, p) merged = addProfile(merged, p)

View File

@@ -1,24 +0,0 @@
#!/bin/sh
set -e
if [ ! -f ./build/test-env-check.sh ]; then
echo "${0} can only be executed in gitea source root directory"
exit 1
fi
echo "check uid ..."
# the uid of gitea defined in "https://gitea.com/gitea/test-env" is 1000
gitea_uid=$(id -u gitea)
if [ "$gitea_uid" != "1000" ]; then
echo "The uid of linux user 'gitea' is expected to be 1000, but it is $gitea_uid"
exit 1
fi
cur_uid=$(id -u)
if [ "$cur_uid" != "0" -a "$cur_uid" != "$gitea_uid" ]; then
echo "The uid of current linux user is expected to be 0 or $gitea_uid, but it is $cur_uid"
exit 1
fi

View File

@@ -1,11 +0,0 @@
#!/bin/sh
set -e
if [ ! -f ./build/test-env-prepare.sh ]; then
echo "${0} can only be executed in gitea source root directory"
exit 1
fi
echo "change the owner of files to gitea ..."
chown -R gitea:gitea .

View File

@@ -14,10 +14,7 @@ import (
"text/tabwriter" "text/tabwriter"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/modules/auth/oauth2"
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@@ -25,11 +22,6 @@ import (
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/storage"
auth_service "code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/auth/source/oauth2"
"code.gitea.io/gitea/services/auth/source/smtp"
repo_service "code.gitea.io/gitea/services/repository"
user_service "code.gitea.io/gitea/services/user"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@@ -191,8 +183,6 @@ var (
cmdAuthUpdateLdapBindDn, cmdAuthUpdateLdapBindDn,
cmdAuthAddLdapSimpleAuth, cmdAuthAddLdapSimpleAuth,
cmdAuthUpdateLdapSimpleAuth, cmdAuthUpdateLdapSimpleAuth,
microcmdAuthAddSMTP,
microcmdAuthUpdateSMTP,
microcmdAuthList, microcmdAuthList,
microcmdAuthDelete, microcmdAuthDelete,
}, },
@@ -298,40 +288,6 @@ var (
Value: "", Value: "",
Usage: "Custom icon URL for OAuth2 login source", Usage: "Custom icon URL for OAuth2 login source",
}, },
cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
},
cli.StringSliceFlag{
Name: "scopes",
Value: nil,
Usage: "Scopes to request when to authenticate against this OAuth2 source",
},
cli.StringFlag{
Name: "required-claim-name",
Value: "",
Usage: "Claim name that has to be set to allow users to login with this source",
},
cli.StringFlag{
Name: "required-claim-value",
Value: "",
Usage: "Claim value that has to be set to allow users to login with this source",
},
cli.StringFlag{
Name: "group-claim-name",
Value: "",
Usage: "Claim name providing group names for this source",
},
cli.StringFlag{
Name: "admin-group",
Value: "",
Usage: "Group Claim value for administrator users",
},
cli.StringFlag{
Name: "restricted-group",
Value: "",
Usage: "Group Claim value for restricted users",
},
} }
microcmdAuthUpdateOauth = cli.Command{ microcmdAuthUpdateOauth = cli.Command{
@@ -369,72 +325,6 @@ var (
}, },
}, },
} }
smtpCLIFlags = []cli.Flag{
cli.StringFlag{
Name: "name",
Value: "",
Usage: "Application Name",
},
cli.StringFlag{
Name: "auth-type",
Value: "PLAIN",
Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
},
cli.StringFlag{
Name: "host",
Value: "",
Usage: "SMTP Host",
},
cli.IntFlag{
Name: "port",
Usage: "SMTP Port",
},
cli.BoolTFlag{
Name: "force-smtps",
Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
},
cli.BoolTFlag{
Name: "skip-verify",
Usage: "Skip TLS verify.",
},
cli.StringFlag{
Name: "helo-hostname",
Value: "",
Usage: "Hostname sent with HELO. Leave blank to send current hostname",
},
cli.BoolTFlag{
Name: "disable-helo",
Usage: "Disable SMTP helo.",
},
cli.StringFlag{
Name: "allowed-domains",
Value: "",
Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
},
cli.BoolTFlag{
Name: "skip-local-2fa",
Usage: "Skip 2FA to log on.",
},
cli.BoolTFlag{
Name: "active",
Usage: "This Authentication Source is Activated.",
},
}
microcmdAuthAddSMTP = cli.Command{
Name: "add-smtp",
Usage: "Add new SMTP authentication source",
Action: runAddSMTP,
Flags: smtpCLIFlags,
}
microcmdAuthUpdateSMTP = cli.Command{
Name: "update-smtp",
Usage: "Update existing SMTP authentication source",
Action: runUpdateSMTP,
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
}
) )
func runChangePassword(c *cli.Context) error { func runChangePassword(c *cli.Context) error {
@@ -442,16 +332,9 @@ func runChangePassword(c *cli.Context) error {
return err return err
} }
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
if len(c.String("password")) < setting.MinPasswordLength {
return fmt.Errorf("Password is not long enough. Needs to be at least %d", setting.MinPasswordLength)
}
if !pwd.IsComplexEnough(c.String("password")) { if !pwd.IsComplexEnough(c.String("password")) {
return errors.New("Password does not meet complexity requirements") return errors.New("Password does not meet complexity requirements")
} }
@@ -463,7 +346,7 @@ func runChangePassword(c *cli.Context) error {
return errors.New("The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password.\nFor more details, see https://haveibeenpwned.com/Passwords") return errors.New("The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password.\nFor more details, see https://haveibeenpwned.com/Passwords")
} }
uname := c.String("username") uname := c.String("username")
user, err := user_model.GetUserByName(uname) user, err := models.GetUserByName(uname)
if err != nil { if err != nil {
return err return err
} }
@@ -471,7 +354,7 @@ func runChangePassword(c *cli.Context) error {
return err return err
} }
if err = user_model.UpdateUserCols(db.DefaultContext, user, "passwd", "passwd_hash_algo", "salt"); err != nil { if err = models.UpdateUserCols(user, "passwd", "passwd_hash_algo", "salt"); err != nil {
return err return err
} }
@@ -503,10 +386,7 @@ func runCreateUser(c *cli.Context) error {
fmt.Fprintf(os.Stderr, "--name flag is deprecated. Use --username instead.\n") fmt.Fprintf(os.Stderr, "--name flag is deprecated. Use --username instead.\n")
} }
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
@@ -529,7 +409,7 @@ func runCreateUser(c *cli.Context) error {
// If this is the first user being created. // If this is the first user being created.
// Take it as the admin and don't force a password update. // Take it as the admin and don't force a password update.
if n := user_model.CountUsers(); n == 0 { if n := models.CountUsers(); n == 0 {
changePassword = false changePassword = false
} }
@@ -537,7 +417,7 @@ func runCreateUser(c *cli.Context) error {
changePassword = c.Bool("must-change-password") changePassword = c.Bool("must-change-password")
} }
u := &user_model.User{ u := &models.User{
Name: username, Name: username,
Email: c.String("email"), Email: c.String("email"),
Passwd: password, Passwd: password,
@@ -547,7 +427,7 @@ func runCreateUser(c *cli.Context) error {
Theme: setting.UI.DefaultTheme, Theme: setting.UI.DefaultTheme,
} }
if err := user_model.CreateUser(u); err != nil { if err := models.CreateUser(u); err != nil {
return fmt.Errorf("CreateUser: %v", err) return fmt.Errorf("CreateUser: %v", err)
} }
@@ -569,14 +449,11 @@ func runCreateUser(c *cli.Context) error {
} }
func runListUsers(c *cli.Context) error { func runListUsers(c *cli.Context) error {
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
users, err := user_model.GetAllUsers() users, err := models.GetAllUsers()
if err != nil { if err != nil {
return err return err
@@ -609,10 +486,7 @@ func runDeleteUser(c *cli.Context) error {
return fmt.Errorf("You must provide the id, username or email of a user to delete") return fmt.Errorf("You must provide the id, username or email of a user to delete")
} }
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
@@ -621,13 +495,13 @@ func runDeleteUser(c *cli.Context) error {
} }
var err error var err error
var user *user_model.User var user *models.User
if c.IsSet("email") { if c.IsSet("email") {
user, err = user_model.GetUserByEmail(c.String("email")) user, err = models.GetUserByEmail(c.String("email"))
} else if c.IsSet("username") { } else if c.IsSet("username") {
user, err = user_model.GetUserByName(c.String("username")) user, err = models.GetUserByName(c.String("username"))
} else { } else {
user, err = user_model.GetUserByID(c.Int64("id")) user, err = models.GetUserByID(c.Int64("id"))
} }
if err != nil { if err != nil {
return err return err
@@ -640,21 +514,18 @@ func runDeleteUser(c *cli.Context) error {
return fmt.Errorf("The user %s does not match the provided id %d", user.Name, c.Int64("id")) return fmt.Errorf("The user %s does not match the provided id %d", user.Name, c.Int64("id"))
} }
return user_service.DeleteUser(user) return models.DeleteUser(user)
} }
func runRepoSyncReleases(_ *cli.Context) error { func runRepoSyncReleases(_ *cli.Context) error {
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
log.Trace("Synchronizing repository releases (this may take a while)") log.Trace("Synchronizing repository releases (this may take a while)")
for page := 1; ; page++ { for page := 1; ; page++ {
repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{ repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
ListOptions: db.ListOptions{ ListOptions: models.ListOptions{
PageSize: models.RepositoryListDefaultPageSize, PageSize: models.RepositoryListDefaultPageSize,
Page: page, Page: page,
}, },
@@ -713,26 +584,20 @@ func getReleaseCount(id int64) (int64, error) {
} }
func runRegenerateHooks(_ *cli.Context) error { func runRegenerateHooks(_ *cli.Context) error {
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext()) return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
} }
func runRegenerateKeys(_ *cli.Context) error { func runRegenerateKeys(_ *cli.Context) error {
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
return asymkey_model.RewriteAllPublicKeys() return models.RewriteAllPublicKeys()
} }
func parseOAuth2Config(c *cli.Context) *oauth2.Source { func parseOAuth2Config(c *cli.Context) *models.OAuth2Config {
var customURLMapping *oauth2.CustomURLMapping var customURLMapping *oauth2.CustomURLMapping
if c.IsSet("use-custom-urls") { if c.IsSet("use-custom-urls") {
customURLMapping = &oauth2.CustomURLMapping{ customURLMapping = &oauth2.CustomURLMapping{
@@ -744,35 +609,25 @@ func parseOAuth2Config(c *cli.Context) *oauth2.Source {
} else { } else {
customURLMapping = nil customURLMapping = nil
} }
return &oauth2.Source{ return &models.OAuth2Config{
Provider: c.String("provider"), Provider: c.String("provider"),
ClientID: c.String("key"), ClientID: c.String("key"),
ClientSecret: c.String("secret"), ClientSecret: c.String("secret"),
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"), OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
CustomURLMapping: customURLMapping, CustomURLMapping: customURLMapping,
IconURL: c.String("icon-url"), IconURL: c.String("icon-url"),
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
Scopes: c.StringSlice("scopes"),
RequiredClaimName: c.String("required-claim-name"),
RequiredClaimValue: c.String("required-claim-value"),
GroupClaimName: c.String("group-claim-name"),
AdminGroup: c.String("admin-group"),
RestrictedGroup: c.String("restricted-group"),
} }
} }
func runAddOauth(c *cli.Context) error { func runAddOauth(c *cli.Context) error {
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
return auth.CreateSource(&auth.Source{ return models.CreateLoginSource(&models.LoginSource{
Type: auth.OAuth2, Type: models.LoginOAuth2,
Name: c.String("name"), Name: c.String("name"),
IsActive: true, IsActived: true,
Cfg: parseOAuth2Config(c), Cfg: parseOAuth2Config(c),
}) })
} }
@@ -782,19 +637,16 @@ func runUpdateOauth(c *cli.Context) error {
return fmt.Errorf("--id flag is missing") return fmt.Errorf("--id flag is missing")
} }
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
source, err := auth.GetSourceByID(c.Int64("id")) source, err := models.GetLoginSourceByID(c.Int64("id"))
if err != nil { if err != nil {
return err return err
} }
oAuth2Config := source.Cfg.(*oauth2.Source) oAuth2Config := source.OAuth2()
if c.IsSet("name") { if c.IsSet("name") {
source.Name = c.String("name") source.Name = c.String("name")
@@ -820,28 +672,6 @@ func runUpdateOauth(c *cli.Context) error {
oAuth2Config.IconURL = c.String("icon-url") oAuth2Config.IconURL = c.String("icon-url")
} }
if c.IsSet("scopes") {
oAuth2Config.Scopes = c.StringSlice("scopes")
}
if c.IsSet("required-claim-name") {
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
}
if c.IsSet("required-claim-value") {
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
}
if c.IsSet("group-claim-name") {
oAuth2Config.GroupClaimName = c.String("group-claim-name")
}
if c.IsSet("admin-group") {
oAuth2Config.AdminGroup = c.String("admin-group")
}
if c.IsSet("restricted-group") {
oAuth2Config.RestrictedGroup = c.String("restricted-group")
}
// update custom URL mapping // update custom URL mapping
var customURLMapping = &oauth2.CustomURLMapping{} var customURLMapping = &oauth2.CustomURLMapping{}
@@ -870,130 +700,15 @@ func runUpdateOauth(c *cli.Context) error {
oAuth2Config.CustomURLMapping = customURLMapping oAuth2Config.CustomURLMapping = customURLMapping
source.Cfg = oAuth2Config source.Cfg = oAuth2Config
return auth.UpdateSource(source) return models.UpdateSource(source)
}
func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
if c.IsSet("auth-type") {
conf.Auth = c.String("auth-type")
validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
if !contains(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
}
conf.Auth = c.String("auth-type")
}
if c.IsSet("host") {
conf.Host = c.String("host")
}
if c.IsSet("port") {
conf.Port = c.Int("port")
}
if c.IsSet("allowed-domains") {
conf.AllowedDomains = c.String("allowed-domains")
}
if c.IsSet("force-smtps") {
conf.ForceSMTPS = c.BoolT("force-smtps")
}
if c.IsSet("skip-verify") {
conf.SkipVerify = c.BoolT("skip-verify")
}
if c.IsSet("helo-hostname") {
conf.HeloHostname = c.String("helo-hostname")
}
if c.IsSet("disable-helo") {
conf.DisableHelo = c.BoolT("disable-helo")
}
if c.IsSet("skip-local-2fa") {
conf.SkipLocalTwoFA = c.BoolT("skip-local-2fa")
}
return nil
}
func runAddSMTP(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
if !c.IsSet("name") || len(c.String("name")) == 0 {
return errors.New("name must be set")
}
if !c.IsSet("host") || len(c.String("host")) == 0 {
return errors.New("host must be set")
}
if !c.IsSet("port") {
return errors.New("port must be set")
}
var active = true
if c.IsSet("active") {
active = c.BoolT("active")
}
var smtpConfig smtp.Source
if err := parseSMTPConfig(c, &smtpConfig); err != nil {
return err
}
// If not set default to PLAIN
if len(smtpConfig.Auth) == 0 {
smtpConfig.Auth = "PLAIN"
}
return auth.CreateSource(&auth.Source{
Type: auth.SMTP,
Name: c.String("name"),
IsActive: active,
Cfg: &smtpConfig,
})
}
func runUpdateSMTP(c *cli.Context) error {
if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing")
}
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
source, err := auth.GetSourceByID(c.Int64("id"))
if err != nil {
return err
}
smtpConfig := source.Cfg.(*smtp.Source)
if err := parseSMTPConfig(c, smtpConfig); err != nil {
return err
}
if c.IsSet("name") {
source.Name = c.String("name")
}
if c.IsSet("active") {
source.IsActive = c.BoolT("active")
}
source.Cfg = smtpConfig
return auth.UpdateSource(source)
} }
func runListAuth(c *cli.Context) error { func runListAuth(c *cli.Context) error {
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
authSources, err := auth.Sources() loginSources, err := models.LoginSources()
if err != nil { if err != nil {
return err return err
@@ -1012,8 +727,8 @@ func runListAuth(c *cli.Context) error {
// loop through each source and print // loop through each source and print
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags) w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n") fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
for _, source := range authSources { for _, source := range loginSources {
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, source.Type.String(), source.IsActive) fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, models.LoginNames[source.Type], source.IsActived)
} }
w.Flush() w.Flush()
@@ -1025,17 +740,14 @@ func runDeleteAuth(c *cli.Context) error {
return fmt.Errorf("--id flag is missing") return fmt.Errorf("--id flag is missing")
} }
ctx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(ctx); err != nil {
return err return err
} }
source, err := auth.GetSourceByID(c.Int64("id")) source, err := models.GetLoginSourceByID(c.Int64("id"))
if err != nil { if err != nil {
return err return err
} }
return auth_service.DeleteSource(source) return models.DeleteSource(source)
} }

View File

@@ -5,22 +5,21 @@
package cmd package cmd
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
"code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/services/auth/source/ldap" "code.gitea.io/gitea/modules/auth/ldap"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
type ( type (
authService struct { authService struct {
initDB func(ctx context.Context) error initDB func() error
createAuthSource func(*auth.Source) error createLoginSource func(loginSource *models.LoginSource) error
updateAuthSource func(*auth.Source) error updateLoginSource func(loginSource *models.LoginSource) error
getAuthSourceByID func(id int64) (*auth.Source, error) getLoginSourceByID func(id int64) (*models.LoginSource, error)
} }
) )
@@ -90,14 +89,6 @@ var (
Name: "public-ssh-key-attribute", Name: "public-ssh-key-attribute",
Usage: "The attribute of the users LDAP record containing the users public ssh key.", Usage: "The attribute of the users LDAP record containing the users public ssh key.",
}, },
cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
},
cli.StringFlag{
Name: "avatar-attribute",
Usage: "The attribute of the users LDAP record containing the users avatar.",
},
} }
ldapBindDnCLIFlags = append(commonLdapCLIFlags, ldapBindDnCLIFlags = append(commonLdapCLIFlags,
@@ -169,105 +160,98 @@ var (
func newAuthService() *authService { func newAuthService() *authService {
return &authService{ return &authService{
initDB: initDB, initDB: initDB,
createAuthSource: auth.CreateSource, createLoginSource: models.CreateLoginSource,
updateAuthSource: auth.UpdateSource, updateLoginSource: models.UpdateSource,
getAuthSourceByID: auth.GetSourceByID, getLoginSourceByID: models.GetLoginSourceByID,
} }
} }
// parseAuthSource assigns values on authSource according to command line flags. // parseLoginSource assigns values on loginSource according to command line flags.
func parseAuthSource(c *cli.Context, authSource *auth.Source) { func parseLoginSource(c *cli.Context, loginSource *models.LoginSource) {
if c.IsSet("name") { if c.IsSet("name") {
authSource.Name = c.String("name") loginSource.Name = c.String("name")
} }
if c.IsSet("not-active") { if c.IsSet("not-active") {
authSource.IsActive = !c.Bool("not-active") loginSource.IsActived = !c.Bool("not-active")
} }
if c.IsSet("synchronize-users") { if c.IsSet("synchronize-users") {
authSource.IsSyncEnabled = c.Bool("synchronize-users") loginSource.IsSyncEnabled = c.Bool("synchronize-users")
} }
} }
// parseLdapConfig assigns values on config according to command line flags. // parseLdapConfig assigns values on config according to command line flags.
func parseLdapConfig(c *cli.Context, config *ldap.Source) error { func parseLdapConfig(c *cli.Context, config *models.LDAPConfig) error {
if c.IsSet("name") { if c.IsSet("name") {
config.Name = c.String("name") config.Source.Name = c.String("name")
} }
if c.IsSet("host") { if c.IsSet("host") {
config.Host = c.String("host") config.Source.Host = c.String("host")
} }
if c.IsSet("port") { if c.IsSet("port") {
config.Port = c.Int("port") config.Source.Port = c.Int("port")
} }
if c.IsSet("security-protocol") { if c.IsSet("security-protocol") {
p, ok := findLdapSecurityProtocolByName(c.String("security-protocol")) p, ok := findLdapSecurityProtocolByName(c.String("security-protocol"))
if !ok { if !ok {
return fmt.Errorf("Unknown security protocol name: %s", c.String("security-protocol")) return fmt.Errorf("Unknown security protocol name: %s", c.String("security-protocol"))
} }
config.SecurityProtocol = p config.Source.SecurityProtocol = p
} }
if c.IsSet("skip-tls-verify") { if c.IsSet("skip-tls-verify") {
config.SkipVerify = c.Bool("skip-tls-verify") config.Source.SkipVerify = c.Bool("skip-tls-verify")
} }
if c.IsSet("bind-dn") { if c.IsSet("bind-dn") {
config.BindDN = c.String("bind-dn") config.Source.BindDN = c.String("bind-dn")
} }
if c.IsSet("user-dn") { if c.IsSet("user-dn") {
config.UserDN = c.String("user-dn") config.Source.UserDN = c.String("user-dn")
} }
if c.IsSet("bind-password") { if c.IsSet("bind-password") {
config.BindPassword = c.String("bind-password") config.Source.BindPassword = c.String("bind-password")
} }
if c.IsSet("user-search-base") { if c.IsSet("user-search-base") {
config.UserBase = c.String("user-search-base") config.Source.UserBase = c.String("user-search-base")
} }
if c.IsSet("username-attribute") { if c.IsSet("username-attribute") {
config.AttributeUsername = c.String("username-attribute") config.Source.AttributeUsername = c.String("username-attribute")
} }
if c.IsSet("firstname-attribute") { if c.IsSet("firstname-attribute") {
config.AttributeName = c.String("firstname-attribute") config.Source.AttributeName = c.String("firstname-attribute")
} }
if c.IsSet("surname-attribute") { if c.IsSet("surname-attribute") {
config.AttributeSurname = c.String("surname-attribute") config.Source.AttributeSurname = c.String("surname-attribute")
} }
if c.IsSet("email-attribute") { if c.IsSet("email-attribute") {
config.AttributeMail = c.String("email-attribute") config.Source.AttributeMail = c.String("email-attribute")
} }
if c.IsSet("attributes-in-bind") { if c.IsSet("attributes-in-bind") {
config.AttributesInBind = c.Bool("attributes-in-bind") config.Source.AttributesInBind = c.Bool("attributes-in-bind")
} }
if c.IsSet("public-ssh-key-attribute") { if c.IsSet("public-ssh-key-attribute") {
config.AttributeSSHPublicKey = c.String("public-ssh-key-attribute") config.Source.AttributeSSHPublicKey = c.String("public-ssh-key-attribute")
}
if c.IsSet("avatar-attribute") {
config.AttributeAvatar = c.String("avatar-attribute")
} }
if c.IsSet("page-size") { if c.IsSet("page-size") {
config.SearchPageSize = uint32(c.Uint("page-size")) config.Source.SearchPageSize = uint32(c.Uint("page-size"))
} }
if c.IsSet("user-filter") { if c.IsSet("user-filter") {
config.Filter = c.String("user-filter") config.Source.Filter = c.String("user-filter")
} }
if c.IsSet("admin-filter") { if c.IsSet("admin-filter") {
config.AdminFilter = c.String("admin-filter") config.Source.AdminFilter = c.String("admin-filter")
} }
if c.IsSet("restricted-filter") { if c.IsSet("restricted-filter") {
config.RestrictedFilter = c.String("restricted-filter") config.Source.RestrictedFilter = c.String("restricted-filter")
} }
if c.IsSet("allow-deactivate-all") { if c.IsSet("allow-deactivate-all") {
config.AllowDeactivateAll = c.Bool("allow-deactivate-all") config.Source.AllowDeactivateAll = c.Bool("allow-deactivate-all")
} }
if c.IsSet("skip-local-2fa") {
config.SkipLocalTwoFA = c.Bool("skip-local-2fa")
}
return nil return nil
} }
// findLdapSecurityProtocolByName finds security protocol by its name ignoring case. // findLdapSecurityProtocolByName finds security protocol by its name ignoring case.
// It returns the value of the security protocol and if it was found. // It returns the value of the security protocol and if it was found.
func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) { func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
for i, n := range ldap.SecurityProtocolNames { for i, n := range models.SecurityProtocolNames {
if strings.EqualFold(name, n) { if strings.EqualFold(name, n) {
return i, true return i, true
} }
@@ -275,23 +259,23 @@ func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
return 0, false return 0, false
} }
// getAuthSource gets the login source by its id defined in the command line flags. // getLoginSource gets the login source by its id defined in the command line flags.
// It returns an error if the id is not set, does not match any source or if the source is not of expected type. // It returns an error if the id is not set, does not match any source or if the source is not of expected type.
func (a *authService) getAuthSource(c *cli.Context, authType auth.Type) (*auth.Source, error) { func (a *authService) getLoginSource(c *cli.Context, loginType models.LoginType) (*models.LoginSource, error) {
if err := argsSet(c, "id"); err != nil { if err := argsSet(c, "id"); err != nil {
return nil, err return nil, err
} }
authSource, err := a.getAuthSourceByID(c.Int64("id")) loginSource, err := a.getLoginSourceByID(c.Int64("id"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
if authSource.Type != authType { if loginSource.Type != loginType {
return nil, fmt.Errorf("Invalid authentication type. expected: %s, actual: %s", authType.String(), authSource.Type.String()) return nil, fmt.Errorf("Invalid authentication type. expected: %s, actual: %s", models.LoginNames[loginType], models.LoginNames[loginSource.Type])
} }
return authSource, nil return loginSource, nil
} }
// addLdapBindDn adds a new LDAP via Bind DN authentication source. // addLdapBindDn adds a new LDAP via Bind DN authentication source.
@@ -300,49 +284,45 @@ func (a *authService) addLdapBindDn(c *cli.Context) error {
return err return err
} }
ctx, cancel := installSignals() if err := a.initDB(); err != nil {
defer cancel()
if err := a.initDB(ctx); err != nil {
return err return err
} }
authSource := &auth.Source{ loginSource := &models.LoginSource{
Type: auth.LDAP, Type: models.LoginLDAP,
IsActive: true, // active by default IsActived: true, // active by default
Cfg: &ldap.Source{ Cfg: &models.LDAPConfig{
Source: &ldap.Source{
Enabled: true, // always true Enabled: true, // always true
}, },
},
} }
parseAuthSource(c, authSource) parseLoginSource(c, loginSource)
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil { if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
return err return err
} }
return a.createAuthSource(authSource) return a.createLoginSource(loginSource)
} }
// updateLdapBindDn updates a new LDAP via Bind DN authentication source. // updateLdapBindDn updates a new LDAP via Bind DN authentication source.
func (a *authService) updateLdapBindDn(c *cli.Context) error { func (a *authService) updateLdapBindDn(c *cli.Context) error {
ctx, cancel := installSignals() if err := a.initDB(); err != nil {
defer cancel()
if err := a.initDB(ctx); err != nil {
return err return err
} }
authSource, err := a.getAuthSource(c, auth.LDAP) loginSource, err := a.getLoginSource(c, models.LoginLDAP)
if err != nil { if err != nil {
return err return err
} }
parseAuthSource(c, authSource) parseLoginSource(c, loginSource)
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil { if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
return err return err
} }
return a.updateAuthSource(authSource) return a.updateLoginSource(loginSource)
} }
// addLdapSimpleAuth adds a new LDAP (simple auth) authentication source. // addLdapSimpleAuth adds a new LDAP (simple auth) authentication source.
@@ -351,47 +331,43 @@ func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
return err return err
} }
ctx, cancel := installSignals() if err := a.initDB(); err != nil {
defer cancel()
if err := a.initDB(ctx); err != nil {
return err return err
} }
authSource := &auth.Source{ loginSource := &models.LoginSource{
Type: auth.DLDAP, Type: models.LoginDLDAP,
IsActive: true, // active by default IsActived: true, // active by default
Cfg: &ldap.Source{ Cfg: &models.LDAPConfig{
Source: &ldap.Source{
Enabled: true, // always true Enabled: true, // always true
}, },
},
} }
parseAuthSource(c, authSource) parseLoginSource(c, loginSource)
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil { if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
return err return err
} }
return a.createAuthSource(authSource) return a.createLoginSource(loginSource)
} }
// updateLdapBindDn updates a new LDAP (simple auth) authentication source. // updateLdapBindDn updates a new LDAP (simple auth) authentication source.
func (a *authService) updateLdapSimpleAuth(c *cli.Context) error { func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
ctx, cancel := installSignals() if err := a.initDB(); err != nil {
defer cancel()
if err := a.initDB(ctx); err != nil {
return err return err
} }
authSource, err := a.getAuthSource(c, auth.DLDAP) loginSource, err := a.getLoginSource(c, models.LoginDLDAP)
if err != nil { if err != nil {
return err return err
} }
parseAuthSource(c, authSource) parseLoginSource(c, loginSource)
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil { if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
return err return err
} }
return a.updateAuthSource(authSource) return a.updateLoginSource(loginSource)
} }

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,7 @@ import (
"strings" "strings"
"syscall" "syscall"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@@ -31,7 +30,7 @@ func argsSet(c *cli.Context, args ...string) error {
return errors.New(a + " is not set") return errors.New(a + " is not set")
} }
if util.IsEmptyString(c.String(a)) { if util.IsEmptyString(a) {
return errors.New(a + " is required") return errors.New(a + " is required")
} }
} }
@@ -57,18 +56,17 @@ func confirm() (bool, error) {
} }
} }
func initDB(ctx context.Context) error { func initDB() error {
setting.LoadFromExisting() return initDBDisableConsole(false)
setting.InitDBConfig() }
setting.NewXORMLogService(false)
if setting.Database.Type == "" { func initDBDisableConsole(disableConsole bool) error {
log.Fatal(`Database settings are missing from the configuration file: %q. setting.NewContext()
Ensure you are running in the correct environment or set the correct configuration file with -c. setting.InitDBConfig()
If this is the intended configuration file complete the [database] section.`, setting.CustomConf)
} setting.NewXORMLogService(disableConsole)
if err := db.InitEngine(ctx); err != nil { if err := models.SetEngine(); err != nil {
return fmt.Errorf("unable to initialise the database using the configuration in %q. Error: %v", setting.CustomConf, err) return fmt.Errorf("models.SetEngine: %v", err)
} }
return nil return nil
} }

View File

@@ -7,7 +7,7 @@ package cmd
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@@ -23,10 +23,7 @@ var CmdConvert = cli.Command{
} }
func runConvert(ctx *cli.Context) error { func runConvert(ctx *cli.Context) error {
stdCtx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(stdCtx); err != nil {
return err return err
} }
@@ -34,14 +31,14 @@ func runConvert(ctx *cli.Context) error {
log.Info("AppWorkPath: %s", setting.AppWorkPath) log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath) log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.LogRootPath) log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf) setting.InitDBConfig()
if !setting.Database.UseMySQL { if !setting.Database.UseMySQL {
fmt.Println("This command can only be used with a MySQL database") fmt.Println("This command can only be used with a MySQL database")
return nil return nil
} }
if err := db.ConvertUtf8ToUtf8mb4(); err != nil { if err := models.ConvertUtf8ToUtf8mb4(); err != nil {
log.Fatal("Failed to convert database from utf8 to utf8mb4: %v", err) log.Fatal("Failed to convert database from utf8 to utf8mb4: %v", err)
return err return err
} }

View File

@@ -43,11 +43,7 @@ func runDocs(ctx *cli.Context) error {
// Clean up markdown. The following bug was fixed in v2, but is present in v1. // Clean up markdown. The following bug was fixed in v2, but is present in v1.
// It affects markdown output (even though the issue is referring to man pages) // It affects markdown output (even though the issue is referring to man pages)
// https://github.com/urfave/cli/issues/1040 // https://github.com/urfave/cli/issues/1040
firstHashtagIndex := strings.Index(docs, "#") docs = docs[strings.Index(docs, "#"):]
if firstHashtagIndex > 0 {
docs = docs[firstHashtagIndex:]
}
} }
out := os.Stdout out := os.Stdout

View File

@@ -12,14 +12,15 @@ import (
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/migrations" "code.gitea.io/gitea/models/migrations"
"code.gitea.io/gitea/modules/doctor" "code.gitea.io/gitea/modules/doctor"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli"
"xorm.io/xorm" "xorm.io/xorm"
"github.com/urfave/cli"
) )
// CmdDoctor represents the available doctor sub-command. // CmdDoctor represents the available doctor sub-command.
@@ -87,7 +88,7 @@ func runRecreateTable(ctx *cli.Context) error {
golog.SetPrefix("") golog.SetPrefix("")
golog.SetOutput(log.NewLoggerAsWriter("INFO", log.GetLogger(log.DEFAULT))) golog.SetOutput(log.NewLoggerAsWriter("INFO", log.GetLogger(log.DEFAULT)))
setting.LoadFromExisting() setting.NewContext()
setting.InitDBConfig() setting.InitDBConfig()
setting.EnableXORMLog = ctx.Bool("debug") setting.EnableXORMLog = ctx.Bool("debug")
@@ -95,10 +96,7 @@ func runRecreateTable(ctx *cli.Context) error {
setting.Cfg.Section("log").Key("XORM").SetValue(",") setting.Cfg.Section("log").Key("XORM").SetValue(",")
setting.NewXORMLogService(!ctx.Bool("debug")) setting.NewXORMLogService(!ctx.Bool("debug"))
stdCtx, cancel := installSignals() if err := models.SetEngine(); err != nil {
defer cancel()
if err := db.InitEngine(stdCtx); err != nil {
fmt.Println(err) fmt.Println(err)
fmt.Println("Check if you are using the right config file. You can use a --config directive to specify one.") fmt.Println("Check if you are using the right config file. You can use a --config directive to specify one.")
return nil return nil
@@ -110,13 +108,13 @@ func runRecreateTable(ctx *cli.Context) error {
names = append(names, args.Get(i)) names = append(names, args.Get(i))
} }
beans, err := db.NamesToBean(names...) beans, err := models.NamesToBean(names...)
if err != nil { if err != nil {
return err return err
} }
recreateTables := migrations.RecreateTables(beans...) recreateTables := migrations.RecreateTables(beans...)
return db.InitEngineWithMigration(context.Background(), func(x *xorm.Engine) error { return models.NewEngine(context.Background(), func(x *xorm.Engine) error {
if err := migrations.EnsureUpToDate(x); err != nil { if err := migrations.EnsureUpToDate(x); err != nil {
return err return err
} }
@@ -126,13 +124,11 @@ func runRecreateTable(ctx *cli.Context) error {
} }
func runDoctor(ctx *cli.Context) error { func runDoctor(ctx *cli.Context) error {
// Silence the default loggers // Silence the default loggers
log.DelNamedLogger("console") log.DelNamedLogger("console")
log.DelNamedLogger(log.DEFAULT) log.DelNamedLogger(log.DEFAULT)
stdCtx, cancel := installSignals()
defer cancel()
// Now setup our own // Now setup our own
logFile := ctx.String("log-file") logFile := ctx.String("log-file")
if !ctx.IsSet("log-file") { if !ctx.IsSet("log-file") {
@@ -215,5 +211,5 @@ func runDoctor(ctx *cli.Context) error {
logger := log.GetLogger("doctorouter") logger := log.GetLogger("doctorouter")
defer logger.Close() defer logger.Close()
return doctor.RunChecks(stdCtx, logger, ctx.Bool("fix"), checks) return doctor.RunChecks(logger, ctx.Bool("fix"), checks)
} }

View File

@@ -7,25 +7,26 @@ package cmd
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"gitea.com/go-chi/session" "gitea.com/go-chi/session"
jsoniter "github.com/json-iterator/go"
archiver "github.com/mholt/archiver/v3" archiver "github.com/mholt/archiver/v3"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
func addFile(w archiver.Writer, filePath, absPath string, verbose bool) error { func addFile(w archiver.Writer, filePath string, absPath string, verbose bool) error {
if verbose { if verbose {
log.Info("Adding file %s\n", filePath) log.Info("Adding file %s\n", filePath)
} }
@@ -48,7 +49,7 @@ func addFile(w archiver.Writer, filePath, absPath string, verbose bool) error {
}) })
} }
func isSubdir(upper, lower string) (bool, error) { func isSubdir(upper string, lower string) (bool, error) {
if relPath, err := filepath.Rel(upper, lower); err != nil { if relPath, err := filepath.Rel(upper, lower); err != nil {
return false, err return false, err
} else if relPath == "." || !strings.HasPrefix(relPath, ".") { } else if relPath == "." || !strings.HasPrefix(relPath, ".") {
@@ -86,7 +87,7 @@ func (o outputType) String() string {
} }
var outputTypeEnum = &outputType{ var outputTypeEnum = &outputType{
Enum: []string{"zip", "tar", "tar.sz", "tar.gz", "tar.xz", "tar.bz2", "tar.br", "tar.lz4"}, Enum: []string{"zip", "tar", "tar.gz", "tar.xz", "tar.bz2"},
Default: "zip", Default: "zip",
} }
@@ -152,24 +153,14 @@ func fatal(format string, args ...interface{}) {
func runDump(ctx *cli.Context) error { func runDump(ctx *cli.Context) error {
var file *os.File var file *os.File
fileName := ctx.String("file") fileName := ctx.String("file")
outType := ctx.String("type")
if fileName == "-" { if fileName == "-" {
file = os.Stdout file = os.Stdout
err := log.DelLogger("console") err := log.DelLogger("console")
if err != nil { if err != nil {
fatal("Deleting default logger failed. Can not write to stdout: %v", err) fatal("Deleting default logger failed. Can not write to stdout: %v", err)
} }
} else {
for _, suffix := range outputTypeEnum.Enum {
if strings.HasSuffix(fileName, "."+suffix) {
fileName = strings.TrimSuffix(fileName, "."+suffix)
break
} }
} setting.NewContext()
fileName += "." + outType
}
setting.LoadFromExisting()
// make sure we are logging to the console no matter what the configuration tells us do to // make sure we are logging to the console no matter what the configuration tells us do to
if _, err := setting.Cfg.Section("log").NewKey("MODE", "console"); err != nil { if _, err := setting.Cfg.Section("log").NewKey("MODE", "console"); err != nil {
fatal("Setting logging mode to console failed: %v", err) fatal("Setting logging mode to console failed: %v", err)
@@ -183,10 +174,7 @@ func runDump(ctx *cli.Context) error {
} }
setting.NewServices() // cannot access session settings otherwise setting.NewServices() // cannot access session settings otherwise
stdCtx, cancel := installSignals() err := models.SetEngine()
defer cancel()
err := db.InitEngine(stdCtx)
if err != nil { if err != nil {
return err return err
} }
@@ -209,6 +197,7 @@ func runDump(ctx *cli.Context) error {
} }
verbose := ctx.Bool("verbose") verbose := ctx.Bool("verbose")
outType := ctx.String("type")
var iface interface{} var iface interface{}
if fileName == "-" { if fileName == "-" {
iface, err = archiver.ByExtension(fmt.Sprintf(".%s", outType)) iface, err = archiver.ByExtension(fmt.Sprintf(".%s", outType))
@@ -258,7 +247,7 @@ func runDump(ctx *cli.Context) error {
fatal("Path does not exist: %s", tmpDir) fatal("Path does not exist: %s", tmpDir)
} }
dbDump, err := os.CreateTemp(tmpDir, "gitea-db.sql") dbDump, err := ioutil.TempFile(tmpDir, "gitea-db.sql")
if err != nil { if err != nil {
fatal("Failed to create tmp file: %v", err) fatal("Failed to create tmp file: %v", err)
} }
@@ -275,7 +264,7 @@ func runDump(ctx *cli.Context) error {
log.Info("Dumping database...") log.Info("Dumping database...")
} }
if err := db.DumpDatabase(dbDump.Name(), targetDBType); err != nil { if err := models.DumpDatabase(dbDump.Name(), targetDBType); err != nil {
fatal("Failed to dump database: %v", err) fatal("Failed to dump database: %v", err)
} }
@@ -317,6 +306,7 @@ func runDump(ctx *cli.Context) error {
var excludes []string var excludes []string
if setting.Cfg.Section("session").Key("PROVIDER").Value() == "file" { if setting.Cfg.Section("session").Key("PROVIDER").Value() == "file" {
var opts session.Options var opts session.Options
json := jsoniter.ConfigCompatibleWithStandardLibrary
if err = json.Unmarshal([]byte(setting.SessionConfig.ProviderConfig), &opts); err != nil { if err = json.Unmarshal([]byte(setting.SessionConfig.ProviderConfig), &opts); err != nil {
return err return err
} }

View File

@@ -11,10 +11,10 @@ import (
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
base "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/migrations"
"code.gitea.io/gitea/modules/migrations/base"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/services/migrations"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@@ -76,10 +76,7 @@ wiki, issues, labels, releases, release_assets, milestones, pull_requests, comme
} }
func runDumpRepository(ctx *cli.Context) error { func runDumpRepository(ctx *cli.Context) error {
stdCtx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(stdCtx); err != nil {
return err return err
} }
@@ -87,7 +84,7 @@ func runDumpRepository(ctx *cli.Context) error {
log.Info("AppWorkPath: %s", setting.AppWorkPath) log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath) log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.LogRootPath) log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf) setting.InitDBConfig()
var ( var (
serviceType structs.GitServiceType serviceType structs.GitServiceType

View File

@@ -2,7 +2,6 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build bindata
// +build bindata // +build bindata
package cmd package cmd
@@ -115,7 +114,7 @@ func initEmbeddedExtractor(c *cli.Context) error {
log.DelNamedLogger(log.DEFAULT) log.DelNamedLogger(log.DEFAULT)
// Read configuration file // Read configuration file
setting.LoadAllowEmpty() setting.NewContext()
pats, err := getPatterns(c.Args()) pats, err := getPatterns(c.Args())
if err != nil { if err != nil {

View File

@@ -2,7 +2,6 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !bindata
// +build !bindata // +build !bindata
package cmd package cmd

View File

@@ -38,7 +38,6 @@ var (
subcmdHookPreReceive, subcmdHookPreReceive,
subcmdHookUpdate, subcmdHookUpdate,
subcmdHookPostReceive, subcmdHookPostReceive,
subcmdHookProcReceive,
}, },
} }
@@ -75,18 +74,6 @@ var (
}, },
}, },
} }
// Note: new hook since git 2.29
subcmdHookProcReceive = cli.Command{
Name: "proc-receive",
Usage: "Delegate proc-receive Git hook",
Description: "This command should only be called by Git",
Action: runHookProcReceive,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "debug",
},
},
}
) )
type delayWriter struct { type delayWriter struct {
@@ -185,7 +172,7 @@ Gitea or set your environment appropriately.`, "")
reponame := os.Getenv(models.EnvRepoName) reponame := os.Getenv(models.EnvRepoName)
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64) userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
prID, _ := strconv.ParseInt(os.Getenv(models.EnvPRID), 10, 64) prID, _ := strconv.ParseInt(os.Getenv(models.EnvPRID), 10, 64)
deployKeyID, _ := strconv.ParseInt(os.Getenv(models.EnvDeployKeyID), 10, 64) isDeployKey, _ := strconv.ParseBool(os.Getenv(models.EnvIsDeployKey))
hookOptions := private.HookOptions{ hookOptions := private.HookOptions{
UserID: userID, UserID: userID,
@@ -194,7 +181,7 @@ Gitea or set your environment appropriately.`, "")
GitQuarantinePath: os.Getenv(private.GitQuarantinePath), GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
GitPushOptions: pushOptions(), GitPushOptions: pushOptions(),
PullRequestID: prID, PullRequestID: prID,
DeployKeyID: deployKeyID, IsDeployKey: isDeployKey,
} }
scanner := bufio.NewScanner(os.Stdin) scanner := bufio.NewScanner(os.Stdin)
@@ -218,11 +205,6 @@ Gitea or set your environment appropriately.`, "")
} }
} }
supportProcRecive := false
if git.CheckGitVersionAtLeast("2.29") == nil {
supportProcRecive = true
}
for scanner.Scan() { for scanner.Scan() {
// TODO: support news feeds for wiki // TODO: support news feeds for wiki
if isWiki { if isWiki {
@@ -241,9 +223,7 @@ Gitea or set your environment appropriately.`, "")
lastline++ lastline++
// If the ref is a branch or tag, check if it's protected // If the ref is a branch or tag, check if it's protected
// if supportProcRecive all ref should be checked because if strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
// permission check was delayed
if supportProcRecive || strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
oldCommitIDs[count] = oldCommitID oldCommitIDs[count] = oldCommitID
newCommitIDs[count] = newCommitID newCommitIDs[count] = newCommitID
refFullNames[count] = refFullName refFullNames[count] = refFullName
@@ -293,6 +273,7 @@ Gitea or set your environment appropriately.`, "")
} }
} else if lastline > 0 { } else if lastline > 0 {
fmt.Fprintf(out, "\n") fmt.Fprintf(out, "\n")
lastline = 0
} }
fmt.Fprintf(out, "Checked %d references in total\n", total) fmt.Fprintf(out, "Checked %d references in total\n", total)
@@ -309,7 +290,7 @@ func runHookPostReceive(c *cli.Context) error {
defer cancel() defer cancel()
// First of all run update-server-info no matter what // First of all run update-server-info no matter what
if _, err := git.NewCommandContext(ctx, "update-server-info").Run(); err != nil { if _, err := git.NewCommand("update-server-info").SetParentContext(ctx).Run(); err != nil {
return fmt.Errorf("Failed to call 'git update-server-info': %v", err) return fmt.Errorf("Failed to call 'git update-server-info': %v", err)
} }
@@ -482,327 +463,3 @@ func pushOptions() map[string]string {
} }
return opts return opts
} }
func runHookProcReceive(c *cli.Context) error {
setup("hooks/proc-receive.log", c.Bool("debug"))
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
return fail(`Rejecting changes as Gitea environment not set.
If you are pushing over SSH you must push with a key managed by
Gitea or set your environment appropriately.`, "")
}
return nil
}
ctx, cancel := installSignals()
defer cancel()
if git.CheckGitVersionAtLeast("2.29") != nil {
return fail("Internal Server Error", "git not support proc-receive.")
}
reader := bufio.NewReader(os.Stdin)
repoUser := os.Getenv(models.EnvRepoUsername)
repoName := os.Getenv(models.EnvRepoName)
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
pusherName := os.Getenv(models.EnvPusherName)
// 1. Version and features negotiation.
// S: PKT-LINE(version=1\0push-options atomic...) / PKT-LINE(version=1\n)
// S: flush-pkt
// H: PKT-LINE(version=1\0push-options...)
// H: flush-pkt
rs, err := readPktLine(reader, pktLineTypeData)
if err != nil {
return err
}
const VersionHead string = "version=1"
var (
hasPushOptions bool
response = []byte(VersionHead)
requestOptions []string
)
index := bytes.IndexByte(rs.Data, byte(0))
if index >= len(rs.Data) {
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
}
if index < 0 {
if len(rs.Data) == 10 && rs.Data[9] == '\n' {
index = 9
} else {
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
}
}
if string(rs.Data[0:index]) != VersionHead {
return fail("Internal Server Error", "Received unsupported version: %s", string(rs.Data[0:index]))
}
requestOptions = strings.Split(string(rs.Data[index+1:]), " ")
for _, option := range requestOptions {
if strings.HasPrefix(option, "push-options") {
response = append(response, byte(0))
response = append(response, []byte("push-options")...)
hasPushOptions = true
}
}
response = append(response, '\n')
_, err = readPktLine(reader, pktLineTypeFlush)
if err != nil {
return err
}
err = writeDataPktLine(os.Stdout, response)
if err != nil {
return err
}
err = writeFlushPktLine(os.Stdout)
if err != nil {
return err
}
// 2. receive commands from server.
// S: PKT-LINE(<old-oid> <new-oid> <ref>)
// S: ... ...
// S: flush-pkt
// # [receive push-options]
// S: PKT-LINE(push-option)
// S: ... ...
// S: flush-pkt
hookOptions := private.HookOptions{
UserName: pusherName,
UserID: pusherID,
}
hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize)
hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize)
hookOptions.RefFullNames = make([]string, 0, hookBatchSize)
for {
// note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed
rs, err = readPktLine(reader, pktLineTypeUnknow)
if err != nil {
return err
}
if rs.Type == pktLineTypeFlush {
break
}
t := strings.SplitN(string(rs.Data), " ", 3)
if len(t) != 3 {
continue
}
hookOptions.OldCommitIDs = append(hookOptions.OldCommitIDs, t[0])
hookOptions.NewCommitIDs = append(hookOptions.NewCommitIDs, t[1])
hookOptions.RefFullNames = append(hookOptions.RefFullNames, t[2])
}
hookOptions.GitPushOptions = make(map[string]string)
if hasPushOptions {
for {
rs, err = readPktLine(reader, pktLineTypeUnknow)
if err != nil {
return err
}
if rs.Type == pktLineTypeFlush {
break
}
kv := strings.SplitN(string(rs.Data), "=", 2)
if len(kv) == 2 {
hookOptions.GitPushOptions[kv[0]] = kv[1]
}
}
}
// 3. run hook
resp, err := private.HookProcReceive(ctx, repoUser, repoName, hookOptions)
if err != nil {
return fail("Internal Server Error", "run proc-receive hook failed :%v", err)
}
// 4. response result to service
// # a. OK, but has an alternate reference. The alternate reference name
// # and other status can be given in option directives.
// H: PKT-LINE(ok <ref>)
// H: PKT-LINE(option refname <refname>)
// H: PKT-LINE(option old-oid <old-oid>)
// H: PKT-LINE(option new-oid <new-oid>)
// H: PKT-LINE(option forced-update)
// H: ... ...
// H: flush-pkt
// # b. NO, I reject it.
// H: PKT-LINE(ng <ref> <reason>)
// # c. Fall through, let 'receive-pack' to execute it.
// H: PKT-LINE(ok <ref>)
// H: PKT-LINE(option fall-through)
for _, rs := range resp.Results {
if len(rs.Err) > 0 {
err = writeDataPktLine(os.Stdout, []byte("ng "+rs.OriginalRef+" "+rs.Err))
if err != nil {
return err
}
continue
}
if rs.IsNotMatched {
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
if err != nil {
return err
}
err = writeDataPktLine(os.Stdout, []byte("option fall-through"))
if err != nil {
return err
}
continue
}
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
if err != nil {
return err
}
err = writeDataPktLine(os.Stdout, []byte("option refname "+rs.Ref))
if err != nil {
return err
}
if rs.OldOID != git.EmptySHA {
err = writeDataPktLine(os.Stdout, []byte("option old-oid "+rs.OldOID))
if err != nil {
return err
}
}
err = writeDataPktLine(os.Stdout, []byte("option new-oid "+rs.NewOID))
if err != nil {
return err
}
if rs.IsForcePush {
err = writeDataPktLine(os.Stdout, []byte("option forced-update"))
if err != nil {
return err
}
}
}
err = writeFlushPktLine(os.Stdout)
return err
}
// git PKT-Line api
// pktLineType message type of pkt-line
type pktLineType int64
const (
// UnKnow type
pktLineTypeUnknow pktLineType = 0
// flush-pkt "0000"
pktLineTypeFlush pktLineType = iota
// data line
pktLineTypeData
)
// gitPktLine pkt-line api
type gitPktLine struct {
Type pktLineType
Length uint64
Data []byte
}
func readPktLine(in *bufio.Reader, requestType pktLineType) (*gitPktLine, error) {
var (
err error
r *gitPktLine
)
// read prefix
lengthBytes := make([]byte, 4)
for i := 0; i < 4; i++ {
lengthBytes[i], err = in.ReadByte()
if err != nil {
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
}
}
r = new(gitPktLine)
r.Length, err = strconv.ParseUint(string(lengthBytes), 16, 32)
if err != nil {
return nil, fail("Internal Server Error", "Pkt-Line format is wrong :%v", err)
}
if r.Length == 0 {
if requestType == pktLineTypeData {
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
}
r.Type = pktLineTypeFlush
return r, nil
}
if r.Length <= 4 || r.Length > 65520 || requestType == pktLineTypeFlush {
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
}
r.Data = make([]byte, r.Length-4)
for i := range r.Data {
r.Data[i], err = in.ReadByte()
if err != nil {
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
}
}
r.Type = pktLineTypeData
return r, nil
}
func writeFlushPktLine(out io.Writer) error {
l, err := out.Write([]byte("0000"))
if err != nil {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
if l != 4 {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
return nil
}
func writeDataPktLine(out io.Writer, data []byte) error {
hexchar := []byte("0123456789abcdef")
hex := func(n uint64) byte {
return hexchar[(n)&15]
}
length := uint64(len(data) + 4)
tmp := make([]byte, 4)
tmp[0] = hex(length >> 12)
tmp[1] = hex(length >> 8)
tmp[2] = hex(length >> 4)
tmp[3] = hex(length)
lr, err := out.Write(tmp)
if err != nil {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
if 4 != lr {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
lr, err = out.Write(data)
if err != nil {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
if int(length-4) != lr {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
return nil
}

View File

@@ -1,41 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"bufio"
"bytes"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPktLine(t *testing.T) {
// test read
s := strings.NewReader("0000")
r := bufio.NewReader(s)
result, err := readPktLine(r, pktLineTypeFlush)
assert.NoError(t, err)
assert.Equal(t, pktLineTypeFlush, result.Type)
s = strings.NewReader("0006a\n")
r = bufio.NewReader(s)
result, err = readPktLine(r, pktLineTypeData)
assert.NoError(t, err)
assert.Equal(t, pktLineTypeData, result.Type)
assert.Equal(t, []byte("a\n"), result.Data)
// test write
w := bytes.NewBuffer([]byte{})
err = writeFlushPktLine(w)
assert.NoError(t, err)
assert.Equal(t, []byte("0000"), w.Bytes())
w.Reset()
err = writeDataPktLine(w, []byte("a\nb"))
assert.NoError(t, err)
assert.Equal(t, []byte("0007a\nb"), w.Bytes())
}

View File

@@ -10,7 +10,6 @@ import (
"code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@@ -18,7 +17,7 @@ func runSendMail(c *cli.Context) error {
ctx, cancel := installSignals() ctx, cancel := installSignals()
defer cancel() defer cancel()
setting.LoadFromExisting() setting.NewContext()
if err := argsSet(c, "title"); err != nil { if err := argsSet(c, "title"); err != nil {
return err return err

View File

@@ -7,7 +7,7 @@ package cmd
import ( import (
"context" "context"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/migrations" "code.gitea.io/gitea/models/migrations"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@@ -24,10 +24,7 @@ var CmdMigrate = cli.Command{
} }
func runMigrate(ctx *cli.Context) error { func runMigrate(ctx *cli.Context) error {
stdCtx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(stdCtx); err != nil {
return err return err
} }
@@ -35,9 +32,9 @@ func runMigrate(ctx *cli.Context) error {
log.Info("AppWorkPath: %s", setting.AppWorkPath) log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath) log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.LogRootPath) log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf) setting.InitDBConfig()
if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil { if err := models.NewEngine(context.Background(), migrations.Migrate); err != nil {
log.Fatal("Failed to initialize ORM engine: %v", err) log.Fatal("Failed to initialize ORM engine: %v", err)
return err return err
} }

View File

@@ -10,10 +10,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/migrations" "code.gitea.io/gitea/models/migrations"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/storage"
@@ -81,7 +78,7 @@ var CmdMigrateStorage = cli.Command{
} }
func migrateAttachments(dstStorage storage.ObjectStorage) error { func migrateAttachments(dstStorage storage.ObjectStorage) error {
return repo_model.IterateAttachment(func(attach *repo_model.Attachment) error { return models.IterateAttachment(func(attach *models.Attachment) error {
_, err := storage.Copy(dstStorage, attach.RelativePath(), storage.Attachments, attach.RelativePath()) _, err := storage.Copy(dstStorage, attach.RelativePath(), storage.Attachments, attach.RelativePath())
return err return err
}) })
@@ -95,24 +92,21 @@ func migrateLFS(dstStorage storage.ObjectStorage) error {
} }
func migrateAvatars(dstStorage storage.ObjectStorage) error { func migrateAvatars(dstStorage storage.ObjectStorage) error {
return user_model.IterateUser(func(user *user_model.User) error { return models.IterateUser(func(user *models.User) error {
_, err := storage.Copy(dstStorage, user.CustomAvatarRelativePath(), storage.Avatars, user.CustomAvatarRelativePath()) _, err := storage.Copy(dstStorage, user.CustomAvatarRelativePath(), storage.Avatars, user.CustomAvatarRelativePath())
return err return err
}) })
} }
func migrateRepoAvatars(dstStorage storage.ObjectStorage) error { func migrateRepoAvatars(dstStorage storage.ObjectStorage) error {
return repo_model.IterateRepository(func(repo *repo_model.Repository) error { return models.IterateRepository(func(repo *models.Repository) error {
_, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath()) _, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath())
return err return err
}) })
} }
func runMigrateStorage(ctx *cli.Context) error { func runMigrateStorage(ctx *cli.Context) error {
stdCtx, cancel := installSignals() if err := initDB(); err != nil {
defer cancel()
if err := initDB(stdCtx); err != nil {
return err return err
} }
@@ -120,9 +114,9 @@ func runMigrateStorage(ctx *cli.Context) error {
log.Info("AppWorkPath: %s", setting.AppWorkPath) log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath) log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.LogRootPath) log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf) setting.InitDBConfig()
if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil { if err := models.NewEngine(context.Background(), migrations.Migrate); err != nil {
log.Fatal("Failed to initialize ORM engine: %v", err) log.Fatal("Failed to initialize ORM engine: %v", err)
return err return err
} }

View File

@@ -50,7 +50,7 @@ func runRestoreRepository(c *cli.Context) error {
ctx, cancel := installSignals() ctx, cancel := installSignals()
defer cancel() defer cancel()
setting.LoadFromExisting() setting.NewContext()
statusCode, errStr := private.RestoreRepo( statusCode, errStr := private.RestoreRepo(
ctx, ctx,

View File

@@ -17,17 +17,14 @@ import (
"time" "time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/pprof" "code.gitea.io/gitea/modules/pprof"
"code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/lfs" "code.gitea.io/gitea/services/lfs"
"github.com/golang-jwt/jwt/v4" "github.com/golang-jwt/jwt"
jsoniter "github.com/json-iterator/go"
"github.com/kballard/go-shellquote" "github.com/kballard/go-shellquote"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@@ -59,18 +56,18 @@ func setup(logPath string, debug bool) {
} else { } else {
_ = log.NewLogger(1000, "console", "console", `{"level":"fatal","stacktracelevel":"NONE","stderr":true}`) _ = log.NewLogger(1000, "console", "console", `{"level":"fatal","stacktracelevel":"NONE","stderr":true}`)
} }
setting.LoadFromExisting() setting.NewContext()
if debug { if debug {
setting.RunMode = "dev" setting.RunMode = "dev"
} }
} }
var ( var (
allowedCommands = map[string]perm.AccessMode{ allowedCommands = map[string]models.AccessMode{
"git-upload-pack": perm.AccessModeRead, "git-upload-pack": models.AccessModeRead,
"git-upload-archive": perm.AccessModeRead, "git-upload-archive": models.AccessModeRead,
"git-receive-pack": perm.AccessModeWrite, "git-receive-pack": models.AccessModeWrite,
lfsAuthenticateVerb: perm.AccessModeNone, lfsAuthenticateVerb: models.AccessModeNone,
} }
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`) alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
) )
@@ -82,7 +79,7 @@ func fail(userMessage, logMessage string, args ...interface{}) error {
fmt.Fprintln(os.Stderr, "Gitea:", userMessage) fmt.Fprintln(os.Stderr, "Gitea:", userMessage)
if len(logMessage) > 0 { if len(logMessage) > 0 {
if !setting.IsProd { if !setting.IsProd() {
fmt.Fprintf(os.Stderr, logMessage+"\n", args...) fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
} }
} }
@@ -92,7 +89,7 @@ func fail(userMessage, logMessage string, args ...interface{}) error {
if len(logMessage) > 0 { if len(logMessage) > 0 {
_ = private.SSHLog(ctx, true, fmt.Sprintf(logMessage+": ", args...)) _ = private.SSHLog(ctx, true, fmt.Sprintf(logMessage+": ", args...))
} }
return cli.NewExitError("", 1) return cli.NewExitError(fmt.Sprintf("Gitea: %s", userMessage), 1)
} }
func runServ(c *cli.Context) error { func runServ(c *cli.Context) error {
@@ -130,9 +127,9 @@ func runServ(c *cli.Context) error {
return fail("Internal error", "Failed to check provided key: %v", err) return fail("Internal error", "Failed to check provided key: %v", err)
} }
switch key.Type { switch key.Type {
case asymkey_model.KeyTypeDeploy: case models.KeyTypeDeploy:
println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.") println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.")
case asymkey_model.KeyTypePrincipal: case models.KeyTypePrincipal:
println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Gitea does not provide shell access.") println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Gitea does not provide shell access.")
default: default:
println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.") println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.")
@@ -149,13 +146,6 @@ func runServ(c *cli.Context) error {
} }
if len(words) < 2 { if len(words) < 2 {
if git.CheckGitVersionAtLeast("2.29") == nil {
// for AGit Flow
if cmd == "ssh_info" {
fmt.Print(`{"type":"gitea","version":1}`)
return nil
}
}
return fail("Too few arguments", "Too few arguments in cmd: %s", cmd) return fail("Too few arguments", "Too few arguments in cmd: %s", cmd)
} }
@@ -191,7 +181,7 @@ func runServ(c *cli.Context) error {
return fail("Invalid repo name", "Invalid repo name: %s", reponame) return fail("Invalid repo name", "Invalid repo name: %s", reponame)
} }
if c.Bool("enable-pprof") { if setting.EnablePprof || c.Bool("enable-pprof") {
if err := os.MkdirAll(setting.PprofDataPath, os.ModePerm); err != nil { if err := os.MkdirAll(setting.PprofDataPath, os.ModePerm); err != nil {
return fail("Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err) return fail("Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)
} }
@@ -216,9 +206,9 @@ func runServ(c *cli.Context) error {
if verb == lfsAuthenticateVerb { if verb == lfsAuthenticateVerb {
if lfsVerb == "upload" { if lfsVerb == "upload" {
requestedMode = perm.AccessModeWrite requestedMode = models.AccessModeWrite
} else if lfsVerb == "download" { } else if lfsVerb == "download" {
requestedMode = perm.AccessModeRead requestedMode = models.AccessModeRead
} else { } else {
return fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb) return fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb)
} }
@@ -243,7 +233,7 @@ func runServ(c *cli.Context) error {
os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10)) os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
os.Setenv(models.EnvRepoID, strconv.FormatInt(results.RepoID, 10)) os.Setenv(models.EnvRepoID, strconv.FormatInt(results.RepoID, 10))
os.Setenv(models.EnvPRID, fmt.Sprintf("%d", 0)) os.Setenv(models.EnvPRID, fmt.Sprintf("%d", 0))
os.Setenv(models.EnvDeployKeyID, fmt.Sprintf("%d", results.DeployKeyID)) os.Setenv(models.EnvIsDeployKey, fmt.Sprintf("%t", results.IsDeployKey))
os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID)) os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID))
os.Setenv(models.EnvAppURL, setting.AppURL) os.Setenv(models.EnvAppURL, setting.AppURL)
@@ -253,8 +243,7 @@ func runServ(c *cli.Context) error {
now := time.Now() now := time.Now()
claims := lfs.Claims{ claims := lfs.Claims{
// FIXME: we need to migrate to RegisteredClaims StandardClaims: jwt.StandardClaims{
StandardClaims: jwt.StandardClaims{ // nolint
ExpiresAt: now.Add(setting.LFS.HTTPAuthExpiry).Unix(), ExpiresAt: now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
NotBefore: now.Unix(), NotBefore: now.Unix(),
}, },
@@ -276,6 +265,7 @@ func runServ(c *cli.Context) error {
} }
tokenAuthentication.Header["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) tokenAuthentication.Header["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
json := jsoniter.ConfigCompatibleWithStandardLibrary
enc := json.NewEncoder(os.Stdout) enc := json.NewEncoder(os.Stdout)
err = enc.Encode(tokenAuthentication) err = enc.Encode(tokenAuthentication)
if err != nil { if err != nil {
@@ -297,15 +287,6 @@ func runServ(c *cli.Context) error {
gitcmd = exec.CommandContext(ctx, verb, repoPath) gitcmd = exec.CommandContext(ctx, verb, repoPath)
} }
// Check if setting.RepoRootPath exists. It could be the case that it doesn't exist, this can happen when
// `[repository]` `ROOT` is a relative path and $GITEA_WORK_DIR isn't passed to the SSH connection.
if _, err := os.Stat(setting.RepoRootPath); err != nil {
if os.IsNotExist(err) {
return fail("Incorrect configuration.",
"Directory `[repository]` `ROOT` was not found, please check if $GITEA_WORK_DIR is passed to the SSH connection or make `[repository]` `ROOT` an absolute value.")
}
}
gitcmd.Dir = setting.RepoRootPath gitcmd.Dir = setting.RepoRootPath
gitcmd.Stdout = os.Stdout gitcmd.Stdout = os.Stdout
gitcmd.Stdin = os.Stdin gitcmd.Stdin = os.Stdin

View File

@@ -9,17 +9,17 @@ import (
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
"os" "os"
"strings" "strings"
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers" "code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/install" "code.gitea.io/gitea/routers/install"
context2 "github.com/gorilla/context"
"github.com/urfave/cli" "github.com/urfave/cli"
ini "gopkg.in/ini.v1" ini "gopkg.in/ini.v1"
) )
@@ -71,7 +71,7 @@ func runHTTPRedirector() {
http.Redirect(w, r, target, http.StatusTemporaryRedirect) http.Redirect(w, r, target, http.StatusTemporaryRedirect)
}) })
var err = runHTTP("tcp", source, "HTTP Redirector", handler) var err = runHTTP("tcp", source, "HTTP Redirector", context2.ClearHandler(handler))
if err != nil { if err != nil {
log.Fatal("Failed to start port redirection: %v", err) log.Fatal("Failed to start port redirection: %v", err)
@@ -124,10 +124,6 @@ func runWeb(ctx *cli.Context) error {
} }
c := install.Routes() c := install.Routes()
err := listen(c, false) err := listen(c, false)
if err != nil {
log.Critical("Unable to open listener for installer. Is Gitea already running?")
graceful.GetManager().DoGracefulShutdown()
}
select { select {
case <-graceful.GetManager().IsShutdown(): case <-graceful.GetManager().IsShutdown():
<-graceful.GetManager().Done() <-graceful.GetManager().Done()
@@ -149,15 +145,7 @@ func runWeb(ctx *cli.Context) error {
log.Info("Global init") log.Info("Global init")
// Perform global initialization // Perform global initialization
setting.LoadFromExisting() routers.GlobalInit(graceful.GetManager().HammerContext())
routers.GlobalInitInstalled(graceful.GetManager().HammerContext())
// We check that AppDataPath exists here (it should have been created during installation)
// We can't check it in `GlobalInitInstalled`, because some integration tests
// use cmd -> GlobalInitInstalled, but the AppDataPath doesn't exist during those tests.
if _, err := os.Stat(setting.AppDataPath); err != nil {
log.Fatal("Can not find APP_DATA_PATH '%s'", setting.AppDataPath)
}
// Override the provided port number within the configuration // Override the provided port number within the configuration
if ctx.IsSet("port") { if ctx.IsSet("port") {
@@ -180,7 +168,7 @@ func setPort(port string) error {
setting.HTTPPort = port setting.HTTPPort = port
switch setting.Protocol { switch setting.Protocol {
case setting.HTTPUnix: case setting.UnixSocket:
case setting.FCGI: case setting.FCGI:
case setting.FCGIUnix: case setting.FCGIUnix:
default: default:
@@ -202,14 +190,10 @@ func setPort(port string) error {
func listen(m http.Handler, handleRedirector bool) error { func listen(m http.Handler, handleRedirector bool) error {
listenAddr := setting.HTTPAddr listenAddr := setting.HTTPAddr
if setting.Protocol != setting.HTTPUnix && setting.Protocol != setting.FCGIUnix { if setting.Protocol != setting.UnixSocket && setting.Protocol != setting.FCGIUnix {
listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort) listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort)
} }
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL) log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
// This can be useful for users, many users do wrong to their config and get strange behaviors behind a reverse-proxy.
// A user may fix the configuration mistake when he sees this log.
// And this is also very helpful to maintainers to provide help to users to resolve their configuration problems.
log.Info("AppURL(ROOT_URL): %s", setting.AppURL)
if setting.LFS.StartServer { if setting.LFS.StartServer {
log.Info("LFS server enabled") log.Info("LFS server enabled")
@@ -221,10 +205,10 @@ func listen(m http.Handler, handleRedirector bool) error {
if handleRedirector { if handleRedirector {
NoHTTPRedirector() NoHTTPRedirector()
} }
err = runHTTP("tcp", listenAddr, "Web", m) err = runHTTP("tcp", listenAddr, "Web", context2.ClearHandler(m))
case setting.HTTPS: case setting.HTTPS:
if setting.EnableLetsEncrypt { if setting.EnableLetsEncrypt {
err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, m) err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m))
break break
} }
if handleRedirector { if handleRedirector {
@@ -234,22 +218,22 @@ func listen(m http.Handler, handleRedirector bool) error {
NoHTTPRedirector() NoHTTPRedirector()
} }
} }
err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, m) err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
case setting.FCGI: case setting.FCGI:
if handleRedirector { if handleRedirector {
NoHTTPRedirector() NoHTTPRedirector()
} }
err = runFCGI("tcp", listenAddr, "FCGI Web", m) err = runFCGI("tcp", listenAddr, "FCGI Web", context2.ClearHandler(m))
case setting.HTTPUnix: case setting.UnixSocket:
if handleRedirector { if handleRedirector {
NoHTTPRedirector() NoHTTPRedirector()
} }
err = runHTTP("unix", listenAddr, "Web", m) err = runHTTP("unix", listenAddr, "Web", context2.ClearHandler(m))
case setting.FCGIUnix: case setting.FCGIUnix:
if handleRedirector { if handleRedirector {
NoHTTPRedirector() NoHTTPRedirector()
} }
err = runFCGI("unix", listenAddr, "Web", m) err = runFCGI("unix", listenAddr, "Web", context2.ClearHandler(m))
default: default:
log.Fatal("Invalid protocol: %s", setting.Protocol) log.Fatal("Invalid protocol: %s", setting.Protocol)
} }

View File

@@ -5,6 +5,7 @@
package cmd package cmd
import ( import (
"crypto/tls"
"net" "net"
"net/http" "net/http"
"net/http/fcgi" "net/http/fcgi"
@@ -19,6 +20,14 @@ func runHTTP(network, listenAddr, name string, m http.Handler) error {
return graceful.HTTPListenAndServe(network, listenAddr, name, m) return graceful.HTTPListenAndServe(network, listenAddr, name, m)
} }
func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler) error {
return graceful.HTTPListenAndServeTLS(network, listenAddr, name, certFile, keyFile, m)
}
func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler) error {
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
}
// NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector // NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector
func NoHTTPRedirector() { func NoHTTPRedirector() {
graceful.GetManager().InformCleanup() graceful.GetManager().InformCleanup()

View File

@@ -1,192 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"crypto/tls"
"net/http"
"os"
"strings"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/klauspost/cpuid/v2"
)
var tlsVersionStringMap = map[string]uint16{
"": tls.VersionTLS12, // Default to tls.VersionTLS12
"tlsv1.0": tls.VersionTLS10,
"tlsv1.1": tls.VersionTLS11,
"tlsv1.2": tls.VersionTLS12,
"tlsv1.3": tls.VersionTLS13,
}
func toTLSVersion(version string) uint16 {
tlsVersion, ok := tlsVersionStringMap[strings.TrimSpace(strings.ToLower(version))]
if !ok {
log.Warn("Unknown tls version: %s", version)
return 0
}
return tlsVersion
}
var curveStringMap = map[string]tls.CurveID{
"x25519": tls.X25519,
"p256": tls.CurveP256,
"p384": tls.CurveP384,
"p521": tls.CurveP521,
}
func toCurvePreferences(preferences []string) []tls.CurveID {
ids := make([]tls.CurveID, 0, len(preferences))
for _, pref := range preferences {
id, ok := curveStringMap[strings.TrimSpace(strings.ToLower(pref))]
if !ok {
log.Warn("Unknown curve: %s", pref)
}
if id != 0 {
ids = append(ids, id)
}
}
return ids
}
var cipherStringMap = map[string]uint16{
"rsa_with_rc4_128_sha": tls.TLS_RSA_WITH_RC4_128_SHA,
"rsa_with_3des_ede_cbc_sha": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
"rsa_with_aes_128_cbc_sha": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
"rsa_with_aes_256_cbc_sha": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
"rsa_with_aes_128_cbc_sha256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
"rsa_with_aes_128_gcm_sha256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
"rsa_with_aes_256_gcm_sha384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
"ecdhe_ecdsa_with_rc4_128_sha": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
"ecdhe_ecdsa_with_aes_128_cbc_sha": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
"ecdhe_ecdsa_with_aes_256_cbc_sha": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
"ecdhe_rsa_with_rc4_128_sha": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
"ecdhe_rsa_with_3des_ede_cbc_sha": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
"ecdhe_rsa_with_aes_128_cbc_sha": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
"ecdhe_rsa_with_aes_256_cbc_sha": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
"ecdhe_ecdsa_with_aes_128_cbc_sha256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
"ecdhe_rsa_with_aes_128_cbc_sha256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
"ecdhe_rsa_with_aes_128_gcm_sha256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
"ecdhe_ecdsa_with_aes_128_gcm_sha256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
"ecdhe_rsa_with_aes_256_gcm_sha384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
"ecdhe_ecdsa_with_aes_256_gcm_sha384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
"ecdhe_rsa_with_chacha20_poly1305_sha256": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
"ecdhe_ecdsa_with_chacha20_poly1305_sha256": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
"ecdhe_rsa_with_chacha20_poly1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
"ecdhe_ecdsa_with_chacha20_poly1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
"aes_128_gcm_sha256": tls.TLS_AES_128_GCM_SHA256,
"aes_256_gcm_sha384": tls.TLS_AES_256_GCM_SHA384,
"chacha20_poly1305_sha256": tls.TLS_CHACHA20_POLY1305_SHA256,
}
func toTLSCiphers(cipherStrings []string) []uint16 {
ciphers := make([]uint16, 0, len(cipherStrings))
for _, cipherString := range cipherStrings {
cipher, ok := cipherStringMap[strings.TrimSpace(strings.ToLower(cipherString))]
if !ok {
log.Warn("Unknown cipher: %s", cipherString)
}
if cipher != 0 {
ciphers = append(ciphers, cipher)
}
}
return ciphers
}
// defaultCiphers uses hardware support to check if AES is specifically
// supported by the CPU.
//
// If AES is supported AES ciphers will be preferred over ChaCha based ciphers
// (This code is directly inspired by the certmagic code.)
func defaultCiphers() []uint16 {
if cpuid.CPU.Supports(cpuid.AESNI) {
return defaultCiphersAESfirst
}
return defaultCiphersChaChaFirst
}
var (
defaultCiphersAES = []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
}
defaultCiphersChaCha = []uint16{
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
}
defaultCiphersAESfirst = append(defaultCiphersAES, defaultCiphersChaCha...)
defaultCiphersChaChaFirst = append(defaultCiphersChaCha, defaultCiphersAES...)
)
// runHTTPs listens on the provided network address and then calls
// Serve to handle requests on incoming TLS connections.
//
// Filenames containing a certificate and matching private key for the server must
// be provided. If the certificate is signed by a certificate authority, the
// certFile should be the concatenation of the server's certificate followed by the
// CA's certificate.
func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler) error {
tlsConfig := &tls.Config{}
if tlsConfig.NextProtos == nil {
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
}
if version := toTLSVersion(setting.SSLMinimumVersion); version != 0 {
tlsConfig.MinVersion = version
}
if version := toTLSVersion(setting.SSLMaximumVersion); version != 0 {
tlsConfig.MaxVersion = version
}
// Set curve preferences
tlsConfig.CurvePreferences = []tls.CurveID{
tls.X25519,
tls.CurveP256,
}
if curves := toCurvePreferences(setting.SSLCurvePreferences); len(curves) > 0 {
tlsConfig.CurvePreferences = curves
}
// Set cipher suites
tlsConfig.CipherSuites = defaultCiphers()
if ciphers := toTLSCiphers(setting.SSLCipherSuites); len(ciphers) > 0 {
tlsConfig.CipherSuites = ciphers
}
tlsConfig.Certificates = make([]tls.Certificate, 1)
certPEMBlock, err := os.ReadFile(certFile)
if err != nil {
log.Error("Failed to load https cert file %s for %s:%s: %v", certFile, network, listenAddr, err)
return err
}
keyPEMBlock, err := os.ReadFile(keyFile)
if err != nil {
log.Error("Failed to load https key file %s for %s:%s: %v", keyFile, network, listenAddr, err)
return err
}
tlsConfig.Certificates[0], err = tls.X509KeyPair(certPEMBlock, keyPEMBlock)
if err != nil {
log.Error("Failed to create certificate from cert file %s and key file %s for %s:%s: %v", certFile, keyFile, network, listenAddr, err)
return err
}
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
}
func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler) error {
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
}

View File

@@ -9,11 +9,11 @@ import (
"strconv" "strconv"
"strings" "strings"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/caddyserver/certmagic" "github.com/caddyserver/certmagic"
context2 "github.com/gorilla/context"
) )
func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error { func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error {
@@ -48,7 +48,7 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
magic.Issuers = []certmagic.Issuer{myACME} magic.Issuers = []certmagic.Issuer{myACME}
// this obtains certificates or renews them if necessary // this obtains certificates or renews them if necessary
err := magic.ManageSync(graceful.GetManager().HammerContext(), []string{domain}) err := magic.ManageSync([]string{domain})
if err != nil { if err != nil {
return err return err
} }
@@ -56,23 +56,6 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
tlsConfig := magic.TLSConfig() tlsConfig := magic.TLSConfig()
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2") tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2")
if version := toTLSVersion(setting.SSLMinimumVersion); version != 0 {
tlsConfig.MinVersion = version
}
if version := toTLSVersion(setting.SSLMaximumVersion); version != 0 {
tlsConfig.MaxVersion = version
}
// Set curve preferences
if curves := toCurvePreferences(setting.SSLCurvePreferences); len(curves) > 0 {
tlsConfig.CurvePreferences = curves
}
// Set cipher suites
if ciphers := toTLSCiphers(setting.SSLCipherSuites); len(ciphers) > 0 {
tlsConfig.CipherSuites = ciphers
}
if enableHTTPChallenge { if enableHTTPChallenge {
go func() { go func() {
log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect) log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
@@ -84,7 +67,7 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
}() }()
} }
return runHTTPSWithTLSConfig("tcp", listenAddr, "Web", tlsConfig, m) return runHTTPSWithTLSConfig("tcp", listenAddr, "Web", tlsConfig, context2.ClearHandler(m))
} }
func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) { func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {

View File

@@ -156,7 +156,6 @@ func runEnvironmentToIni(c *cli.Context) error {
destination = setting.CustomConf destination = setting.CustomConf
} }
if destination != setting.CustomConf || changed { if destination != setting.CustomConf || changed {
log.Info("Settings saved to: %q", destination)
err = cfg.SaveTo(destination) err = cfg.SaveTo(destination)
if err != nil { if err != nil {
return err return err
@@ -225,6 +224,7 @@ func DecodeSectionKey(encoded string) (string, string) {
if !inKey { if !inKey {
if splitter := strings.Index(remaining, "__"); splitter > -1 { if splitter := strings.Index(remaining, "__"); splitter > -1 {
section += remaining[:splitter] section += remaining[:splitter]
inKey = true
key += remaining[splitter+2:] key += remaining[splitter+2:]
} else { } else {
section += remaining section += remaining

View File

@@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
############################################################################# ########################################################################
# This script sets some defaults for gitea to run in a FHS compliant manner # # This script some defaults for gitea to run in a FHS compliant manner #
############################################################################# ########################################################################
# It assumes that you place this script as gitea in /usr/bin # It assumes that you place this script as gitea in /usr/bin
# #
@@ -33,8 +33,10 @@ for i in "$@"; do
done done
if [ -z "$APP_INI_SET" ]; then if [ -z "$APP_INI_SET" ]; then
CONF_ARG=("-c" "${GITEA_APP_INI:-$APP_INI}") CONF_ARG="-c \"$APP_INI\""
fi fi
# Provide FHS compliant defaults # Provide FHS compliant defaults to
GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" exec -a "$0" "$GITEA" "${CONF_ARG[@]}" "$@" GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" "$GITEA" $CONF_ARG "$@"

View File

@@ -6,11 +6,11 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/unittest"
) )
// To generate derivative fixtures, execute the following from Gitea's repository base dir: // To generate derivative fixtures, execute the following from Gitea's repository base dir:
@@ -31,13 +31,11 @@ var (
func main() { func main() {
pathToGiteaRoot := "." pathToGiteaRoot := "."
fixturesDir = filepath.Join(pathToGiteaRoot, "models", "fixtures") fixturesDir = filepath.Join(pathToGiteaRoot, "models", "fixtures")
if err := unittest.CreateTestEngine(unittest.FixturesOptions{ if err := models.CreateTestEngine(fixturesDir); err != nil {
Dir: fixturesDir,
}); err != nil {
fmt.Printf("CreateTestEngine: %+v", err) fmt.Printf("CreateTestEngine: %+v", err)
os.Exit(1) os.Exit(1)
} }
if err := unittest.PrepareTestDatabase(); err != nil { if err := models.PrepareTestDatabase(); err != nil {
fmt.Printf("PrepareTestDatabase: %+v\n", err) fmt.Printf("PrepareTestDatabase: %+v\n", err)
os.Exit(1) os.Exit(1)
} }
@@ -66,7 +64,7 @@ func generate(name string) error {
return err return err
} }
path := filepath.Join(fixturesDir, name+".yml") path := filepath.Join(fixturesDir, name+".yml")
if err := os.WriteFile(path, []byte(data), 0644); err != nil { if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil {
return fmt.Errorf("%s: %+v", path, err) return fmt.Errorf("%s: %+v", path, err)
} }
fmt.Printf("%s created.\n", path) fmt.Printf("%s created.\n", path)

View File

@@ -1,2 +0,0 @@
dashboards_out
vendor

View File

@@ -1,31 +0,0 @@
JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 1 --string-style s --comment-style s
.PHONY: all
all: build dashboards_out
vendor: jsonnetfile.json
jb install
.PHONY: build
build: vendor
.PHONY: fmt
fmt:
find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
xargs -n 1 -- $(JSONNET_FMT) -i
.PHONY: lint
lint: build
find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
while read f; do \
$(JSONNET_FMT) "$$f" | diff -u "$$f" -; \
done
mixtool lint mixin.libsonnet
dashboards_out: mixin.libsonnet config.libsonnet $(wildcard dashboards/*)
@mkdir -p dashboards_out
jsonnet -J vendor -m dashboards_out lib/dashboards.jsonnet
.PHONY: clean
clean:
rm -rf dashboards_out

View File

@@ -1,33 +0,0 @@
# Gitea Mixin
Gitea Mixin is a set of configurable Grafana dashboards based on the metrics exported by the Gitea built-in metrics endpoint.
## Generate config files
You can manually generate dashboards, but first you should install some tools:
```bash
go install github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@latest
go install github.com/google/go-jsonnet/cmd/jsonnet@latest
# or in brew: brew install go-jsonnet
```
For linting and formatting, you would also need `mixtool` and `jsonnetfmt` installed. If you
have a working Go development environment, it's easiest to run the following:
```bash
go install github.com/monitoring-mixins/mixtool/cmd/mixtool@latest
go install github.com/google/go-jsonnet/cmd/jsonnetfmt@latest
```
The files in `dashboards_out` need to be imported
into your Grafana server. The exact details will be depending on your environment.
Edit `config.libsonnet` if required and then build JSON dashboard files for Grafana:
```bash
make
```
For more advanced uses of mixins, see
https://github.com/monitoring-mixins/docs.

View File

@@ -1,99 +0,0 @@
{
_config+:: {
local c = self,
dashboardNamePrefix: 'Gitea',
dashboardTags: ['gitea'],
dashboardPeriod: 'now-1h',
dashboardTimezone: 'default',
dashboardRefresh: '1m',
// please see https://docs.gitea.io/en-us/config-cheat-sheet/#metrics-metrics
// Show issue by repository metrics with format gitea_issues_by_repository{repository="org/repo"} 5.
// Requires Gitea 1.16.0 with ENABLED_ISSUE_BY_REPOSITORY set to true.
showIssuesByRepository: true,
// Show graphs for issue by label metrics with format gitea_issues_by_label{label="bug"} 2.
// Requires Gitea 1.16.0 with ENABLED_ISSUE_BY_LABEL set to true.
showIssuesByLabel: true,
// Requires Gitea 1.16.0.
showIssuesOpenClose: true,
// add or remove metrics from dashboard
giteaStatMetrics:
[
{
name: 'gitea_organizations',
description: 'Organizations',
},
{
name: 'gitea_teams',
description: 'Teams',
},
{
name: 'gitea_users',
description: 'Users',
},
{
name: 'gitea_repositories',
description: 'Repositories',
},
{
name: 'gitea_milestones',
description: 'Milestones',
},
{
name: 'gitea_stars',
description: 'Stars',
},
{
name: 'gitea_releases',
description: 'Releases',
},
]
+
if c.showIssuesOpenClose then
[
{
name: 'gitea_issues_open',
description: 'Issues opened',
},
{
name: 'gitea_issues_closed',
description: 'Issues closed',
},
] else
[
{
name: 'gitea_issues',
description: 'Issues',
},
],
//set this for using label colors on graphs
issueLabels: [
{
label: 'bug',
color: '#ee0701',
},
{
label: 'duplicate',
color: '#cccccc',
},
{
label: 'invalid',
color: '#e6e6e6',
},
{
label: 'enhancement',
color: '#84b6eb',
},
{
label: 'help wanted',
color: '#128a0c',
},
{
label: 'question',
color: '#cc317c',
},
],
},
}

View File

@@ -1 +0,0 @@
(import 'overview.libsonnet')

View File

@@ -1,461 +0,0 @@
local grafana = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet';
local prometheus = grafana.prometheus;
local addIssueLabelsOverrides(labels) =
{
fieldConfig+: {
overrides+: [
{
matcher: {
id: 'byRegexp',
options: label.label,
},
properties: [
{
id: 'color',
value: {
fixedColor: label.color,
mode: 'fixed',
},
},
],
}
for label in labels
],
},
};
{
grafanaDashboards+:: {
local giteaSelector = 'job="$job", instance="$instance"',
local giteaStatsPanel =
grafana.statPanel.new(
'Gitea stats',
datasource='$datasource',
reducerFunction='lastNotNull',
graphMode='none',
colorMode='value',
)
.addTargets(
[
prometheus.target(expr='%s{%s}' % [metric.name, giteaSelector], legendFormat=metric.description, intervalFactor=10)
for metric in $._config.giteaStatMetrics
]
)
+ {
fieldConfig+: {
defaults+: {
color: {
fixedColor: 'blue',
mode: 'fixed',
},
},
},
},
local giteaUptimePanel =
grafana.statPanel.new(
'Uptime',
datasource='$datasource',
reducerFunction='last',
graphMode='area',
colorMode='value',
)
.addTarget(prometheus.target(expr='time()-process_start_time_seconds{%s}' % giteaSelector, intervalFactor=1))
+ {
fieldConfig+: {
defaults+: {
color: {
fixedColor: 'blue',
mode: 'fixed',
},
unit: 's',
},
},
},
local giteaMemoryPanel =
grafana.graphPanel.new(
'Memory usage',
datasource='$datasource'
)
.addTarget(prometheus.target(expr='process_resident_memory_bytes{%s}' % giteaSelector, intervalFactor=2))
+ {
type: 'timeseries',
options+: {
tooltip: {
mode: 'multi',
},
legend+: {
displayMode: 'hidden',
},
},
fieldConfig+: {
defaults+: {
custom+: {
lineInterpolation: 'smooth',
fillOpacity: 15,
},
color: {
fixedColor: 'green',
mode: 'fixed',
},
unit: 'decbytes',
},
},
},
local giteaCpuPanel =
grafana.graphPanel.new(
'CPU usage',
datasource='$datasource'
)
.addTarget(prometheus.target(expr='rate(process_cpu_seconds_total{%s}[$__rate_interval])*100' % giteaSelector, intervalFactor=2))
+ {
type: 'timeseries',
options+: {
tooltip: {
mode: 'multi',
},
legend+: {
displayMode: 'hidden',
},
},
fieldConfig+: {
defaults+: {
custom+: {
lineInterpolation: 'smooth',
gradientMode: 'scheme',
fillOpacity: 15,
axisSoftMin: 0,
axisSoftMax: 0,
},
color: {
mode: 'continuous-GrYlRd', // from green to red (100%)
},
unit: 'percent',
},
overrides: [
{
matcher: {
id: 'byRegexp',
options: '.+',
},
properties: [
{
id: 'max',
value: 100,
},
{
id: 'min',
value: 0,
},
],
},
],
},
},
local giteaFileDescriptorsPanel =
grafana.graphPanel.new(
'File descriptors usage',
datasource='$datasource',
)
.addTarget(prometheus.target(expr='process_open_fds{%s}' % giteaSelector, intervalFactor=2))
.addTarget(prometheus.target(expr='process_max_fds{%s}' % giteaSelector, intervalFactor=2))
.addSeriesOverride(
{
alias: '/process_max_fds.+/',
color: '#F2495C', // red
dashes: true,
fill: 0,
},
)
+ {
type: 'timeseries',
options+: {
tooltip: {
mode: 'multi',
},
legend+: {
displayMode: 'hidden',
},
},
fieldConfig+: {
defaults+: {
custom+: {
lineInterpolation: 'smooth',
gradientMode: 'scheme',
fillOpacity: 0,
},
color: {
fixedColor: 'green',
mode: 'fixed',
},
unit: '',
},
overrides: [
{
matcher: {
id: 'byFrameRefID',
options: 'B',
},
properties: [
{
id: 'custom.lineStyle',
value: {
fill: 'dash',
dash: [
10,
10,
],
},
},
{
id: 'color',
value: {
mode: 'fixed',
fixedColor: 'red',
},
},
],
},
],
},
},
local giteaChangesPanelPrototype =
grafana.graphPanel.new(
'',
datasource='$datasource',
interval='$agg_interval',
maxDataPoints=10000,
)
+ {
type: 'timeseries',
options+: {
tooltip: {
mode: 'multi',
},
legend+: {
calcs+: [
'sum',
],
},
},
fieldConfig+: {
defaults+: {
noValue: '0',
custom+: {
drawStyle: 'bars',
barAlignment: -1,
fillOpacity: 50,
gradientMode: 'hue',
pointSize: 1,
lineWidth: 0,
stacking: {
group: 'A',
mode: 'normal',
},
},
},
},
},
local giteaChangesPanelAll =
giteaChangesPanelPrototype
.addTarget(prometheus.target(expr='changes(process_start_time_seconds{%s}[$__interval]) > 0' % [giteaSelector], legendFormat='Restarts', intervalFactor=1))
.addTargets(
[
prometheus.target(expr='floor(delta(%s{%s}[$__interval])) > 0' % [metric.name, giteaSelector], legendFormat=metric.description, intervalFactor=1)
for metric in $._config.giteaStatMetrics
]
) + { id: 200 }, // some unique number, beyond the maximum number of panels in the dashboard,
local giteaChangesPanelTotal =
grafana.statPanel.new(
'Changes',
datasource='-- Dashboard --',
reducerFunction='sum',
graphMode='none',
textMode='value_and_name',
colorMode='value',
)
+ {
targets+: [
{
panelId: giteaChangesPanelAll.id,
refId: 'A',
},
],
}
+ {
fieldConfig+: {
defaults+: {
color: {
mode: 'palette-classic',
},
},
},
},
local giteaChangesByRepositories =
giteaChangesPanelPrototype
.addTarget(prometheus.target(expr='floor(increase(gitea_issues_by_repository{%s}[$__interval])) > 0' % [giteaSelector], legendFormat='{{ repository }}', intervalFactor=1))
+ { id: 210 }, // some unique number, beyond the maximum number of panels in the dashboard,
local giteaChangesByRepositoriesTotal =
grafana.statPanel.new(
'Issues by repository',
datasource='-- Dashboard --',
reducerFunction='sum',
graphMode='none',
textMode='value_and_name',
colorMode='value',
)
+ {
id: 211,
targets+: [
{
panelId: giteaChangesByRepositories.id,
refId: 'A',
},
],
}
+ {
fieldConfig+: {
defaults+: {
color: {
mode: 'palette-classic',
},
},
},
},
local giteaChangesByLabel =
giteaChangesPanelPrototype
.addTarget(prometheus.target(expr='floor(increase(gitea_issues_by_label{%s}[$__interval])) > 0' % [giteaSelector], legendFormat='{{ label }}', intervalFactor=1))
+ addIssueLabelsOverrides($._config.issueLabels)
+ { id: 220 }, // some unique number, beyond the maximum number of panels in the dashboard,
local giteaChangesByLabelTotal =
grafana.statPanel.new(
'Issues by labels',
datasource='-- Dashboard --',
reducerFunction='sum',
graphMode='none',
textMode='value_and_name',
colorMode='value',
)
+ addIssueLabelsOverrides($._config.issueLabels)
+ {
id: 221,
targets+: [
{
panelId: giteaChangesByLabel.id,
refId: 'A',
},
],
}
+ {
fieldConfig+: {
defaults+: {
color: {
mode: 'palette-classic',
},
},
},
},
'gitea-overview.json':
grafana.dashboard.new(
'%s Overview' % $._config.dashboardNamePrefix,
time_from='%s' % $._config.dashboardPeriod,
editable=false,
tags=($._config.dashboardTags),
timezone='%s' % $._config.dashboardTimezone,
refresh='%s' % $._config.dashboardRefresh,
graphTooltip='shared_crosshair',
uid='gitea-overview'
)
.addTemplate(
{
current: {
text: 'Prometheus',
value: 'Prometheus',
},
hide: 0,
label: 'Data Source',
name: 'datasource',
options: [],
query: 'prometheus',
refresh: 1,
regex: '',
type: 'datasource',
},
)
.addTemplate(
{
hide: 0,
label: null,
name: 'job',
options: [],
query: 'label_values(gitea_organizations, job)',
refresh: 1,
regex: '',
type: 'query',
},
)
.addTemplate(
{
hide: 0,
label: null,
name: 'instance',
options: [],
query: 'label_values(gitea_organizations{job="$job"}, instance)',
refresh: 1,
regex: '',
type: 'query',
},
)
.addTemplate(
{
hide: 0,
label: 'aggregation interval',
name: 'agg_interval',
auto_min: '1m',
auto: true,
query: '1m,10m,1h,1d,7d',
type: 'interval',
},
)
.addPanel(grafana.row.new(title='General'), gridPos={ x: 0, y: 0, w: 0, h: 0 },)
.addPanel(giteaStatsPanel, gridPos={ x: 0, y: 0, w: 16, h: 4 })
.addPanel(giteaUptimePanel, gridPos={ x: 16, y: 0, w: 8, h: 4 })
.addPanel(giteaMemoryPanel, gridPos={ x: 0, y: 4, w: 8, h: 6 })
.addPanel(giteaCpuPanel, gridPos={ x: 8, y: 4, w: 8, h: 6 })
.addPanel(giteaFileDescriptorsPanel, gridPos={ x: 16, y: 4, w: 8, h: 6 })
.addPanel(grafana.row.new(title='Changes', collapse=false), gridPos={ x: 0, y: 10, w: 24, h: 8 })
.addPanel(giteaChangesPanelTotal, gridPos={ x: 0, y: 12, w: 6, h: 8 })
+ // use patching instead of .addPanel() to keep static ids
{
panels+: std.flattenArrays([
[
giteaChangesPanelAll { gridPos: { x: 6, y: 12, w: 18, h: 8 } },
],
if $._config.showIssuesByRepository then
[
giteaChangesByRepositoriesTotal { gridPos: { x: 0, y: 20, w: 6, h: 8 } },
giteaChangesByRepositories { gridPos: { x: 6, y: 20, w: 18, h: 8 } },
] else [],
if $._config.showIssuesByLabel then
[
giteaChangesByLabelTotal { gridPos: { x: 0, y: 28, w: 6, h: 8 } },
giteaChangesByLabel { gridPos: { x: 6, y: 28, w: 18, h: 8 } },
] else [],
]),
},
},
}

View File

@@ -1,15 +0,0 @@
{
"version": 1,
"dependencies": [
{
"source": {
"git": {
"remote": "https://github.com/grafana/grafonnet-lib.git",
"subdir": "grafonnet"
}
},
"version": "master"
}
],
"legacyImports": false
}

View File

@@ -1,16 +0,0 @@
{
"version": 1,
"dependencies": [
{
"source": {
"git": {
"remote": "https://github.com/grafana/grafonnet-lib.git",
"subdir": "grafonnet"
}
},
"version": "3626fc4dc2326931c530861ac5bebe39444f6cbf",
"sum": "gF8foHByYcB25jcUOBqP6jxk0OPifQMjPvKY0HaCk6w="
}
],
"legacyImports": false
}

View File

@@ -1 +0,0 @@
std.manifestYamlDoc((import '../mixin.libsonnet').prometheusAlerts)

View File

@@ -1,6 +0,0 @@
local dashboards = (import '../mixin.libsonnet').grafanaDashboards;
{
[name]: dashboards[name]
for name in std.objectFields(dashboards)
}

View File

@@ -1 +0,0 @@
std.manifestYamlDoc((import '../mixin.libsonnet').prometheusRules)

View File

@@ -1,2 +0,0 @@
(import 'dashboards/dashboards.libsonnet') +
(import 'config.libsonnet')

View File

@@ -12,6 +12,7 @@ import (
"context" "context"
"flag" "flag"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
@@ -25,8 +26,6 @@ import (
"time" "time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
gitea_git "code.gitea.io/gitea/modules/git" gitea_git "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/external" "code.gitea.io/gitea/modules/markup/external"
@@ -37,6 +36,7 @@ import (
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing"
context2 "github.com/gorilla/context"
"xorm.io/xorm" "xorm.io/xorm"
) )
@@ -49,13 +49,13 @@ func runPR() {
log.Fatal(err) log.Fatal(err)
} }
setting.SetCustomPathAndConf("", "", "") setting.SetCustomPathAndConf("", "", "")
setting.LoadAllowEmpty() setting.NewContext()
setting.RepoRootPath, err = os.MkdirTemp(os.TempDir(), "repos") setting.RepoRootPath, err = ioutil.TempDir(os.TempDir(), "repos")
if err != nil { if err != nil {
log.Fatalf("TempDir: %v\n", err) log.Fatalf("TempDir: %v\n", err)
} }
setting.AppDataPath, err = os.MkdirTemp(os.TempDir(), "appdata") setting.AppDataPath, err = ioutil.TempDir(os.TempDir(), "appdata")
if err != nil { if err != nil {
log.Fatalf("TempDir: %v\n", err) log.Fatalf("TempDir: %v\n", err)
} }
@@ -87,29 +87,27 @@ func runPR() {
setting.Database.Path = ":memory:" setting.Database.Path = ":memory:"
setting.Database.Timeout = 500 setting.Database.Timeout = 500
*/ */
dbCfg := setting.Cfg.Section("database") db := setting.Cfg.Section("database")
dbCfg.NewKey("DB_TYPE", "sqlite3") db.NewKey("DB_TYPE", "sqlite3")
dbCfg.NewKey("PATH", ":memory:") db.NewKey("PATH", ":memory:")
routers.InitGitServices() routers.NewServices()
setting.Database.LogSQL = true setting.Database.LogSQL = true
//x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared") //x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
db.InitEngineWithMigration(context.Background(), func(_ *xorm.Engine) error { models.NewEngine(context.Background(), func(_ *xorm.Engine) error {
return nil return nil
}) })
db.HasEngine = true models.HasEngine = true
//x.ShowSQL(true) //x.ShowSQL(true)
err = unittest.InitFixtures( err = models.InitFixtures(
unittest.FixturesOptions{ path.Join(curDir, "models/fixtures/"),
Dir: path.Join(curDir, "models/fixtures/"),
},
) )
if err != nil { if err != nil {
fmt.Printf("Error initializing test database: %v\n", err) fmt.Printf("Error initializing test database: %v\n", err)
os.Exit(1) os.Exit(1)
} }
unittest.LoadFixtures() models.LoadFixtures()
util.RemoveAll(setting.RepoRootPath) util.RemoveAll(setting.RepoRootPath)
util.RemoveAll(models.LocalCopyPath()) util.RemoveAll(models.LocalCopyPath())
util.CopyDir(path.Join(curDir, "integrations/gitea-repositories-meta"), setting.RepoRootPath) util.CopyDir(path.Join(curDir, "integrations/gitea-repositories-meta"), setting.RepoRootPath)
@@ -138,7 +136,7 @@ func runPR() {
*/ */
//Start the server //Start the server
http.ListenAndServe(":8080", c) http.ListenAndServe(":8080", context2.ClearHandler(c))
log.Printf("[PR] Cleaning up ...\n") log.Printf("[PR] Cleaning up ...\n")
/* /*
@@ -182,7 +180,7 @@ func main() {
codeFilePath = filepath.FromSlash(codeFilePath) //Convert to running OS codeFilePath = filepath.FromSlash(codeFilePath) //Convert to running OS
//Copy this file if it will not exist in the PR branch //Copy this file if it will not exist in the PR branch
dat, err := os.ReadFile(codeFilePath) dat, err := ioutil.ReadFile(codeFilePath)
if err != nil { if err != nil {
log.Fatalf("Failed to cache this code file : %v", err) log.Fatalf("Failed to cache this code file : %v", err)
} }
@@ -215,7 +213,7 @@ func main() {
//Use git cli command for windows //Use git cli command for windows
runCmd("git", "fetch", remoteUpstream, fmt.Sprintf("pull/%s/head:%s", pr, branch)) runCmd("git", "fetch", remoteUpstream, fmt.Sprintf("pull/%s/head:%s", pr, branch))
} else { } else {
ref := fmt.Sprintf("%s%s/head:%s", gitea_git.PullPrefix, pr, branchRef) ref := fmt.Sprintf("refs/pull/%s/head:%s", pr, branchRef)
err = repo.Fetch(&git.FetchOptions{ err = repo.Fetch(&git.FetchOptions{
RemoteName: remoteUpstream, RemoteName: remoteUpstream,
RefSpecs: []config.RefSpec{ RefSpecs: []config.RefSpec{
@@ -246,7 +244,7 @@ func main() {
if err != nil { if err != nil {
log.Fatalf("Failed to duplicate this code file in PR : %v", err) log.Fatalf("Failed to duplicate this code file in PR : %v", err)
} }
err = os.WriteFile(codeFilePath, dat, 0644) err = ioutil.WriteFile(codeFilePath, dat, 0644)
if err != nil { if err != nil {
log.Fatalf("Failed to duplicate this code file in PR : %v", err) log.Fatalf("Failed to duplicate this code file in PR : %v", err)
} }

View File

@@ -51,16 +51,6 @@ RUN_MODE = ; prod
;REDIRECT_OTHER_PORT = false ;REDIRECT_OTHER_PORT = false
;PORT_TO_REDIRECT = 80 ;PORT_TO_REDIRECT = 80
;; ;;
;; Minimum and maximum supported TLS versions
;SSL_MIN_VERSION=TLSv1.2
;SSL_MAX_VERSION=
;;
;; SSL Curve Preferences
;SSL_CURVE_PREFERENCES=X25519,P256
;;
;; SSL Cipher Suites
;SSL_CIPHER_SUITES=; Will default to "ecdhe_ecdsa_with_aes_256_gcm_sha384,ecdhe_rsa_with_aes_256_gcm_sha384,ecdhe_ecdsa_with_aes_128_gcm_sha256,ecdhe_rsa_with_aes_128_gcm_sha256,ecdhe_ecdsa_with_chacha20_poly1305,ecdhe_rsa_with_chacha20_poly1305" if aes is supported by hardware, otherwise chacha will be first.
;;
;; Timeout for any write to the connection. (Set to 0 to disable all timeouts.) ;; Timeout for any write to the connection. (Set to 0 to disable all timeouts.)
;PER_WRITE_TIMEOUT = 30s ;PER_WRITE_TIMEOUT = 30s
;; ;;
@@ -388,10 +378,6 @@ INTERNAL_TOKEN=
;; ;;
;; Validate against https://haveibeenpwned.com/Passwords to see if a password has been exposed ;; Validate against https://haveibeenpwned.com/Passwords to see if a password has been exposed
;PASSWORD_CHECK_PWN = false ;PASSWORD_CHECK_PWN = false
;;
;; Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations.
;; This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security.
;SUCCESSFUL_TOKENS_CACHE_SIZE = 20
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -402,7 +388,7 @@ INTERNAL_TOKEN=
;; Enables OAuth2 provider ;; Enables OAuth2 provider
ENABLE = true ENABLE = true
;; ;;
;; Algorithm used to sign OAuth2 tokens. Valid values: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, EdDSA ;; Algorithm used to sign OAuth2 tokens. Valid values: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512
;JWT_SIGNING_ALGORITHM = RS256 ;JWT_SIGNING_ALGORITHM = RS256
;; ;;
;; Private key file path used to sign OAuth2 tokens. The path is relative to APP_DATA_PATH. ;; Private key file path used to sign OAuth2 tokens. The path is relative to APP_DATA_PATH.
@@ -435,10 +421,9 @@ ENABLE = true
;; NOTE: THE DEFAULT VALUES HERE WILL NEED TO BE CHANGED ;; NOTE: THE DEFAULT VALUES HERE WILL NEED TO BE CHANGED
;; Two Factor authentication with security keys ;; Two Factor authentication with security keys
;; https://developers.yubico.com/U2F/App_ID.html ;; https://developers.yubico.com/U2F/App_ID.html
;;
;; DEPRECATED - this only applies to previously registered security keys using the U2F standard
APP_ID = ; e.g. http://localhost:3000/ APP_ID = ; e.g. http://localhost:3000/
;; Comma separated list of trusted facets
TRUSTED_FACETS = ; e.g. http://localhost:3000/
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -591,10 +576,6 @@ PATH =
;; ;;
;; (Go-Git only) Don't cache objects greater than this in memory. (Set to 0 to disable.) ;; (Go-Git only) Don't cache objects greater than this in memory. (Set to 0 to disable.)
;LARGE_OBJECT_THRESHOLD = 1048576 ;LARGE_OBJECT_THRESHOLD = 1048576
;; Set to true to forcibly set core.protectNTFS=false
;DISABLE_CORE_PROTECT_NTFS=false
;; Disable the usage of using partial clones for git.
;DISABLE_PARTIAL_CLONE = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -671,9 +652,6 @@ PATH =
;; Default value for AllowCreateOrganization ;; Default value for AllowCreateOrganization
;; Every new user will have rights set to create organizations depending on this setting ;; Every new user will have rights set to create organizations depending on this setting
;DEFAULT_ALLOW_CREATE_ORGANIZATION = true ;DEFAULT_ALLOW_CREATE_ORGANIZATION = true
;; Default value for IsRestricted
;; Every new user will have restricted permissions depending on this setting
;DEFAULT_USER_IS_RESTRICTED = false
;; ;;
;; Either "public", "limited" or "private", default is "public" ;; Either "public", "limited" or "private", default is "public"
;; Limited is for users visible only to signed users ;; Limited is for users visible only to signed users
@@ -782,18 +760,18 @@ PATH =
;; Global limit of repositories per user, applied at creation time. -1 means no limit ;; Global limit of repositories per user, applied at creation time. -1 means no limit
;MAX_CREATION_LIMIT = -1 ;MAX_CREATION_LIMIT = -1
;; ;;
;; Mirror sync queue length, increase if mirror syncing starts hanging (DEPRECATED: please use [queue.mirror] LENGTH instead) ;; Mirror sync queue length, increase if mirror syncing starts hanging
;MIRROR_QUEUE_LENGTH = 1000 ;MIRROR_QUEUE_LENGTH = 1000
;; ;;
;; Patch test queue length, increase if pull request patch testing starts hanging (DEPRECATED: please use [queue.pr_patch_checker] LENGTH instead) ;; Patch test queue length, increase if pull request patch testing starts hanging
;PULL_REQUEST_QUEUE_LENGTH = 1000 ;PULL_REQUEST_QUEUE_LENGTH = 1000
;; ;;
;; Preferred Licenses to place at the top of the List ;; Preferred Licenses to place at the top of the List
;; The name here must match the filename in options/license or custom/options/license ;; The name here must match the filename in conf/license or custom/conf/license
;PREFERRED_LICENSES = Apache License 2.0,MIT License ;PREFERRED_LICENSES = Apache License 2.0,MIT License
;; ;;
;; Disable the ability to interact with repositories using the HTTP protocol ;; Disable the ability to interact with repositories using the HTTP protocol
;DISABLE_HTTP_GIT = false ;;DISABLE_HTTP_GIT = false
;; ;;
;; Value for Access-Control-Allow-Origin header, default is not to present ;; Value for Access-Control-Allow-Origin header, default is not to present
;; WARNING: This may be harmful to your website if you do not give it a right value. ;; WARNING: This may be harmful to your website if you do not give it a right value.
@@ -815,6 +793,9 @@ PATH =
;; Prefix archive files by placing them in a directory named after the repository ;; Prefix archive files by placing them in a directory named after the repository
;PREFIX_ARCHIVE_FILES = true ;PREFIX_ARCHIVE_FILES = true
;; ;;
;; Disable the creation of new mirrors. Pre-existing mirrors remain valid.
;DISABLE_MIRRORS = false
;;
;; Disable migrating feature. ;; Disable migrating feature.
;DISABLE_MIGRATIONS = false ;DISABLE_MIGRATIONS = false
;; ;;
@@ -903,9 +884,6 @@ PATH =
;; ;;
;; In default merge messages only include approvers who are official ;; In default merge messages only include approvers who are official
;DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY = true ;DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY = true
;;
;; Add co-authored-by and co-committed-by trailers if committer does not match author
;ADD_CO_COMMITTER_TRAILERS = true
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -922,7 +900,6 @@ PATH =
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. ;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
;ALLOWED_TYPES = ;ALLOWED_TYPES =
;DEFAULT_PAGING_NUM = 10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1013,9 +990,6 @@ PATH =
;; ;;
;; allow request with credentials ;; allow request with credentials
;ALLOW_CREDENTIALS = false ;ALLOW_CREDENTIALS = false
;;
;; set X-FRAME-OPTIONS header
;X_FRAME_OPTIONS = SAMEORIGIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1053,10 +1027,10 @@ PATH =
;SHOW_USER_EMAIL = true ;SHOW_USER_EMAIL = true
;; ;;
;; Set the default theme for the Gitea install ;; Set the default theme for the Gitea install
;DEFAULT_THEME = auto ;DEFAULT_THEME = gitea
;; ;;
;; All available themes. Allow users select personalized themes regardless of the value of `DEFAULT_THEME`. ;; All available themes. Allow users select personalized themes regardless of the value of `DEFAULT_THEME`.
;THEMES = auto,gitea,arc-green ;THEMES = gitea,arc-green
;; ;;
;; All available reactions users can choose on issues/prs and comments. ;; All available reactions users can choose on issues/prs and comments.
;; Values can be emoji alias (:smile:) or a unicode emoji. ;; Values can be emoji alias (:smile:) or a unicode emoji.
@@ -1075,7 +1049,7 @@ PATH =
;SEARCH_REPO_DESCRIPTION = true ;SEARCH_REPO_DESCRIPTION = true
;; ;;
;; Whether to enable a Service Worker to cache frontend assets ;; Whether to enable a Service Worker to cache frontend assets
;USE_SERVICE_WORKER = false ;USE_SERVICE_WORKER = true
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1412,13 +1386,6 @@ PATH =
;; Deliver timeout in seconds ;; Deliver timeout in seconds
;DELIVER_TIMEOUT = 5 ;DELIVER_TIMEOUT = 5
;; ;;
;; Webhook can only call allowed hosts for security reasons. Comma separated list, eg: external, 192.168.1.0/24, *.mydomain.com
;; Built-in: loopback (for localhost), private (for LAN/intranet), external (for public hosts on internet), * (for all hosts)
;; CIDR list: 1.2.3.0/8, 2001:db8::/32
;; Wildcard hosts: *.mydomain.com, 192.168.100.*
;; Since 1.15.7. Default to * for 1.15.x, external for 1.16 and later
;ALLOWED_HOST_LIST = external
;;
;; Allow insecure certification ;; Allow insecure certification
;SKIP_TLS_VERIFY = false ;SKIP_TLS_VERIFY = false
;; ;;
@@ -1473,9 +1440,6 @@ PATH =
;; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format ;; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
;FROM = ;FROM =
;; ;;
;; Sometimes it is helpful to use a different address on the envelope. Set this to use ENVELOPE_FROM as the from on the envelope. Set to `<>` to send an empty address.
;ENVELOPE_FROM =
;;
;; Mailer user name and password ;; Mailer user name and password
;; Please Note: Authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via STARTTLS) or `HOST=localhost`. ;; Please Note: Authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via STARTTLS) or `HOST=localhost`.
;USER = ;USER =
@@ -1497,9 +1461,6 @@ PATH =
;; ;;
;; Timeout for Sendmail ;; Timeout for Sendmail
;SENDMAIL_TIMEOUT = 5m ;SENDMAIL_TIMEOUT = 5m
;;
;; convert \r\n to \n for Sendmail
;SENDMAIL_CONVERT_CRLF = true
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1593,10 +1554,6 @@ PATH =
;AVATAR_MAX_WIDTH = 4096 ;AVATAR_MAX_WIDTH = 4096
;AVATAR_MAX_HEIGHT = 3072 ;AVATAR_MAX_HEIGHT = 3072
;; ;;
;; The multiplication factor for rendered avatar images.
;; Larger values result in finer rendering on HiDPI devices.
;AVATAR_RENDERED_SIZE_FACTOR = 3
;;
;; Maximum allowed file size for uploaded avatars. ;; Maximum allowed file size for uploaded avatars.
;; This is to limit the amount of RAM used when resizing the image. ;; This is to limit the amount of RAM used when resizing the image.
;AVATAR_MAX_FILE_SIZE = 1048576 ;AVATAR_MAX_FILE_SIZE = 1048576
@@ -1623,7 +1580,7 @@ PATH =
;ENABLED = true ;ENABLED = true
;; ;;
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. ;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
;ALLOWED_TYPES = .docx,.gif,.gz,.jpeg,.jpg,.mp4,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip ;ALLOWED_TYPES = .docx,.gif,.gz,.jpeg,.jpg,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip
;; ;;
;; Max size of each file. Defaults to 4MB ;; Max size of each file. Defaults to 4MB
;MAX_SIZE = 4 ;MAX_SIZE = 4
@@ -1714,7 +1671,7 @@ PATH =
;; Notice if not success ;; Notice if not success
;NO_SUCCESS_NOTICE = false ;NO_SUCCESS_NOTICE = false
;; Time interval for job to run ;; Time interval for job to run
;SCHEDULE = @midnight ;SCHEDULE = @every 24h
;; Archives created more than OLDER_THAN ago are subject to deletion ;; Archives created more than OLDER_THAN ago are subject to deletion
;OLDER_THAN = 24h ;OLDER_THAN = 24h
@@ -1732,12 +1689,6 @@ PATH =
;RUN_AT_START = false ;RUN_AT_START = false
;; Notice if not success ;; Notice if not success
;NO_SUCCESS_NOTICE = true ;NO_SUCCESS_NOTICE = true
;; Limit the number of mirrors added to the queue to this number
;; (negative values mean no limit, 0 will result in no result in no mirrors being queued effectively disabling pull mirror updating.)
;PULL_LIMIT=50
;; Limit the number of mirrors added to the queue to this number
;; (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating)
;PUSH_LIMIT=50
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1746,7 +1697,7 @@ PATH =
;[cron.repo_health_check] ;[cron.repo_health_check]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SCHEDULE = @midnight ;SCHEDULE = @every 24h
;; Enable running Repository health check task periodically. ;; Enable running Repository health check task periodically.
;ENABLED = true ;ENABLED = true
;; Run Repository health check task when Gitea starts. ;; Run Repository health check task when Gitea starts.
@@ -1771,7 +1722,7 @@ PATH =
;RUN_AT_START = true ;RUN_AT_START = true
;; Notice if not success ;; Notice if not success
;NO_SUCCESS_NOTICE = false ;NO_SUCCESS_NOTICE = false
;SCHEDULE = @midnight ;SCHEDULE = @every 24h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1785,7 +1736,7 @@ PATH =
;; Notice if not success ;; Notice if not success
;NO_SUCCESS_NOTICE = false ;NO_SUCCESS_NOTICE = false
;; Interval as a duration between each synchronization. (default every 24h) ;; Interval as a duration between each synchronization. (default every 24h)
;SCHEDULE = @midnight ;SCHEDULE = @every 24h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1800,7 +1751,7 @@ PATH =
;; Notice if not success ;; Notice if not success
;NO_SUCCESS_NOTICE = false ;NO_SUCCESS_NOTICE = false
;; Interval as a duration between each synchronization (default every 24h) ;; Interval as a duration between each synchronization (default every 24h)
;SCHEDULE = @midnight ;SCHEDULE = @every 24h
;; Create new users, update existing user data and disable users that are not in external source anymore (default) ;; Create new users, update existing user data and disable users that are not in external source anymore (default)
;; or only create new users if UPDATE_EXISTING is set to false ;; or only create new users if UPDATE_EXISTING is set to false
;UPDATE_EXISTING = true ;UPDATE_EXISTING = true
@@ -1818,7 +1769,7 @@ PATH =
;; Notice if not success ;; Notice if not success
;NO_SUCCESS_NOTICE = false ;NO_SUCCESS_NOTICE = false
;; Interval as a duration between each synchronization (default every 24h) ;; Interval as a duration between each synchronization (default every 24h)
;SCHEDULE = @midnight ;SCHEDULE = @every 24h
;; deleted branches than OLDER_THAN ago are subject to deletion ;; deleted branches than OLDER_THAN ago are subject to deletion
;OLDER_THAN = 24h ;OLDER_THAN = 24h
@@ -1834,7 +1785,7 @@ PATH =
;; Whether to always run at start up time (if ENABLED) ;; Whether to always run at start up time (if ENABLED)
;RUN_AT_START = false ;RUN_AT_START = false
;; Time interval for job to run ;; Time interval for job to run
;SCHEDULE = @midnight ;SCHEDULE = @every 24h
;; OlderThan or PerWebhook. How the records are removed, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook). ;; OlderThan or PerWebhook. How the records are removed, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
;CLEANUP_TYPE = OlderThan ;CLEANUP_TYPE = OlderThan
;; If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted. ;; If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
@@ -1924,7 +1875,7 @@ PATH =
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = false ;ENABLED = false
;RUN_AT_START = false ;RUN_AT_START = false
;NO_SUCCESS_NOTICE = false ;NO_SUCCESS_NOTICE = f;alse
;SCHEDULE = @every 72h ;SCHEDULE = @every 72h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1948,7 +1899,7 @@ PATH =
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = false ;ENABLED = false
;RUN_AT_START = false ;RUN_AT_START = false
;NO_SUCCESS_NOTICE = false ;NO_SUCCESS_NOTICE = f;alse
;SCHEDULE = @every 72h ;SCHEDULE = @every 72h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1964,19 +1915,6 @@ PATH =
;SCHEDULE = @every 168h ;SCHEDULE = @every 168h
;OLDER_THAN = 8760h ;OLDER_THAN = 8760h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check for new Gitea versions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.update_checker]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = false
;RUN_AT_START = false
;ENABLE_SUCCESS_NOTICE = false
;SCHEDULE = @every 168h
;HTTP_ENDPOINT = https://dl.gitea.io/gitea/version.json
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Git Operation timeout in seconds ;; Git Operation timeout in seconds
@@ -1996,12 +1934,6 @@ PATH =
;[mirror] ;[mirror]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Enables the mirror functionality. Set to **false** to disable all mirrors.
;ENABLED = true
;; Disable the creation of **new** pull mirrors. Pre-existing mirrors remain valid. Will be ignored if `mirror.ENABLED` is `false`.
;DISABLE_NEW_PULL = false
;; Disable the creation of **new** push mirrors. Pre-existing mirrors remain valid. Will be ignored if `mirror.ENABLED` is `false`.
;DISABLE_NEW_PUSH = false
;; Default interval as a duration between each check ;; Default interval as a duration between each check
;DEFAULT_INTERVAL = 8h ;DEFAULT_INTERVAL = 8h
;; Min interval as a duration must be > 1m ;; Min interval as a duration must be > 1m
@@ -2028,8 +1960,8 @@ PATH =
;[i18n] ;[i18n]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN ;LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,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,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,ελληνικά,فارسی,magyar nyelv,bahasa Indonesia,മലയാളം ;NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2050,15 +1982,6 @@ PATH =
;; Show template execution time in the footer ;; Show template execution time in the footer
;SHOW_FOOTER_TEMPLATE_LOAD_TIME = true ;SHOW_FOOTER_TEMPLATE_LOAD_TIME = true
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[markup]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set the maximum number of characters in a mermaid source. (Set to -1 to disable limits)
;MERMAID_MAX_SOURCE_CHARACTERS = 5000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[markup.sanitizer.1] ;[markup.sanitizer.1]
@@ -2095,10 +2018,6 @@ PATH =
;ENABLED = false ;ENABLED = false
;; If you want to add authorization, specify a token here ;; If you want to add authorization, specify a token here
;TOKEN = ;TOKEN =
;; Enable issue by label metrics; default is false
;ENABLED_ISSUE_BY_LABEL = false
;; Enable issue by repository metrics; default is false
;ENABLED_ISSUE_BY_REPOSITORY = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2133,21 +2052,12 @@ PATH =
;ALLOWED_DOMAINS = ;ALLOWED_DOMAINS =
;; ;;
;; Blocklist for migrating, default is blank. Multiple domains could be separated by commas. ;; Blocklist for migrating, default is blank. Multiple domains could be separated by commas.
;; When ALLOWED_DOMAINS is not blank, this option has a higher priority to deny domains. ;; When ALLOWED_DOMAINS is not blank, this option will be ignored.
;BLOCKED_DOMAINS = ;BLOCKED_DOMAINS =
;; ;;
;; Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291 (false by default) ;; Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291 (false by default)
;ALLOW_LOCALNETWORKS = false ;ALLOW_LOCALNETWORKS = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[federation]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Enable/Disable federation capabilities
; ENABLED = true
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; default storage for attachments, lfs and avatars ;; default storage for attachments, lfs and avatars
@@ -2198,11 +2108,3 @@ PATH =
;; ;;
;; Minio enabled ssl only available when STORAGE_TYPE is `minio` ;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
;MINIO_USE_SSL = false ;MINIO_USE_SSL = false
;[proxy]
;; Enable the proxy, all requests to external via HTTP will be affected
;PROXY_ENABLED = false
;; Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy/no_proxy
;PROXY_URL =
;; Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
;PROXY_HOSTS =

View File

@@ -1,4 +1,4 @@
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-rootless image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-rootless
{{#if build.tags}} {{#if build.tags}}
tags: tags:
{{#each build.tags}} {{#each build.tags}}
@@ -8,12 +8,12 @@ tags:
{{/if}} {{/if}}
manifests: manifests:
- -
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-amd64-rootless image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-amd64-rootless
platform: platform:
architecture: amd64 architecture: amd64
os: linux os: linux
- -
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-arm64-rootless image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-arm64-rootless
platform: platform:
architecture: arm64 architecture: arm64
os: linux os: linux

View File

@@ -1,4 +1,4 @@
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}} image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}
{{#if build.tags}} {{#if build.tags}}
tags: tags:
{{#each build.tags}} {{#each build.tags}}
@@ -8,12 +8,12 @@ tags:
{{/if}} {{/if}}
manifests: manifests:
- -
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-amd64 image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-amd64
platform: platform:
architecture: amd64 architecture: amd64
os: linux os: linux
- -
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-arm64 image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-arm64
platform: platform:
architecture: arm64 architecture: arm64
os: linux os: linux

View File

@@ -2,5 +2,5 @@
[[ -f ./setup ]] && source ./setup [[ -f ./setup ]] && source ./setup
pushd /app/gitea >/dev/null pushd /app/gitea >/dev/null
exec su-exec $USER /usr/local/bin/gitea web exec su-exec $USER /app/gitea/gitea web
popd popd

View File

@@ -1,17 +0,0 @@
#!/bin/bash
###############################################################
# This script sets defaults for gitea to run in the container #
###############################################################
# It assumes that you place this script as gitea in /usr/local/bin
#
# And place the original in /usr/lib/gitea with working files in /data/gitea
GITEA="/app/gitea/gitea"
WORK_DIR="/app/gitea"
CUSTOM_PATH="/data/gitea"
# Provide docker defaults
GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" GITEA_CUSTOM="${GITEA_CUSTOM:-$CUSTOM_PATH}" exec -a "$0" "$GITEA" $CONF_ARG "$@"

View File

@@ -1,40 +0,0 @@
#!/bin/bash
###############################################################
# This script sets defaults for gitea to run in the container #
###############################################################
# It assumes that you place this script as gitea in /usr/local/bin
#
# And place the original in /usr/lib/gitea with working files in /data/gitea
GITEA="/app/gitea/gitea"
WORK_DIR="/var/lib/gitea"
APP_INI="/etc/gitea/app.ini"
APP_INI_SET=""
for i in "$@"; do
case "$i" in
"-c")
APP_INI_SET=1
;;
"-c="*)
APP_INI_SET=1
;;
"--config")
APP_INI_SET=1
;;
"--config="*)
APP_INI_SET=1
;;
*)
;;
esac
done
if [ -z "$APP_INI_SET" ]; then
CONF_ARG=("-c" "${GITEA_APP_INI:-$APP_INI}")
fi
# Provide docker defaults
GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" exec -a "$0" "$GITEA" "${CONF_ARG[@]}" "$@"

View File

@@ -15,7 +15,7 @@ const fuseOptions = {
shouldSort: true, shouldSort: true,
includeMatches: true, includeMatches: true,
matchAllTokens: true, matchAllTokens: true,
threshold: 0, // for parsing diacritics threshold: 0.0, // for parsing diacritics
tokenize: true, tokenize: true,
location: 0, location: 0,
distance: 100, distance: 100,
@@ -52,7 +52,7 @@ function doSearch() {
executeSearch(searchQuery); executeSearch(searchQuery);
} else { } else {
const para = document.createElement('P'); const para = document.createElement('P');
para.textContent = 'Please enter a word or phrase above'; para.innerText = 'Please enter a word or phrase above';
document.getElementById('search-results').appendChild(para); document.getElementById('search-results').appendChild(para);
} }
} }
@@ -60,17 +60,17 @@ function doSearch() {
function getJSON(url, fn) { function getJSON(url, fn) {
const request = new XMLHttpRequest(); const request = new XMLHttpRequest();
request.open('GET', url, true); request.open('GET', url, true);
request.addEventListener('load', () => { request.onload = function () {
if (request.status >= 200 && request.status < 400) { if (request.status >= 200 && request.status < 400) {
const data = JSON.parse(request.responseText); const data = JSON.parse(request.responseText);
fn(data); fn(data);
} else { } else {
console.error(`Target reached on ${url} with error ${request.status}`); console.error(`Target reached on ${url} with error ${request.status}`);
} }
}); };
request.addEventListener('error', () => { request.onerror = function () {
console.error(`Connection error ${request.status}`); console.error(`Connection error ${request.status}`);
}); };
request.send(); request.send();
} }
@@ -84,20 +84,20 @@ function executeSearch(searchQuery) {
populateResults(result); populateResults(result);
} else { } else {
const para = document.createElement('P'); const para = document.createElement('P');
para.textContent = 'No matches found'; para.innerText = 'No matches found';
document.getElementById('search-results').appendChild(para); document.getElementById('search-results').appendChild(para);
} }
}); });
} }
function populateResults(result) { function populateResults(result) {
for (const [key, value] of result.entries()) { result.forEach((value, key) => {
const content = value.item.contents; const content = value.item.contents;
let snippet = ''; let snippet = '';
const snippetHighlights = []; const snippetHighlights = [];
if (fuseOptions.tokenize) { if (fuseOptions.tokenize) {
snippetHighlights.push(searchQuery); snippetHighlights.push(searchQuery);
for (const mvalue of value.matches) { value.matches.forEach((mvalue) => {
if (mvalue.key === 'tags' || mvalue.key === 'categories') { if (mvalue.key === 'tags' || mvalue.key === 'categories') {
snippetHighlights.push(mvalue.value); snippetHighlights.push(mvalue.value);
} else if (mvalue.key === 'contents') { } else if (mvalue.key === 'contents') {
@@ -111,7 +111,7 @@ function populateResults(result) {
snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1)); snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1));
} }
} }
} });
} }
if (snippet.length < 1) { if (snippet.length < 1) {
@@ -130,10 +130,10 @@ function populateResults(result) {
}); });
document.getElementById('search-results').appendChild(htmlToElement(output)); document.getElementById('search-results').appendChild(htmlToElement(output));
for (const snipvalue of snippetHighlights) { snippetHighlights.forEach((snipvalue) => {
new Mark(document.getElementById(`summary-${key}`)).mark(snipvalue); new Mark(document.getElementById(`summary-${key}`)).mark(snipvalue);
} });
} });
} }
function render(templateString, data) { function render(templateString, data) {

View File

@@ -18,9 +18,9 @@ params:
description: Git with a cup of tea description: Git with a cup of tea
author: The Gitea Authors author: The Gitea Authors
website: https://docs.gitea.io website: https://docs.gitea.io
version: 1.16.4 version: 1.14.6
minGoVersion: 1.16 minGoVersion: 1.16
goVersion: 1.18 goVersion: 1.16
minNodeVersion: 12.17 minNodeVersion: 12.17
outputs: outputs:

View File

@@ -20,12 +20,12 @@ Some jurisdictions (such as EU), requires certain legal pages (e.g. Privacy Poli
Gitea source code ships with sample pages, available in `contrib/legal` directory. Copy them to `custom/public/`. For example, to add Privacy Policy: Gitea source code ships with sample pages, available in `contrib/legal` directory. Copy them to `custom/public/`. For example, to add Privacy Policy:
``` ```
wget -O /path/to/custom/public/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/legal/privacy.html.sample wget -O /path/to/custom/public/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/master/contrib/legal/privacy.html.sample
``` ```
Now you need to edit the page to meet your requirements. In particular you must change the email addresses, web addresses and references to "Your Gitea Instance" to match your situation. Now you need to edit the page to meet your requirements. In particular you must change the email addresses, web addresses and references to "Your Gitea Instance" to match your situation.
You absolutely must not place a general ToS or privacy statement that implies that the Gitea project is responsible for your server. You absolutely must not place a general ToS or privacy statement that implies that the gitea project is responsible for your server.
## Make it Visible ## Make it Visible

View File

@@ -27,12 +27,39 @@ on the client is at least the same as on the server (or later). Login to
Gitea server as admin and head to Site Administration -> Configuration to Gitea server as admin and head to Site Administration -> Configuration to
see Git version of the server. see Git version of the server.
By default, clone filters are enabled, unless `DISABLE_PARTIAL_CLONE` under By default, clone filters are disabled, which cause the server to ignore
`[git]` is set to `true`. `--filter` option.
To enable clone filters on per-repo basis, edit the repo's `config` on
repository location. Consult `ROOT` option on `repository` section of
Gitea configuration (`app.ini`) for the exact location. For example, to
enable clone filters for `some-repo`, edit
`/var/gitea/data/gitea-repositories/some-user/some-repo.git/config` and add:
```ini
[uploadpack]
allowfilter = true
```
To enable clone filters globally, add that config above to `~/.gitconfig`
of user that run Gitea (for example `git`).
Alternatively, you can use `git config` to set the option.
To enable for a specific repo:
```bash
cd /var/gitea/data/gitea-repositories/some-user/some-repo.git
git config --local uploadpack.allowfilter true
```
To enable globally, login as user that run Gitea and:
```bash
git config --global uploadpack.allowfilter true
```
See [GitHub blog post: Get up to speed with partial clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/) See [GitHub blog post: Get up to speed with partial clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/)
for common use cases of clone filters (blobless and treeless clones), and for common use cases of clone filters (blobless and treeless clones), and
[GitLab docs for partial clone](https://docs.gitlab.com/ee/topics/git/partial_clone.html) [Gitlab docs for partial clone](https://docs.gitlab.com/ee/topics/git/partial_clone.html)
for more advanced use cases (such as filter by file size and remove for more advanced use cases (such as filter by file size and remove
filters to turn partial clone into full clone). filters to turn partial clone into full clone).

View File

@@ -76,20 +76,20 @@ To extract resources embedded in Gitea's executable, use the following syntax:
gitea [--config {file}] embedded extract [--destination {dir}|--custom] [--overwrite|--rename] [--include-vendored] {patterns...} gitea [--config {file}] embedded extract [--destination {dir}|--custom] [--overwrite|--rename] [--include-vendored] {patterns...}
``` ```
The `--config` option tells Gitea the location of the `app.ini` configuration file if The `--config` option tells gitea the location of the `app.ini` configuration file if
it's not in its default location. This option is only used with the `--custom` flag. it's not in its default location. This option is only used with the `--custom` flag.
The `--destination` option tells Gitea the directory where the files must be extracted to. The `--destination` option tells gitea the directory where the files must be extracted to.
The default is the current directory. The default is the current directory.
The `--custom` flag tells Gitea to extract the files directly into the `custom` directory. The `--custom` flag tells gitea to extract the files directly into the `custom` directory.
For this to work, the command needs to know the location of the `app.ini` configuration For this to work, the command needs to know the location of the `app.ini` configuration
file (`--config`) and, depending of the configuration, be ran from the directory where file (`--config`) and, depending of the configuration, be ran from the directory where
Gitea normally starts. See [Customizing Gitea]({{< relref "doc/advanced/customizing-gitea.en-us.md" >}}) for details. gitea normally starts. See [Customizing Gitea]({{< relref "doc/advanced/customizing-gitea.en-us.md" >}}) for details.
The `--overwrite` flag allows any existing files in the destination directory to be overwritten. The `--overwrite` flag allows any existing files in the destination directory to be overwritten.
The `--rename` flag tells Gitea to rename any existing files in the destination directory The `--rename` flag tells gitea to rename any existing files in the destination directory
as `filename.bak`. Previous `.bak` files are overwritten. as `filename.bak`. Previous `.bak` files are overwritten.
At least one file search pattern must be provided; see `list` subcomand above for pattern At least one file search pattern must be provided; see `list` subcomand above for pattern

View File

@@ -23,8 +23,8 @@ or any corresponding location. When installing from a distribution, this will
typically be found at `/etc/gitea/conf/app.ini`. typically be found at `/etc/gitea/conf/app.ini`.
The defaults provided here are best-effort (not built automatically). They are The defaults provided here are best-effort (not built automatically). They are
accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini) accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
(s/main/\<tag|release\>). Any string in the format `%(X)s` is a feature powered (s/master/\<tag|release\>). Any string in the format `%(X)s` is a feature powered
by [ini](https://github.com/go-ini/ini/#recursive-values), for reading values recursively. by [ini](https://github.com/go-ini/ini/#recursive-values), for reading values recursively.
Values containing `#` or `;` must be quoted using `` ` `` or `"""`. Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
@@ -54,10 +54,10 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `DEFAULT_PUSH_CREATE_PRIVATE`: **true**: Default private when creating a new repository with push-to-create. - `DEFAULT_PUSH_CREATE_PRIVATE`: **true**: Default private when creating a new repository with push-to-create.
- `MAX_CREATION_LIMIT`: **-1**: Global maximum creation limit of repositories per user, - `MAX_CREATION_LIMIT`: **-1**: Global maximum creation limit of repositories per user,
`-1` means no limit. `-1` means no limit.
- `PULL_REQUEST_QUEUE_LENGTH`: **1000**: Length of pull request patch test queue, make it. **DEPRECATED** use `LENGTH` in `[queue.pr_patch_checker]`. - `PULL_REQUEST_QUEUE_LENGTH`: **1000**: Length of pull request patch test queue, make it
as large as possible. Use caution when editing this value. as large as possible. Use caution when editing this value.
- `MIRROR_QUEUE_LENGTH`: **1000**: Patch test queue length, increase if pull request patch - `MIRROR_QUEUE_LENGTH`: **1000**: Patch test queue length, increase if pull request patch
testing starts hanging. **DEPRECATED** use `LENGTH` in `[queue.mirror]`. testing starts hanging.
- `PREFERRED_LICENSES`: **Apache License 2.0,MIT License**: Preferred Licenses to place at - `PREFERRED_LICENSES`: **Apache License 2.0,MIT License**: Preferred Licenses to place at
the top of the list. Name must match file name in options/license or custom/options/license. the top of the list. Name must match file name in options/license or custom/options/license.
- `DISABLE_HTTP_GIT`: **false**: Disable the ability to interact with repositories over the - `DISABLE_HTTP_GIT`: **false**: Disable the ability to interact with repositories over the
@@ -73,6 +73,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `DISABLED_REPO_UNITS`: **_empty_**: Comma separated list of globally disabled repo units. Allowed values: \[repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects\] - `DISABLED_REPO_UNITS`: **_empty_**: Comma separated list of globally disabled repo units. Allowed values: \[repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects\]
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects**: Comma separated list of default repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list. - `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects**: Comma separated list of default repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository. - `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
- `DISABLE_MIRRORS`: **false**: Disable the creation of **new** mirrors. Pre-existing mirrors remain valid.
- `DISABLE_MIGRATIONS`: **false**: Disable migrating feature. - `DISABLE_MIGRATIONS`: **false**: Disable migrating feature.
- `DISABLE_STARS`: **false**: Disable stars feature. - `DISABLE_STARS`: **false**: Disable stars feature.
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories. - `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
@@ -98,7 +99,6 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `DEFAULT_MERGE_MESSAGE_MAX_APPROVERS`: **10**: In default merge messages limit the number of approvers listed as `Reviewed-by:`. Set to `-1` to include all. - `DEFAULT_MERGE_MESSAGE_MAX_APPROVERS`: **10**: In default merge messages limit the number of approvers listed as `Reviewed-by:`. Set to `-1` to include all.
- `DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY`: **true**: In default merge messages only include approvers who are officially allowed to review. - `DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY`: **true**: In default merge messages only include approvers who are officially allowed to review.
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: In default squash-merge messages include the commit message of all commits comprising the pull request. - `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: In default squash-merge messages include the commit message of all commits comprising the pull request.
- `ADD_CO_COMMITTER_TRAILERS`: **true**: Add co-authored-by and co-committed-by trailers to merge commit messages if committer does not match author.
### Repository - Issue (`repository.issue`) ### Repository - Issue (`repository.issue`)
@@ -107,7 +107,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
### Repository - Upload (`repository.upload`) ### Repository - Upload (`repository.upload`)
- `ENABLED`: **true**: Whether repository file uploads are enabled - `ENABLED`: **true**: Whether repository file uploads are enabled
- `TEMP_PATH`: **data/tmp/uploads**: Path for uploads (tmp gets deleted on Gitea restart) - `TEMP_PATH`: **data/tmp/uploads**: Path for uploads (tmp gets deleted on gitea restart)
- `ALLOWED_TYPES`: **\<empty\>**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. - `ALLOWED_TYPES`: **\<empty\>**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
- `FILE_MAX_SIZE`: **3**: Max size of each file in megabytes. - `FILE_MAX_SIZE`: **3**: Max size of each file in megabytes.
- `MAX_FILES`: **5**: Max number of files per upload - `MAX_FILES`: **5**: Max number of files per upload
@@ -115,8 +115,6 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
### Repository - Release (`repository.release`) ### Repository - Release (`repository.release`)
- `ALLOWED_TYPES`: **\<empty\>**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. - `ALLOWED_TYPES`: **\<empty\>**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
- `DEFAULT_PAGING_NUM`: **10**: The default paging number of releases user interface
- For settings related to file attachments on releases, see the `attachment` section.
### Repository - Signing (`repository.signing`) ### Repository - Signing (`repository.signing`)
@@ -164,7 +162,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `METHODS`: **GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS**: list of methods allowed to request - `METHODS`: **GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS**: list of methods allowed to request
- `MAX_AGE`: **10m**: max time to cache response - `MAX_AGE`: **10m**: max time to cache response
- `ALLOW_CREDENTIALS`: **false**: allow request with credentials - `ALLOW_CREDENTIALS`: **false**: allow request with credentials
- `X_FRAME_OPTIONS`: **SAMEORIGIN**: Set the `X-Frame-Options` header value.
## UI (`ui`) ## UI (`ui`)
@@ -175,9 +172,9 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `FEED_PAGING_NUM`: **20**: Number of items that are displayed in home feed. - `FEED_PAGING_NUM`: **20**: Number of items that are displayed in home feed.
- `GRAPH_MAX_COMMIT_NUM`: **100**: Number of maximum commits shown in the commit graph. - `GRAPH_MAX_COMMIT_NUM`: **100**: Number of maximum commits shown in the commit graph.
- `CODE_COMMENT_LINES`: **4**: Number of line of codes shown for a code comment. - `CODE_COMMENT_LINES`: **4**: Number of line of codes shown for a code comment.
- `DEFAULT_THEME`: **auto**: \[auto, gitea, arc-green\]: Set the default theme for the Gitea install. - `DEFAULT_THEME`: **gitea**: \[gitea, arc-green\]: Set the default theme for the Gitea install.
- `SHOW_USER_EMAIL`: **true**: Whether the email of the user should be shown in the Explore Users page. - `SHOW_USER_EMAIL`: **true**: Whether the email of the user should be shown in the Explore Users page.
- `THEMES`: **auto,gitea,arc-green**: All available themes. Allow users select personalized themes. - `THEMES`: **gitea,arc-green**: All available themes. Allow users select personalized themes.
regardless of the value of `DEFAULT_THEME`. regardless of the value of `DEFAULT_THEME`.
- `THEME_COLOR_META_TAG`: **#6cc644**: Value of `theme-color` meta tag, used by Android >= 5.0. An invalid color like "none" or "disable" will have the default style. More info: https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android - `THEME_COLOR_META_TAG`: **#6cc644**: Value of `theme-color` meta tag, used by Android >= 5.0. An invalid color like "none" or "disable" will have the default style. More info: https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android
- `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB) - `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB)
@@ -185,11 +182,11 @@ The following configuration set `Content-Type: application/vnd.android.package-a
Values can be emoji alias (:smile:) or a unicode emoji. Values can be emoji alias (:smile:) or a unicode emoji.
For custom reactions, add a tightly cropped square image to public/img/emoji/reaction_name.png For custom reactions, add a tightly cropped square image to public/img/emoji/reaction_name.png
- `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: Additional Emojis not defined in the utf8 standard. - `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: Additional Emojis not defined in the utf8 standard.
By default we support Gitea (:gitea:), to add more copy them to public/img/emoji/emoji_name.png and By default we support gitea (:gitea:), to add more copy them to public/img/emoji/emoji_name.png and
add it to this config. add it to this config.
- `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used. - `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used.
- `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page. - `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page.
- `USE_SERVICE_WORKER`: **false**: Whether to enable a Service Worker to cache frontend assets. - `USE_SERVICE_WORKER`: **true**: Whether to enable a Service Worker to cache frontend assets.
### UI - Admin (`ui.admin`) ### UI - Admin (`ui.admin`)
@@ -233,7 +230,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
## Server (`server`) ## Server (`server`)
- `PROTOCOL`: **http**: \[http, https, fcgi, http+unix, fcgi+unix\] - `PROTOCOL`: **http**: \[http, https, fcgi, unix, fcgi+unix\]
- `DOMAIN`: **localhost**: Domain name of this server. - `DOMAIN`: **localhost**: Domain name of this server.
- `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**: - `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**:
Overwrite the automatically generated public URL. Overwrite the automatically generated public URL.
@@ -241,14 +238,14 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `STATIC_URL_PREFIX`: **\<empty\>**: - `STATIC_URL_PREFIX`: **\<empty\>**:
Overwrite this option to request static resources from a different URL. Overwrite this option to request static resources from a different URL.
This includes CSS files, images, JS files and web fonts. This includes CSS files, images, JS files and web fonts.
Avatar images are dynamic resources and still served by Gitea. 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`. 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. 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. The static files are located in the `public/` directory of the gitea source repository.
- `HTTP_ADDR`: **0.0.0.0**: HTTP listen address. - `HTTP_ADDR`: **0.0.0.0**: HTTP listen address.
- If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings. defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
- If `PROTOCOL` is set to `http+unix` or `fcgi+unix`, this should be the name of the Unix socket file to use. Relative paths will be made absolute against the AppWorkPath. - If `PROTOCOL` is set to `unix` or `fcgi+unix`, this should be the name of the Unix socket file to use.
- `HTTP_PORT`: **3000**: HTTP listen port. - `HTTP_PORT`: **3000**: HTTP listen port.
- If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings. defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
@@ -257,7 +254,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
(DMZ) URL for Gitea workers (such as SSH update) accessing web service. In (DMZ) URL for Gitea workers (such as SSH update) accessing web service. In
most cases you do not need to change the default value. Alter it only if most cases you do not need to change the default value. Alter it only if
your SSH server node is not the same as HTTP node. Do not set this variable your SSH server node is not the same as HTTP node. Do not set this variable
if `PROTOCOL` is set to `http+unix`. if `PROTOCOL` is set to `unix`.
- `PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the connection. (Set to 0 to - `PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the connection. (Set to 0 to
disable all timeouts.) disable all timeouts.)
- `PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to connections. - `PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to connections.
@@ -273,11 +270,11 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `SSH_CREATE_AUTHORIZED_KEYS_FILE`: **true**: Gitea will create a authorized_keys file by default when it is not using the internal ssh server. If you intend to use the AuthorizedKeysCommand functionality then you should turn this off. - `SSH_CREATE_AUTHORIZED_KEYS_FILE`: **true**: Gitea will create a authorized_keys file by default when it is not using the internal ssh server. If you intend to use the AuthorizedKeysCommand functionality then you should turn this off.
- `SSH_AUTHORIZED_KEYS_BACKUP`: **true**: Enable SSH Authorized Key Backup when rewriting all keys, default is true. - `SSH_AUTHORIZED_KEYS_BACKUP`: **true**: Enable SSH Authorized Key Backup when rewriting all keys, default is true.
- `SSH_TRUSTED_USER_CA_KEYS`: **\<empty\>**: Specifies the public keys of certificate authorities that are trusted to sign user certificates for authentication. Multiple keys should be comma separated. E.g.`ssh-<algorithm> <key>` or `ssh-<algorithm> <key1>, ssh-<algorithm> <key2>`. For more information see `TrustedUserCAKeys` in the sshd config man pages. When empty no file will be created and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` will default to `off`. - `SSH_TRUSTED_USER_CA_KEYS`: **\<empty\>**: Specifies the public keys of certificate authorities that are trusted to sign user certificates for authentication. Multiple keys should be comma separated. E.g.`ssh-<algorithm> <key>` or `ssh-<algorithm> <key1>, ssh-<algorithm> <key2>`. For more information see `TrustedUserCAKeys` in the sshd config man pages. When empty no file will be created and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` will default to `off`.
- `SSH_TRUSTED_USER_CA_KEYS_FILENAME`: **`RUN_USER`/.ssh/gitea-trusted-user-ca-keys.pem**: Absolute path of the `TrustedUserCaKeys` file Gitea will manage. If you're running your own ssh server and you want to use the Gitea managed file you'll also need to modify your sshd_config to point to this file. The official docker image will automatically work without further configuration. - `SSH_TRUSTED_USER_CA_KEYS_FILENAME`: **`RUN_USER`/.ssh/gitea-trusted-user-ca-keys.pem**: Absolute path of the `TrustedUserCaKeys` file gitea will manage. If you're running your own ssh server and you want to use the gitea managed file you'll also need to modify your sshd_config to point to this file. The official docker image will automatically work without further configuration.
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set. - `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set.
- `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`. - `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
- `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`. - `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models/asymkey.PublicKey` and the others are strings which are shellquoted. - `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models.PublicKey` and the others are strings which are shellquoted.
- `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect. - `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect.
- `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect. - `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect.
- `SSH_SERVER_MACS`: **hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect - `SSH_SERVER_MACS`: **hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect
@@ -299,11 +296,11 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `STATIC_CACHE_TIME`: **6h**: Web browser cache time for static resources on `custom/`, `public/` and all uploaded avatars. Note that this cache is disabled when `RUN_MODE` is "dev". - `STATIC_CACHE_TIME`: **6h**: Web browser cache time for static resources on `custom/`, `public/` and all uploaded avatars. Note that this cache is disabled when `RUN_MODE` is "dev".
- `ENABLE_GZIP`: **false**: Enable gzip compression for runtime-generated content, static resources excluded. - `ENABLE_GZIP`: **false**: Enable gzip compression for runtime-generated content, static resources excluded.
- `ENABLE_PPROF`: **false**: Application profiling (memory and cpu). For "web" command it listens on localhost:6060. For "serv" command it dumps to disk at `PPROF_DATA_PATH` as `(cpuprofile|memprofile)_<username>_<temporary id>` - `ENABLE_PPROF`: **false**: Application profiling (memory and cpu). For "web" command it listens on localhost:6060. For "serv" command it dumps to disk at `PPROF_DATA_PATH` as `(cpuprofile|memprofile)_<username>_<temporary id>`
- `PPROF_DATA_PATH`: **data/tmp/pprof**: `PPROF_DATA_PATH`, use an absolute path when you start Gitea as service - `PPROF_DATA_PATH`: **data/tmp/pprof**: `PPROF_DATA_PATH`, use an absolute path when you start gitea as service
- `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore, organizations, login\]. - `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore, organizations, login\].
- `LFS_START_SERVER`: **false**: Enables Git LFS support. - `LFS_START_SERVER`: **false**: Enables git-lfs support.
- `LFS_CONTENT_PATH`: **%(APP_DATA_PATH)/lfs**: Default LFS content path. (if it is on local storage.) **DEPRECATED** use settings in `[lfs]`. - `LFS_CONTENT_PATH`: **%(APP_DATA_PATH)/lfs**: DEPRECATED: Default LFS content path. (if it is on local storage.)
- `LFS_JWT_SECRET`: **\<empty\>**: LFS authentication secret, change this a unique string. - `LFS_JWT_SECRET`: **\<empty\>**: LFS authentication secret, change this a unique string.
- `LFS_HTTP_AUTH_EXPIRY`: **20m**: LFS authentication validity period in time.Duration, pushes taking longer than this may fail. - `LFS_HTTP_AUTH_EXPIRY`: **20m**: LFS authentication validity period in time.Duration, pushes taking longer than this may fail.
- `LFS_MAX_FILE_SIZE`: **0**: Maximum allowed LFS file size in bytes (Set to 0 for no limit). - `LFS_MAX_FILE_SIZE`: **0**: Maximum allowed LFS file size in bytes (Set to 0 for no limit).
@@ -311,42 +308,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, allows redirecting http requests on `PORT_TO_REDIRECT` to the https port Gitea listens on. - `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, allows redirecting http requests on `PORT_TO_REDIRECT` to the https port Gitea listens on.
- `PORT_TO_REDIRECT`: **80**: Port for the http redirection service to listen on. Used when `REDIRECT_OTHER_PORT` is true. - `PORT_TO_REDIRECT`: **80**: Port for the http redirection service to listen on. Used when `REDIRECT_OTHER_PORT` is true.
- `SSL_MIN_VERSION`: **TLSv1.2**: Set the minimum version of ssl support.
- `SSL_MAX_VERSION`: **\<empty\>**: Set the maximum version of ssl support.
- `SSL_CURVE_PREFERENCES`: **X25519,P256**: Set the preferred curves,
- `SSL_CIPHER_SUITES`: **ecdhe_ecdsa_with_aes_256_gcm_sha384,ecdhe_rsa_with_aes_256_gcm_sha384,ecdhe_ecdsa_with_aes_128_gcm_sha256,ecdhe_rsa_with_aes_128_gcm_sha256,ecdhe_ecdsa_with_chacha20_poly1305,ecdhe_rsa_with_chacha20_poly1305**: Set the preferred cipher suites.
- If there is not hardware support for AES suites by default the cha cha suites will be preferred over the AES suites
- supported suites as of go 1.17 are:
- TLS 1.0 - 1.2 cipher suites
- "rsa_with_rc4_128_sha"
- "rsa_with_3des_ede_cbc_sha"
- "rsa_with_aes_128_cbc_sha"
- "rsa_with_aes_256_cbc_sha"
- "rsa_with_aes_128_cbc_sha256"
- "rsa_with_aes_128_gcm_sha256"
- "rsa_with_aes_256_gcm_sha384"
- "ecdhe_ecdsa_with_rc4_128_sha"
- "ecdhe_ecdsa_with_aes_128_cbc_sha"
- "ecdhe_ecdsa_with_aes_256_cbc_sha"
- "ecdhe_rsa_with_rc4_128_sha"
- "ecdhe_rsa_with_3des_ede_cbc_sha"
- "ecdhe_rsa_with_aes_128_cbc_sha"
- "ecdhe_rsa_with_aes_256_cbc_sha"
- "ecdhe_ecdsa_with_aes_128_cbc_sha256"
- "ecdhe_rsa_with_aes_128_cbc_sha256"
- "ecdhe_rsa_with_aes_128_gcm_sha256"
- "ecdhe_ecdsa_with_aes_128_gcm_sha256"
- "ecdhe_rsa_with_aes_256_gcm_sha384"
- "ecdhe_ecdsa_with_aes_256_gcm_sha384"
- "ecdhe_rsa_with_chacha20_poly1305_sha256"
- "ecdhe_ecdsa_with_chacha20_poly1305_sha256"
- TLS 1.3 cipher suites
- "aes_128_gcm_sha256"
- "aes_256_gcm_sha384"
- "chacha20_poly1305_sha256"
- Aliased names
- "ecdhe_rsa_with_chacha20_poly1305" is an alias for "ecdhe_rsa_with_chacha20_poly1305_sha256"
- "ecdhe_ecdsa_with_chacha20_poly1305" is alias for "ecdhe_ecdsa_with_chacha20_poly1305_sha256"
- `ENABLE_LETSENCRYPT`: **false**: If enabled you must set `DOMAIN` to valid internet facing domain (ensure DNS is set and port 80 is accessible by letsencrypt validation server). - `ENABLE_LETSENCRYPT`: **false**: If enabled you must set `DOMAIN` to valid internet facing domain (ensure DNS is set and port 80 is accessible by letsencrypt validation server).
By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf). By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf).
- `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt. - `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt.
@@ -378,7 +339,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `require`: Enable TLS without any verifications. - `require`: Enable TLS without any verifications.
- `verify-ca`: Enable TLS with verification of the database server certificate against its root certificate. - `verify-ca`: Enable TLS with verification of the database server certificate against its root certificate.
- `verify-full`: Enable TLS and verify the database server name matches the given certificate in either the `Common Name` or `Subject Alternative Name` fields. - `verify-full`: Enable TLS and verify the database server name matches the given certificate in either the `Common Name` or `Subject Alternative Name` fields.
- `SQLITE_TIMEOUT`: **500**: Query timeout for SQLite3 only. - `SQLITE_TIMEOUT`: **500**: Query timeout for sqlite3 only.
- `ITERATE_BUFFER_SIZE`: **50**: Internal buffer size for iterating. - `ITERATE_BUFFER_SIZE`: **50**: Internal buffer size for iterating.
- `CHARSET`: **utf8mb4**: For MySQL only, either "utf8" or "utf8mb4". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this. - `CHARSET`: **utf8mb4**: For MySQL only, either "utf8" or "utf8mb4". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path. - `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
@@ -419,8 +380,6 @@ relation to port exhaustion.
## Queue (`queue` and `queue.*`) ## Queue (`queue` and `queue.*`)
Configuration at `[queue]` will set defaults for queues with overrides for individual queues at `[queue.*]`. (However see below.)
- `TYPE`: **persistable-channel**: General queue type, currently support: `persistable-channel` (uses a LevelDB internally), `channel`, `level`, `redis`, `dummy` - `TYPE`: **persistable-channel**: General queue type, currently support: `persistable-channel` (uses a LevelDB internally), `channel`, `level`, `redis`, `dummy`
- `DATADIR`: **queues/**: Base DataDir for storing persistent and level queues. `DATADIR` for individual queues can be set in `queue.name` sections but will default to `DATADIR/`**`common`**. (Previously each queue would default to `DATADIR/`**`name`**.) - `DATADIR`: **queues/**: Base DataDir for storing persistent and level queues. `DATADIR` for individual queues can be set in `queue.name` sections but will default to `DATADIR/`**`common`**. (Previously each queue would default to `DATADIR/`**`name`**.)
- `LENGTH`: **20**: Maximal queue size before channel queues block - `LENGTH`: **20**: Maximal queue size before channel queues block
@@ -439,37 +398,6 @@ Configuration at `[queue]` will set defaults for queues with overrides for indiv
- `BOOST_TIMEOUT`: **5m**: Boost workers will timeout after this long. - `BOOST_TIMEOUT`: **5m**: Boost workers will timeout after this long.
- `BOOST_WORKERS`: **1** (v1.14 and before: **5**): This many workers will be added to the worker pool if there is a boost. - `BOOST_WORKERS`: **1** (v1.14 and before: **5**): This many workers will be added to the worker pool if there is a boost.
Gitea creates the following non-unique queues:
- `code_indexer`
- `issue_indexer`
- `notification-service`
- `task`
- `mail`
- `push_update`
And the following unique queues:
- `repo_stats_update`
- `repo-archive`
- `mirror`
- `pr_patch_checker`
Certain queues have defaults that override the defaults set in `[queue]` (this occurs mostly to support older configuration):
- `[queue.issue_indexer]`
- `TYPE` this will default to `[queue]` `TYPE` if it is set but if not it will appropriately convert `[indexer]` `ISSUE_INDEXER_QUEUE_TYPE` if that is set.
- `LENGTH` will default to `[indexer]` `UPDATE_BUFFER_LEN` if that is set.
- `BATCH_LENGTH` will default to `[indexer]` `ISSUE_INDEXER_QUEUE_BATCH_NUMBER` if that is set.
- `DATADIR` will default to `[indexer]` `ISSUE_INDEXER_QUEUE_DIR` if that is set.
- `CONN_STR` will default to `[indexer]` `ISSUE_INDEXER_QUEUE_CONN_STR` if that is set.
- `[queue.mailer]`
- `LENGTH` will default to **100** or whatever `[mailer]` `SEND_BUFFER_LEN` is.
- `[queue.pr_patch_checker]`
- `LENGTH` will default to **1000** or whatever `[repository]` `PULL_REQUEST_QUEUE_LENGTH` is.
- `[queue.mirror]`
- `LENGTH` will default to **1000** or whatever `[repository]` `MIRROR_QUEUE_LENGTH` is.
## Admin (`admin`) ## Admin (`admin`)
- `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled - `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
@@ -477,7 +405,7 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
## Security (`security`) ## Security (`security`)
- `INSTALL_LOCK`: **false**: Controls access to the installation page. When set to "true", the installation page is not accessible. - `INSTALL_LOCK`: **false**: Disallow access to the install page.
- `SECRET_KEY`: **\<random at every install\>**: Global secret key. This should be changed. - `SECRET_KEY`: **\<random at every install\>**: Global secret key. This should be changed.
- `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days. - `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days.
- `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username. - `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username.
@@ -490,15 +418,15 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
- `REVERSE_PROXY_LIMIT`: **1**: Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request. - `REVERSE_PROXY_LIMIT`: **1**: Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request.
Number of trusted proxy count. Set to zero to not use these headers. Number of trusted proxy count. Set to zero to not use these headers.
- `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: List of IP addresses and networks separated by comma of trusted proxy servers. Use `*` to trust all. - `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: List of IP addresses and networks separated by comma of trusted proxy servers. Use `*` to trust all.
- `DISABLE_GIT_HOOKS`: **true**: Set to `false` to enable users with Git Hook privilege to create custom Git Hooks. - `DISABLE_GIT_HOOKS`: **true**: Set to `false` to enable users with git hook privilege to create custom git hooks.
WARNING: Custom Git Hooks can be used to perform arbitrary code execution on the host operating system. WARNING: Custom git hooks can be used to perform arbitrary code execution on the host operating system.
This enables the users to access and modify this config file and the Gitea database and interrupt the Gitea service. This enables the users to access and modify this config file and the Gitea database and interrupt the Gitea service.
By modifying the Gitea database, users can gain Gitea administrator privileges. By modifying the Gitea database, users can gain Gitea administrator privileges.
It also enables them to access other resources available to the user on the operating system that is running the It also enables them to access other resources available to the user on the operating system that is running the
Gitea instance and perform arbitrary actions in the name of the Gitea OS user. Gitea instance and perform arbitrary actions in the name of the Gitea OS user.
This maybe harmful to you website or your operating system. This maybe harmful to you website or your operating system.
- `DISABLE_WEBHOOKS`: **false**: Set to `true` to disable webhooks feature. - `DISABLE_WEBHOOKS`: **false**: Set to `true` to disable webhooks feature.
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to Gitea repositories you should set the environment appropriately. - `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to gitea repositories you should set the environment appropriately.
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server. - `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary. - `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`) - `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
@@ -512,7 +440,6 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
- spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~`` - spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~``
- off - do not check password complexity - off - do not check password complexity
- `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed. - `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed.
- `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**: Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security.
## OpenID (`openid`) ## OpenID (`openid`)
@@ -575,12 +502,11 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
- `HCAPTCHA_SITEKEY`: **""**: Sign up at https://www.hcaptcha.com/ to get a sitekey for hcaptcha. - `HCAPTCHA_SITEKEY`: **""**: Sign up at https://www.hcaptcha.com/ to get a sitekey for hcaptcha.
- `DEFAULT_KEEP_EMAIL_PRIVATE`: **false**: By default set users to keep their email address private. - `DEFAULT_KEEP_EMAIL_PRIVATE`: **false**: By default set users to keep their email address private.
- `DEFAULT_ALLOW_CREATE_ORGANIZATION`: **true**: Allow new users to create organizations by default. - `DEFAULT_ALLOW_CREATE_ORGANIZATION`: **true**: Allow new users to create organizations by default.
- `DEFAULT_USER_IS_RESTRICTED`: **false**: Give new users restricted permissions by default
- `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default. - `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default.
- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access. - `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access.
- `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles. - `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles.
- `ENABLE_TIMETRACKING`: **true**: Enable Timetracking feature. - `ENABLE_TIMETRACKING`: **true**: Enable Timetracking feature.
- `DEFAULT_ENABLE_TIMETRACKING`: **true**: Allow repositories to use timetracking by default. - `DEFAULT_ENABLE_TIMETRACKING`: **true**: Allow repositories to use timetracking by deault.
- `DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME`: **true**: Only allow users with write permissions to track time. - `DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME`: **true**: Only allow users with write permissions to track time.
- `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register - `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register
on this instance. on this instance.
@@ -593,18 +519,19 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
- `ALLOWED_USER_VISIBILITY_MODES`: **public,limited,private**: Set which visibility modes a user can have - `ALLOWED_USER_VISIBILITY_MODES`: **public,limited,private**: Set which visibility modes a user can have
- `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private". - `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private".
- `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation. - `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation.
- `ALLOW_ONLY_INTERNAL_REGISTRATION`: **false** Set to true to force registration only via Gitea. - `ALLOW_ONLY_INTERNAL_REGISTRATION`: **false** Set to true to force registration only via gitea.
- `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services. - `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services.
- `NO_REPLY_ADDRESS`: **noreply.DOMAIN** Value for the domain part of the user's email address in the Git log if user has set KeepEmailPrivate to true. DOMAIN resolves to the value in server.DOMAIN. - `NO_REPLY_ADDRESS`: **noreply.DOMAIN** Value for the domain part of the user's email address in the git log if user has set KeepEmailPrivate to true. DOMAIN resolves to the value in server.DOMAIN.
The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS. The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
- `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted. - `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted.
- `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles - `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles
### Service - Explore (`service.explore`) ### Service - Expore (`service.explore`)
- `REQUIRE_SIGNIN_VIEW`: **false**: Only allow signed in users to view the explore pages. - `REQUIRE_SIGNIN_VIEW`: **false**: Only allow signed in users to view the explore pages.
- `DISABLE_USERS_PAGE`: **false**: Disable the users explore page. - `DISABLE_USERS_PAGE`: **false**: Disable the users explore page.
## SSH Minimum Key Sizes (`ssh.minimum_key_sizes`) ## SSH Minimum Key Sizes (`ssh.minimum_key_sizes`)
Define allowed algorithms and their minimum key length (use -1 to disable a type): Define allowed algorithms and their minimum key length (use -1 to disable a type):
@@ -618,18 +545,10 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
- `QUEUE_LENGTH`: **1000**: Hook task queue length. Use caution when editing this value. - `QUEUE_LENGTH`: **1000**: Hook task queue length. Use caution when editing this value.
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks. - `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
- `ALLOWED_HOST_LIST`: **external**: Since 1.15.7. Default to `*` for 1.15.x, `external` for 1.16 and later. Webhook can only call allowed hosts for security reasons. Comma separated list.
- Built-in networks:
- `loopback`: 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
- `private`: RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
- `external`: A valid non-private unicast IP, you can access all hosts on public internet.
- `*`: All hosts are allowed.
- CIDR list: `1.2.3.0/8` for IPv4 and `2001:db8::/32` for IPv6
- Wildcard hosts: `*.mydomain.com`, `192.168.100.*`
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification. - `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page. - `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
- `PROXY_URL`: **\<empty\>**: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy. If not given, will use global proxy setting. - `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
- `PROXY_HOSTS`: **\<empty\>`**: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts. If not given, will use global proxy setting. - `PROXY_HOSTS`: ****: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
## Mailer (`mailer`) ## Mailer (`mailer`)
@@ -643,7 +562,6 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
- Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`. - Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`.
- `FROM`: **\<empty\>**: Mail from address, RFC 5322. This can be just an email address, or - `FROM`: **\<empty\>**: Mail from address, RFC 5322. This can be just an email address, or
the "Name" \<email@example.com\> format. the "Name" \<email@example.com\> format.
- `ENVELOPE_FROM`: **\<empty\>**: Address set as the From address on the SMTP mail envelope. Set to `<>` to send an empty address.
- `USER`: **\<empty\>**: Username of mailing user (usually the sender's e-mail address). - `USER`: **\<empty\>**: Username of mailing user (usually the sender's e-mail address).
- `PASSWD`: **\<empty\>**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password. - `PASSWD`: **\<empty\>**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password.
- Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or `HOST=localhost`. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information. - Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or `HOST=localhost`. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information.
@@ -658,7 +576,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
- `MAILER_TYPE`: **smtp**: \[smtp, sendmail, dummy\] - `MAILER_TYPE`: **smtp**: \[smtp, sendmail, dummy\]
- **smtp** Use SMTP to send mail - **smtp** Use SMTP to send mail
- **sendmail** Use the operating system's `sendmail` command instead of SMTP. - **sendmail** Use the operating system's `sendmail` command instead of SMTP.
This is common on Linux systems. This is common on linux systems.
- **dummy** Send email messages to the log as a testing phase. - **dummy** Send email messages to the log as a testing phase.
- Note that enabling sendmail will ignore all other `mailer` settings except `ENABLED`, - Note that enabling sendmail will ignore all other `mailer` settings except `ENABLED`,
`FROM`, `SUBJECT_PREFIX` and `SENDMAIL_PATH`. `FROM`, `SUBJECT_PREFIX` and `SENDMAIL_PATH`.
@@ -667,8 +585,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
command or full path). command or full path).
- `SENDMAIL_ARGS`: **_empty_**: Specify any extra sendmail arguments. - `SENDMAIL_ARGS`: **_empty_**: Specify any extra sendmail arguments.
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail - `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
- `SENDMAIL_CONVERT_CRLF`: **true**: Most versions of sendmail prefer LF line endings rather than CRLF line endings. Set this to false if your version of sendmail requires CRLF line endings. - `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue.
- `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue. **DEPRECATED** use `LENGTH` in `[queue.mailer]`
## Cache (`cache`) ## Cache (`cache`)
@@ -711,7 +628,6 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
- `AVATAR_MAX_WIDTH`: **4096**: Maximum avatar image width in pixels. - `AVATAR_MAX_WIDTH`: **4096**: Maximum avatar image width in pixels.
- `AVATAR_MAX_HEIGHT`: **3072**: Maximum avatar image height in pixels. - `AVATAR_MAX_HEIGHT`: **3072**: Maximum avatar image height in pixels.
- `AVATAR_MAX_FILE_SIZE`: **1048576** (1Mb): Maximum avatar image file size in bytes. - `AVATAR_MAX_FILE_SIZE`: **1048576** (1Mb): Maximum avatar image file size in bytes.
- `AVATAR_RENDERED_SIZE_FACTOR`: **3**: The multiplication factor for rendered avatar images. Larger values result in finer rendering on HiDPI devices.
- `REPOSITORY_AVATAR_STORAGE_TYPE`: **default**: Storage type defined in `[storage.xxx]`. Default is `default` which will read `[storage]` if no section `[storage]` will be a type `local`. - `REPOSITORY_AVATAR_STORAGE_TYPE`: **default**: Storage type defined in `[storage.xxx]`. Default is `default` which will read `[storage]` if no section `[storage]` will be a type `local`.
- `REPOSITORY_AVATAR_UPLOAD_PATH`: **data/repo-avatars**: Path to store repository avatar image files. - `REPOSITORY_AVATAR_UPLOAD_PATH`: **data/repo-avatars**: Path to store repository avatar image files.
@@ -732,7 +648,7 @@ Default templates for project boards:
## Issue and pull request attachments (`attachment`) ## Issue and pull request attachments (`attachment`)
- `ENABLED`: **true**: Whether issue and pull request attachments are enabled. - `ENABLED`: **true**: Whether issue and pull request attachments are enabled.
- `ALLOWED_TYPES`: **.docx,.gif,.gz,.jpeg,.jpg,mp4,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. - `ALLOWED_TYPES`: **.docx,.gif,.gz,.jpeg,.jpg,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
- `MAX_SIZE`: **4**: Maximum size (MB). - `MAX_SIZE`: **4**: Maximum size (MB).
- `MAX_FILES`: **5**: Maximum number of attachments that can be uploaded at once. - `MAX_FILES`: **5**: Maximum number of attachments that can be uploaded at once.
- `STORAGE_TYPE`: **local**: Storage type for attachments, `local` for local disk or `minio` for s3 compatible object storage service, default is `local` or other name defined with `[storage.xxx]` - `STORAGE_TYPE`: **local**: Storage type for attachments, `local` for local disk or `minio` for s3 compatible object storage service, default is `local` or other name defined with `[storage.xxx]`
@@ -753,11 +669,11 @@ Default templates for project boards:
- `LEVEL`: **Info**: General log level. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\] - `LEVEL`: **Info**: General log level. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
- `STACKTRACE_LEVEL`: **None**: Default log level at which to log create stack traces. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\] - `STACKTRACE_LEVEL`: **None**: Default log level at which to log create stack traces. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
- `ROUTER_LOG_LEVEL`: **Info**: The log level that the router should log at. (If you are setting the access log, its recommended to place this at Debug.) - `ROUTER_LOG_LEVEL`: **Info**: The log level that the router should log at. (If you are setting the access log, its recommended to place this at Debug.)
- `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default Gitea logger.) - `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default gitea logger.)
NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`. NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`.
- `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template - `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template
- `ENABLE_SSH_LOG`: **false**: save ssh log to log file - `ENABLE_SSH_LOG`: **false**: save ssh log to log file
- `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default Gitea logger.) - `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default gitea logger.)
- `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log. - `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log.
- The following variables are available: - The following variables are available:
- `Ctx`: the `context.Context` of the request. - `Ctx`: the `context.Context` of the request.
@@ -824,43 +740,41 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
- `ENABLED`: **true**: Enable service. - `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED). - `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`. - `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
- `OLDER_THAN`: **24h**: Archives created more than `OLDER_THAN` ago are subject to deletion, e.g. `12h`. - `OLDER_THAN`: **24h**: Archives created more than `OLDER_THAN` ago are subject to deletion, e.g. `12h`.
#### Cron - Update Mirrors (`cron.update_mirrors`) #### Cron - Update Mirrors (`cron.update_mirrors`)
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`. - `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
- `NO_SUCCESS_NOTICE`: **true**: The cron task for update mirrors success report is not very useful - as it just means that the mirrors have been queued. Therefore this is turned off by default. - `NO_SUCCESS_NOTICE`: **true**: The cron task for update mirrors success report is not very useful - as it just means that the mirrors have been queued. Therefore this is turned off by default.
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
#### Cron - Repository Health Check (`cron.repo_health_check`) #### Cron - Repository Health Check (`cron.repo_health_check`)
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check. - `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository health check.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout. - `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **\<empty\>**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck - `ARGS`: **\<empty\>**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
#### Cron - Repository Statistics Check (`cron.check_repo_stats`) #### Cron - Repository Statistics Check (`cron.check_repo_stats`)
- `RUN_AT_START`: **true**: Run repository statistics check at start time. - `RUN_AT_START`: **true**: Run repository statistics check at start time.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check. - `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository statistics check.
### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`) ### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job. - `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED). - `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table. - `SCHEDULE`: **@every 24h**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook). - `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted. - `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
- `NUMBER_TO_KEEP`: **10**: If CLEANUP_TYPE is set to PerWebhook, this is number of hook_task records to keep for a webhook (i.e. keep the most recent x deliveries). - `NUMBER_TO_KEEP`: **10**: If CLEANUP_TYPE is set to PerWebhook, this is number of hook_task records to keep for a webhook (i.e. keep the most recent x deliveries).
#### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`) #### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts. - `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`) #### Cron - Sync External Users (`cron.sync_external_users`)
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts. - `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false. - `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
### Extended cron tasks (not enabled by default) ### Extended cron tasks (not enabled by default)
@@ -907,19 +821,12 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
- `ENABLED`: **false**: Enable service. - `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices. - `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check. - `SCHEDULE`: **@every 128h**: Cron syntax for scheduling a work, e.g. `@every 128h`.
- `OLDER_THAN`: **@every 8760h**: any action older than this expression will be deleted from database, suggest using `8760h` (1 year) because that's the max length of heatmap. - `OLDER_THAN`: **@every 8760h**: any action older than this expression will be deleted from database, suggest using `8760h` (1 year) because that's the max length of heatmap.
#### Cron - Check for new Gitea versions ('cron.update_checker')
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.io/gitea/version.json**: the endpoint that Gitea will check for newer versions
## Git (`git`) ## Git (`git`)
- `PATH`: **""**: The path of Git executable. If empty, Gitea searches through the PATH environment. - `PATH`: **""**: The path of git executable. If empty, Gitea searches through the PATH environment.
- `DISABLE_DIFF_HIGHLIGHT`: **false**: Disables highlight of added and removed changes. - `DISABLE_DIFF_HIGHLIGHT`: **false**: Disables highlight of added and removed changes.
- `MAX_GIT_DIFF_LINES`: **1000**: Max number of lines allowed of a single file in diff view. - `MAX_GIT_DIFF_LINES`: **1000**: Max number of lines allowed of a single file in diff view.
- `MAX_GIT_DIFF_LINE_CHARACTERS`: **5000**: Max character count per line highlighted in diff view. - `MAX_GIT_DIFF_LINE_CHARACTERS`: **5000**: Max character count per line highlighted in diff view.
@@ -927,14 +834,11 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
- `COMMITS_RANGE_SIZE`: **50**: Set the default commits range size - `COMMITS_RANGE_SIZE`: **50**: Set the default commits range size
- `BRANCHES_RANGE_SIZE`: **20**: Set the default branches range size - `BRANCHES_RANGE_SIZE`: **20**: Set the default branches range size
- `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`. See more on http://git-scm.com/docs/git-gc/ - `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`. See more on http://git-scm.com/docs/git-gc/
- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use Git wire protocol version 2 when Git version >= 2.18, default is true, set to false when you always want Git wire protocol version 1 - `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use git wire protocol version 2 when git version >= 2.18, default is true, set to false when you always want git wire protocol version 1
- `PULL_REQUEST_PUSH_MESSAGE`: **true**: Respond to pushes to a non-default branch with a URL for creating a Pull Request (if the repository has them enabled) - `PULL_REQUEST_PUSH_MESSAGE`: **true**: Respond to pushes to a non-default branch with a URL for creating a Pull Request (if the repository has them enabled)
- `VERBOSE_PUSH`: **true**: Print status information about pushes as they are being processed. - `VERBOSE_PUSH`: **true**: Print status information about pushes as they are being processed.
- `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay. - `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay.
- `LARGE_OBJECT_THRESHOLD`: **1048576**: (Go-Git only), don't cache objects greater than this in memory. (Set to 0 to disable.) - `LARGE_OBJECT_THRESHOLD`: **1048576**: (Go-Git only), don't cache objects greater than this in memory. (Set to 0 to disable.)
- `DISABLE_CORE_PROTECT_NTFS`: **false** Set to true to forcibly set `core.protectNTFS` to false.
- `DISABLE_PARTIAL_CLONE`: **false** Disable the usage of using partial clones for git.
## Git - Timeout settings (`git.timeout`) ## Git - Timeout settings (`git.timeout`)
- `DEFAUlT`: **360**: Git operations default timeout seconds. - `DEFAUlT`: **360**: Git operations default timeout seconds.
- `MIGRATE`: **600**: Migrate external repositories timeout seconds. - `MIGRATE`: **600**: Migrate external repositories timeout seconds.
@@ -946,8 +850,6 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
## Metrics (`metrics`) ## Metrics (`metrics`)
- `ENABLED`: **false**: Enables /metrics endpoint for prometheus. - `ENABLED`: **false**: Enables /metrics endpoint for prometheus.
- `ENABLED_ISSUE_BY_LABEL`: **false**: Enable issue by label metrics with format `gitea_issues_by_label{label="bug"} 2`.
- `ENABLED_ISSUE_BY_REPOSITORY`: **false**: Enable issue by repository metrics with format `gitea_issues_by_repository{repository="org/repo"} 5`.
- `TOKEN`: **\<empty\>**: You need to specify the token, if you want to include in the authorization the metrics . The same token need to be used in prometheus parameters `bearer_token` or `bearer_token_file`. - `TOKEN`: **\<empty\>**: You need to specify the token, if you want to include in the authorization the metrics . The same token need to be used in prometheus parameters `bearer_token` or `bearer_token_file`.
## API (`api`) ## API (`api`)
@@ -955,7 +857,7 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
- `ENABLE_SWAGGER`: **true**: Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true. - `ENABLE_SWAGGER`: **true**: Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true.
- `MAX_RESPONSE_ITEMS`: **50**: Max number of items in a page. - `MAX_RESPONSE_ITEMS`: **50**: Max number of items in a page.
- `DEFAULT_PAGING_NUM`: **30**: Default paging number of API. - `DEFAULT_PAGING_NUM`: **30**: Default paging number of API.
- `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: Default and maximum number of items per page for Git trees API. - `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: Default and maximum number of items per page for git trees API.
- `DEFAULT_MAX_BLOB_SIZE`: **10485760**: Default max size of a blob that can be return by the blobs API. - `DEFAULT_MAX_BLOB_SIZE`: **10485760**: Default max size of a blob that can be return by the blobs API.
## OAuth2 (`oauth2`) ## OAuth2 (`oauth2`)
@@ -971,16 +873,15 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
## i18n (`i18n`) ## i18n (`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,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN**: List of locales shown in language selector - `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,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR**: List of locales shown in language selector
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,ελληνικά,فارسی,magyar nyelv,bahasa Indonesia,മലയാളം**: Visible names corresponding to the locales - `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어**: Visible names corresponding to the locales
## U2F (`U2F`) **DEPRECATED** ## U2F (`U2F`)
- `APP_ID`: **`ROOT_URL`**: Declares the facet of the application which is used for authentication of previously registered U2F keys. Requires HTTPS. - `APP_ID`: **`ROOT_URL`**: Declares the facet of the application. Requires HTTPS.
- `TRUSTED_FACETS`: List of additional facets which are trusted. This is not support by all browsers.
## Markup (`markup`) ## Markup (`markup`)
- `MERMAID_MAX_SOURCE_CHARACTERS`: **5000**: Set the maximum size of a Mermaid source. (Set to -1 to disable)
Gitea can support Markup using external tools. The example below will add a markup named `asciidoc`. Gitea can support Markup using external tools. The example below will add a markup named `asciidoc`.
```ini ```ini
@@ -1025,14 +926,6 @@ Multiple sanitisation rules can be defined by adding unique subsections, e.g. `[
To apply a sanitisation rules only for a specify external renderer they must use the renderer name, e.g. `[markup.sanitizer.asciidoc.rule-1]`. To apply a sanitisation rules only for a specify external renderer they must use the renderer name, e.g. `[markup.sanitizer.asciidoc.rule-1]`.
If the rule is defined above the renderer ini section or the name does not match a renderer it is applied to every renderer. If the rule is defined above the renderer ini section or the name does not match a renderer it is applied to every renderer.
## Highlight Mappings (`highlight.mapping`)
- `file_extension e.g. .toml`: **language e.g. ini**. File extension to language mapping overrides.
- Gitea will highlight files using the `linguist-language` or `gitlab-language` attribute from the `.gitattributes` file
if available. If this is not set or the language is unavailable, the file extension will be looked up
in this mapping or the filetype using heuristics.
## Time (`time`) ## Time (`time`)
- `FORMAT`: Time format to display on UI. i.e. RFC1123 or 2006-01-02 15:04:05 - `FORMAT`: Time format to display on UI. i.e. RFC1123 or 2006-01-02 15:04:05
@@ -1051,19 +944,11 @@ Task queue configuration has been moved to `queue.task`. However, the below conf
- `MAX_ATTEMPTS`: **3**: Max attempts per http/https request on migrations. - `MAX_ATTEMPTS`: **3**: Max attempts per http/https request on migrations.
- `RETRY_BACKOFF`: **3**: Backoff time per http/https request retry (seconds) - `RETRY_BACKOFF`: **3**: Backoff time per http/https request retry (seconds)
- `ALLOWED_DOMAINS`: **\<empty\>**: Domains allowlist for migrating repositories, default is blank. It means everything will be allowed. Multiple domains could be separated by commas. - `ALLOWED_DOMAINS`: **\<empty\>**: Domains allowlist for migrating repositories, default is blank. It means everything will be allowed. Multiple domains could be separated by commas.
- `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option has a higher priority to deny domains. - `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option will be ignored.
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291 - `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291
- `SKIP_TLS_VERIFY`: **false**: Allow skip tls verify
## Federation (`federation`)
- `ENABLED`: **true**: Enable/Disable federation capabilities
## Mirror (`mirror`) ## Mirror (`mirror`)
- `ENABLED`: **true**: Enables the mirror functionality. Set to **false** to disable all mirrors.
- `DISABLE_NEW_PULL`: **false**: Disable the creation of **new** pull mirrors. Pre-existing mirrors remain valid. Will be ignored if `mirror.ENABLED` is `false`.
- `DISABLE_NEW_PUSH`: **false**: Disable the creation of **new** push mirrors. Pre-existing mirrors remain valid. Will be ignored if `mirror.ENABLED` is `false`.
- `DEFAULT_INTERVAL`: **8h**: Default interval between each check - `DEFAULT_INTERVAL`: **8h**: Default interval between each check
- `MIN_INTERVAL`: **10m**: Minimum interval for checking. (Must be >1m). - `MIN_INTERVAL`: **10m**: Minimum interval for checking. (Must be >1m).
@@ -1134,19 +1019,6 @@ is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`.
- `MINIO_BASE_PATH`: **repo-archive/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_BASE_PATH`: **repo-archive/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio`
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio` - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
## Proxy (`proxy`)
- `PROXY_ENABLED`: **false**: Enable the proxy if true, all requests to external via HTTP will be affected, if false, no proxy will be used even environment http_proxy/https_proxy
- `PROXY_URL`: **\<empty\>**: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
- `PROXY_HOSTS`: **\<empty\>**: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
i.e.
```ini
PROXY_ENABLED = true
PROXY_URL = socks://127.0.0.1:1080
PROXY_HOSTS = *.github.com
```
## Other (`other`) ## Other (`other`)
- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer. - `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.

View File

@@ -36,11 +36,6 @@ menu:
- `MAX_CREATION_LIMIT`: 全局最大每个用户创建的git工程数目 `-1` 表示没限制。 - `MAX_CREATION_LIMIT`: 全局最大每个用户创建的git工程数目 `-1` 表示没限制。
- `PULL_REQUEST_QUEUE_LENGTH`: 小心:合并请求测试队列的长度,尽量放大。 - `PULL_REQUEST_QUEUE_LENGTH`: 小心:合并请求测试队列的长度,尽量放大。
### Repository - Release (`repository.release`)
- `ALLOWED_TYPES`: **\<empty\>**: 允许扩展名的列表,用逗号分隔 (`.zip`), mime 类型 (`text/plain`) 或者匹配符号 (`image/*`, `audio/*`, `video/*`). 空值或者 `*/*` 允许所有类型。
- `DEFAULT_PAGING_NUM`: **10**: 默认的发布版本页面分页。
## UI (`ui`) ## UI (`ui`)
- `EXPLORE_PAGING_NUM`: 探索页面每页显示的仓库数量。 - `EXPLORE_PAGING_NUM`: 探索页面每页显示的仓库数量。
@@ -84,14 +79,14 @@ menu:
## Database (`database`) ## Database (`database`)
- `DB_TYPE`: 数据库类型,可选 `mysql`, `postgres`, `mssql``sqlite3` - `DB_TYPE`: 数据库类型,可选 `mysql`, `postgres`, `mssql`, `tidb``sqlite3`
- `HOST`: 数据库服务器地址和端口。 - `HOST`: 数据库服务器地址和端口。
- `NAME`: 数据库名称。 - `NAME`: 数据库名称。
- `USER`: 数据库用户名。 - `USER`: 数据库用户名。
- `PASSWD`: 数据库用户密码。 - `PASSWD`: 数据库用户密码。
- `SSL_MODE`: MySQL 或 PostgreSQL数据库是否启用SSL模式。 - `SSL_MODE`: MySQL 或 PostgreSQL数据库是否启用SSL模式。
- `CHARSET`: **utf8mb4**: 仅当数据库为 MySQL 时有效, 可以为 "utf8" 或 "utf8mb4"。注意:如果使用 "utf8mb4",你的 MySQL InnoDB 版本必须在 5.6 以上。 - `CHARSET`: **utf8mb4**: 仅当数据库为 MySQL 时有效, 可以为 "utf8" 或 "utf8mb4"。注意:如果使用 "utf8mb4",你的 MySQL InnoDB 版本必须在 5.6 以上。
- `PATH`: SQLite3 数据文件存放路径。 - `PATH`: Tidb 或者 SQLite3 数据文件存放路径。
- `LOG_SQL`: **true**: 显示生成的SQL默认为真。 - `LOG_SQL`: **true**: 显示生成的SQL默认为真。
- `MAX_IDLE_CONNS` **0**: 最大空闲数据库连接 - `MAX_IDLE_CONNS` **0**: 最大空闲数据库连接
- `CONN_MAX_LIFETIME` **3s**: 数据库连接最大存活时间 - `CONN_MAX_LIFETIME` **3s**: 数据库连接最大存活时间
@@ -262,18 +257,18 @@ test01.xls: application/vnd.ms-excel; charset=binary
### Cron - Repository Health Check (`cron.repo_health_check`) ### Cron - Repository Health Check (`cron.repo_health_check`)
- `SCHEDULE`: 仓库健康监测的Cron语法比如`@midnight` - `SCHEDULE`: 仓库健康监测的Cron语法比如`@every 24h`
- `TIMEOUT`: 仓库健康监测的超时时间,比如:`60s`. - `TIMEOUT`: 仓库健康监测的超时时间,比如:`60s`.
- `ARGS`: 执行 `git fsck` 命令的参数,比如:`--unreachable --tags` - `ARGS`: 执行 `git fsck` 命令的参数,比如:`--unreachable --tags`
### Cron - Repository Statistics Check (`cron.check_repo_stats`) ### Cron - Repository Statistics Check (`cron.check_repo_stats`)
- `RUN_AT_START`: 是否启动时自动运行仓库统计。 - `RUN_AT_START`: 是否启动时自动运行仓库统计。
- `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@midnight`. - `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@every 24h`.
### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`) ### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
- `SCHEDULE`: **@midnight** : 每次同步的间隔时间。此任务总是在启动时自动进行。 - `SCHEDULE`: **@every 24h** : 每次同步的间隔时间。此任务总是在启动时自动进行。
## Git (`git`) ## Git (`git`)
@@ -335,9 +330,8 @@ IS_INPUT_FILE = false
- `MAX_ATTEMPTS`: **3**: 在迁移过程中的 http/https 请求重试次数。 - `MAX_ATTEMPTS`: **3**: 在迁移过程中的 http/https 请求重试次数。
- `RETRY_BACKOFF`: **3**: 等待下一次重试的时间,单位秒。 - `RETRY_BACKOFF`: **3**: 等待下一次重试的时间,单位秒。
- `ALLOWED_DOMAINS`: **\<empty\>**: 迁移仓库的域名白名单,默认为空,表示允许从任意域名迁移仓库,多个域名用逗号分隔。 - `ALLOWED_DOMAINS`: **\<empty\>**: 迁移仓库的域名白名单,默认为空,表示允许从任意域名迁移仓库,多个域名用逗号分隔。
- `BLOCKED_DOMAINS`: **\<empty\>**: 迁移仓库的域名黑名单,默认为空,多个域名用逗号分隔。如果 `ALLOWED_DOMAINS` 不为空,此选项有更高的优先级拒绝这里的域名 - `BLOCKED_DOMAINS`: **\<empty\>**: 迁移仓库的域名黑名单,默认为空,多个域名用逗号分隔。如果 `ALLOWED_DOMAINS` 不为空,此选项将会被忽略
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918 - `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918
- `SKIP_TLS_VERIFY`: **false**: 允许忽略 TLS 认证
## LFS (`lfs`) ## LFS (`lfs`)
@@ -403,19 +397,6 @@ Repository archive 的存储配置。 如果 `STORAGE_TYPE` 为空,则此配
- `MINIO_BASE_PATH`: **repo-archive/**: Minio base path ,仅当 `STORAGE_TYPE``minio` 时有效。 - `MINIO_BASE_PATH`: **repo-archive/**: Minio base path ,仅当 `STORAGE_TYPE``minio` 时有效。
- `MINIO_USE_SSL`: **false**: Minio 是否启用 ssl ,仅当 `STORAGE_TYPE``minio` 时有效。 - `MINIO_USE_SSL`: **false**: Minio 是否启用 ssl ,仅当 `STORAGE_TYPE``minio` 时有效。
## Proxy (`proxy`)
- `PROXY_ENABLED`: **false**: 是否启用全局代理。如果为否,则不使用代理,环境变量中的代理也不使用
- `PROXY_URL`: **\<empty\>**: 代理服务器地址,支持 http://, https//, socks://,为空则不启用代理而使用环境变量中的 http_proxy/https_proxy
- `PROXY_HOSTS`: **\<empty\>**: 逗号分隔的多个需要代理的网址,支持 * 号匹配符号, ** 表示匹配所有网站
i.e.
```ini
PROXY_ENABLED = true
PROXY_URL = socks://127.0.0.1:1080
PROXY_HOSTS = *.github.com
```
## Other (`other`) ## Other (`other`)
- `SHOW_FOOTER_BRANDING`: 为真则在页面底部显示Gitea的字样。 - `SHOW_FOOTER_BRANDING`: 为真则在页面底部显示Gitea的字样。

View File

@@ -92,7 +92,7 @@ shouldn't be touched without fully understanding these components.
Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/main/templates/home.tmpl) for your version of Gitea from `templates` to `$GITEA_CUSTOM/templates`. Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/main/templates/home.tmpl) for your version of Gitea from `templates` to `$GITEA_CUSTOM/templates`.
Edit as you wish. Edit as you wish.
Dont forget to restart your Gitea to apply the changes. Dont forget to restart your gitea to apply the changes.
### Adding links and tabs ### Adding links and tabs
@@ -200,7 +200,7 @@ to the file `templates/custom/footer.tmpl`
You also need to download the content of the library [Madeleine.js](https://jinjunho.github.io/Madeleine.js/) and place it under `$GITEA_CUSTOM/public/` folder. You also need to download the content of the library [Madeleine.js](https://jinjunho.github.io/Madeleine.js/) and place it under `$GITEA_CUSTOM/public/` folder.
You should end-up with a folder structure similar to: You should end-up with a folder structucture similar to:
``` ```
$GITEA_CUSTOM/templates $GITEA_CUSTOM/templates
@@ -248,7 +248,7 @@ $GITEA_CUSTOM/public
`-- three.min.js `-- three.min.js
``` ```
Then restart Gitea and open a STL file on your Gitea instance. Then restart gitea and open a STL file on your gitea instance.
## Customizing Gitea mails ## Customizing Gitea mails
@@ -287,7 +287,7 @@ To add a custom license, add a file with the license text to `$GITEA_CUSTOM/opti
### Locales ### Locales
Locales are managed via our [Crowdin](https://crowdin.com/project/gitea). Locales are managed via our [crowdin](https://crowdin.com/project/gitea).
You can override a locale by placing an altered locale file in `$GITEA_CUSTOM/options/locale`. You can override a locale by placing an altered locale file in `$GITEA_CUSTOM/options/locale`.
Gitea's default locale files can be found in the [`options/locale`](https://github.com/go-gitea/gitea/tree/main/options/locale) source folder and these should be used as examples for your changes. Gitea's default locale files can be found in the [`options/locale`](https://github.com/go-gitea/gitea/tree/main/options/locale) source folder and these should be used as examples for your changes.
@@ -321,24 +321,8 @@ A full list of supported emoji's is at [emoji list](https://gitea.com/gitea/gite
## Customizing the look of Gitea ## Customizing the look of Gitea
The default built-in themes are `gitea` (light), `arc-green` (dark), and `auto` (chooses light or dark depending on operating system settings). As of version 1.6.0 Gitea has built-in themes. The two built-in themes are, the default theme `gitea`, and a dark theme `arc-green`. To change the look of your Gitea install change the value of `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` to another one of the available options.
The default theme can be changed via `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini`. As of version 1.8.0 Gitea also has per-user themes. The list of themes a user can choose from can be configured with the `THEMES` value in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` (defaults to `gitea` and `arc-green`, light and dark respectively)
Gitea also has support for user themes, which means every user can select which theme should be used.
The list of themes a user can choose from can be configured with the `THEMES` value in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini`.
To make a custom theme available to all users:
1. Add a CSS file to `$GITEA_PUBLIC/public/css/theme-<theme-name>.css`.
The value of `$GITEA_PUBLIC` of your instance can be queried by calling `gitea help` and looking up the value of "CustomPath".
2. Add `<theme-name>` to the comma-separated list of setting `THEMES` in `app.ini`
Community themes are listed in [gitea/awesome-gitea#themes](https://gitea.com/gitea/awesome-gitea#themes).
The `arc-green` theme source can be found [here](https://github.com/go-gitea/gitea/blob/main/web_src/less/themes/theme-arc-green.less).
If your custom theme is considered a dark theme, set the global css variable `--is-dark-theme` to `true`.
This allows Gitea to adjust the Monaco code editor's theme accordingly.
## Customizing fonts ## Customizing fonts

View File

@@ -328,13 +328,13 @@ This is equivalent to sending all logs to the console, with default go log being
## Releasing-and-Reopening, Pausing and Resuming logging ## Releasing-and-Reopening, Pausing and Resuming logging
If you are running on Unix you may wish to release-and-reopen logs in order to use `logrotate` or other tools. If you are running on Unix you may wish to release-and-reopen logs in order to use `logrotate` or other tools.
It is possible force Gitea to release and reopen it's logging files and connections by sending `SIGUSR1` to the It is possible force gitea to release and reopen it's logging files and connections by sending `SIGUSR1` to the
running process, or running `gitea manager logging release-and-reopen`. running process, or running `gitea manager logging release-and-reopen`.
Alternatively, you may wish to pause and resume logging - this can be accomplished through the use of the Alternatively, you may wish to pause and resume logging - this can be accomplished through the use of the
`gitea manager logging pause` and `gitea manager logging resume` commands. Please note that whilst logging `gitea manager logging pause` and `gitea manager logging resume` commands. Please note that whilst logging
is paused log events below INFO level will not be stored and only a limited number of events will be stored. is paused log events below INFO level will not be stored and only a limited number of events will be stored.
Logging may block, albeit temporarily, slowing Gitea considerably whilst paused - therefore it is Logging may block, albeit temporarily, slowing gitea considerably whilst paused - therefore it is
recommended that pausing only done for a very short period of time. recommended that pausing only done for a very short period of time.
## Adding and removing logging whilst Gitea is running ## Adding and removing logging whilst Gitea is running
@@ -439,6 +439,6 @@ Gitea includes built-in log rotation, which should be enough for most deployment
- Install `logrotate`. - Install `logrotate`.
- Configure `logrotate` to match your deployment requirements, see `man 8 logrotate` for configuration syntax details. In the `postrotate/endscript` block send Gitea a `USR1` signal via `kill -USR1` or `kill -10` to the `gitea` process itself, or run `gitea manager logging release-and-reopen` (with the appropriate environment). Ensure that your configurations apply to all files emitted by Gitea loggers as described in the above sections. - Configure `logrotate` to match your deployment requirements, see `man 8 logrotate` for configuration syntax details. In the `postrotate/endscript` block send Gitea a `USR1` signal via `kill -USR1` or `kill -10` to the `gitea` process itself, or run `gitea manager logging release-and-reopen` (with the appropriate environment). Ensure that your configurations apply to all files emitted by Gitea loggers as described in the above sections.
- Always do `logrotate /etc/logrotate.conf --debug` to test your configurations. - Always do `logrotate /etc/logrotate.conf --debug` to test your configurations.
- If you are using docker and are running from outside of the container you can use `docker exec -u $OS_USER $CONTAINER_NAME sh -c 'gitea manager logging release-and-reopen'` or `docker exec $CONTAINER_NAME sh -c '/bin/s6-svc -1 /etc/s6/gitea/'` or send `USR1` directly to the Gitea process itself. - If you are using docker and are running from outside of the container you can use `docker exec -u $OS_USER $CONTAINER_NAME sh -c 'gitea manager logging release-and-reopen'` or `docker exec $CONTAINER_NAME sh -c '/bin/s6-svc -1 /etc/s6/gitea/'` or send `USR1` directly to the gitea process itself.
The next `logrotate` jobs will include your configurations, so no restart is needed. You can also immediately reload `logrotate` with `logrotate /etc/logrotate.conf --force`. The next `logrotate` jobs will include your configurations, so no restart is needed. You can also immediately reload `logrotate` with `logrotate /etc/logrotate.conf --force`.

View File

@@ -208,7 +208,7 @@ Please check [Gitea's logs](https://docs.gitea.io/en-us/logging-configuration/)
{{end}} {{end}}
<p> <p>
<p> <p>
<a href="{{AppUrl}}/{{.Doer.LowerName}}">@{{.Doer.Name}}</a> <a href="{{AppURL}}/{{.Doer.LowerName}}">@{{.Doer.Name}}</a>
{{if not (eq .Doer.FullName "")}} {{if not (eq .Doer.FullName "")}}
({{.Doer.FullName}}) ({{.Doer.FullName}})
{{end}} {{end}}

View File

@@ -37,8 +37,8 @@ sudo yum install make
Si vous utilisez Windows, vous pouvez télécharger une des versions suivantes de Make: Si vous utilisez Windows, vous pouvez télécharger une des versions suivantes de Make:
- [Simple binaire](http://www.equation.com/servlet/equation.cmd?fa=make). Copiez-le quelque part et mettez à jour `PATH`. - [Simple binaire](http://www.equation.com/servlet/equation.cmd?fa=make). Copiez le quelque part et mettez à jour `PATH`.
- [32-bits version](ftp://ftp.equation.com/make/32/make.exe) - [32-bits version](ftp://ftp.equation.com/make/32/make.exe)
- [64-bits version](ftp://ftp.equation.com/make/64/make.exe) - [64-bits version](ftp://ftp.equation.com/make/64/make.exe)
- [MinGW](http://www.mingw.org/) inclut un _build_. Le fichier binaire est nommé `mingw32-make.exe` plutôt que `make.exe`. Ajoutez le dossier `bin` à votre `PATH`. - [MinGW](http://www.mingw.org/) includes a build. The binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to your `PATH`.
- [Chocolatey package](https://chocolatey.org/packages/make). Exécutez `choco install make`. - [Chocolatey package](https://chocolatey.org/packages/make). Run `choco install make`

View File

@@ -15,7 +15,7 @@ menu:
# Protected tags # Protected tags
Protected tags allow control over who has permission to create or update Git tags. Each rule allows you to match either an individual tag name, or use an appropriate pattern to control multiple tags at once. Protected tags allow control over who has permission to create or update git tags. Each rule allows you to match either an individual tag name, or use an appropriate pattern to control multiple tags at once.
**Table of Contents** **Table of Contents**

View File

@@ -20,8 +20,8 @@ menu:
{{< toc >}} {{< toc >}}
Gitea will verify GPG commit signatures in the provided tree by Gitea will verify GPG commit signatures in the provided tree by
checking if the commits are signed by a key within the Gitea database, checking if the commits are signed by a key within the gitea database,
or if the commit matches the default key for Git. or if the commit matches the default key for git.
Keys are not checked to determine if they have expired or revoked. Keys are not checked to determine if they have expired or revoked.
Keys are also not checked with keyservers. Keys are also not checked with keyservers.
@@ -33,8 +33,8 @@ 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 Please note: The signer of a commit does not have to be an author or
committer of a commit. committer of a commit.
This functionality requires Git >= 1.7.9 but for full functionality This functionality requires git >= 1.7.9 but for full functionality
this requires Git >= 2.0.0. this requires git >= 2.0.0.
## Automatic Signing ## Automatic Signing
@@ -54,7 +54,7 @@ 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` a signing key. Gitea generates all its commits using the server `git`
command at present - and therefore the server `gpg` will be used for command at present - and therefore the server `gpg` will be used for
signing (if configured.) Administrators should review best-practices signing (if configured.) Administrators should review best-practices
for GPG - in particular it is probably advisable to only install a for gpg - in particular it is probably advisable to only install a
signing secret subkey without the master signing and certifying secret signing secret subkey without the master signing and certifying secret
key. key.
@@ -93,7 +93,7 @@ The `default` option will interrogate `git config` for
`commit.gpgsign` option - if this is set, then it will use the results `commit.gpgsign` option - if this is set, then it will use the results
of the `user.signingkey`, `user.name` and `user.email` as appropriate. of the `user.signingkey`, `user.name` and `user.email` as appropriate.
Please note: by adjusting Git's `config` file within Gitea's Please note: by adjusting git's `config` file within Gitea's
repositories, `SIGNING_KEY=default` could be used to provide different repositories, `SIGNING_KEY=default` could be used to provide different
signing keys on a per-repository basis. However, this is clearly not an signing keys on a per-repository basis. However, this is clearly not an
ideal UI and therefore subject to change. ideal UI and therefore subject to change.

View File

@@ -1,13 +0,0 @@
---
date: "2016-12-01T16:00:00+02:00"
title: "开发者"
slug: "developers"
weight: 40
toc: false
draft: false
menu:
sidebar:
name: "开发者"
weight: 50
identifier: "developers"
---

View File

@@ -110,8 +110,8 @@ the `token=` string in a GET request.
API Reference guide is auto-generated by swagger and available on: API Reference guide is auto-generated by swagger and available on:
`https://gitea.your.host/api/swagger` `https://gitea.your.host/api/swagger`
or on the or on
[Gitea demo instance](https://try.gitea.io/api/swagger) [gitea demo instance](https://try.gitea.io/api/swagger)
The OpenAPI document is at: The OpenAPI document is at:
`https://gitea.your.host/swagger.v1.json` `https://gitea.your.host/swagger.v1.json`

View File

@@ -1,125 +0,0 @@
---
date: "2021-11-01T23:41:00+08:00"
title: "Guidelines for Backend Development"
slug: "guidelines-backend"
weight: 20
toc: false
draft: false
menu:
sidebar:
parent: "developers"
name: "Guidelines for Backend"
weight: 20
identifier: "guidelines-backend"
---
# Guidelines for Backend Development
**Table of Contents**
{{< toc >}}
## Background
Gitea uses Golang as the backend programming language. It uses many third-party packages and also write some itself.
For example, Gitea uses [Chi](https://github.com/go-chi/chi) as basic web framework. [Xorm](https://xorm.io) is an ORM framework that is used to interact with the database.
So it's very important to manage these packages. Please take the below guidelines before you start to write backend code.
## Package Design Guideline
### Packages List
To maintain understandable code and avoid circular dependencies it is important to have a good code structure. The Gitea backend is divided into the following parts:
- `build`: Scripts to help build Gitea.
- `cmd`: All Gitea actual sub commands includes web, doctor, serv, hooks, admin and etc. `web` will start the web service. `serv` and `hooks` will be invoked by Git or OpenSSH. Other sub commands could help to maintain Gitea.
- `integrations`: Integration tests
- `models`: Contains the data structures used by xorm to construct database tables. It also contains functions to query and update the database. Dependencies to other Gitea code should be avoided. You can make exceptions in cases such as logging.
- `models/db`: Basic database operations. All other `models/xxx` packages should depend on this package. The `GetEngine` function should only be invoked from `models/`.
- `models/fixtures`: Sample data used in unit tests and integration tests. One `yml` file means one table which will be loaded into database when beginning the tests.
- `models/migrations`: Stores database migrations between versions. PRs that change a database structure **MUST** also have a migration step.
- `modules`: Different modules to handle specific functionality in Gitea. Work in Progress: Some of them should be moved to `services`, in particular those that depend on models because they rely on the database.
- `modules/setting`: Store all system configurations read from ini files and has been referenced by everywhere. But they should be used as function parameters when possible.
- `modules/git`: Package to interactive with `Git` command line or Gogit package.
- `public`: Compiled 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) must not depend on routers.
- `routers/api` Contains routers for `/api/v1` aims to handle RESTful API requests.
- `routers/install` Could only respond when system is in INSTALL mode (INSTALL_LOCK=false).
- `routers/private` will only be invoked by internal sub commands, especially `serv` and `hooks`.
- `routers/web` will handle HTTP requests from web browsers or Git SMART HTTP protocols.
- `services`: Support functions for common routing operations or command executions. Uses `models` and `modules` to handle the requests.
- `templates`: Golang templates for generating the html output.
### Package Dependencies
Since Golang don't support import cycles, we have to decide the package dependencies carefully. There are some levels between those packages. Below is the ideal package dependencies direction.
`cmd` -> `routers` -> `services` -> `models` -> `modules`
From left to right, left packages could depend on right packages, but right packages MUST not depend on left packages. The sub packages on the same level could depend on according this level's rules.
**NOTICE**
Why do we need database transactions outside of `models`? And how?
Some actions should allow for rollback when database record insertion/update/deletion failed.
So services must be allowed to create a database transaction. Here is some example,
```go
// servcies/repository/repo.go
func CreateXXXX() error {\
ctx, committer, err := db.TxContext()
if err != nil {
return err
}
defer committer.Close()
// do something, if return err, it will rollback automatically when `committer.Close()` is invoked.
if err := issues.UpdateIssue(ctx, repoID); err != nil {
// ...
}
// ......
return committer.Commit()
}
```
You should **not** use `db.GetEngine(ctx)` in `services` directly, but just write a function under `models/`.
If the function will be used in the transaction, just let `context.Context` as the function's first parameter.
```go
// models/issues/issue.go
func UpdateIssue(ctx context.Context, repoID int64) error {
e := db.GetEngine(ctx)
// ......
}
```
### Package Name
For the top level package, use a plural as package name, i.e. `services`, `models`, for sub packages, use singular,
i.e. `servcies/user`, `models/repository`.
### Import Alias
Since there are some packages which use the same package name, it is possible that you find packages like `modules/user`, `models/user`, and `services/user`. When these packages are imported in one Go file, it's difficult to know which package we are using and if it's a variable name or an import name. So, we always recommend to use import aliases. To differ from package variables which are commonly in camelCase, just use **snake_case** for import aliases.
i.e. `import user_service "code.gitea.io/gitea/services/user"`
### Important Gotchas
- Never write `x.Update(exemplar)` without an explicit `WHERE` clause:
- This will cause all rows in the table to be updated with the non-zero values of the exemplar - including IDs.
- You should usually write `x.ID(id).Update(exemplar)`.
- If during a migration you are inserting into a table using `x.Insert(exemplar)` where the ID is preset:
- You will need to ``SET IDENTITY_INSERT `table` ON`` for the MSSQL variant (the migration will fail otherwise)
- However, you will also need to update the id sequence for postgres - the migration will silently pass here but later insertions will fail:
``SELECT setval('table_name_id_seq', COALESCE((SELECT MAX(id)+1 FROM `table_name`), 1), false)``
### Future Tasks
Currently, we are creating some refactors to do the following things:
- Correct that codes which doesn't follow the rules.
- There are too many files in `models`, so we are moving some of them into a sub package `models/xxx`.
- Some `modules` sub packages should be moved to `services` because they depend on `models`.

View File

@@ -1,129 +0,0 @@
---
date: "2021-10-13T16:00:00+02:00"
title: "Guidelines for Frontend Development"
slug: "guidelines-frontend"
weight: 20
toc: false
draft: false
menu:
sidebar:
parent: "developers"
name: "Guidelines for Frontend"
weight: 20
identifier: "guidelines-frontend"
---
# Guidelines for Frontend Development
**Table of Contents**
{{< toc >}}
## Background
Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue2](https://vuejs.org/v2/guide/) for its frontend.
The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template)
## General Guidelines
We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html) and [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)
### Gitea specific guidelines:
1. Every feature (Fomantic-UI/jQuery module) should be put in separate files/directories.
2. HTML ids and classes should use kebab-case.
3. HTML ids and classes used in JavaScript should be unique for the whole project, and should contain 2-3 feature related keywords. We recommend to use the `js-` prefix for classes that are only used in JavaScript.
4. jQuery events across different features should use their own namespaces.
5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names to overwrite framework styles. We recommend to use the `us-` prefix for user defined styles.
6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}`
7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future).
### Framework Usage
Mixing different frameworks together is highly discouraged. A JavaScript module should follow one major framework and follow the framework's best practice.
Recommended implementations:
* Vue + Native
* Fomantic-UI (jQuery)
* Native only
Discouraged implementations:
* Vue + jQuery
* jQuery + Native
### `async` Functions
Only mark a function as `async` if and only if there are `await` calls
or `Promise` returns inside the function.
It's not recommended to use `async` event listeners, which may lead to problems.
The reason is that the code after await is executed outside the event dispatch.
Reference: https://github.com/github/eslint-plugin-github/blob/main/docs/rules/async-preventdefault.md
If we want to call an `async` function in a non-async context,
it's recommended to use `const _promise = asyncFoo()` to tell readers
that this is done by purpose, we want to call the async function and ignore the Promise.
Some lint rules and IDEs also have warnings if the returned Promise is not handled.
#### DOM Event Listener
```js
el.addEventListener('click', (e) => {
(async () => {
await asyncFoo(); // recommended
// then we shound't do e.preventDefault() after await, no effect
})();
const _promise = asyncFoo(); // recommended
e.preventDefault(); // correct
});
el.addEventListener('async', async (e) => { // not recommended but acceptable
e.preventDefault(); // acceptable
await asyncFoo(); // skip out event dispatch
e.preventDefault(); // WRONG
});
```
#### jQuery Event Listener
```js
$('#el').on('click', (e) => {
(async () => {
await asyncFoo(); // recommended
// then we shound't do e.preventDefault() after await, no effect
})();
const _promise = asyncFoo(); // recommended
e.preventDefault(); // correct
return false; // correct
});
$('#el').on('click', async (e) => { // not recommended but acceptable
e.preventDefault(); // acceptable
return false; // WRONG, jQuery expects the returned value is a boolean, not a Promise
await asyncFoo(); // skip out event dispatch
return false; // WRONG
});
```
### HTML Attributes and `dataset`
We forbid `dataset` usage, its camel-casing behaviour makes it hard to grep for attributes. However there are still some special cases, so the current guideline is:
* For legacy code:
* `$.data()` should be refactored to `$.attr()`.
* `$.data()` can be used to bind some non-string data to elements in rare cases, but it is highly discouraged.
* For new code:
* `node.dataset` should not be used, use `node.getAttribute` instead.
* never bind any user data to a DOM node, use a suitable design pattern to describe the relation between node and data.
### Vue2/Vue3 and JSX
Gitea is using Vue2 now, we plan to upgrade to Vue3. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.

View File

@@ -29,16 +29,17 @@ required to build the JavaScript and CSS files. The minimum supported Node.js
version is {{< min-node-version >}} and the latest LTS version is recommended. version is {{< min-node-version >}} and the latest LTS version is recommended.
**Note**: When executing make tasks that require external tools, like **Note**: When executing make tasks that require external tools, like
`make watch-backend`, Gitea will automatically download and build these as `make misspell-check`, Gitea will automatically download and build these as
necessary. To be able to use these you must have the `"$GOPATH"/bin` directory necessary. To be able to use these you must have the `"$GOPATH"/bin` directory
on the executable path. If you don't add the go bin directory to the on the executable path. If you don't add the go bin directory to the
executable path you will have to manage this yourself. executable path you will have to manage this yourself.
**Note 2**: Go version {{< min-go-version >}} or higher is required. **Note 2**: Go version {{< min-go-version >}} or higher is required; however, it is important
Gitea uses `gofmt` to format source code. However, the results of to note that our continuous integration will check that the formatting of the
`gofmt` can differ by the version of `go`. Therefore it is source code is not changed by `gofmt` using `make fmt-check`. Unfortunately,
the results of `gofmt` can differ by the version of `go`. It is therefore
recommended to install the version of Go that our continuous integration is recommended to install the version of Go that our continuous integration is
running. As of last update, the Go version should be {{< go-version >}}. running. As of last update, it should be Go version {{< go-version >}}.
## Installing Make ## Installing Make
@@ -66,16 +67,13 @@ sudo yum install make
One of these three distributions of Make will run on Windows: One of these three distributions of Make will run on Windows:
- [Single binary build](http://www.equation.com/servlet/equation.cmd?fa=make). Copy somewhere and add to `PATH`. - [Single binary build](http://www.equation.com/servlet/equation.cmd?fa=make). Copy somewhere and add to `PATH`.
- [32-bits version](http://www.equation.com/ftpdir/make/32/make.exe) - [32-bits version](ftp://ftp.equation.com/make/32/make.exe)
- [64-bits version](http://www.equation.com/ftpdir/make/64/make.exe) - [64-bits version](ftp://ftp.equation.com/make/64/make.exe)
- [MinGW-w64](https://www.mingw-w64.org) / [MSYS2](https://www.msys2.org/). - [MinGW](http://www.mingw.org/) includes a build.
- MSYS2 is a collection of tools and libraries providing you with an easy-to-use environment for building, installing and running native Windows software, it includes MinGW-w64. - The binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to `PATH`.
- In MingGW-w64, the binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to `PATH`.
- In MSYS2, you can use `make` directly. See [MSYS2 Porting](https://www.msys2.org/wiki/Porting/).
- To compile Gitea with CGO_ENABLED (eg: SQLite3), you might need to use [tdm-gcc](https://jmeubank.github.io/tdm-gcc/) instead of MSYS2 gcc, because MSYS2 gcc headers lack some Windows-only CRT functions like `_beginthread`.
- [Chocolatey package](https://chocolatey.org/packages/make). Run `choco install make` - [Chocolatey package](https://chocolatey.org/packages/make). Run `choco install make`
**Note**: If you are attempting to build using make with Windows Command Prompt, you may run into issues. The above prompts (Git bash, or MinGW) are recommended, however if you only have command prompt (or potentially PowerShell) you can set environment variables using the [set](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/set_1) command, e.g. `set TAGS=bindata`. **Note**: If you are attempting to build using make with Windows Command Prompt, you may run into issues. The above prompts (git bash, or mingw) are recommended, however if you only have command prompt (or potentially powershell) you can set environment variables using the [set](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/set_1) command, e.g. `set TAGS=bindata`.
## Downloading and cloning the Gitea source code ## Downloading and cloning the Gitea source code
@@ -134,46 +132,42 @@ See `make help` for all available `make` targets. Also see [`.drone.yml`](https:
To run and continuously rebuild when source files change: To run and continuously rebuild when source files change:
```bash ```bash
# for both frontend and backend
make watch make watch
# or: watch frontend files (html/js/css) only
make watch-frontend
# or: watch backend files (go) only
make watch-backend
``` ```
On macOS, watching all backend source files may hit the default open files limit which can be increased via `ulimit -n 12288` for the current shell or in your shell startup file for all future shells. On macOS, watching all backend source files may hit the default open files limit which can be increased via `ulimit -n 12288` for the current shell or in your shell startup file for all future shells.
### Formatting, code analysis and spell check ### Formatting, code analysis and spell check
Our continuous integration will reject PRs that fail the code linters (including format check, code analysis and spell check). Our continuous integration will reject PRs that are not properly formatted, fail
code analysis or spell check.
You should format your code: You should format your code with `go fmt` using:
```bash ```bash
make fmt make fmt
``` ```
and lint the source code: and can test whether your changes would match the results with:
```bash ```bash
# lint both frontend and backend code make fmt-check # which runs make fmt internally
make lint
# lint only backend code
make lint-backend
``` ```
**Note**: The results of `gofmt` are dependent on the version of `go` present. **Note**: The results of `go fmt` are dependent on the version of `go` present.
You should run the same version of go that is on the continuous integration You should run the same version of go that is on the continuous integration
server as mentioned above. server as mentioned above. `make fmt-check` will only check if your `go` would
format differently - this may be different from the CI server version.
You should run revive, vet and spell-check on the code with:
```bash
make revive vet misspell-check
```
### Working on JS and CSS ### Working on JS and CSS
Frontend development should follow [Guidelines for Frontend Development](./guidelines-frontend.md) Either use the `watch-frontend` target mentioned above or just build once:
To build with frontend resources, either use the `watch-frontend` target mentioned above or just build once:
```bash ```bash
make build && ./gitea make build && ./gitea
@@ -185,13 +179,15 @@ Before committing, make sure the linters pass:
make lint-frontend make lint-frontend
``` ```
Note: When working on frontend code, set `USE_SERVICE_WORKER` to `false` in `app.ini` to prevent undesirable caching of frontend assets.
### Building and adding SVGs ### Building and adding SVGs
SVG icons are built using the `make svg` target which compiles the icon sources defined in `build/generate-svg.js` into the output directory `public/img/svg`. Custom icons can be added in the `web_src/svg` directory. SVG icons are built using the `make svg` target which compiles the icon sources defined in `build/generate-svg.js` into the output directory `public/img/svg`. Custom icons can be added in the `web_src/svg` directory.
### Building the Logo ### Building the Logo
The PNG and SVG versions of the Gitea logo are built from a single SVG source file `assets/logo.svg` using the `TAGS="gitea" make generate-images` target. To run it, Node.js and npm must be available. The PNG and SVG versions of the gitea logo are built from a single SVG source file `assets/logo.svg` using the `TAGS="gitea" make generate-images` target. To run it, Node.js and npm must be available.
The same process can also be used to generate custom logo PNGs from a SVG source file by updating `assets/logo.svg` and running `make generate-images`. Omitting the `gitea` tag will update only the user-designated logo files. The same process can also be used to generate custom logo PNGs from a SVG source file by updating `assets/logo.svg` and running `make generate-images`. Omitting the `gitea` tag will update only the user-designated logo files.
@@ -259,24 +255,17 @@ in `models/migrations/`. You can ensure that your migrations work for the main
database types using: database types using:
```bash ```bash
make test-sqlite-migration # with SQLite switched for the appropriate database make test-sqlite-migration # with sqlite switched for the appropriate database
``` ```
## Testing ## Testing
There are two types of test run by Gitea: Unit tests and Integration Tests. There are two types of test run by Gitea: Unit tests and Integration Tests.
### Unit Tests
Unit tests are covered by `*_test.go` in `go test` system.
You can set the environment variable `GITEA_UNIT_TESTS_LOG_SQL=1` to display all SQL statements when running the tests in verbose mode (i.e. when `GOTESTFLAGS=-v` is set).
```bash ```bash
TAGS="bindata sqlite sqlite_unlock_notify" make test # Runs the unit tests TAGS="bindata sqlite sqlite_unlock_notify" make test # Runs the unit tests
``` ```
### Integration Tests
Unit tests will not and cannot completely test Gitea alone. Therefore, we Unit tests will not and cannot completely test Gitea alone. Therefore, we
have written integration tests; however, these are database dependent. have written integration tests; however, these are database dependent.
@@ -284,16 +273,14 @@ have written integration tests; however, these are database dependent.
TAGS="bindata sqlite sqlite_unlock_notify" make build test-sqlite TAGS="bindata sqlite sqlite_unlock_notify" make build test-sqlite
``` ```
will run the integration tests in an SQLite environment. Integration tests will run the integration tests in an sqlite environment. Integration tests
require `git lfs` to be installed. Other database tests are available but require `git lfs` to be installed. Other database tests are available but
may need adjustment to the local environment. may need adjustment to the local environment.
Take a look at [`integrations/README.md`](https://github.com/go-gitea/gitea/blob/main/integrations/README.md) Look at
[`integrations/README.md`](https://github.com/go-gitea/gitea/blob/main/integrations/README.md)
for more information and how to run a single test. for more information and how to run a single test.
### Testing for a PR
Our continuous integration will test the code passes its unit tests and that Our continuous integration will test the code passes its unit tests and that
all supported databases will pass integration test in a Docker environment. all supported databases will pass integration test in a Docker environment.
Migration from several recent versions of Gitea will also be tested. Migration from several recent versions of Gitea will also be tested.
@@ -312,7 +299,7 @@ make trans-copy clean build
``` ```
You will require a copy of [Hugo](https://gohugo.io/) to run this task. Please You will require a copy of [Hugo](https://gohugo.io/) to run this task. Please
note: this may generate a number of untracked Git objects, which will need to note: this may generate a number of untracked git objects, which will need to
be cleaned up. be cleaned up.
## Visual Studio Code ## Visual Studio Code
@@ -322,19 +309,6 @@ Visual Studio Code. Look at
[`contrib/ide/README.md`](https://github.com/go-gitea/gitea/blob/main/contrib/ide/README.md) [`contrib/ide/README.md`](https://github.com/go-gitea/gitea/blob/main/contrib/ide/README.md)
for more information. for more information.
## GoLand
Clicking the `Run Application` arrow on the function `func main()` in `/main.go`
can quickly start a debuggable Gitea instance.
The `Output Directory` in `Run/Debug Configuration` MUST be set to the
gitea project directory (which contains `main.go` and `go.mod`),
otherwise, the started instance's working directory is a GoLand's temporary directory
and prevents Gitea from loading dynamic resources (eg: templates) in a development environment.
To run unit tests with SQLite in GoLand, set `-tags sqlite,sqlite_unlock_notify`
in `Go tool arguments` of `Run/Debug Configuration`.
## Submitting PRs ## Submitting PRs
Once you're happy with your changes, push them up and open a pull request. It Once you're happy with your changes, push them up and open a pull request. It

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