Compare commits

...

76 Commits

Author SHA1 Message Date
John Olheiser
9169b39458 Changelog 1.11.0 (#10204)
* Changelog 1.11.0

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Backport snackport

Co-Authored-By: techknowlogick <matti@mdranta.net>

* Update CHANGELOG.md

Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>

Co-authored-by: techknowlogick <matti@mdranta.net>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
2020-02-10 13:34:30 +02:00
Lauris BH
80eb50655a Fix followers and following tabs in profile (#10202) (#10203) 2020-02-09 21:00:24 +00:00
6543
b16c555541 Fix code-expansion arc-green theme bug (#10180) (#10185)
* fix code-expansion theme bug

* working solution without important

* no new color

* the midle
2020-02-08 00:04:03 +01:00
guillep2k
b5b44364e3 Allow emoji on review head comments (#10159) (#10174)
Co-authored-by: techknowlogick <matti@mdranta.net>

Co-authored-by: techknowlogick <matti@mdranta.net>
Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
2020-02-07 21:39:24 +01:00
guillep2k
6af58022c8 Prevent double waitgroup decrement (#10170) (#10175)
* Prevent double waitgroup decrement

Co-authored-by: zeripath <art27@cantab.net>
2020-02-07 17:12:49 +00:00
guillep2k
e48b460a0a Fix issue/pull link (#10158) (#10173) 2020-02-07 11:51:23 +08:00
John Olheiser
2cd2614eaa Fix push-create SSH bugs (#10145) (#10151)
* Attempt to fix push-create SSH bugs

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Fix binding

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Invalid ctx

Signed-off-by: jolheiser <john.olheiser@gmail.com>
2020-02-05 15:50:06 +01:00
6543
0129e76ef5 Prevent DeleteUser API abuse (#10125) (#10128)
* fix & co

* word suggestions from @jolheiser
2020-02-03 19:44:06 +02:00
6543
6896dad675 working part of #9998 (#10114) (#10115)
Co-authored-by: zeripath <art27@cantab.net>

Co-authored-by: zeripath <art27@cantab.net>
2020-02-03 11:19:04 +08:00
zeripath
1ed4323005 Add button to revert SimpleMDE to plain textarea (#10099) (#10102) 2020-02-01 22:24:58 +02:00
Lunny Xiao
049af0d3d0 Fix branch page pull request title and link error (#10092) (#10097)
* Fix branch page pull request title and link error (#10092)
2020-02-01 15:14:56 +00:00
6543
f5727d83dd [BugFix] [API] Pull.API.Convert: Only try to get HeadBranch if HeadRepo exist (#10029) (#10088) 2020-01-31 20:49:45 -05:00
Lauris BH
912ce27421 Update topics repo count when deleting repository (#10081) 2020-01-31 08:04:49 +00:00
6543
b3549bb5ec [UI] Show pull icon on pull (#10061) (#10062) 2020-01-29 20:40:43 +00:00
Lunny Xiao
491cbeca67 Fix milestone API state parameter unhandled (#10049) (#10052)
* Fix milestone API state parameter unhandled

* Fix test
2020-01-29 18:01:44 +02:00
zeripath
895d92ffe5 Ensure that feeds are appropriately restricted (#10018) (#10019)
* Ensure that feeds are appropriately restricted

* Placate golangci-lint
2020-01-28 23:54:09 +02:00
zeripath
4b11f967bd PRs: Move to use a temporary repo for pushing new prs (#10009) (#10042)
* Move to use a temporary repo for pushing new prs
2020-01-28 18:46:59 +00:00
Lunny Xiao
1e73dd2446 Fix wiki raw view on sub path (#10002) (#10040)
* Fix wiki raw view on sub path

* Add test for subpath wiki raw file

* Fix bug
2020-01-28 15:10:25 +00:00
6543
315026c2c5 trim whitespace of MilestoneName at creation/rename (#10017) (#10034) 2020-01-28 16:52:24 +08:00
Lunny Xiao
16dfd9ffbe Sanitize credentials in mirror form (#9975) (#9991) 2020-01-26 08:16:53 +00:00
Lunny Xiao
16f7b43903 Fix pull view when head repository or head branch missed and close related pull requests when delete head repository or head branch (#9927) (#9974)
* fix pull view when head repository or head branch missed and close related pull requests when delete branch

* fix pull view broken when head repository deleted

* close pull requests when head repositories deleted

* Add tests for broken pull request head repository or branch

* fix typo

* ignore special error when close pull request

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

Co-authored-by: Lauris BH <lauris@nix.lv>
2020-01-25 17:39:53 +08:00
techknowlogick
043febdbc9 Switch to use -f instead of -F for sendmail (#9961) (#9970)
Fix #9385

Co-authored-by: zeripath <art27@cantab.net>
2020-01-24 20:45:53 -05:00
guillep2k
60f91d56f0 Fix check for push on default branch (#9963)
Co-authored-by: techknowlogick <matti@mdranta.net>
2020-01-24 19:56:30 -05:00
guillep2k
16fc15ae6a Fix file rename/copy not supported by indexer (#9967) 2020-01-24 18:25:00 -05:00
techknowlogick
ef8f6d99f1 Fix regression with tag test running (#9941) 2020-01-22 15:49:08 -05:00
John Olheiser
4b688135f9 Changelog 1.11.0-rc2 (#9853)
Signed-off-by: jolheiser <john.olheiser@gmail.com>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2020-01-22 14:56:55 -05:00
John Olheiser
e24861a546 Don't convert ellipsis in markdown (#9905) (#9937)
* Don't convert ellipsis

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Formatting

Co-Authored-By: zeripath <art27@cantab.net>

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
Co-authored-by: zeripath <art27@cantab.net>

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
Co-authored-by: zeripath <art27@cantab.net>
2020-01-22 16:24:04 +00:00
6543
128cc34344 Fixed repo link in generated comment for cross repository dependency (#9863) (#9935)
* fixed link to issue in issue comments after adding/removing a dependency, before links assumed the issue was in the same repository. also changed the format of the displayed issue since the issue will not necessarily be in the same repo

* based on pr comments, changed to use HTMLURL instead of piecing together the issue url, and added an if statement around the issue link display as a nil protection

* only showing repo name in dependency comment if the issue is from another repo

Co-authored-by: Brad Albright <32200834+bhalbright@users.noreply.github.com>
Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
2020-01-22 12:54:40 +02:00
Lauris BH
f82a805478 Check if diff actually contains sections when rendering (#9926) (#9933) 2020-01-22 08:02:57 +00:00
Lunny Xiao
0dced15c1a Fix wrong hint when status checking is running on pull request view (#9886) (#9928)
* Fix wrong hint when status checking is running on pull request view

* fix lint

* fix test

* fix test

* fix wrong tmpl

* fix import

* rename function name
2020-01-22 08:06:11 +02:00
John Olheiser
db9342c854 Fix RocketChat (#9908) (#9921)
* Fix RocketChat??

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Don't send attachment for repo create/delete

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Make fmt

Signed-off-by: jolheiser <john.olheiser@gmail.com>

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

Co-authored-by: Lauris BH <lauris@nix.lv>
2020-01-21 17:24:18 -05:00
zeripath
79c1d48532 Do not try to recreate ldap user if they are already created (#9900) (#9919)
* Do not try to recreate ldap user if they are already created

* just remove autoregister

Co-authored-by: techknowlogick <matti@mdranta.net>

Co-authored-by: techknowlogick <matti@mdranta.net>
2020-01-21 21:17:00 +01:00
zeripath
05b9864086 Update queue_redis.go (#9911) 2020-01-21 20:02:25 +08:00
zeripath
ff508c9c9b Add option to prevent LDAP from deactivating everything on empty search (#9879) (#9896)
* Add option to prevent LDAP from deactivating everything on empty search

* Update options/locale/locale_en-US.ini

Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2020-01-20 21:18:23 +02:00
Lunny Xiao
f96c1a2c79 Fix wrong permissions check when issues/prs shared operations (#9885) (#9889)
* Fix wrong permissions check when issues/prs shared operations

* move redirect to the last of the function

* fix swagger

Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Lauris BH <lauris@nix.lv>
2020-01-20 17:59:33 +02:00
6543
ce756ee89f Check user != nil before checking values (#9881) (#9883)
* Check user != nil before checking values

* Handle autoAdmin

Co-authored-by: zeripath <art27@cantab.net>
2020-01-19 22:01:39 -05:00
zeripath
f2e9d4b851 Allow hyphen in language name (#9873) (#9880)
Co-authored-by: techknowlogick <matti@mdranta.net>
2020-01-19 19:23:35 -05:00
zeripath
e878d743f4 Ensure that 2fa is checked on reset-password (#9857) (#9876)
* Ensure that 2fa is checked on reset-password

* Apply suggestions from code review

Co-Authored-By: Lauris BH <lauris@nix.lv>

* Properly manage scratch_code regeneration

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

Co-authored-by: Lauris BH <lauris@nix.lv>
2020-01-19 23:21:21 +00:00
6543
3fa14d89a2 [Backport] CI optimisation & add github token env var (#9875)
* ci: use docker image for golangci-lint (#9737)

* ci: re-ordering Drone CI for optimizing time (#9719)

* ci: try re-ordering for optimizing time

* ci: try re-ordering for optimizing time

* ci: try re-ordering for optimizing time

* ci: try re-ordering for optimizing time

* ci: try re-ordering for optimizing time

* ci: try re-ordering for optimizing time

* ci: try offloading mysql8 to arm64

* Revert "ci: try offloading mysql8 to arm64"

This reverts commit c60de5db1c.

* ci: try offloading pgsql to arm64

* ci: activate ldap on arm64

* ci: test mysql8 in place pgsql arm64

* chore: clean un-needed move

* typo

* ci: revert runnning mysql on arm64

* ci: run compliance on arm

* chore: limit change

* chore: readd maybe need for release fetch-tags

* ci: remove docker-linux-amd64-dry-run

* ci: remove docker-linux-amd64-dry-run

* Revert "ci: remove docker-linux-amd64-dry-run"

This reverts commit 0715f65b11.

Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>

* ci: use new mssql image (#9720)

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>

* ci: run notify on arm64 (#9762)

* ci: run notify on arm64

Free one jobs on amrd64

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

Based on: https://github.com/appleboy/drone-discord/blob/master/.drone.yml#L339

* improve trigger

Co-authored-by: techknowlogick <matti@mdranta.net>

* ci: move some integration tests on arm64 (#9747)

* tests: configure github remaining limit + read token (#9800)

* ci: configure remaining github limmit

* prepend with github since package is common to all migrations

* add RefreshRate

* Update github.go

* add missing space

* go fmt

* Read env variable GITHUB_READ_TOKEN for token

* Update .drone.yml

* ci: simplify tag/release by always running coverage (#9774)

* ci: simplify tag/release by always running coverage

* use mod and vendor for unit test coverage

* remove not needed lfs for unit test

* use arm drone agent for docs (#9776)

* run translations pipeline on arm server (#9865)

* add git-check to Makefile

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: techknowlogick <matti@mdranta.net>
2020-01-19 23:21:54 +01:00
zeripath
bcb722daec Make CertFile and KeyFile relative to CustomPath (#9868) (#9874)
* Make CertFile and KeyFile relative to CustomPath

The current code will absolute CertFile and KeyFile against the current working directory. This is quite unexpected for users. This code makes relative paths absolute against the CustomPath.

Fix #4196

* Improve error reporting when reading certificates

* Apply suggestions from code review

Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>

Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>

Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
2020-01-19 19:59:30 +00:00
Lunny Xiao
8add1dfacc Fix issues/pulls dependencies problems (#9842) (#9864)
* Fix issues/pulls dependencies problems

* fix swagger and api param name

* fix js
2020-01-19 12:56:57 -05:00
David Svantesson
aa6ed1b7c1 Explicitly refer to PR in squash-merge commit message in case of external tracker (#9844) (#9855)
* Explicitly refer to PR in squash-merge commit message in case of external tracker

* documentation

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

Co-authored-by: zeripath <art27@cantab.net>
2020-01-18 22:28:33 +08:00
6543
95cb921097 fix (#9837) 2020-01-17 23:31:46 -05:00
6543
6730df9e8c Changelog 1.10.3 (#9832) (#9849) 2020-01-17 17:02:30 -05:00
Moritz
b577500a54 Fix markdown anchor links (#9673) (#9840) 2020-01-17 11:49:50 -05:00
Lunny Xiao
fe46185407 Fix download file wrong content-type (#9825) (#9834)
* Fix download file wrong content-type

* change the error text to be more precise

* fix test

Co-authored-by: Lauris BH <lauris@nix.lv>
2020-01-17 15:11:20 +01:00
Lunny Xiao
69a2a29c33 Fix wrong identify poster on a migrated pull request when submi… (#9827) (#9830) 2020-01-17 13:38:11 +01:00
Lunny Xiao
f766719895 fix dump non-exist log directory (#9818) (#9819) 2020-01-17 13:02:41 +08:00
Lunny Xiao
e2ddc42377 Fix compare (#9808) (#9814)
Co-authored-by: techknowlogick <matti@mdranta.net>

Co-authored-by: techknowlogick <matti@mdranta.net>
2020-01-17 10:08:28 +08:00
John Olheiser
3521177a34 Fix push-to-create (#9772) (#9797)
* Fix push-to-create

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Check URL path and service

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Send dummy payload on receive-pack GET

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* The space was actually a NUL byte

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Use real bare repo instead of manufactured payload

Signed-off-by: jolheiser <john.olheiser@gmail.com>

Co-authored-by: zeripath <art27@cantab.net>
2020-01-16 07:40:37 +02:00
Lunny Xiao
c8bb0ecf52 Fix missing msteam webhook on organization (#9781) (#9794) 2020-01-16 03:09:47 +00:00
zeripath
dbe6136348 Fix missing unlock in uniquequeue (#9791) 2020-01-16 01:09:31 +01:00
6543
6d1f7e90cf Fix (#9761) Korean locales (#9780)
* backport korean 20-20-01-15 | fix #9761

* update state 14:43:10 UTC
2020-01-15 11:28:44 -05:00
David Svantesson
42663a687c Fix add team on collaborator page when same name as organization (#9778) 2020-01-15 14:18:18 +01:00
6543
73c90c26d4 Backport Locales [2020-01-14] (#9773)
* backport state of 2020-01-14

* Apply suggestions from code review

Co-Authored-By: 6543 <6543@obermui.de>

Co-authored-by: zeripath <art27@cantab.net>
2020-01-15 07:03:38 +00:00
John Olheiser
c579ad92b5 Fix SimpleMDE quote reply (#9757) (#9768)
Signed-off-by: jolheiser <john.olheiser@gmail.com>

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

Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
2020-01-15 03:23:55 +01:00
6543
602c5da953 Fix #9752 (#9769) (#9775)
Co-authored-by: zeripath <art27@cantab.net>
2020-01-15 01:41:28 +01:00
6543
1980e59ac2 Fix milestones page (#9771)
Signed-off-by: jolheiser <john.olheiser@gmail.com>

Co-authored-by: John Olheiser <42128690+jolheiser@users.noreply.github.com>
2020-01-14 23:33:12 +01:00
Lunny Xiao
28508792ba Fix missing updated time on migrated issues and comments (#9744) (#9764)
* Fix missing updated time on migrated issues and comments

* Fix testing and missing updated on migrating pullrequest

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
2020-01-14 17:55:03 +01:00
silverwind
3e23dad075 fix webpack polyfills (#9735) (#9738)
webpack polyfills did not work because useBuiltIns: 'entry' expects a
explicit core-js import. Changed it to 'usage' which does not require
these explicit imports and polyfills based on browserslist.

As a result, the built index.js now went from 128kB to 192kB.

Ref: https://babeljs.io/docs/en/babel-preset-env#usebuiltins
2020-01-12 17:43:16 -05:00
zeripath
b13b9d3dbd Move Errored PRs out of StatusChecking (#9675) (#9726)
* Move Errored PRs out of StatusChecking (#9675)

* Set Errored PRs out of StatusChecking

* Ensure that api status is correctly set too

* Update models/pull.go

Co-Authored-By: John Olheiser <42128690+jolheiser@users.noreply.github.com>

Co-authored-by: John Olheiser <42128690+jolheiser@users.noreply.github.com>

* Update services/pull/check.go

Co-authored-by: John Olheiser <42128690+jolheiser@users.noreply.github.com>
2020-01-12 20:52:40 +01:00
zeripath
4072f28e60 Make hook status printing configurable with delay (#9641) (#9725)
* Delay printing hook statuses until after 1 second

* Move to a 5s delay, wrapped writer structure and add config

* Update cmd/hook.go

* Apply suggestions from code review

* Update cmd/hook.go

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
2020-01-12 18:02:36 +00:00
6543
dbeef6bb02 [BugFix] [API] ​/repos​/issues​/search (#9698) (#9724)
* fix

* fix options

* add TEST

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
2020-01-12 10:20:49 +00:00
silverwind
fec35440db silence fomantic error regarding tabs (#9713) (#9718)
Fomantic expects all tabs to have a target element with content as
defined by the data-tab attribute. All our usage of the tab module seems
to use <a> element tabs that link to new pages so these content elements
are never present and fomantic complains about that in the console with
an "Activated tab cannot be found" error. This silences that error.
2020-01-11 23:20:33 -05:00
zeripath
f8ea50cc7a Remove unused lock (#9710) 2020-01-11 19:06:39 +00:00
zeripath
0e53a16cca Missed q.lock.Unlock() will cause panic (#9706) 2020-01-11 17:05:24 +00:00
zeripath
7eaba6ba8a Never allow an empty password to validate (#9682) (#9683)
* Restore IsPasswordSet previous value

* Update models/user.go

Co-authored-by: Lauris BH <lauris@nix.lv>
2020-01-11 16:27:03 +02:00
guillep2k
ff16099c6d Don't attempt to close issue if already closed (#9699) 2020-01-11 01:42:11 -05:00
John Olheiser
a516a7ba0f Load milestone in API PR list (#9671) (#9700) 2020-01-10 22:58:03 -05:00
silverwind
11bce6fd3d eliminate horizontal scroll caused by footer (#9674)
Co-authored-by: zeripath <art27@cantab.net>
2020-01-10 08:45:59 +08:00
techknowlogick
3fb906dc02 remove google font call (#9668) (#9681) 2020-01-09 16:40:57 -05:00
zeripath
3a00a690c9 Prevent redirect to Host (#9678) (#9679) 2020-01-09 16:37:37 -05:00
John Olheiser
a2b7cc1bb1 Fix nil reference in repo generation (#9660) (#9666)
* Fix nil reference

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Tighten

Signed-off-by: jolheiser <john.olheiser@gmail.com>
2020-01-09 16:50:21 +00:00
John Olheiser
04a77b1f42 Add HTML URL to API Issues (#9654) (#9661)
* Add HTML URL to API Issues

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Swagger

Signed-off-by: jolheiser <john.olheiser@gmail.com>

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

Co-authored-by: Lauris BH <lauris@nix.lv>
2020-01-09 08:07:21 +02:00
John Olheiser
f523372d07 Add PR review webhook to Telegram (#9653) (#9655)
Signed-off-by: jolheiser <john.olheiser@gmail.com>

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
2020-01-08 21:42:28 +02:00
6543
e39c238ef4 fix #9648 (#9652) 2020-01-08 17:32:25 +01:00
141 changed files with 2193 additions and 836 deletions

View File

@@ -1,44 +1,57 @@
# The full repository name
repo: go-gitea/gitea
# Service type (gitea or github)
service: github
# Base URL for Gitea instance if using gitea service type (optional)
# Default: https://gitea.com
base-url:
# Changelog groups and which labeled PRs to add to each group
groups:
-
-
name: BREAKING
labels:
- kind/breaking
-
-
name: FEATURE
labels:
- kind/feature
-
name: SECURITY
labels:
- kind/security
-
name: BUGFIXES
labels:
- kind/bug
-
-
name: ENHANCEMENT
labels:
- kind/enhancement
- kind/refactor
- kind/ui
-
name: SECURITY
labels:
- kind/security
-
name: TESTING
labels:
- kind/testing
-
-
name: TRANSLATION
labels:
- kind/translation
-
-
name: BUILD
labels:
- kind/build
- kind/lint
-
-
name: DOCS
labels:
- kind/docs
-
-
name: MISC
default: true
default: true
# regex indicating which labels to skip for the changelog
skip-labels: skip-changelog|backport\/.+

View File

@@ -1,6 +1,61 @@
---
kind: pipeline
name: testing
name: compliance
platform:
os: linux
arch: arm64
workspace:
base: /go
path: src/code.gitea.io/gitea
steps:
- name: pre-build
pull: always
image: node:10 # this step is kept at the lowest version of node that we support
commands:
- make css
- make js
- name: build-without-gcc
pull: always
image: golang:1.11 # this step is kept as the lowest version of golang that we support
environment:
GO111MODULE: on
GOPROXY: off
commands:
- go build -mod=vendor -o gitea_no_gcc # test if build succeeds without the sqlite tag
- name: build-linux-386
pull: always
image: golang:1.13
environment:
GO111MODULE: on
GOPROXY: off
GOOS: linux
GOARCH: 386
commands:
- go build -mod=vendor -o gitea_linux_386 # test if compatible with 32 bit
- name: check
pull: always
image: golang:1.13
commands:
- make clean
- make golangci-lint
- make revive
- make swagger-check
- make swagger-validate
- make test-vendor
environment:
GOPROXY: https://goproxy.cn # proxy.golang.org is blocked in China, this proxy is not
GOSUMDB: sum.golang.org
TAGS: bindata sqlite sqlite_unlock_notify
---
kind: pipeline
name: testing-amd64
platform:
os: linux
@@ -25,15 +80,9 @@ services:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: testgitea
- name: pgsql
pull: default
image: postgres:9.5
environment:
POSTGRES_DB: test
- name: mssql
pull: default
image: microsoft/mssql-server-linux:latest
image: mcr.microsoft.com/mssql/server:latest
environment:
ACCEPT_EULA: Y
MSSQL_PID: Standard
@@ -54,52 +103,23 @@ steps:
exclude:
- pull_request
- name: pre-build
pull: always
image: node:10 # this step is kept at the lowest version of node that we support
commands:
- make css
- make js
- name: build-without-gcc
pull: always
image: golang:1.11 # this step is kept as the lowest version of golang that we support
environment:
GO111MODULE: on
GOPROXY: off
commands:
- curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt -y install nodejs
- go build -mod=vendor -o gitea_no_gcc # test if build succeeds without the sqlite tag
- name: build-linux-386
pull: always
image: golang:1.13
environment:
GO111MODULE: on
GOPROXY: off
GOOS: linux
GOARCH: 386
commands:
- curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt -y install nodejs
- go build -mod=vendor -o gitea_linux_386 # test if compatible with 32 bit
- name: build
pull: always
image: golang:1.13
commands:
- curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt -y install nodejs
- make clean
- make golangci-lint
- make revive
- make swagger-check
- make swagger-validate
- make test-vendor
- make build
environment:
GOPROXY: https://goproxy.cn # proxy.golang.org is blocked in China, this proxy is not
GOSUMDB: sum.golang.org
TAGS: bindata sqlite sqlite_unlock_notify
- name: tag-pre-condition
pull: always
image: alpine/git
commands:
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
- name: unit-test
pull: always
image: golang:1.13
@@ -108,70 +128,8 @@ steps:
environment:
GOPROXY: off
TAGS: bindata sqlite sqlite_unlock_notify
depends_on:
- build
when:
branch:
- master
event:
- push
- pull_request
- name: release-test
pull: always
image: golang:1.13
commands:
- make test
environment:
GOPROXY: off
TAGS: bindata sqlite sqlite_unlock_notify
depends_on:
- build
when:
branch:
- "release/*"
event:
- push
- pull_request
- name: tag-pre-condition
pull: always
image: alpine/git
commands:
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
depends_on:
- build
when:
event:
- tag
- name: tag-test
pull: always
image: golang:1.13
commands:
- make test
environment:
GOPROXY: off
TAGS: bindata
depends_on:
- tag-pre-condition
when:
event:
- tag
- name: test-sqlite
pull: always
image: golang:1.13
commands:
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
- apt-get install -y git-lfs
- timeout -s ABRT 20m make test-sqlite-migration
- timeout -s ABRT 20m make test-sqlite
environment:
GOPROXY: off
TAGS: bindata
depends_on:
- build
GITHUB_READ_TOKEN:
from_secret: github_read_token
- name: test-mysql
pull: always
@@ -187,30 +145,6 @@ steps:
TEST_LDAP: 1
depends_on:
- build
when:
branch:
- master
event:
- push
- pull_request
- name: tag-test-mysql
pull: always
image: golang:1.13
commands:
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
- apt-get install -y git-lfs
- timeout -s ABRT 20m make test-mysql-migration
- timeout -s ABRT 20m make test-mysql
environment:
GOPROXY: off
TAGS: bindata
TEST_LDAP: 1
depends_on:
- build
when:
event:
- tag
- name: test-mysql8
pull: always
@@ -227,21 +161,6 @@ steps:
depends_on:
- build
- name: test-pgsql
pull: always
image: golang:1.13
commands:
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
- apt-get install -y git-lfs
- timeout -s ABRT 20m make test-pgsql-migration
- timeout -s ABRT 20m make test-pgsql
environment:
GOPROXY: off
TAGS: bindata
TEST_LDAP: 1
depends_on:
- build
- name: test-mssql
pull: always
image: golang:1.13
@@ -293,13 +212,89 @@ steps:
- push
- pull_request
---
kind: pipeline
name: testing-arm64
platform:
os: linux
arch: arm64
workspace:
base: /go
path: src/code.gitea.io/gitea
services:
- name: pgsql
pull: default
image: postgres:9.5
environment:
POSTGRES_DB: test
- name: ldap
pull: default
image: gitea/test-openldap:latest
steps:
- name: fetch-tags
pull: default
image: docker:git
commands:
- git fetch --tags --force
when:
event:
exclude:
- pull_request
- name: build
pull: always
image: golang:1.13
commands:
- curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt -y install nodejs
- make build
environment:
GOPROXY: https://goproxy.cn # proxy.golang.org is blocked in China, this proxy is not
GOSUMDB: sum.golang.org
TAGS: bindata sqlite sqlite_unlock_notify
- name: test-sqlite
pull: always
image: golang:1.13
commands:
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
- apt-get install -y git-lfs
- timeout -s ABRT 20m make test-sqlite-migration
- timeout -s ABRT 20m make test-sqlite
environment:
GOPROXY: off
TAGS: bindata
depends_on:
- build
- name: test-pgsql
pull: always
image: golang:1.13
commands:
- "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash"
- apt-get install -y git-lfs
- timeout -s ABRT 20m make test-pgsql-migration
- timeout -s ABRT 20m make test-pgsql
environment:
GOPROXY: off
TAGS: bindata
TEST_LDAP: 1
depends_on:
- build
---
kind: pipeline
name: translations
platform:
os: linux
arch: amd64
arch: arm64
workspace:
base: /go
@@ -378,7 +373,8 @@ trigger:
- push
depends_on:
- testing
- testing-amd64
- testing-arm64
- translations
steps:
@@ -476,7 +472,8 @@ trigger:
- tag
depends_on:
- testing
- testing-arm64
- testing-amd64
steps:
- name: fetch-tags
@@ -545,17 +542,14 @@ name: docs
platform:
os: linux
arch: amd64
workspace:
base: /go
path: src/code.gitea.io/gitea
arch: arm64
steps:
- name: build-docs
pull: always
image: webhippie/hugo:latest
image: plugins/hugo:latest
commands:
- apk add --no-cache make bash curl
- cd docs
- make trans-copy
- make clean
@@ -563,7 +557,7 @@ steps:
- name: publish-docs
pull: always
image: lucap/drone-netlify:latest
image: techknowlogick/drone-netlify:latest
settings:
path: docs/public/
site_id: d2260bae-7861-4c02-8646-8f6440b12672
@@ -578,7 +572,7 @@ steps:
---
kind: pipeline
name: docker-linux-amd64
name: docker-linux-amd64-release
platform:
os: linux
@@ -589,13 +583,13 @@ workspace:
path: src/code.gitea.io/gitea
depends_on:
- testing
- testing-amd64
- testing-arm64
trigger:
ref:
- refs/heads/master
- "refs/tags/**"
- "refs/pull/**"
steps:
- name: fetch-tags
@@ -603,23 +597,6 @@ steps:
image: docker:git
commands:
- git fetch --tags --force
when:
event:
exclude:
- pull_request
- name: dryrun
pull: always
image: plugins/docker:linux-amd64
settings:
dry_run: true
repo: gitea/gitea
tags: linux-amd64
build_args:
- GOPROXY=off
when:
event:
- pull_request
- name: publish
pull: always
@@ -641,7 +618,7 @@ steps:
---
kind: pipeline
name: docker-linux-arm64
name: docker-linux-arm64-dry-run
platform:
os: linux
@@ -652,25 +629,13 @@ workspace:
path: src/code.gitea.io/gitea
depends_on:
- testing
- compliance
trigger:
ref:
- refs/heads/master
- "refs/tags/**"
- "refs/pull/**"
steps:
- name: fetch-tags
pull: default
image: docker:git
commands:
- git fetch --tags --force
when:
event:
exclude:
- pull_request
- name: dryrun
pull: always
image: plugins/docker:linux-arm64
@@ -684,6 +649,33 @@ steps:
event:
- pull_request
---
kind: pipeline
name: docker-linux-arm64-release
platform:
os: linux
arch: arm64
workspace:
base: /go
path: src/code.gitea.io/gitea
depends_on:
- testing-amd64
- testing-arm64
trigger:
ref:
- refs/heads/master
- "refs/tags/**"
steps:
- name: fetch-tags
pull: default
image: docker:git
commands:
- git fetch --tags --force
- name: publish
pull: always
image: plugins/docker:linux-arm64
@@ -729,45 +721,49 @@ trigger:
- "refs/tags/**"
depends_on:
- docker-linux-amd64
- docker-linux-arm64
- docker-linux-amd64-release
- docker-linux-arm64-release
---
kind: pipeline
name: notify
name: notifications
platform:
os: linux
arch: amd64
workspace:
base: /go
path: src/code.gitea.io/gitea
arch: arm64
clone:
disable: true
when:
trigger:
branch:
- master
- "release/*"
event:
- push
- tag
status:
- success
- failure
depends_on:
- testing
- testing-amd64
- testing-arm64
- translations
- release-version
- release-master
- docker-linux-amd64
- docker-linux-arm64
- docker-linux-amd64-release
- docker-linux-arm64-release
- docker-manifest
- docs
steps:
- name: discord
pull: always
image: appleboy/drone-discord:1.0.0
environment:
DISCORD_WEBHOOK_ID:
image: appleboy/drone-discord:1.2.4
settings:
message: "{{#success build.status}} ✅ Build #{{build.number}} of `{{repo.name}}` succeeded.\n\n📝 Commit by {{commit.author}} on `{{commit.branch}}`:\n``` {{commit.message}} ```\n\n🌐 {{ build.link }} {{else}} ❌ Build #{{build.number}} of `{{repo.name}}` failed.\n\n📝 Commit by {{commit.author}} on `{{commit.branch}}`:\n``` {{commit.message}} ```\n\n🌐 {{ build.link }} {{/success}}\n"
webhook_id:
from_secret: discord_webhook_id
DISCORD_WEBHOOK_TOKEN:
webhook_token:
from_secret: discord_webhook_token

View File

@@ -4,13 +4,22 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.11.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.11.0-rc1) - 2020-01-07
## [1.11.0](https://github.com/go-gitea/gitea/releases/tag/v1.11.0) - 2020-02-10
* BREAKING
* Fix followers and following tabs in profile (#10202) (#10203)
* Make CertFile and KeyFile relative to CustomPath (#9868) (#9874)
* Remove unused endpoints (#9538)
* Prefix all user-generated IDs in markup (#9477)
* Enforce Gitea environment for pushes (#8982)
* Hide some user information via API if user have no enough permission (#8655)
* Hide some user information via API if user have not enough permissions (#8655)
* Move startpage/homepage translation to crowdin (#8596)
* SECURITY
* Never allow an empty password to validate (#9682) (#9683)
* Prevent redirect to Host (#9678) (#9679)
* Swagger hide search field (#9554)
* Add "search" to reserved usernames (#9063)
* Switch to fomantic-ui (#9374)
* Only serve attachments when linked to issue/release and if accessible by user (#9340)
* FEATURES
* Webhooks should only show sender if it makes sense (#9601)
* Provide Default messages for merges (#9393)
@@ -44,6 +53,68 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Sign merges, CRUD, Wiki and Repository initialisation with gpg key (#7631)
* Add basic repository lfs management (#7199)
* BUGFIXES
* Fix code-expansion arc-green theme bug (#10180) (#10185)
* Prevent double wait-group decrement (#10170) (#10175)
* Allow emoji on review head comments (#10159) (#10174)
* Fix issue/pull link (#10158) (#10173)
* Fix push-create SSH bugs (#10145) (#10151)
* Prevent DeleteUser API abuse (#10125) (#10128)
* Fix issues/pulls dashboard paging error (#10114) (#10115)
* Add button to revert SimpleMDE to plain textarea (#10099) (#10102)
* Fix branch page pull request title and link error (#10092) (#10097)
* Fix PR API: Only try to get HeadBranch if HeadRepo exist (#10029) (#10088)
* Update topics repo count when deleting repository (#10051) (#10081)
* Show pull icon on pull requests (#10061) (#10062)
* Fix milestone API state parameter unhandled (#10049) (#10052)
* Move to using a temporary repo for pushing new PRs (#10009) (#10042)
* Fix wiki raw view on sub path (#10002) (#10040)
* Ensure that feeds are appropriately restricted (#10018) (#10019)
* Sanitize credentials in mirror form (#9975) (#9991)
* Close related pull requests when deleting head repository or head branch (#9927) (#9974)
* Switch to use -f instead of -F for sendmail (#9961) (#9970)
* Fix file rename/copy not supported by indexer (#9965) (#9967)
* Fix repo indexer not updating upon push (#9957) (#9963)
* Don't convert ellipsis in markdown (#9905) (#9937)
* Fixed repo link in generated comment for cross repository dependency (#9863) (#9935)
* Check if diff actually contains sections when rendering (#9926) (#9933)
* Fix wrong hint when status checking is running on pull request view (#9886) (#9928)
* Fix RocketChat (#9908) (#9921)
* Do not try to recreate ldap user if they are already created (#9900) (#9919)
* Create terminated channel in queue_redis (#9910) (#9911)
* Prevent empty LDAP search result from deactivating all users (#9879) (#9896)
* Fix wrong permissions check when issues/prs shared operations (#9885) (#9889)
* Check user != nil before checking values (#9881) (#9883)
* Allow hyphen in language name (#9873) (#9880)
* Ensure that 2fa is checked on reset-password (#9857) (#9876)
* Fix issues/pulls dependencies problems (#9842) (#9864)
* Fix markdown anchor links (#9673) (#9840)
* Allow assignee on Pull Creation when Issue Unit is deactivated (#9836) (#9837)
* Fix download file wrong content-type (#9825) (#9834)
* Fix wrong poster identity on a migrated pull request when submit review (#9827) (#9830)
* Fix database dump when log directory is missing (#9818) (#9819)
* Fix compare (#9808) (#9814)
* Fix push-to-create (#9772) (#9797)
* Fix missing msteam webhook on organization (#9781) (#9794)
* Fix missing unlock in uniquequeue (#9790) (#9791)
* Fix add team on collaborator page when same name as organization (#9778)
* DeleteRepoFile incorrectly handles Delete to new branch (#9769) (#9775)
* Fix milestones page (#9771)
* Fix SimpleMDE quote reply (#9757) (#9768)
* Fix missing updated time on migrated issues and comments (#9744) (#9764)
* Move Errored PRs out of StatusChecking (#9675) (#9726)
* Make hook status printing configurable with delay (#9641) (#9725)
* Fix /repos/issues/search (#9698) (#9724)
* Silence fomantic error regarding tabs (#9713) (#9718)
* Remove unused lock (#9709) (#9710)
* Remove q.lock.Unlock() in setInternal to prevent panic (#9705) (#9706)
* Load milestone in API PR list (#9671) (#9700)
* Don't attempt to close issue if already closed (#9696) (#9699)
* Remove google font call (#9668) (#9681)
* Eliminate horizontal scroll caused by footer (#9674)
* Fix nil reference in repo generation (#9660) (#9666)
* Add HTML URL to API Issues (#9654) (#9661)
* Add PR review webhook to Telegram (#9653) (#9655)
* Use filepath.IsAbs instead of path.IsAbs (#9651) (#9652)
* Disable remove button on repository teams when have access to all (#9640)
* Clean up old references on branch delete (#9614)
* Hide public repos owned by private orgs (#9609)
@@ -175,6 +246,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Fix migrate mirror 500 bug (#8526)
* Fix password complexity regex for special characters (on master) (#8525)
* ENHANCEMENTS
* Explicitly refer to PR in squash-merge commit message in case of external tracker (#9844) (#9855)
* Add a /user/login landing page option (#9622)
* Some more e-mail notification fixes (#9596)
* Add branch protection option to block merge on requested changes. (#9592)
@@ -291,12 +363,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* wiki - add 'write' 'preview' buttons to wiki edit like in issues (#7241)
* Change target branch for pull request (#6488)
* Display PR commits and diffs using base repo rather than forked (#3648)
* SECURITY
* Swagger hide search field (#9554)
* Add "search" to reserved usernames (#9063)
* Switch to fomantic-ui (#9374)
* Only serve attachments when linked to issue/release and if accessible by user (#9340)
* Hide credentials when submitting migration through API (#9102)
* TESTING
* Add debug option to serv to help debug problems (#9492)
* Fix the intermittent TestGPGGit failures (#9360)
@@ -310,10 +376,12 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Update Github Migration Tests (#8893) (#8938)
* Update heatmap fixtures to restore tests (#8615)
* TRANSLATION
* Fix Korean locales (#9761) (#9780)
* Fix placeholders in the error message (#9060)
* Fix spelling of admin.users.max_repo_creation (#8934)
* Improve german translation of homepage (#8549)
* BUILD
* Fix webpack polyfills (#9735) (#9738)
* Update gitea.com/macaron to 1.4.0 (#9608)
* Upgrade lato fonts to v16. (#9498)
* Update alpine to 3.11 (#9440)
@@ -344,6 +412,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Update the provided gitea.service to mention socket activation (#8531)
* Doc added how to setup email (#8520)
* MISC
* Backport Locales [2020-01-14] (#9773)
* Add translatable Powered by Gitea text in footer (#9600)
* Add contrib/environment-to-ini (#9519)
* Remove unnecessary loading of settings in update hook (#9496)
@@ -384,6 +453,24 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Update CodeMirror to version 5.49.0 (#8381)
* Wiki editor: enable side-by-side button (#7242)
## [1.10.3](https://github.com/go-gitea/gitea/releases/tag/v1.10.3) - 2020-01-17
* SECURITY
* Hide credentials when submitting migration (#9102) (#9704)
* Never allow an empty password to validate (#9682) (#9684)
* Prevent redirect to Host (#9678) (#9680)
* Hide public repos owned by private orgs (#9609) (#9616)
* BUGFIXES
* Allow assignee on Pull Creation when Issue Unit is deactivated (#9836) (#9838)
* Fix download file wrong content-type (#9825) (#9835)
* Fix wrong identify poster on a migrated pull request when submit review (#9827) (#9831)
* Fix dump non-exist log directory (#9818) (#9820)
* Fix compare (#9808) (#9815)
* Fix missing msteam webhook on organization (#9781) (#9795)
* Fix add team on collaborator page when same name as organization (#9783)
* Fix cache problem on dashboard (#9358) (#9703)
* Send tag create and push webhook when release created on UI (#8671) (#9702)
* Branches not at ref commit ID should not be listed as Merged (#9614) (#9639)
## [1.10.2](https://github.com/go-gitea/gitea/releases/tag/v1.10.2) - 2020-01-02
* BUGFIXES
* Allow only specific Columns to be updated on Issue via API (#9539) (#9580)
@@ -1483,13 +1570,13 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* BUGFIXES
* Allow resend of confirmation email when logged in (#6482) (#6487)
## [1.7.5](https://github.com/go-gitea/gitea/releases/tag/v1.7.5) - 2019-03-27
## [1.7.5](https://github.com/go-gitea/gitea/releases/tag/v1.7.5) - 2019-03-27
* BUGFIXES
* Fix unitTypeCode not being used in accessLevelUnit (#6419) (#6423)
* Fix bug where manifest.json was being requested without cookies and continuously creating new sessions (#6372) (#6383)
* Fix ParsePatch function to work with quoted diff --git strings (#6323) (#6332)
## [1.7.4](https://github.com/go-gitea/gitea/releases/tag/v1.7.4) - 2019-03-12
## [1.7.4](https://github.com/go-gitea/gitea/releases/tag/v1.7.4) - 2019-03-12
* SECURITY
* Fix potential XSS vulnerability in repository description. (#6306) (#6308)
* BUGFIXES

View File

@@ -119,6 +119,13 @@ go-check:
exit 1; \
fi
.PHONY: git-check
git-check:
@if git lfs >/dev/null 2>&1 ; then : ; else \
echo "Gitea requires git with lfs support to run tests." ; \
exit 1; \
fi
.PHONY: node-check
node-check:
$(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | grep -Eo '[0-9]+\.?[0-9]+?\.?[0-9]?' | tr '.' ' ');))
@@ -233,7 +240,7 @@ coverage:
.PHONY: unit-test-coverage
unit-test-coverage:
$(GO) test -tags='sqlite sqlite_unlock_notify' -cover -coverprofile coverage.out $(PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
GO111MODULE=on $(GO) test -mod=vendor -tags='sqlite sqlite_unlock_notify' -cover -coverprofile coverage.out $(PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
.PHONY: vendor
vendor:
@@ -376,7 +383,7 @@ integrations.mssql.test: $(GO_SOURCES)
integrations.sqlite.test: $(GO_SOURCES)
GO111MODULE=on $(GO) test -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags 'sqlite sqlite_unlock_notify'
integrations.cover.test: $(GO_SOURCES)
integrations.cover.test: git-check $(GO_SOURCES)
GO111MODULE=on $(GO) test -mod=vendor -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(PACKAGES) | tr ' ' ',') -o integrations.cover.test
.PHONY: migrations.mysql.test

View File

@@ -61,6 +61,10 @@ var (
Name: "admin-filter",
Usage: "An LDAP filter specifying if a user should be given administrator privileges.",
},
cli.BoolFlag{
Name: "allow-deactivate-all",
Usage: "Allow empty search results to deactivate all users.",
},
cli.StringFlag{
Name: "username-attribute",
Usage: "The attribute of the users LDAP record containing the user name.",
@@ -231,6 +235,9 @@ func parseLdapConfig(c *cli.Context, config *models.LDAPConfig) error {
if c.IsSet("admin-filter") {
config.Source.AdminFilter = c.String("admin-filter")
}
if c.IsSet("allow-deactivate-all") {
config.Source.AllowDeactivateAll = c.Bool("allow-deactivate-all")
}
return nil
}

View File

@@ -151,8 +151,10 @@ func runDump(ctx *cli.Context) error {
}
}
if err := z.AddDir("log", setting.LogRootPath); err != nil {
fatal("Failed to include log: %v", err)
if com.IsExist(setting.LogRootPath) {
if err := z.AddDir("log", setting.LogRootPath); err != nil {
fatal("Failed to include log: %v", err)
}
}
if err = z.Close(); err != nil {

View File

@@ -8,10 +8,12 @@ import (
"bufio"
"bytes"
"fmt"
"io"
"net/http"
"os"
"strconv"
"strings"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
@@ -58,6 +60,85 @@ var (
}
)
type delayWriter struct {
internal io.Writer
buf *bytes.Buffer
timer *time.Timer
}
func newDelayWriter(internal io.Writer, delay time.Duration) *delayWriter {
timer := time.NewTimer(delay)
return &delayWriter{
internal: internal,
buf: &bytes.Buffer{},
timer: timer,
}
}
func (d *delayWriter) Write(p []byte) (n int, err error) {
if d.buf != nil {
select {
case <-d.timer.C:
_, err := d.internal.Write(d.buf.Bytes())
if err != nil {
return 0, err
}
d.buf = nil
return d.internal.Write(p)
default:
return d.buf.Write(p)
}
}
return d.internal.Write(p)
}
func (d *delayWriter) WriteString(s string) (n int, err error) {
if d.buf != nil {
select {
case <-d.timer.C:
_, err := d.internal.Write(d.buf.Bytes())
if err != nil {
return 0, err
}
d.buf = nil
return d.internal.Write([]byte(s))
default:
return d.buf.WriteString(s)
}
}
return d.internal.Write([]byte(s))
}
func (d *delayWriter) Close() error {
if d == nil {
return nil
}
stopped := d.timer.Stop()
if stopped {
return nil
}
select {
case <-d.timer.C:
default:
}
if d.buf == nil {
return nil
}
_, err := d.internal.Write(d.buf.Bytes())
d.buf = nil
return err
}
type nilWriter struct{}
func (n *nilWriter) Write(p []byte) (int, error) {
return len(p), nil
}
func (n *nilWriter) WriteString(s string) (int, error) {
return len(s), nil
}
func runHookPreReceive(c *cli.Context) error {
if os.Getenv(models.EnvIsInternal) == "true" {
return nil
@@ -101,6 +182,18 @@ Gitea or set your environment appropriately.`, "")
total := 0
lastline := 0
var out io.Writer
out = &nilWriter{}
if setting.Git.VerbosePush {
if setting.Git.VerbosePushDelay > 0 {
dWriter := newDelayWriter(os.Stdout, setting.Git.VerbosePushDelay)
defer dWriter.Close()
out = dWriter
} else {
out = os.Stdout
}
}
for scanner.Scan() {
// TODO: support news feeds for wiki
if isWiki {
@@ -124,12 +217,10 @@ Gitea or set your environment appropriately.`, "")
newCommitIDs[count] = newCommitID
refFullNames[count] = refFullName
count++
fmt.Fprintf(os.Stdout, "*")
os.Stdout.Sync()
fmt.Fprintf(out, "*")
if count >= hookBatchSize {
fmt.Fprintf(os.Stdout, " Checking %d branches\n", count)
os.Stdout.Sync()
fmt.Fprintf(out, " Checking %d branches\n", count)
hookOptions.OldCommitIDs = oldCommitIDs
hookOptions.NewCommitIDs = newCommitIDs
@@ -147,12 +238,10 @@ Gitea or set your environment appropriately.`, "")
lastline = 0
}
} else {
fmt.Fprintf(os.Stdout, ".")
os.Stdout.Sync()
fmt.Fprintf(out, ".")
}
if lastline >= hookBatchSize {
fmt.Fprintf(os.Stdout, "\n")
os.Stdout.Sync()
fmt.Fprintf(out, "\n")
lastline = 0
}
}
@@ -162,8 +251,7 @@ Gitea or set your environment appropriately.`, "")
hookOptions.NewCommitIDs = newCommitIDs[:count]
hookOptions.RefFullNames = refFullNames[:count]
fmt.Fprintf(os.Stdout, " Checking %d branches\n", count)
os.Stdout.Sync()
fmt.Fprintf(out, " Checking %d branches\n", count)
statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
switch statusCode {
@@ -173,14 +261,11 @@ Gitea or set your environment appropriately.`, "")
fail(msg, "")
}
} else if lastline > 0 {
fmt.Fprintf(os.Stdout, "\n")
os.Stdout.Sync()
fmt.Fprintf(out, "\n")
lastline = 0
}
fmt.Fprintf(os.Stdout, "Checked %d references in total\n", total)
os.Stdout.Sync()
fmt.Fprintf(out, "Checked %d references in total\n", total)
return nil
}
@@ -206,6 +291,19 @@ Gitea or set your environment appropriately.`, "")
}
}
var out io.Writer
var dWriter *delayWriter
out = &nilWriter{}
if setting.Git.VerbosePush {
if setting.Git.VerbosePushDelay > 0 {
dWriter = newDelayWriter(os.Stdout, setting.Git.VerbosePushDelay)
defer dWriter.Close()
out = dWriter
} else {
out = os.Stdout
}
}
// the environment setted on serv command
repoUser := os.Getenv(models.EnvRepoUsername)
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
@@ -241,7 +339,7 @@ Gitea or set your environment appropriately.`, "")
continue
}
fmt.Fprintf(os.Stdout, ".")
fmt.Fprintf(out, ".")
oldCommitIDs[count] = string(fields[0])
newCommitIDs[count] = string(fields[1])
refFullNames[count] = string(fields[2])
@@ -250,16 +348,15 @@ Gitea or set your environment appropriately.`, "")
}
count++
total++
os.Stdout.Sync()
if count >= hookBatchSize {
fmt.Fprintf(os.Stdout, " Processing %d references\n", count)
os.Stdout.Sync()
fmt.Fprintf(out, " Processing %d references\n", count)
hookOptions.OldCommitIDs = oldCommitIDs
hookOptions.NewCommitIDs = newCommitIDs
hookOptions.RefFullNames = refFullNames
resp, err := private.HookPostReceive(repoUser, repoName, hookOptions)
if resp == nil {
_ = dWriter.Close()
hookPrintResults(results)
fail("Internal Server Error", err)
}
@@ -277,9 +374,9 @@ Gitea or set your environment appropriately.`, "")
fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
}
}
fmt.Fprintf(os.Stdout, "Processed %d references in total\n", total)
os.Stdout.Sync()
fmt.Fprintf(out, "Processed %d references in total\n", total)
_ = dWriter.Close()
hookPrintResults(results)
return nil
}
@@ -288,19 +385,18 @@ Gitea or set your environment appropriately.`, "")
hookOptions.NewCommitIDs = newCommitIDs[:count]
hookOptions.RefFullNames = refFullNames[:count]
fmt.Fprintf(os.Stdout, " Processing %d references\n", count)
os.Stdout.Sync()
fmt.Fprintf(out, " Processing %d references\n", count)
resp, err := private.HookPostReceive(repoUser, repoName, hookOptions)
if resp == nil {
_ = dWriter.Close()
hookPrintResults(results)
fail("Internal Server Error", err)
}
wasEmpty = wasEmpty || resp.RepoWasEmpty
results = append(results, resp.Results...)
fmt.Fprintf(os.Stdout, "Processed %d references in total\n", total)
os.Stdout.Sync()
fmt.Fprintf(out, "Processed %d references in total\n", total)
if wasEmpty && masterPushed {
// We need to tell the repo to reset the default branch to master
@@ -309,7 +405,7 @@ Gitea or set your environment appropriately.`, "")
fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
}
}
_ = dWriter.Close()
hookPrintResults(results)
return nil

View File

@@ -12,6 +12,7 @@ import (
"net/url"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"time"
@@ -72,6 +73,7 @@ var (
"git-receive-pack": models.AccessModeWrite,
lfsAuthenticateVerb: models.AccessModeNone,
}
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
)
func fail(userMessage, logMessage string, args ...interface{}) {
@@ -147,6 +149,10 @@ func runServ(c *cli.Context) error {
username := strings.ToLower(rr[0])
reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git"))
if alphaDashDotPattern.MatchString(reponame) {
fail("Invalid repo name", "Invalid repo name: %s", reponame)
}
if setting.EnablePprof || c.Bool("enable-pprof") {
if err := os.MkdirAll(setting.PprofDataPath, os.ModePerm); err != nil {
fail("Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)

View File

@@ -275,8 +275,9 @@ DISABLE_ROUTER_LOG = false
; not forget to export the private key):
; $ openssl pkcs12 -in cert.pfx -out cert.pem -nokeys
; $ openssl pkcs12 -in cert.pfx -out key.pem -nocerts -nodes
CERT_FILE = custom/https/cert.pem
KEY_FILE = custom/https/key.pem
; Paths are relative to CUSTOM_PATH
CERT_FILE = https/cert.pem
KEY_FILE = https/key.pem
; Root directory containing templates and static files.
; default is the path where Gitea is executed
STATIC_ROOT_PATH =

View File

@@ -18,7 +18,7 @@ params:
description: Git with a cup of tea
author: The Gitea Authors
website: https://docs.gitea.io
version: 1.10.2
version: 1.11.0
outputs:
home:

View File

@@ -181,8 +181,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `SSH_LISTEN_PORT`: **%(SSH\_PORT)s**: Port for the built-in SSH server.
- `OFFLINE_MODE`: **false**: Disables use of CDN for static files and Gravatar for profile pictures.
- `DISABLE_ROUTER_LOG`: **false**: Mute printing of the router log.
- `CERT_FILE`: **custom/https/cert.pem**: Cert file path used for HTTPS.
- `KEY_FILE`: **custom/https/key.pem**: Key file path used for HTTPS.
- `CERT_FILE`: **https/cert.pem**: Cert file path used for HTTPS. From 1.11 paths are relative to `CUSTOM_PATH`.
- `KEY_FILE`: **https/key.pem**: Key file path used for HTTPS. From 1.11 paths are relative to `CUSTOM_PATH`.
- `STATIC_ROOT_PATH`: **./**: Upper level of template and static files path.
- `STATIC_CACHE_TIME`: **6h**: Web browser cache time for static resources on `custom/`, `public/` and all uploaded avatars.
- `ENABLE_GZIP`: **false**: Enables application-level GZIP support.
@@ -522,6 +522,8 @@ NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false`
- `MAX_GIT_DIFF_FILES`: **100**: Max number of files shown in diff view.
- `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`. See more on http://git-scm.com/docs/git-gc/
- `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
- `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.
## Git - Timeout settings (`git.timeout`)
- `DEFAUlT`: **360**: Git operations default timeout seconds.

View File

@@ -136,7 +136,8 @@ the `!` marker to identify pull requests. For example:
> This is pull request [!1234](#), and links to a pull request in Gitea.
The `!` and `#` can be used interchangeably for issues and pull request _except_
for this case, where a distinction is required.
for this case, where a distinction is required. If the repository uses external
tracker, commit message for squash merge will use `!` as reference by default.
## Issues and Pull Requests References Summary

View File

@@ -0,0 +1,47 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package integrations
import (
"fmt"
"net/http"
"testing"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
)
func TestAPIIssuesMilestone(t *testing.T) {
defer prepareTestEnv(t)()
milestone := models.AssertExistsAndLoadBean(t, &models.Milestone{ID: 1}).(*models.Milestone)
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: milestone.RepoID}).(*models.Repository)
owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User)
assert.Equal(t, int64(1), int64(milestone.NumIssues))
assert.Equal(t, structs.StateOpen, milestone.State())
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
// update values of issue
milestoneState := "closed"
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%d?token=%s", owner.Name, repo.Name, milestone.ID, token)
req := NewRequestWithJSON(t, "PATCH", urlStr, structs.EditMilestoneOption{
State: &milestoneState,
})
resp := session.MakeRequest(t, req, http.StatusOK)
var apiMilestone structs.Milestone
DecodeJSON(t, resp, &apiMilestone)
assert.EqualValues(t, "closed", apiMilestone.State)
req = NewRequest(t, "GET", urlStr)
resp = session.MakeRequest(t, req, http.StatusOK)
var apiMilestone2 structs.Milestone
DecodeJSON(t, resp, &apiMilestone2)
assert.EqualValues(t, "closed", apiMilestone2.State)
}

View File

@@ -7,6 +7,7 @@ package integrations
import (
"fmt"
"net/http"
"net/url"
"testing"
"code.gitea.io/gitea/models"
@@ -120,3 +121,47 @@ func TestAPIEditIssue(t *testing.T) {
assert.Equal(t, body, issueAfter.Content)
assert.Equal(t, title, issueAfter.Title)
}
func TestAPISearchIssue(t *testing.T) {
defer prepareTestEnv(t)()
session := loginUser(t, "user2")
token := getTokenForLoggedInUser(t, session)
link, _ := url.Parse("/api/v1/repos/issues/search")
req := NewRequest(t, "GET", link.String())
resp := session.MakeRequest(t, req, http.StatusOK)
var apiIssues []*api.Issue
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 8)
query := url.Values{}
query.Add("token", token)
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 8)
query.Add("state", "closed")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 2)
query.Set("state", "all")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 10) //there are more but 10 is page item limit
query.Add("page", "2")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 0)
}

View File

@@ -422,6 +422,9 @@ func doPushCreate(ctx APITestContext, u *url.URL) func(t *testing.T) {
tmpDir, err := ioutil.TempDir("", ctx.Reponame)
assert.NoError(t, err)
_, err = git.NewCommand("clone", u.String()).RunInDir(tmpDir)
assert.Error(t, err)
err = git.InitRepository(tmpDir, false)
assert.NoError(t, err)
@@ -449,6 +452,13 @@ func doPushCreate(ctx APITestContext, u *url.URL) func(t *testing.T) {
_, err = git.NewCommand("remote", "add", "origin", u.String()).RunInDir(tmpDir)
assert.NoError(t, err)
invalidCtx := ctx
invalidCtx.Reponame = fmt.Sprintf("invalid/repo-tmp-push-create-%s", u.Scheme)
u.Path = invalidCtx.GitPath()
_, err = git.NewCommand("remote", "add", "invalid", u.String()).RunInDir(tmpDir)
assert.NoError(t, err)
// Push to create disabled
setting.Repository.EnablePushCreateUser = false
_, err = git.NewCommand("push", "origin", "master").RunInDir(tmpDir)
@@ -456,6 +466,12 @@ func doPushCreate(ctx APITestContext, u *url.URL) func(t *testing.T) {
// Push to create enabled
setting.Repository.EnablePushCreateUser = true
// Invalid repo
_, err = git.NewCommand("push", "invalid", "master").RunInDir(tmpDir)
assert.Error(t, err)
// Valid repo
_, err = git.NewCommand("push", "origin", "master").RunInDir(tmpDir)
assert.NoError(t, err)

View File

@@ -1 +1 @@
0cf15c3f66ec8384480ed9c3cf87c9e97fbb0ec3
423313fbd38093bb10d0c8387db9105409c6f196

View File

@@ -106,3 +106,57 @@ func TestPullCreate_TitleEscape(t *testing.T) {
assert.Equal(t, "&lt;u&gt;XSS PR&lt;/u&gt;", titleHTML)
})
}
func testUIDeleteBranch(t *testing.T, session *TestSession, ownerName, repoName, branchName string) {
relURL := "/" + path.Join(ownerName, repoName, "branches")
req := NewRequest(t, "GET", relURL)
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
req = NewRequestWithValues(t, "POST", relURL+"/delete", map[string]string{
"_csrf": getCsrf(t, htmlDoc.doc),
"name": branchName,
})
session.MakeRequest(t, req, http.StatusOK)
}
func testDeleteRepository(t *testing.T, session *TestSession, ownerName, repoName string) {
relURL := "/" + path.Join(ownerName, repoName, "settings")
req := NewRequest(t, "GET", relURL)
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
req = NewRequestWithValues(t, "POST", relURL+"?action=delete", map[string]string{
"_csrf": getCsrf(t, htmlDoc.doc),
"repo_name": repoName,
})
session.MakeRequest(t, req, http.StatusFound)
}
func TestPullBranchDelete(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
defer prepareTestEnv(t)()
session := loginUser(t, "user1")
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
testCreateBranch(t, session, "user1", "repo1", "branch/master", "master1", http.StatusFound)
testEditFile(t, session, "user1", "repo1", "master1", "README.md", "Hello, World (Edited)\n")
resp := testPullCreate(t, session, "user1", "repo1", "master1", "This is a pull title")
// check the redirected URL
url := resp.HeaderMap.Get("Location")
assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
req := NewRequest(t, "GET", url)
session.MakeRequest(t, req, http.StatusOK)
// delete head branch and confirm pull page is ok
testUIDeleteBranch(t, session, "user1", "repo1", "master1")
req = NewRequest(t, "GET", url)
session.MakeRequest(t, req, http.StatusOK)
// delete head repository and confirm pull page is ok
testDeleteRepository(t, session, "user1", "repo1")
req = NewRequest(t, "GET", url)
session.MakeRequest(t, req, http.StatusOK)
})
}

View File

@@ -11,7 +11,6 @@ import (
"strings"
"testing"
"code.gitea.io/gitea/models"
api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
@@ -48,20 +47,20 @@ func TestPullCreate_CommitStatus(t *testing.T) {
commitID := path.Base(commitURL)
statusList := []models.CommitStatusState{
models.CommitStatusPending,
models.CommitStatusError,
models.CommitStatusFailure,
models.CommitStatusWarning,
models.CommitStatusSuccess,
statusList := []api.CommitStatusState{
api.CommitStatusPending,
api.CommitStatusError,
api.CommitStatusFailure,
api.CommitStatusWarning,
api.CommitStatusSuccess,
}
statesIcons := map[models.CommitStatusState]string{
models.CommitStatusPending: "circle icon yellow",
models.CommitStatusSuccess: "check icon green",
models.CommitStatusError: "warning icon red",
models.CommitStatusFailure: "remove icon red",
models.CommitStatusWarning: "warning sign icon yellow",
statesIcons := map[api.CommitStatusState]string{
api.CommitStatusPending: "circle icon yellow",
api.CommitStatusSuccess: "check icon green",
api.CommitStatusError: "warning icon red",
api.CommitStatusFailure: "remove icon red",
api.CommitStatusWarning: "warning sign icon yellow",
}
// Update commit status, and check if icon is updated as well

View File

@@ -432,6 +432,8 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
}
cond = cond.And(builder.In("repo_id", repoIDs))
} else {
cond = cond.And(builder.In("repo_id", AccessibleRepoIDsQuery(opts.RequestingUserID)))
}
cond = cond.And(builder.Eq{"user_id": opts.RequestedUser.ID})

View File

@@ -19,52 +19,19 @@ import (
"xorm.io/xorm"
)
// CommitStatusState holds the state of a Status
// It can be "pending", "success", "error", "failure", and "warning"
type CommitStatusState string
// IsWorseThan returns true if this State is worse than the given State
func (css CommitStatusState) IsWorseThan(css2 CommitStatusState) bool {
switch css {
case CommitStatusError:
return true
case CommitStatusFailure:
return css2 != CommitStatusError
case CommitStatusWarning:
return css2 != CommitStatusError && css2 != CommitStatusFailure
case CommitStatusSuccess:
return css2 != CommitStatusError && css2 != CommitStatusFailure && css2 != CommitStatusWarning
default:
return css2 != CommitStatusError && css2 != CommitStatusFailure && css2 != CommitStatusWarning && css2 != CommitStatusSuccess
}
}
const (
// CommitStatusPending is for when the Status is Pending
CommitStatusPending CommitStatusState = "pending"
// CommitStatusSuccess is for when the Status is Success
CommitStatusSuccess CommitStatusState = "success"
// CommitStatusError is for when the Status is Error
CommitStatusError CommitStatusState = "error"
// CommitStatusFailure is for when the Status is Failure
CommitStatusFailure CommitStatusState = "failure"
// CommitStatusWarning is for when the Status is Warning
CommitStatusWarning CommitStatusState = "warning"
)
// CommitStatus holds a single Status of a single Commit
type CommitStatus struct {
ID int64 `xorm:"pk autoincr"`
Index int64 `xorm:"INDEX UNIQUE(repo_sha_index)"`
RepoID int64 `xorm:"INDEX UNIQUE(repo_sha_index)"`
Repo *Repository `xorm:"-"`
State CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
TargetURL string `xorm:"TEXT"`
Description string `xorm:"TEXT"`
ContextHash string `xorm:"char(40) index"`
Context string `xorm:"TEXT"`
Creator *User `xorm:"-"`
ID int64 `xorm:"pk autoincr"`
Index int64 `xorm:"INDEX UNIQUE(repo_sha_index)"`
RepoID int64 `xorm:"INDEX UNIQUE(repo_sha_index)"`
Repo *Repository `xorm:"-"`
State api.CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
TargetURL string `xorm:"TEXT"`
Description string `xorm:"TEXT"`
ContextHash string `xorm:"char(40) index"`
Context string `xorm:"TEXT"`
Creator *User `xorm:"-"`
CreatorID int64
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
@@ -118,9 +85,9 @@ func (status *CommitStatus) APIFormat() *api.Status {
// CalcCommitStatus returns commit status state via some status, the commit statues should order by id desc
func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus {
var lastStatus *CommitStatus
var state CommitStatusState
var state api.CommitStatusState
for _, status := range statuses {
if status.State.IsWorseThan(state) {
if status.State.NoBetterThan(state) {
state = status.State
lastStatus = status
}

View File

@@ -7,6 +7,7 @@ package models
import (
"testing"
"code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
)
@@ -23,22 +24,22 @@ func TestGetCommitStatuses(t *testing.T) {
assert.Len(t, statuses, 5)
assert.Equal(t, "ci/awesomeness", statuses[0].Context)
assert.Equal(t, CommitStatusPending, statuses[0].State)
assert.Equal(t, structs.CommitStatusPending, statuses[0].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[0].APIURL())
assert.Equal(t, "cov/awesomeness", statuses[1].Context)
assert.Equal(t, CommitStatusWarning, statuses[1].State)
assert.Equal(t, structs.CommitStatusWarning, statuses[1].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[1].APIURL())
assert.Equal(t, "cov/awesomeness", statuses[2].Context)
assert.Equal(t, CommitStatusSuccess, statuses[2].State)
assert.Equal(t, structs.CommitStatusSuccess, statuses[2].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[2].APIURL())
assert.Equal(t, "ci/awesomeness", statuses[3].Context)
assert.Equal(t, CommitStatusFailure, statuses[3].State)
assert.Equal(t, structs.CommitStatusFailure, statuses[3].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[3].APIURL())
assert.Equal(t, "deploy/awesomeness", statuses[4].Context)
assert.Equal(t, CommitStatusError, statuses[4].State)
assert.Equal(t, structs.CommitStatusError, statuses[4].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL())
}

View File

@@ -381,6 +381,7 @@ func (issue *Issue) apiFormat(e Engine) *api.Issue {
apiIssue := &api.Issue{
ID: issue.ID,
URL: issue.APIURL(),
HTMLURL: issue.HTMLURL(),
Index: issue.Index,
Poster: issue.Poster.APIFormat(),
Title: issue.Title,
@@ -402,11 +403,12 @@ func (issue *Issue) apiFormat(e Engine) *api.Issue {
apiIssue.Closed = issue.ClosedUnix.AsTimePtr()
}
issue.loadMilestone(e)
if issue.Milestone != nil {
apiIssue.Milestone = issue.Milestone.APIFormat()
}
issue.loadAssignees(e)
issue.loadAssignees(e)
if len(issue.Assignees) > 0 {
for _, assignee := range issue.Assignees {
apiIssue.Assignees = append(apiIssue.Assignees, assignee.APIFormat())
@@ -436,7 +438,7 @@ func (issue *Issue) HashTag() string {
// IsPoster returns true if given user by ID is the poster.
func (issue *Issue) IsPoster(uid int64) bool {
return issue.PosterID == uid
return issue.OriginalAuthorID == 0 && issue.PosterID == uid
}
func (issue *Issue) hasLabel(e Engine, labelID int64) bool {

View File

@@ -376,6 +376,11 @@ func (comments CommentList) loadDependentIssues(e Engine) error {
for _, comment := range comments {
if comment.DependentIssue == nil {
comment.DependentIssue = issues[comment.DependentIssueID]
if comment.DependentIssue != nil {
if err := comment.DependentIssue.loadRepo(e); err != nil {
return err
}
}
}
}
return nil

View File

@@ -6,6 +6,7 @@ package models
import (
"fmt"
"strings"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
@@ -95,6 +96,8 @@ func NewMilestone(m *Milestone) (err error) {
return err
}
m.Name = strings.TrimSpace(m.Name)
if _, err = sess.Insert(m); err != nil {
return err
}
@@ -268,6 +271,7 @@ func GetMilestones(repoID int64, page int, isClosed bool, sortType string) (Mile
}
func updateMilestone(e Engine, m *Milestone) error {
m.Name = strings.TrimSpace(m.Name)
_, err := e.ID(m.ID).AllCols().
SetExpr("num_issues", builder.Select("count(*)").From("issue").Where(
builder.Eq{"milestone_id": m.ID},
@@ -283,12 +287,33 @@ func updateMilestone(e Engine, m *Milestone) error {
}
// UpdateMilestone updates information of given milestone.
func UpdateMilestone(m *Milestone) error {
if err := updateMilestone(x, m); err != nil {
func UpdateMilestone(m *Milestone, oldIsClosed bool) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
return updateMilestoneCompleteness(x, m.ID)
if m.IsClosed && !oldIsClosed {
m.ClosedDateUnix = timeutil.TimeStampNow()
}
if err := updateMilestone(sess, m); err != nil {
return err
}
if err := updateMilestoneCompleteness(sess, m.ID); err != nil {
return err
}
// if IsClosed changed, update milestone numbers of repository
if oldIsClosed != m.IsClosed {
if err := updateRepoMilestoneNum(sess, m.RepoID); err != nil {
return err
}
}
return sess.Commit()
}
func updateMilestoneCompleteness(e Engine, milestoneID int64) error {

View File

@@ -158,10 +158,11 @@ func TestUpdateMilestone(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
milestone := AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone)
milestone.Name = "newMilestoneName"
milestone.Name = " newMilestoneName "
milestone.Content = "newMilestoneContent"
assert.NoError(t, UpdateMilestone(milestone))
AssertExistsAndLoadBean(t, milestone)
assert.NoError(t, UpdateMilestone(milestone, milestone.IsClosed))
milestone = AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone)
assert.EqualValues(t, "newMilestoneName", milestone.Name)
CheckConsistencyFor(t, &Milestone{})
}

View File

@@ -461,7 +461,7 @@ var (
// LoginViaLDAP queries if login/password is valid against the LDAP directory pool,
// and create a local user if success when enabled.
func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
func LoginViaLDAP(user *User, login, password string, source *LoginSource) (*User, error) {
sr := source.Cfg.(*LDAPConfig).SearchEntry(login, password, source.Type == LoginDLDAP)
if sr == nil {
// User not in LDAP, do nothing
@@ -473,17 +473,25 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR
// Update User admin flag if exist
if isExist, err := IsUserExist(0, sr.Username); err != nil {
return nil, err
} else if isExist &&
!user.ProhibitLogin && len(source.LDAP().AdminFilter) > 0 && user.IsAdmin != sr.IsAdmin {
// Change existing admin flag only if AdminFilter option is set
user.IsAdmin = sr.IsAdmin
err = UpdateUserCols(user, "is_admin")
if err != nil {
return nil, err
} else if isExist {
if user == nil {
user, err = GetUserByName(sr.Username)
if err != nil {
return nil, err
}
}
if user != nil &&
!user.ProhibitLogin && len(source.LDAP().AdminFilter) > 0 && user.IsAdmin != sr.IsAdmin {
// Change existing admin flag only if AdminFilter option is set
user.IsAdmin = sr.IsAdmin
err = UpdateUserCols(user, "is_admin")
if err != nil {
return nil, err
}
}
}
if !autoRegister {
if user != nil {
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(user, source, sr.SSHPublicKey) {
return user, RewriteAllPublicKeys()
}
@@ -594,7 +602,7 @@ func SMTPAuth(a smtp.Auth, cfg *SMTPConfig) error {
// LoginViaSMTP queries if login/password is valid against the SMTP,
// and create a local user if success when enabled.
func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPConfig, autoRegister bool) (*User, error) {
func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPConfig) (*User, error) {
// Verify allowed domains.
if len(cfg.AllowedDomains) > 0 {
idx := strings.Index(login, "@")
@@ -625,7 +633,7 @@ func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPC
return nil, err
}
if !autoRegister {
if user != nil {
return user, nil
}
@@ -657,7 +665,7 @@ func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPC
// LoginViaPAM queries if login/password is valid against the PAM,
// and create a local user if success when enabled.
func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMConfig, autoRegister bool) (*User, error) {
func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMConfig) (*User, error) {
if err := pam.Auth(cfg.ServiceName, login, password); err != nil {
if strings.Contains(err.Error(), "Authentication failure") {
return nil, ErrUserNotExist{0, login, 0}
@@ -665,7 +673,7 @@ func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMCon
return nil, err
}
if !autoRegister {
if user != nil {
return user, nil
}
@@ -683,7 +691,7 @@ func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMCon
}
// ExternalUserLogin attempts a login using external source types.
func ExternalUserLogin(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
func ExternalUserLogin(user *User, login, password string, source *LoginSource) (*User, error) {
if !source.IsActived {
return nil, ErrLoginSourceNotActived
}
@@ -691,11 +699,11 @@ func ExternalUserLogin(user *User, login, password string, source *LoginSource,
var err error
switch source.Type {
case LoginLDAP, LoginDLDAP:
user, err = LoginViaLDAP(user, login, password, source, autoRegister)
user, err = LoginViaLDAP(user, login, password, source)
case LoginSMTP:
user, err = LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig), autoRegister)
user, err = LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig))
case LoginPAM:
user, err = LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig), autoRegister)
user, err = LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig))
default:
return nil, ErrUnsupportedLoginType
}
@@ -775,7 +783,7 @@ func UserSignIn(username, password string) (*User, error) {
return nil, ErrLoginSourceNotExist{user.LoginSource}
}
return ExternalUserLogin(user, user.LoginName, password, &source, false)
return ExternalUserLogin(user, user.LoginName, password, &source)
}
}
@@ -789,7 +797,7 @@ func UserSignIn(username, password string) (*User, error) {
// don't try to authenticate against OAuth2 and SSPI sources here
continue
}
authUser, err := ExternalUserLogin(nil, username, password, source, true)
authUser, err := ExternalUserLogin(nil, username, password, source)
if err == nil {
return authUser, nil
}

View File

@@ -35,6 +35,7 @@ const (
PullRequestStatusChecking
PullRequestStatusMergeable
PullRequestStatusManuallyMerged
PullRequestStatusError
)
// PullRequest represents relation between pull request and repositories.
@@ -67,7 +68,11 @@ type PullRequest struct {
// MustHeadUserName returns the HeadRepo's username if failed return blank
func (pr *PullRequest) MustHeadUserName() string {
if err := pr.LoadHeadRepo(); err != nil {
log.Error("LoadHeadRepo: %v", err)
if !IsErrRepoNotExist(err) {
log.Error("LoadHeadRepo: %v", err)
} else {
log.Warn("LoadHeadRepo %d but repository does not exist: %v", pr.HeadRepoID, err)
}
return ""
}
return pr.HeadRepo.MustOwnerName()
@@ -384,6 +389,13 @@ func (pr *PullRequest) GetDefaultSquashMessage() string {
log.Error("LoadIssue: %v", err)
return ""
}
if err := pr.LoadBaseRepo(); err != nil {
log.Error("LoadBaseRepo: %v", err)
return ""
}
if pr.BaseRepo.UnitEnabled(UnitTypeExternalTracker) {
return fmt.Sprintf("%s (!%d)", pr.Issue.Title, pr.Issue.Index)
}
return fmt.Sprintf("%s (#%d)", pr.Issue.Title, pr.Issue.Index)
}
@@ -408,7 +420,7 @@ func (pr *PullRequest) apiFormat(e Engine) *api.PullRequest {
err error
)
if err = pr.Issue.loadRepo(e); err != nil {
log.Error("loadRepo[%d]: %v", pr.ID, err)
log.Error("pr.Issue.loadRepo[%d]: %v", pr.ID, err)
return nil
}
apiIssue := pr.Issue.apiFormat(e)
@@ -419,19 +431,14 @@ func (pr *PullRequest) apiFormat(e Engine) *api.PullRequest {
return nil
}
}
if pr.HeadRepo == nil {
if pr.HeadRepoID != 0 && pr.HeadRepo == nil {
pr.HeadRepo, err = getRepositoryByID(e, pr.HeadRepoID)
if err != nil {
if err != nil && !IsErrRepoNotExist(err) {
log.Error("GetRepositoryById[%d]: %v", pr.ID, err)
return nil
}
}
if err = pr.Issue.loadRepo(e); err != nil {
log.Error("pr.Issue.loadRepo[%d]: %v", pr.ID, err)
return nil
}
apiPullRequest := &api.PullRequest{
ID: pr.ID,
URL: pr.Issue.HTMLURL(),
@@ -483,37 +490,45 @@ func (pr *PullRequest) apiFormat(e Engine) *api.PullRequest {
apiPullRequest.Base = apiBaseBranchInfo
}
headBranch, err = pr.HeadRepo.GetBranch(pr.HeadBranch)
if err != nil {
if git.IsErrBranchNotExist(err) {
apiPullRequest.Head = nil
} else {
log.Error("GetBranch[%s]: %v", pr.HeadBranch, err)
return nil
}
} else {
apiHeadBranchInfo := &api.PRBranchInfo{
Name: pr.HeadBranch,
Ref: pr.HeadBranch,
RepoID: pr.HeadRepoID,
Repository: pr.HeadRepo.innerAPIFormat(e, AccessModeNone, false),
}
headCommit, err = headBranch.GetCommit()
if pr.HeadRepo != nil {
headBranch, err = pr.HeadRepo.GetBranch(pr.HeadBranch)
if err != nil {
if git.IsErrNotExist(err) {
apiHeadBranchInfo.Sha = ""
if git.IsErrBranchNotExist(err) {
apiPullRequest.Head = nil
} else {
log.Error("GetCommit[%s]: %v", headBranch.Name, err)
log.Error("GetBranch[%s]: %v", pr.HeadBranch, err)
return nil
}
} else {
apiHeadBranchInfo.Sha = headCommit.ID.String()
apiHeadBranchInfo := &api.PRBranchInfo{
Name: pr.HeadBranch,
Ref: pr.HeadBranch,
RepoID: pr.HeadRepoID,
Repository: pr.HeadRepo.innerAPIFormat(e, AccessModeNone, false),
}
headCommit, err = headBranch.GetCommit()
if err != nil {
if git.IsErrNotExist(err) {
apiHeadBranchInfo.Sha = ""
} else {
log.Error("GetCommit[%s]: %v", headBranch.Name, err)
return nil
}
} else {
apiHeadBranchInfo.Sha = headCommit.ID.String()
}
apiPullRequest.Head = apiHeadBranchInfo
}
} else {
apiPullRequest.Head = &api.PRBranchInfo{
Name: pr.HeadBranch,
Ref: fmt.Sprintf("refs/pull/%d/head", pr.Index),
RepoID: -1,
}
apiPullRequest.Head = apiHeadBranchInfo
}
if pr.Status != PullRequestStatusChecking {
mergeable := pr.Status != PullRequestStatusConflict && !pr.IsWorkInProgress()
mergeable := !(pr.Status == PullRequestStatusConflict || pr.Status == PullRequestStatusError) && !pr.IsWorkInProgress()
apiPullRequest.Mergeable = mergeable
}
if pr.HasMerged {

View File

@@ -204,6 +204,14 @@ type Repository struct {
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}
// SanitizedOriginalURL returns a sanitized OriginalURL
func (repo *Repository) SanitizedOriginalURL() string {
if repo.OriginalURL == "" {
return ""
}
return util.SanitizeURLCredentials(repo.OriginalURL, false)
}
// ColorFormat returns a colored string to represent this repo
func (repo *Repository) ColorFormat(s fmt.State) {
var ownerName interface{}
@@ -1902,6 +1910,12 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
return err
}
if len(repo.Topics) > 0 {
if err = removeTopicsFromRepo(sess, repo.ID); err != nil {
return err
}
}
// FIXME: Remove repository files should be executed after transaction succeed.
repoPath := repo.repoPath(sess)
removeAllWithNotice(sess, "Delete repository files", repoPath)

View File

@@ -124,41 +124,43 @@ func generateRepoCommit(e Engine, repo, templateRepo, generateRepo *Repository,
return fmt.Errorf("checkGiteaTemplate: %v", err)
}
if err := os.Remove(gt.Path); err != nil {
return fmt.Errorf("remove .giteatemplate: %v", err)
}
if gt != nil {
if err := os.Remove(gt.Path); err != nil {
return fmt.Errorf("remove .giteatemplate: %v", err)
}
// Avoid walking tree if there are no globs
if len(gt.Globs()) > 0 {
tmpDirSlash := strings.TrimSuffix(filepath.ToSlash(tmpDir), "/") + "/"
if err := filepath.Walk(tmpDirSlash, func(path string, info os.FileInfo, walkErr error) error {
if walkErr != nil {
return walkErr
}
if info.IsDir() {
return nil
}
base := strings.TrimPrefix(filepath.ToSlash(path), tmpDirSlash)
for _, g := range gt.Globs() {
if g.Match(base) {
content, err := ioutil.ReadFile(path)
if err != nil {
return err
}
if err := ioutil.WriteFile(path,
[]byte(generateExpansion(string(content), templateRepo, generateRepo)),
0644); err != nil {
return err
}
break
// Avoid walking tree if there are no globs
if len(gt.Globs()) > 0 {
tmpDirSlash := strings.TrimSuffix(filepath.ToSlash(tmpDir), "/") + "/"
if err := filepath.Walk(tmpDirSlash, func(path string, info os.FileInfo, walkErr error) error {
if walkErr != nil {
return walkErr
}
if info.IsDir() {
return nil
}
base := strings.TrimPrefix(filepath.ToSlash(path), tmpDirSlash)
for _, g := range gt.Globs() {
if g.Match(base) {
content, err := ioutil.ReadFile(path)
if err != nil {
return err
}
if err := ioutil.WriteFile(path,
[]byte(generateExpansion(string(content), templateRepo, generateRepo)),
0644); err != nil {
return err
}
break
}
}
return nil
}); err != nil {
return err
}
return nil
}); err != nil {
return err
}
}

View File

@@ -315,6 +315,17 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) {
// accessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible
func accessibleRepositoryCondition(userID int64) builder.Cond {
if userID <= 0 {
return builder.And(
builder.Eq{"`repository`.is_private": false},
builder.Or(
// A. Aren't in organisations __OR__
builder.NotIn("`repository`.owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})),
// B. Is a public organisation.
builder.In("`repository`.owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"visibility": structs.VisibleTypePublic}))),
)
}
return builder.Or(
// 1. Be able to see all non-private repositories that either:
builder.And(
@@ -349,6 +360,12 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err
return SearchRepository(opts)
}
// AccessibleRepoIDsQuery queries accessible repository ids. Usable as a subquery wherever repo ids need to be filtered.
func AccessibleRepoIDsQuery(userID int64) *builder.Builder {
// NB: Please note this code needs to still work if user is nil
return builder.Select("id").From("repository").Where(accessibleRepositoryCondition(userID))
}
// FindUserAccessibleRepoIDs find all accessible repositories' ID by user's id
func FindUserAccessibleRepoIDs(userID int64) ([]int64, error) {
var accessCond builder.Cond = builder.Eq{"is_private": false}

View File

@@ -129,7 +129,7 @@ func addTopicByNameToRepo(e Engine, repoID int64, topicName string) (*Topic, err
}
// removeTopicFromRepo remove a topic from a repo and decrements the topic repo count
func removeTopicFromRepo(repoID int64, topic *Topic, e Engine) error {
func removeTopicFromRepo(e Engine, repoID int64, topic *Topic) error {
topic.RepoCount--
if _, err := e.ID(topic.ID).Cols("repo_count").Update(topic); err != nil {
return err
@@ -145,6 +145,24 @@ func removeTopicFromRepo(repoID int64, topic *Topic, e Engine) error {
return nil
}
// removeTopicsFromRepo remove all topics from the repo and decrements respective topics repo count
func removeTopicsFromRepo(e Engine, repoID int64) error {
_, err := e.Where(
builder.In("id",
builder.Select("topic_id").From("repo_topic").Where(builder.Eq{"repo_id": repoID}),
),
).Cols("repo_count").SetExpr("repo_count", "repo_count-1").Update(&Topic{})
if err != nil {
return err
}
if _, err = e.Delete(&RepoTopic{RepoID: repoID}); err != nil {
return err
}
return nil
}
// FindTopicOptions represents the options when fdin topics
type FindTopicOptions struct {
RepoID int64
@@ -217,7 +235,7 @@ func DeleteTopic(repoID int64, topicName string) (*Topic, error) {
return nil, nil
}
err = removeTopicFromRepo(repoID, topic, x)
err = removeTopicFromRepo(x, repoID, topic)
return topic, err
}
@@ -278,7 +296,7 @@ func SaveTopics(repoID int64, topicNames ...string) error {
}
for _, topic := range removeTopics {
err := removeTopicFromRepo(repoID, topic, sess)
err := removeTopicFromRepo(sess, repoID, topic)
if err != nil {
return err
}

View File

@@ -503,7 +503,7 @@ func (u *User) ValidatePassword(passwd string) bool {
// IsPasswordSet checks if the password is set or left empty
func (u *User) IsPasswordSet() bool {
return len(u.Passwd) > 0
return !u.ValidatePassword("")
}
// UploadAvatar saves custom avatar for user.
@@ -1760,6 +1760,15 @@ func SyncExternalUsers(ctx context.Context) {
continue
}
if len(sr) == 0 {
if !s.LDAP().AllowDeactivateAll {
log.Error("LDAP search found no entries but did not report an error. Refusing to deactivate all users")
continue
} else {
log.Warn("LDAP search found no entries but did not report an error. All users will be deactivated as per settings")
}
}
for _, su := range sr {
select {
case <-ctx.Done():

View File

@@ -30,6 +30,7 @@ type AuthenticationForm struct {
SearchPageSize int
Filter string
AdminFilter string
AllowDeactivateAll bool
IsActive bool
IsSyncEnabled bool
SMTPAuth string

View File

@@ -47,6 +47,7 @@ type Source struct {
Filter string // Query filter to validate entry
AdminFilter string // Query filter to check if user is admin
Enabled bool // if this source is disabled
AllowDeactivateAll bool // Allow an empty search response to deactivate all users from this source
}
// SearchResult : user data

View File

@@ -1,4 +1,5 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2020 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.
@@ -122,7 +123,7 @@ func (ctx *Context) RedirectToFirst(location ...string) {
}
u, err := url.Parse(loc)
if err != nil || (u.Scheme != "" && !strings.HasPrefix(strings.ToLower(loc), strings.ToLower(setting.AppURL))) {
if err != nil || ((u.Scheme != "" || u.Host != "") && !strings.HasPrefix(strings.ToLower(loc), strings.ToLower(setting.AppURL))) {
continue
}

View File

@@ -91,12 +91,12 @@ func (r *Repository) CanUseTimetracker(issue *models.Issue, user *models.User) b
// 2. Is the user a contributor, admin, poster or assignee and do the repository policies require this?
isAssigned, _ := models.IsUserAssignedToIssue(issue, user)
return r.Repository.IsTimetrackerEnabled() && (!r.Repository.AllowOnlyContributorsToTrackTime() ||
r.Permission.CanWrite(models.UnitTypeIssues) || issue.IsPoster(user.ID) || isAssigned)
r.Permission.CanWriteIssuesOrPulls(issue.IsPull) || issue.IsPoster(user.ID) || isAssigned)
}
// CanCreateIssueDependencies returns whether or not a user can create dependencies.
func (r *Repository) CanCreateIssueDependencies(user *models.User) bool {
return r.Permission.CanWrite(models.UnitTypeIssues) && r.Repository.IsDependenciesEnabled()
func (r *Repository) CanCreateIssueDependencies(user *models.User, isPull bool) bool {
return r.Repository.IsDependenciesEnabled() && r.Permission.CanWriteIssuesOrPulls(isPull)
}
// GetCommitsCount returns cached commit count for current view

View File

@@ -7,10 +7,12 @@ package graceful
import (
"crypto/tls"
"io/ioutil"
"net"
"os"
"strings"
"sync"
"sync/atomic"
"syscall"
"time"
@@ -99,12 +101,25 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string, serve ServeFuncti
}
config.Certificates = make([]tls.Certificate, 1)
var err error
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
certPEMBlock, err := ioutil.ReadFile(certFile)
if err != nil {
log.Error("Failed to load https cert file %s for %s:%s: %v", certFile, srv.network, srv.address, err)
return err
}
keyPEMBlock, err := ioutil.ReadFile(keyFile)
if err != nil {
log.Error("Failed to load https key file %s for %s:%s: %v", keyFile, srv.network, srv.address, err)
return err
}
config.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, srv.network, srv.address, err)
return err
}
return srv.ListenAndServeTLSConfig(config, serve)
}
@@ -201,9 +216,12 @@ func (wl *wrappedListener) Accept() (net.Conn, error) {
}
}
closed := int32(0)
c = wrappedConn{
Conn: c,
server: wl.server,
closed: &closed,
}
wl.server.wg.Add(1)
@@ -227,12 +245,12 @@ func (wl *wrappedListener) File() (*os.File, error) {
type wrappedConn struct {
net.Conn
server *Server
closed *int32
}
func (w wrappedConn) Close() error {
err := w.Conn.Close()
if err == nil {
if atomic.CompareAndSwapInt32(w.closed, 0, 1) {
w.server.wg.Done()
}
return err
return w.Conn.Close()
}

View File

@@ -116,7 +116,12 @@ func nonGenesisChanges(repo *models.Repository, revision string) (*repoChanges,
if len(line) == 0 {
continue
}
filename := strings.TrimSpace(line[1:])
fields := strings.Split(line, "\t")
if len(fields) < 2 {
log.Warn("Unparseable output for diff --name-status: `%s`)", line)
continue
}
filename := fields[1]
if len(filename) == 0 {
continue
} else if filename[0] == '"' {
@@ -126,11 +131,31 @@ func nonGenesisChanges(repo *models.Repository, revision string) (*repoChanges,
}
}
switch status := line[0]; status {
switch status := fields[0][0]; status {
case 'M', 'A':
updatedFilenames = append(updatedFilenames, filename)
case 'D':
changes.RemovedFilenames = append(changes.RemovedFilenames, filename)
case 'R', 'C':
if len(fields) < 3 {
log.Warn("Unparseable output for diff --name-status: `%s`)", line)
continue
}
dest := fields[2]
if len(dest) == 0 {
log.Warn("Unparseable output for diff --name-status: `%s`)", line)
continue
}
if dest[0] == '"' {
dest, err = strconv.Unquote(dest)
if err != nil {
return nil, err
}
}
if status == 'R' {
changes.RemovedFilenames = append(changes.RemovedFilenames, filename)
}
updatedFilenames = append(updatedFilenames, dest)
default:
log.Warn("Unrecognized status: %c (line=%s)", status, line)
}

View File

@@ -79,6 +79,9 @@ func (g *GiteaASTTransformer) Transform(node *ast.Document, reader text.Reader,
}
link = []byte(giteautil.URLJoin(pc.Get(urlPrefixKey).(string), lnk))
}
if len(link) > 0 && link[0] == '#' {
link = []byte("#user-content-" + string(link)[1:])
}
v.Destination = link
}
return ast.WalkContinue, nil

View File

@@ -48,8 +48,9 @@ func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
common.FootnoteExtension,
extension.NewTypographer(
extension.WithTypographicSubstitutions(extension.TypographicSubstitutions{
extension.EnDash: nil,
extension.EmDash: nil,
extension.EnDash: nil,
extension.EmDash: nil,
extension.Ellipsis: nil,
}),
),
),

View File

@@ -38,7 +38,7 @@ func NewSanitizer() {
func ReplaceSanitizer() {
sanitizer.policy = bluemonday.UGCPolicy()
// We only want to allow HighlightJS specific classes for code blocks
sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^language-\w+$`)).OnElements("code")
sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^language-[\w-]+$`)).OnElements("code")
// Checkboxes
sanitizer.policy.AllowAttrs("type").Matching(regexp.MustCompile(`^checkbox$`)).OnElements("input")

View File

@@ -14,6 +14,7 @@ type Comment struct {
PosterName string
PosterEmail string
Created time.Time
Updated time.Time
Content string
Reactions *Reactions
}

View File

@@ -19,6 +19,7 @@ type Issue struct {
State string // closed, open
IsLocked bool
Created time.Time
Updated time.Time
Closed *time.Time
Labels []*Label
Reactions *Reactions

View File

@@ -21,6 +21,7 @@ type PullRequest struct {
Milestone string
State string
Created time.Time
Updated time.Time
Closed *time.Time
Labels []*Label
PatchURL string

View File

@@ -332,6 +332,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
MilestoneID: milestoneID,
Labels: labels,
CreatedUnix: timeutil.TimeStamp(issue.Created.Unix()),
UpdatedUnix: timeutil.TimeStamp(issue.Updated.Unix()),
}
userid, ok := g.userMap[issue.PosterID]
@@ -406,6 +407,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {
Type: models.CommentTypeComment,
Content: comment.Content,
CreatedUnix: timeutil.TimeStamp(comment.Created.Unix()),
UpdatedUnix: timeutil.TimeStamp(comment.Updated.Unix()),
}
if userid > 0 {
@@ -574,6 +576,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
IsLocked: pr.IsLocked,
Labels: labels,
CreatedUnix: timeutil.TimeStamp(pr.Created.Unix()),
UpdatedUnix: timeutil.TimeStamp(pr.Updated.Unix()),
}
userid, ok := g.userMap[pr.PosterID]

View File

@@ -24,6 +24,8 @@ import (
var (
_ base.Downloader = &GithubDownloaderV3{}
_ base.DownloaderFactory = &GithubDownloaderV3Factory{}
// GithubLimitRateRemaining limit to wait for new rate to apply
GithubLimitRateRemaining = 0
)
func init() {
@@ -115,7 +117,7 @@ func (g *GithubDownloaderV3) SetContext(ctx context.Context) {
}
func (g *GithubDownloaderV3) sleep() {
for g.rate != nil && g.rate.Remaining <= 0 {
for g.rate != nil && g.rate.Remaining <= GithubLimitRateRemaining {
timer := time.NewTimer(time.Until(g.rate.Reset.Time))
select {
case <-g.ctx.Done():
@@ -124,15 +126,24 @@ func (g *GithubDownloaderV3) sleep() {
case <-timer.C:
}
rates, _, err := g.client.RateLimits(g.ctx)
err := g.RefreshRate()
if err != nil {
log.Error("g.client.RateLimits: %s", err)
}
g.rate = rates.GetCore()
}
}
// RefreshRate update the current rate (doesn't count in rate limit)
func (g *GithubDownloaderV3) RefreshRate() error {
rates, _, err := g.client.RateLimits(g.ctx)
if err != nil {
return err
}
g.rate = rates.GetCore()
return nil
}
// GetRepoInfo returns a repository information
func (g *GithubDownloaderV3) GetRepoInfo() (*base.Repository, error) {
g.sleep()
@@ -385,6 +396,7 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool,
Milestone: milestone,
State: *issue.State,
Created: *issue.CreatedAt,
Updated: *issue.UpdatedAt,
Labels: labels,
Reactions: reactions,
Closed: issue.ClosedAt,
@@ -428,6 +440,7 @@ func (g *GithubDownloaderV3) GetComments(issueNumber int64) ([]*base.Comment, er
PosterEmail: email,
Content: *comment.Body,
Created: *comment.CreatedAt,
Updated: *comment.UpdatedAt,
Reactions: reactions,
})
}
@@ -523,6 +536,7 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq
Milestone: milestone,
State: *pr.State,
Created: *pr.CreatedAt,
Updated: *pr.UpdatedAt,
Closed: pr.ClosedAt,
Labels: labels,
Merged: merged,

View File

@@ -6,6 +6,7 @@
package migrations
import (
"os"
"testing"
"time"
@@ -62,7 +63,11 @@ func assertLabelEqual(t *testing.T, name, color, description string, label *base
}
func TestGitHubDownloadRepo(t *testing.T) {
downloader := NewGithubDownloaderV3("", "", "go-gitea", "test_repo")
GithubLimitRateRemaining = 3 //Wait at 3 remaining since we could have 3 CI in //
downloader := NewGithubDownloaderV3(os.Getenv("GITHUB_READ_TOKEN"), "", "go-gitea", "test_repo")
err := downloader.RefreshRate()
assert.NoError(t, err)
repo, err := downloader.GetRepoInfo()
assert.NoError(t, err)
assert.EqualValues(t, &base.Repository{
@@ -157,6 +162,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
PosterName: "guillep2k",
State: "closed",
Created: time.Date(2019, 11, 9, 17, 0, 29, 0, time.UTC),
Updated: time.Date(2019, 11, 12, 20, 29, 53, 0, time.UTC),
Labels: []*base.Label{
{
Name: "bug",
@@ -189,6 +195,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
PosterName: "mrsdizzie",
State: "closed",
Created: time.Date(2019, 11, 12, 21, 0, 6, 0, time.UTC),
Updated: time.Date(2019, 11, 12, 22, 7, 14, 0, time.UTC),
Labels: []*base.Label{
{
Name: "duplicate",
@@ -219,6 +226,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
PosterID: 1669571,
PosterName: "mrsdizzie",
Created: time.Date(2019, 11, 12, 21, 0, 13, 0, time.UTC),
Updated: time.Date(2019, 11, 12, 21, 0, 13, 0, time.UTC),
Content: "This is a comment",
Reactions: &base.Reactions{
TotalCount: 1,
@@ -235,6 +243,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
PosterID: 1669571,
PosterName: "mrsdizzie",
Created: time.Date(2019, 11, 12, 22, 7, 14, 0, time.UTC),
Updated: time.Date(2019, 11, 12, 22, 7, 14, 0, time.UTC),
Content: "A second comment",
Reactions: &base.Reactions{
TotalCount: 0,
@@ -266,6 +275,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
PosterName: "mrsdizzie",
State: "closed",
Created: time.Date(2019, 11, 12, 21, 21, 43, 0, time.UTC),
Updated: time.Date(2019, 11, 12, 21, 39, 28, 0, time.UTC),
Labels: []*base.Label{
{
Name: "documentation",
@@ -302,6 +312,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
PosterName: "mrsdizzie",
State: "open",
Created: time.Date(2019, 11, 12, 21, 54, 18, 0, time.UTC),
Updated: time.Date(2020, 1, 4, 11, 30, 1, 0, time.UTC),
Labels: []*base.Label{
{
Name: "bug",

View File

@@ -6,6 +6,7 @@ package indexer
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
code_indexer "code.gitea.io/gitea/modules/indexer/code"
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
"code.gitea.io/gitea/modules/log"
@@ -118,7 +119,7 @@ func (r *indexerNotifier) NotifyMigrateRepository(doer *models.User, u *models.U
}
func (r *indexerNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) {
if setting.Indexer.RepoIndexerEnabled && refName == repo.DefaultBranch {
if setting.Indexer.RepoIndexerEnabled && refName == git.BranchPrefix+repo.DefaultBranch {
code_indexer.UpdateRepoIndexer(repo)
}
}

View File

@@ -6,6 +6,7 @@ package queue
import (
"context"
"sync"
"time"
"code.gitea.io/gitea/modules/log"
@@ -33,6 +34,7 @@ type PersistableChannelQueueConfiguration struct {
type PersistableChannelQueue struct {
*ChannelQueue
delayedStarter
lock sync.Mutex
closed chan struct{}
}

View File

@@ -84,11 +84,12 @@ func NewRedisQueue(handle HandlerFunc, cfg, exemplar interface{}) (Queue, error)
boostWorkers: config.BoostWorkers,
maxNumberOfWorkers: config.MaxWorkers,
},
queueName: config.QueueName,
exemplar: exemplar,
closed: make(chan struct{}),
workers: config.Workers,
name: config.Name,
queueName: config.QueueName,
exemplar: exemplar,
closed: make(chan struct{}),
terminated: make(chan struct{}),
workers: config.Workers,
name: config.Name,
}
if len(dbs) == 0 {
return nil, errors.New("no redis host specified")

View File

@@ -28,7 +28,6 @@ type WrappedQueueConfiguration struct {
}
type delayedStarter struct {
lock sync.Mutex
internal Queue
underlying Type
cfg interface{}
@@ -62,7 +61,6 @@ func (q *delayedStarter) setInternal(atShutdown func(context.Context, func()), h
queue, err := NewQueue(q.underlying, handle, q.cfg, exemplar)
if err == nil {
q.internal = queue
q.lock.Unlock()
break
}
if err.Error() != "resource temporarily unavailable" {
@@ -90,6 +88,7 @@ func (q *delayedStarter) setInternal(atShutdown func(context.Context, func()), h
// WrappedQueue wraps a delayed starting queue
type WrappedQueue struct {
delayedStarter
lock sync.Mutex
handle HandlerFunc
exemplar interface{}
channel chan Data

View File

@@ -103,8 +103,8 @@ func UpdateIssuesCommit(doer *models.User, repo *models.Repository, commits []*m
refMarked[key] = true
// FIXME: this kind of condition is all over the code, it should be consolidated in a single place
canclose := perm.IsAdmin() || perm.IsOwner() || perm.CanWrite(models.UnitTypeIssues) || refIssue.PosterID == doer.ID
cancomment := canclose || perm.CanRead(models.UnitTypeIssues)
canclose := perm.IsAdmin() || perm.IsOwner() || perm.CanWriteIssuesOrPulls(refIssue.IsPull) || refIssue.PosterID == doer.ID
cancomment := canclose || perm.CanReadIssuesOrPulls(refIssue.IsPull)
// Don't proceed if the user can't comment
if !cancomment {
@@ -137,9 +137,11 @@ func UpdateIssuesCommit(doer *models.User, repo *models.Repository, commits []*m
continue
}
}
if err := changeIssueStatus(refRepo, refIssue, doer, ref.Action == references.XRefActionCloses); err != nil {
return err
close := (ref.Action == references.XRefActionCloses)
if close != refIssue.IsClosed {
if err := changeIssueStatus(refRepo, refIssue, doer, close); err != nil {
return err
}
}
}
}

View File

@@ -46,7 +46,7 @@ func DeleteRepoFile(repo *models.Repository, doer *models.User, opts *DeleteRepo
// If we aren't branching to a new branch, make sure user can commit to the given branch
if opts.NewBranch != opts.OldBranch {
newBranch, err := repo.GetBranch(opts.NewBranch)
if git.IsErrNotExist(err) {
if err != nil && !git.IsErrBranchNotExist(err) {
return nil, err
}
if newBranch != nil {

View File

@@ -475,9 +475,18 @@ func PushUpdate(repo *models.Repository, branch string, opts PushUpdateOptions)
return err
}
log.Trace("TriggerTask '%s/%s' by %s", repo.Name, branch, pusher.Name)
if !isDelRef {
if err = models.RemoveDeletedBranch(repo.ID, opts.Branch); err != nil {
log.Error("models.RemoveDeletedBranch %s/%s failed: %v", repo.ID, opts.Branch, err)
}
go pull_service.AddTestPullRequestTask(pusher, repo.ID, branch, true)
log.Trace("TriggerTask '%s/%s' by %s", repo.Name, branch, pusher.Name)
go pull_service.AddTestPullRequestTask(pusher, repo.ID, branch, true)
// close all related pulls
} else if err = pull_service.CloseBranchPulls(pusher, repo.ID, branch); err != nil {
log.Error("close related pull request failed: %v", err)
}
if err = models.WatchIfAuto(opts.PusherID, repo.ID, true); err != nil {
log.Warn("Fail to perform auto watch on user %v for repo %v: %v", opts.PusherID, repo.ID, err)
@@ -524,12 +533,15 @@ func PushUpdates(repo *models.Repository, optsList []*PushUpdateOptions) error {
if err = models.RemoveDeletedBranch(repo.ID, opts.Branch); err != nil {
log.Error("models.RemoveDeletedBranch %s/%s failed: %v", repo.ID, opts.Branch, err)
}
log.Trace("TriggerTask '%s/%s' by %s", repo.Name, opts.Branch, pusher.Name)
go pull_service.AddTestPullRequestTask(pusher, repo.ID, opts.Branch, true)
// close all related pulls
} else if err = pull_service.CloseBranchPulls(pusher, repo.ID, opts.Branch); err != nil {
log.Error("close related pull request failed: %v", err)
}
log.Trace("TriggerTask '%s/%s' by %s", repo.Name, opts.Branch, pusher.Name)
go pull_service.AddTestPullRequestTask(pusher, repo.ID, opts.Branch, true)
if err = models.WatchIfAuto(opts.PusherID, repo.ID, true); err != nil {
log.Warn("Fail to perform auto watch on user %v for repo %v: %v", opts.PusherID, repo.ID, err)
}

View File

@@ -21,6 +21,8 @@ var (
MaxGitDiffLines int
MaxGitDiffLineCharacters int
MaxGitDiffFiles int
VerbosePush bool
VerbosePushDelay time.Duration
GCArgs []string `ini:"GC_ARGS" delim:" "`
EnableAutoGitWireProtocol bool
Timeout struct {
@@ -36,6 +38,8 @@ var (
MaxGitDiffLines: 1000,
MaxGitDiffLineCharacters: 5000,
MaxGitDiffFiles: 100,
VerbosePush: true,
VerbosePushDelay: 5 * time.Second,
GCArgs: []string{},
EnableAutoGitWireProtocol: true,
Timeout: struct {

View File

@@ -7,6 +7,7 @@ package setting
import (
"fmt"
"path"
"path/filepath"
"strconv"
"strings"
"time"
@@ -44,7 +45,7 @@ func GetQueueSettings(name string) QueueSettings {
q := QueueSettings{}
sec := Cfg.Section("queue." + name)
// DataDir is not directly inheritable
q.DataDir = path.Join(Queue.DataDir, name)
q.DataDir = filepath.Join(Queue.DataDir, name)
// QueueName is not directly inheritable either
q.QueueName = name + Queue.QueueName
for _, key := range sec.Keys() {
@@ -55,8 +56,8 @@ func GetQueueSettings(name string) QueueSettings {
q.QueueName = key.MustString(q.QueueName)
}
}
if !path.IsAbs(q.DataDir) {
q.DataDir = path.Join(AppDataPath, q.DataDir)
if !filepath.IsAbs(q.DataDir) {
q.DataDir = filepath.Join(AppDataPath, q.DataDir)
}
sec.Key("DATADIR").SetValue(q.DataDir)
// The rest are...
@@ -82,8 +83,8 @@ func GetQueueSettings(name string) QueueSettings {
func NewQueueService() {
sec := Cfg.Section("queue")
Queue.DataDir = sec.Key("DATADIR").MustString("queues/")
if !path.IsAbs(Queue.DataDir) {
Queue.DataDir = path.Join(AppDataPath, Queue.DataDir)
if !filepath.IsAbs(Queue.DataDir) {
Queue.DataDir = filepath.Join(AppDataPath, Queue.DataDir)
}
Queue.Length = sec.Key("LENGTH").MustInt(20)
Queue.BatchLength = sec.Key("BATCH_LENGTH").MustInt(20)

View File

@@ -554,6 +554,12 @@ func NewContext() {
Protocol = HTTPS
CertFile = sec.Key("CERT_FILE").String()
KeyFile = sec.Key("KEY_FILE").String()
if !filepath.IsAbs(CertFile) && len(CertFile) > 0 {
CertFile = filepath.Join(CustomPath, CertFile)
}
if !filepath.IsAbs(KeyFile) && len(KeyFile) > 0 {
KeyFile = filepath.Join(CustomPath, KeyFile)
}
case "fcgi":
Protocol = FCGI
case "fcgi+unix":

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
package structs // import "code.gitea.io/gitea/modules/structs"
import (
"time"
)

View File

@@ -0,0 +1,63 @@
// Copyright 2020 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 structs
// CommitStatusState holds the state of a Status
// It can be "pending", "success", "error", "failure", and "warning"
type CommitStatusState string
const (
// CommitStatusPending is for when the Status is Pending
CommitStatusPending CommitStatusState = "pending"
// CommitStatusSuccess is for when the Status is Success
CommitStatusSuccess CommitStatusState = "success"
// CommitStatusError is for when the Status is Error
CommitStatusError CommitStatusState = "error"
// CommitStatusFailure is for when the Status is Failure
CommitStatusFailure CommitStatusState = "failure"
// CommitStatusWarning is for when the Status is Warning
CommitStatusWarning CommitStatusState = "warning"
)
// NoBetterThan returns true if this State is no better than the given State
func (css CommitStatusState) NoBetterThan(css2 CommitStatusState) bool {
switch css {
case CommitStatusError:
return true
case CommitStatusFailure:
return css2 != CommitStatusError
case CommitStatusWarning:
return css2 != CommitStatusError && css2 != CommitStatusFailure
case CommitStatusPending:
return css2 != CommitStatusError && css2 != CommitStatusFailure && css2 != CommitStatusWarning
default:
return css2 != CommitStatusError && css2 != CommitStatusFailure && css2 != CommitStatusWarning && css2 != CommitStatusPending
}
}
// IsPending represents if commit status state is pending
func (css CommitStatusState) IsPending() bool {
return css == CommitStatusPending
}
// IsSuccess represents if commit status state is success
func (css CommitStatusState) IsSuccess() bool {
return css == CommitStatusSuccess
}
// IsError represents if commit status state is error
func (css CommitStatusState) IsError() bool {
return css == CommitStatusError
}
// IsFailure represents if commit status state is failure
func (css CommitStatusState) IsFailure() bool {
return css == CommitStatusFailure
}
// IsWarning represents if commit status state is warning
func (css CommitStatusState) IsWarning() bool {
return css == CommitStatusWarning
}

View File

@@ -38,6 +38,7 @@ type RepositoryMeta struct {
type Issue struct {
ID int64 `json:"id"`
URL string `json:"url"`
HTMLURL string `json:"html_url"`
Index int64 `json:"number"`
Poster *User `json:"user"`
OriginalAuthor string `json:"original_author"`

View File

@@ -82,6 +82,7 @@ func (q *UniqueQueue) AddFunc(id interface{}, fn func()) {
idStr := com.ToStr(id)
q.table.lock.Lock()
if _, ok := q.table.pool[idStr]; ok {
q.table.lock.Unlock()
return
}
q.table.pool[idStr] = struct{}{}

View File

@@ -7,6 +7,8 @@ package util
import (
"net/url"
"strings"
"code.gitea.io/gitea/modules/log"
)
// urlSafeError wraps an error whose message may contain a sensitive URL
@@ -36,6 +38,7 @@ func SanitizeMessage(message, unsanitizedURL string) string {
func SanitizeURLCredentials(unsanitizedURL string, usePlaceholder bool) string {
u, err := url.Parse(unsanitizedURL)
if err != nil {
log.Error("parse url %s failed: %v", unsanitizedURL, err)
// don't log the error, since it might contain unsanitized URL.
return "(unparsable url)"
}

View File

@@ -0,0 +1,25 @@
// Copyright 2020 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 util
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSanitizeURLCredentials(t *testing.T) {
var kases = map[string]string{
"https://github.com/go-gitea/test_repo.git": "https://github.com/go-gitea/test_repo.git",
"https://mytoken@github.com/go-gitea/test_repo.git": "https://github.com/go-gitea/test_repo.git",
"http://github.com/go-gitea/test_repo.git": "http://github.com/go-gitea/test_repo.git",
"/test/repos/repo1": "/test/repos/repo1",
"git@github.com:go-gitea/test_repo.git": "(unparsable url)",
}
for source, value := range kases {
assert.EqualValues(t, value, SanitizeURLCredentials(source, false))
}
}

View File

@@ -142,7 +142,7 @@ func getDingtalkIssuesPayload(p *api.IssuePayload) (*DingtalkPayload, error) {
Title: issueTitle,
HideAvatar: "0",
SingleTitle: "view issue",
SingleURL: p.Issue.URL,
SingleURL: p.Issue.HTMLURL,
},
}, nil
}

View File

@@ -236,7 +236,7 @@ func getDiscordIssuesPayload(p *api.IssuePayload, meta *DiscordMeta) (*DiscordPa
{
Title: text,
Description: attachmentText,
URL: p.Issue.URL,
URL: p.Issue.HTMLURL,
Color: color,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,

View File

@@ -299,7 +299,7 @@ func getMSTeamsIssuesPayload(p *api.IssuePayload) (*MSTeamsPayload, error) {
Targets: []MSTeamsActionTarget{
{
Os: "default",
URI: p.Issue.URL,
URI: p.Issue.HTMLURL,
},
},
},

View File

@@ -158,7 +158,7 @@ func getSlackIssuesPayload(p *api.IssuePayload, slack *SlackMeta) (*SlackPayload
pl.Attachments = []SlackAttachment{{
Color: fmt.Sprintf("%x", color),
Title: issueTitle,
TitleLink: p.Issue.URL,
TitleLink: p.Issue.HTMLURL,
Text: attachmentText,
}}
}
@@ -232,8 +232,10 @@ func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, e
Username: slack.Username,
IconURL: slack.IconURL,
Attachments: []SlackAttachment{{
Color: slack.Color,
Text: attachmentText,
Color: slack.Color,
Title: p.Repo.HTMLURL,
TitleLink: p.Repo.HTMLURL,
Text: attachmentText,
}},
}, nil
}
@@ -289,12 +291,11 @@ func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackM
func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*SlackPayload, error) {
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
var text, title, attachmentText string
var text string
switch p.Action {
case api.HookRepoCreated:
text = fmt.Sprintf("[%s] Repository created by %s", repoLink, senderLink)
title = p.Repository.HTMLURL
case api.HookRepoDeleted:
text = fmt.Sprintf("[%s] Repository deleted by %s", repoLink, senderLink)
}
@@ -304,12 +305,6 @@ func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*Sla
Text: text,
Username: slack.Username,
IconURL: slack.IconURL,
Attachments: []SlackAttachment{{
Color: slack.Color,
Title: title,
TitleLink: title,
Text: attachmentText,
}},
}, nil
}

View File

@@ -148,6 +148,25 @@ func getTelegramPullRequestPayload(p *api.PullRequestPayload) (*TelegramPayload,
}, nil
}
func getTelegramPullRequestApprovalPayload(p *api.PullRequestPayload, event models.HookEventType) (*TelegramPayload, error) {
var text, attachmentText string
switch p.Action {
case api.HookIssueSynchronized:
action, err := parseHookPullRequestEventType(event)
if err != nil {
return nil, err
}
text = fmt.Sprintf("[%s] Pull request review %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
attachmentText = p.Review.Content
}
return &TelegramPayload{
Message: text + "\n" + attachmentText,
}, nil
}
func getTelegramRepositoryPayload(p *api.RepositoryPayload) (*TelegramPayload, error) {
var title string
switch p.Action {
@@ -192,6 +211,8 @@ func GetTelegramPayload(p api.Payloader, event models.HookEventType, meta string
return getTelegramPushPayload(p.(*api.PushPayload))
case models.HookEventPullRequest:
return getTelegramPullRequestPayload(p.(*api.PullRequestPayload))
case models.HookEventPullRequestRejected, models.HookEventPullRequestApproved, models.HookEventPullRequestComment:
return getTelegramPullRequestApprovalPayload(p.(*api.PullRequestPayload), event)
case models.HookEventRepository:
return getTelegramRepositoryPayload(p.(*api.RepositoryPayload))
case models.HookEventRelease:

View File

@@ -2035,4 +2035,3 @@ error.probable_bad_default_signature=VAROVÁNÍ! Ačkoli výchozí klíč má to
[units]
error.no_unit_allowed_repo=Nejste oprávněni přistupovat k žádné části tohoto repozitáře.
error.unit_not_allowed=Nejste oprávněni přistupovat k této části repozitáře.

View File

@@ -606,7 +606,7 @@ clone_helper=Benötigst du Hilfe beim Klonen? Öffne die <a target="_blank" rel=
fork_repo=Repository forken
fork_from=Fork von
fork_visibility_helper=Die Sichtbarkeit eines geforkten Repositorys kann nicht geändert werden.
use_template=Verwende dieses Template
use_template=Dieses Template verwenden
generate_repo=Repository erstellen
generate_from=Erstelle aus
repo_desc=Beschreibung
@@ -1062,6 +1062,8 @@ pulls.no_merge_desc=Dieser Pull-Request kann nicht gemerged werden, da keine Mer
pulls.no_merge_helper=Aktiviere Mergeoptionen in den Repositoryeinstellungen oder merge den Pull-Request manuell.
pulls.no_merge_wip=Dieser Pull Request kann nicht zusammengeführt werden, da er als Work In Progress gekennzeichnet ist.
pulls.no_merge_status_check=Dieser Pull-Request kann nicht zusammengeführt werden, da nicht alle erforderlichen Statusprüfungen erfolgreich waren.
pulls.no_merge_not_ready=Dieser Pull-Request kann nicht zusammengeführt werden, überprüfe den Reviewstatus und die Statusprüfungen.
pulls.no_merge_access=Du bist nicht berechtigt, diesen Pull-Request zu Mergen.
pulls.merge_pull_request=Pull-Request zusammenführen
pulls.rebase_merge_pull_request=Rebase und Mergen
pulls.rebase_merge_commit_pull_request=Rebasen und Mergen (--no-ff)
@@ -1412,6 +1414,8 @@ settings.protect_approvals_whitelist_enabled=Freigaben auf Benutzer oder Teams a
settings.protect_approvals_whitelist_enabled_desc=Nur Bewertungen von Benutzern auf der Whitelist oder Teams zählen zu den erforderlichen Genehmigungen. Gibt es keine Whitelist, so zählen Reviews von jedem mit Schreibzugriff zu den erforderlichen Genehmigungen.
settings.protect_approvals_whitelist_users=Freigeschaltete Reviewer:
settings.protect_approvals_whitelist_teams=Freigeschaltete Teams:
settings.dismiss_stale_approvals=Entferne alte Genehmigungen
settings.dismiss_stale_approvals_desc=Wenn neue Commits gepusht werden, die den Inhalt des Pull-Requests ändern, werden alte Genehmigungen entfernt.
settings.add_protected_branch=Schutz aktivieren
settings.delete_protected_branch=Schutz deaktivieren
settings.update_protect_branch_success=Branch-Schutz für den Branch „%s“ wurde geändert.
@@ -1747,6 +1751,7 @@ users.new_account=Benutzerkonto erstellen
users.name=Benutzername
users.activated=Aktiviert
users.admin=Administrator
users.restricted=Eingeschränkt
users.repos=Repositories
users.created=Registriert am
users.last_login=Letzte Anmeldung
@@ -1765,6 +1770,7 @@ users.max_repo_creation_desc=(Gib -1 ein, um das globale Standardlimit zu verwen
users.is_activated=Account ist aktiviert
users.prohibit_login=Anmelden deaktivieren
users.is_admin=Ist Administrator
users.is_restricted=Ist eingeschränkt
users.allow_git_hook=Darf „Git Hooks“ erstellen
users.allow_import_local=Darf lokale Repositories importieren
users.allow_create_organization=Darf Organisationen erstellen
@@ -2025,8 +2031,47 @@ monitor.execute_time=Ausführungszeit
monitor.process.cancel=Prozess abbrechen
monitor.process.cancel_desc=Abbrechen eines Prozesses kann Datenverlust verursachen
monitor.process.cancel_notices=Abbrechen: <strong>%s</strong>?
monitor.queues=Warteschlangen
monitor.queue=Warteschlange: %s
monitor.queue.name=Name
monitor.queue.type=Typ
monitor.queue.numberworkers=Anzahl der Worker
monitor.queue.maxnumberworkers=Maximale Anzahl der Worker
monitor.queue.review=Konfiguration überprüfen
monitor.queue.review_add=Worker hinzufügen/prüfen
monitor.queue.configuration=Erstkonfiguration
monitor.queue.nopool.title=Kein Worker-Pool
monitor.queue.nopool.desc=Diese Warteschlange umgibt andere Warteschlangen und hat selbst keinen Worker-Pool.
monitor.queue.wrapped.desc=Eine Wrapped Queue umfasst eine langsame Start-Warteschlange und puffert die in der Warteschlange stehenden Aufträge in einem Kanal. Sie besitzt selbst keinen Worker-Pool.
monitor.queue.persistable-channel.desc=Ein persistierender Channel umfasst zwei Warteschlangen, eine Channel-Warteschlange mit einem eigenen Worker-Pool und eine Level-Warteschlange für persistente Anfragen aus früheren Shutdowns. Er hat selbst keinen Worker-Pool.
monitor.queue.pool.timeout=Timeout
monitor.queue.pool.addworkers.title=Worker hinzufügen
monitor.queue.pool.addworkers.submit=Worker hinzufügen
monitor.queue.pool.addworkers.numberworkers.placeholder=Anzahl der Worker
monitor.queue.pool.addworkers.timeout.placeholder=Setze auf 0 für keinen Timeout
monitor.queue.pool.addworkers.musttimeoutduration=Timeout muss eine Golang-Dauer sein, z. B. 5m oder 0
monitor.queue.settings.title=Pool-Einstellungen
monitor.queue.settings.desc=Pools wachsen dynamisch mit einem Boost als Reaktion auf die Blockierung ihrer Workerwarteschlangen. Diese Änderungen wirken sich nicht auf die aktuellen Worker Gruppen aus.
monitor.queue.settings.timeout=Timeout verlängern
monitor.queue.settings.timeout.placeholder=Derzeit %[1]v
monitor.queue.settings.timeout.error=Timeout muss eine Golang-Dauer sein, z.B. 5m oder 0
monitor.queue.settings.numberworkers=Anzahl der Worker erhöhen
monitor.queue.settings.numberworkers.placeholder=Derzeit %[1]v
monitor.queue.settings.maxnumberworkers.placeholder=Derzeit %[1]v
monitor.queue.settings.maxnumberworkers.error=Die Anzahl der Worker muss eine Zahl sein
monitor.queue.settings.submit=Einstellungen aktualisieren
monitor.queue.settings.changed=Einstellungen aktualisiert
monitor.queue.settings.blocktimeout=Aktuelle Block-Timeout
monitor.queue.settings.blocktimeout.value=%[1]v
monitor.queue.pool.none=Diese Warteschlange hat keinen Pool
monitor.queue.pool.added=Workergruppe hinzugefügt
monitor.queue.pool.workers.title=Aktive Workergruppen
monitor.queue.pool.workers.none=Keine Workergruppen.
monitor.queue.pool.cancel=Workergruppen herunterfahren
monitor.queue.pool.cancelling=Workergruppe fährt herunter
monitor.queue.pool.cancel_notices=Diese Gruppe von %s Workern herunterfahren?
notices.system_notice_list=Systemmitteilungen
notices.view_detail_header=Meldungsdetails ansehen
@@ -2120,4 +2165,3 @@ error.probable_bad_default_signature=WARNHINWEIS! Obwohl der Standardschlüssel
[units]
error.no_unit_allowed_repo=Du hast keine Berechtigung, um auf irgendeinen Bereich dieses Repositories zuzugreifen.
error.unit_not_allowed=Du hast keine Berechtigung, um auf diesen Repository-Bereich zuzugreifen.

View File

@@ -1063,6 +1063,8 @@ pulls.no_merge_desc = This pull request cannot be merged because all repository
pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually.
pulls.no_merge_wip = This pull request can not be merged because it is marked as being a work in progress.
pulls.no_merge_status_check = This pull request cannot be merged because not all required status checkes are successful.
pulls.no_merge_not_ready = This pull request is not ready to be merged, check review status and status checks.
pulls.no_merge_access = You are not authorized to merge this pull request.
pulls.merge_pull_request = Merge Pull Request
pulls.rebase_merge_pull_request = Rebase and Merge
pulls.rebase_merge_commit_pull_request = Rebase and Merge (--no-ff)
@@ -1413,6 +1415,8 @@ settings.protect_approvals_whitelist_enabled = Restrict approvals to whitelisted
settings.protect_approvals_whitelist_enabled_desc = Only reviews from whitelisted users or teams will count to the required approvals. Without approval whitelist, reviews from anyone with write access count to the required approvals.
settings.protect_approvals_whitelist_users = Whitelisted reviewers:
settings.protect_approvals_whitelist_teams = Whitelisted teams for reviews:
settings.dismiss_stale_approvals = Dismiss stale approvals
settings.dismiss_stale_approvals_desc = When new commits that change the content of the pull request are pushed to the branch, old approvals will be dismissed.
settings.add_protected_branch = Enable protection
settings.delete_protected_branch = Disable protection
settings.update_protect_branch_success = Branch protection for branch '%s' has been updated.
@@ -1748,6 +1752,7 @@ users.new_account = Create User Account
users.name = Username
users.activated = Activated
users.admin = Admin
users.restricted = Restricted
users.repos = Repos
users.created = Created
users.last_login = Last Sign-In
@@ -1766,6 +1771,7 @@ users.max_repo_creation_desc = (Enter -1 to use the global default limit.)
users.is_activated = User Account Is Activated
users.prohibit_login = Disable Sign-In
users.is_admin = Is Administrator
users.is_restricted = Is Restricted
users.allow_git_hook = May Create Git Hooks
users.allow_import_local = May Import Local Repositories
users.allow_create_organization = May Create Organizations
@@ -1820,6 +1826,7 @@ auths.attribute_surname = Surname Attribute
auths.attribute_mail = Email Attribute
auths.attribute_ssh_public_key = Public SSH Key Attribute
auths.attributes_in_bind = Fetch Attributes in Bind DN Context
auths.allow_deactivate_all = Allow an empty search result to deactivate all users
auths.use_paged_search = Use Paged Search
auths.search_page_size = Page Size
auths.filter = User Filter

View File

@@ -2109,4 +2109,3 @@ error.probable_bad_default_signature=¡ADVERTENCIA! ¡La clave por defecto tiene
[units]
error.no_unit_allowed_repo=No tiene permisos para acceder a ninguna sección de este repositorio.
error.unit_not_allowed=No tiene permisos para acceder a esta sección del repositorio.

View File

@@ -2120,4 +2120,3 @@ error.probable_bad_default_signature=هشدار! اگرچه اینجا یک کل
[units]
error.no_unit_allowed_repo=شما اجازه دسترسی به هیچ قسمت از این مخزن را ندارید.
error.unit_not_allowed=شما اجازه دسترسی به این قسمت مخزن را ندارید.

View File

@@ -2096,4 +2096,3 @@ error.probable_bad_default_signature=AVERTISSEMENT ! Bien que la clé par défau
[units]
error.no_unit_allowed_repo=Vous n'êtes pas autorisé à accéder à n'importe quelle section de ce dépôt.
error.unit_not_allowed=Vous n'êtes pas autorisé à accéder à cette section du dépôt.

View File

@@ -10,6 +10,7 @@ link_account=Tautan Akun
register=Daftar
website=Situs Web
version=Versi
powered_by=Diberdayakan oleh %s
page=Halaman
template=Contoh
language=Bahasa
@@ -29,8 +30,16 @@ twofa_scratch=Kode Awal Dua Faktor
passcode=Kode Akses
u2f_insert_key=Masukkan kunci keamanan anda
u2f_sign_in=Tekan tombol pada kunci keamanan anda. Jika kunci keamanan anda tidak memiliki tombol, masukkan kembali.
u2f_press_button=Silahkan tekan tombol pada kunci keamanan anda…
u2f_use_twofa=Menggunakan kode dua faktor dari telepon anda
u2f_error=Tidak dapat membaca kunci keamanan Anda.
u2f_unsupported_browser=Browser Anda tidak mendukung kunci keamanan U2F.
u2f_error_1=Terdapat kesalahan yang tidak diketahui. Mohon coba lagi.
u2f_error_2=Pastikan menggunakan URL yang benar dan terenkripsi (https://).
u2f_error_3=Server tidak bisa memproses permintaan anda.
u2f_error_4=Kunci keamanan tidak diperbolehkan untuk permintaan ini. Pastikan bahwa kunci ini belum terdaftar sebelumnya.
u2f_error_5=Waktu habis sebelum kunci Anda dapat dibaca. Mohon muat ulang halaman ini dan coba lagi.
u2f_reload=Muat Ulang
repository=Repositori
@@ -58,25 +67,51 @@ forks=Garpu
activities=Aktivitas
pull_requests=Tarik Permintaan
issues=Masalah
milestones=Tonggak
cancel=Batal
add=Tambah
add_all=Tambah Semua
remove=Buang
remove_all=Buang Semua
write=Tulis
preview=Pratinjau
loading=Memuat…
[startpage]
app_desc=Sebuah layanan hosting Git sendiri yang tanpa kesulitan
install=Mudah dipasang
install_desc=Cukup <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/install-from-binary/">jalankan program biner</a> yang sesuai dengan sistem operasi Anda. Atau jalankan Gitea dengan <a target="_blank" rel="noopener noreferrer" href="https://github.com/go-gitea/gitea/tree/master/docker">Docker</a> atau <a target="_blank" rel="noopener noreferrer" href="https://github.com/alvaroaleman/ansible-gitea/blob/master/Vagrantfile">Vagrant</a>, atau install dari <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/install-from-package/">paket</a>.
platform=Lintas platform
platform_desc=Gitea bisa digunakan di mana <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a> bisa dijalankan: Windows, macOS, Linux, ARM, dll. Silahkan pilih yang Anda suka!
lightweight=Ringan
lightweight_desc=Gitea hanya membutuhkan persyaratan minimal dan bisa berjalan pada Raspberry Pi yang murah. Bisa menghemat listrik!
license=Sumber Terbuka
license_desc="Go get" (Dapatkan kode sumber dari) <a target="_blank" rel="noopener noreferrer" href="https://code.gitea.io/gitea">code.gitea.io/gitea</a>! Mari bergabung dengan <a target="_blank" rel="noopener noreferrer" href="https://github.com/go-gitea/gitea">berkontribusi</a> untuk membuat proyek ini lebih baik. Jangan malu untuk menjadi kontributor!
[install]
install=Pemasangan
title=Konfigurasi Awal
docker_helper=Jika Anda menjalankan Gitea di dalam Docker, baca <a target="_blank" rel="noopener" href="%s">dokumentasi </a> sebelum mengubah pengaturan.
requite_db_desc=Gitea memerlukan MySQL, PostgreSQL, MSSQL atau SQLite3.
db_title=Pengaturan Basis Data
db_type=Tipe Basis Data
host=Host
user=Nama Pengguna
password=Kata Sandi
db_name=Nama Basis Data
db_helper=Untuk pengguna MySQL: Mohon gunakan mesin penyimpanan InnoDB, dan jika Anda menggunakan enkoding "utf8mb4", versi InnoDB Anda harus diatas 5.6.
ssl_mode=SSL
charset=Jenis karakter
path=Jalur
sqlite_helper=Jalur berkas untuk basis data SQLite3 atau TiDB.<br>Masukkan path absolut jika anda menjalankan Gitea sebagai layanan.
err_empty_db_path=Jalur basis data SQLite3 tidak boleh kosong.
no_admin_and_disable_registration=Anda tidak dapat menonaktifkan pendaftaran tanpa membuat akun admin.
err_empty_admin_password=Sandi administrator tidak boleh kosong.
err_empty_admin_email=Email administrator tidak boleh kosong.
err_admin_name_is_reserved=Nama pengguna Administrator tidak valid, nama tersebut dicadangkan
err_admin_name_is_invalid=Nama Administrator tidak valid.
general_title=Pengaturan Umum
app_name=Judul Situs
@@ -111,13 +146,20 @@ server_service_title=Server dan Pengaturan Layanan Pihak Ketiga
offline_mode=Aktifkan Mode Lokal
offline_mode_popup=Non-aktifkan jaringan pengiriman konten dari pihak ketiga dan layani semua sumber daya secara lokal.
disable_gravatar=Non-aktifkan Gravatar
federated_avatar_lookup=Aktifkan Avatar Terfederasi
federated_avatar_lookup_popup=Mengaktifkan pencarian avatar federasi menggunakan Libravatar.
disable_registration=Matikan Swa-pendaftaran
disable_registration_popup=Nonaktifkan pendaftaran oleh pengguna. Hanya admin yang dapat membuat akun pengguna baru.
allow_only_external_registration_popup=Perbolehkan Pendaftaran Hanya Melalui Layanan External
openid_signin=Aktifkan Login OpenID
openid_signin_popup=Aktifkan masuk pengguna lewat OpenID.
openid_signup=Aktifkan Pendaftaran OpenID
openid_signup_popup=Aktifkan pendaftaran berdasarkan OpenID.
enable_captcha=Aktifkan CAPTCHA
enable_captcha_popup=Membutukan CAPTCHA untuk pendaftaran.
require_sign_in_view=Anda Harus Login untuk Melihat Halaman
require_sign_in_view_popup=Batasi akses halaman hanya pada pengguna yang masuk. Pengunjung hanya dapat melihat halaman masuk dan pendaftaran.
admin_setting_desc=Akun administrator tidak wajib dibuat. Pengguna yang pertama kali mendaftar akan secara otomatis menjadi administrator.
admin_title=Pengaturan Akun Admin
admin_name=Nama Pengguna Admin
admin_password=Kata sandi
@@ -127,7 +169,15 @@ install_btn_confirm=Memasang Gitea
test_git_failed=Tidak dapat menguji perintah 'git': %v
sqlite3_not_available=Gitea versi ini tidak mendukung SQLite3, Silahkan untuh versi biner resmi dari %s (bukan versi 'gobuild').
invalid_db_setting=Pengaturan basis data tidak valid: %v
invalid_repo_path=Lokasi folder repositori tidak valid: %v
run_user_not_match=Nama pengguna 'run as' bukanlah nama pengguna saat ini: %s -> %s
save_config_failed=Gagal menyimpan konfigurasi: %v
invalid_admin_setting=Pengaturan akun administrator tidak valid: %v
install_success=Selamat datang! Terimakasih telah memilih Gitea. Selamat bersenang-senang dan hati-hati!
invalid_log_root_path=Jalur folder log tidak valid: %v
default_keep_email_private=Sembunyikan Alamat Email secara Asali
default_keep_email_private_popup=Sembunyikan alamat email pengguna baru secara asali.
default_allow_create_organization_popup=Perbolehkan pengguna baru untuk membuat organisasi.
[home]
uname_holder=Nama Pengguna atau Alamat Surel
@@ -161,36 +211,50 @@ social_register_helper_msg=Sudah memiliki akun? Hubungkan sekarang!
remember_me=Ingat Saya
forgot_password_title=Lupa Kata Sandi
forgot_password=Lupa kata sandi?
sign_up_now=Butuh akun? Daftar sekarang.
sign_up_successful=Akun berhasil dibuat.
confirmation_mail_sent_prompt=Surel konfirmasi baru telah dikirim ke <b>%s</b>. Silakan periksa kotak masuk anda dalam %s ke depan untuk menyelesaikan proses pendaftaran.
active_your_account=Aktifkan Akun Anda
account_activated=Akun telah diaktifkan
prohibit_login_desc=Akun Anda tidak diperbolehkan untuk masuk, silakan hubungi admin situs.
has_unconfirmed_mail=Hai %s, anda memiliki sebuah alamat surel yang belum dikonfirmasi (<b>%s</b>). Jika anda belum menerima surel konfirmasi atau perlu untuk mengirim ulang yang baru, silakan klik pada tombol di bawah.
resend_mail=Klik di sini untuk mengirim ulang surel aktivasi anda
email_not_associate=Alamat surel tidak terhubung dengan akun apapun.
send_reset_mail=Kirim Surel Pemulihan Akun
reset_password=Pemulihan Akun
password_too_short=Panjang kata sandi tidak boleh kurang dari %d karakter.
verify=Verifikasi
scratch_code=Kode coretan
use_scratch_code=Gunakan kode coretan
twofa_scratch_used=Anda telah menggunakan kode coretan anda. Anda telah dialihkan ke halaman pengaturan dua-faktor jadi anda boleh menghapus pendaftaran perangkat anda atau menghasilkan kode coretan yang baru.
twofa_passcode_incorrect=Kata sandi Anda salah. Jika Anda salah tempatkan perangkat Anda, gunakan kode gosok Anda untuk masuk.
twofa_scratch_token_incorrect=Kode coretan anda tidak tepat.
login_openid=OpenID
openid_connect_submit=Sambungkan
openid_connect_title=Sambungkan ke akun yang sudah ada
openid_register_title=Buat akun baru
openid_signin_desc=Masukkan URI OpenID Anda. Misalnya: https://anne.me, bob.openid.org.cn, atau gnusocial.net/carry.
email_domain_blacklisted=Anda tidak dapat mendaftar dengan alamat email.
authorize_application=Izinkan aplikasi
[mail]
activate_account=Silakan aktifkan akun anda
activate_email=Verifikasi alamat surel anda
reset_password=Pulihkan akun Anda
register_success=Pendaftaran berhasil
register_notify=Selamat Datang di Gitea
[modal]
yes=Ya
no=Tidak
modify=Perbarui
[form]
UserName=Nama Pengguna
RepoName=Nama repositori
Email=Alamat surel
Password=Kata Sandi
Retype=Ketik Ulang Kata Sandi
SSHTitle=Nama kunci SSH
HttpsUrl=HTTPS URL
PayloadUrl=Muatan URL
@@ -205,6 +269,7 @@ CommitChoice=Pilihan Commit
TreeName=Jalur berkas
Content=Konten
SSPISeparatorReplacement=Pemisah
require_error=` tidak boleh kosong.`
size_error=` harus berukuran %s.`
@@ -214,53 +279,100 @@ email_error=` bukan alamat surel yang valid. `
url_error=` bukan URL yang valid.`
include_error=` harus mengandung substring '%s'.`
unknown_error=Kesalahan yang tidak diketahui:
lang_select_error=Pilih bahasa dari daftar.
email_been_used=Alamat email sudah digunakan.
openid_been_used=Alamat OpenID '%s' sudah digunakan.
username_password_incorrect=Nama pengguna atau sandi salah.
password_complexity=Kata sandi tidak memenuhi persyaratan kerumitan:
password_lowercase_one=Sekurang-kurangnya satu karakter kecil
password_uppercase_one=Sekurang-kurangnya satu karakter besar
password_digit_one=Sekurang-kurangnya satu angka
password_special_one=Sekurang-kurangnya satu karater khusus (tanda baca, kurung, kutip, dll.)
enterred_invalid_repo_name=Nama repositori yang Anda masukkan salah.
enterred_invalid_owner_name=Nama pemilik baru salah.
enterred_invalid_password=Kata sandi yang Anda masukkan salah.
user_not_exist=Pengguna tidak ada.
team_not_exist=Tim tidak ada.
last_org_owner=Anda tidak dapat menghapus pengguna terakhir dari tim pemilik. Harus ada setidaknya satu pemilik dalam tim yang diberikan.
cannot_add_org_to_team=Sebuah organisasi tidak dapat ditambahkan sebagai anggota tim.
invalid_ssh_key=Tidak dapat memverifikasi kunci SSH Anda: %s
invalid_gpg_key=Tidak dapat memverifikasi kunci GPG Anda: %s
unable_verify_ssh_key=Tidak dapat memverifikasi kunci SSH; periksa kembali bila ada kesalahan.
auth_failed=Otentikasi gagal: %v
still_own_repo=Akun anda memiliki satu atau lebih repositori, pindahkan atau transfer terlebih dahulu.
still_has_org=Akun Anda adalah anggota dari satu atau lebih organisasi, tinggalkan terlebih dahulu.
org_still_own_repo=Organisasi ini masih memiliki satu atau lebih repositori; hapus atau transfer terlebih dahulu.
target_branch_not_exist=Target cabang tidak ada.
[user]
change_avatar=Ganti avatar anda…
join_on=Telah bergabung di
repositories=Repositori
activity=Aktivitas Publik
followers=Pengikut
starred=Repositori Terbintang
following=Mengikuti
follow=Ikuti
unfollow=Berhenti Mengikuti
heatmap.loading=Memuat Peta Panas…
user_bio=Biografi
form.name_reserved=Nama pengguna '%s' dicadangkan.
form.name_pattern_not_allowed=Pola '%s' tidak diperbolehkan dalam nama pengguna.
[settings]
profile=Profil
account=Akun
password=Kata Sandi
security=Keamanan
avatar=Avatar
ssh_gpg_keys=Kunci SSH / GPG
social=Akun Sosial
applications=Aplikasi
orgs=Kelola organisasi
repos=Repositori
delete=Hapus Akun
twofa=Otentikasi Dua-Faktor
account_link=Akun Tertaut
organization=Organisasi
uid=Uid
u2f=Kunci keamanan
public_profile=Profil Publik
profile_desc=Alamat email Anda akan digunakan untuk notifikasi dan operasi lainnya.
password_username_disabled=Pengguna non-lokal tidak diizinkan untuk mengubah nama pengguna mereka. Silakan hubungi administrator sistem anda untuk lebih lanjut.
full_name=Nama Lengkap
website=Situs Web
location=Lokasi
update_theme=Perbarui Tema
update_profile=Perbarui Profil
update_profile_success=Profil anda telah diperbarui.
change_username=Nama pengguna Anda telah diganti.
change_username_prompt=Catatan: Perubahan nama pengguna juga mengubah URL akun Anda.
continue=Lanjutkan
cancel=Batalkan
language=Bahasa
ui=Tema
lookup_avatar_by_mail=Cari Avatar melalui Alamat Email
federated_avatar_lookup=Aktifkan Pencarian Avatar Representasi
enable_custom_avatar=Gunakan Avatar Pilihan
choose_new_avatar=Pilih avatar baru
update_avatar=Perbarui Avatar
delete_current_avatar=Hapus Avatar Saat Ini
uploaded_avatar_not_a_image=Berkas yang diunggah bukanlah gambar.
uploaded_avatar_is_too_big=Berkas yang diunggah melebihi ukuran maksimum.
update_avatar_success=Avatar Anda telah diperbarui.
change_password=Perbarui kata sandi
old_password=Kata Sandi Saat Ini
new_password=Kata Sandi Baru
retype_new_password=Ketik Ulang Kata Sandi Baru
password_incorrect=Kata sandi saat ini salah.
emails=Alamat Surel
email_desc=Alamat surel utama anda akan digunakan untuk notifikasi dan operasi lainnya.
@@ -318,6 +430,7 @@ confirm_delete_account=Konfirmasi Penghapusan
owner=Pemilik
repo_name=Nama Repositori
visibility=Jarak pandang
clone_helper=Butuh bantuan kloning? Kunjungi <a target="_blank" rel="noopener noreferrer" href="%s">Bantuan</a>.
fork_repo=Cabang Gudang penyimpanan
fork_from=Cabang Dari
repo_desc=Deskripsi
@@ -508,6 +621,7 @@ pulls.new=Permintaan Tarik Baru
pulls.filter_branch=Penyaringan cabang
pulls.no_results=Hasil tidak ditemukan.
pulls.create=Buat Permintaan Tarik
pulls.title_desc=ingin menggabungkan komit %[1]d dari <code>%[2]s</code> menuju <code id="branch_target">%[3]s</code>
pulls.merged_title_desc=commit %[1]d telah digabungkan dari <code>%[2]s</code> menjadi <code>%[3]s</code> %[4]s
pulls.tab_conversation=Percakapan
pulls.tab_commits=Melakukan
@@ -625,6 +739,7 @@ settings.webhook.request=Permintaan
settings.webhook.response=Tanggapan
settings.webhook.headers=Tajuk
settings.webhook.body=Tubuh
settings.githooks_desc=Kaitan Git diberdayakan oleh Git itu sendiri. Anda bisa menyunting berkas kaitan di bawah untuk mempersiapkan operasi kustom.
settings.githook_edit_desc=Jika hook tidak aktif, konten sampel akan dipaparkan. Meninggalkan konten dengan nilai kosong akan menonaktifkan hook ini.
settings.githook_name=Nama Hook
settings.githook_content=Konten Hook

View File

@@ -1062,6 +1062,8 @@ pulls.no_merge_desc=リポジトリのマージオプションがすべて無効
pulls.no_merge_helper=リポジトリ設定でマージを有効にするか、手動でマージしてください。
pulls.no_merge_wip=このプルリクエストはWork in Progressとマークされているため、マージすることはできません。
pulls.no_merge_status_check=すべての必要なステータスチェックが成功していないため、このプルリクエストはマージできません。
pulls.no_merge_not_ready=このプルリクエストはマージする準備ができていません。 レビュー状況とステータスチェックを確認してください。
pulls.no_merge_access=このプルリクエストをマージする権限がありません。
pulls.merge_pull_request=プルリクエストをマージ
pulls.rebase_merge_pull_request=リベースしてマージ
pulls.rebase_merge_commit_pull_request=リベースしてマージ(--no-ff)
@@ -1412,6 +1414,8 @@ settings.protect_approvals_whitelist_enabled=ホワイトリストに登録し
settings.protect_approvals_whitelist_enabled_desc=ホワイトリストに登録したユーザーやチームによるレビューのみを、必要な承認とみなします。 承認のホワイトリストが無い場合は、書き込み権限がある人によるレビューを必要な承認とみなします。
settings.protect_approvals_whitelist_users=ホワイトリストに含めるレビューア:
settings.protect_approvals_whitelist_teams=ホワイトリストに含めるレビューチーム:
settings.dismiss_stale_approvals=古くなった承認を取り消す
settings.dismiss_stale_approvals_desc=プルリクエストの内容を変える新たなコミットがブランチにプッシュされた場合、以前の承認を取り消します。
settings.add_protected_branch=保護を有効にする
settings.delete_protected_branch=保護を無効にする
settings.update_protect_branch_success=ブランチ '%s' の保護を更新しました。
@@ -1747,6 +1751,7 @@ users.new_account=ユーザーアカウントを作成
users.name=ユーザー名
users.activated=アクティベート済み
users.admin=管理者
users.restricted=制限あり
users.repos=リポジトリ
users.created=作成日
users.last_login=前回のサインイン
@@ -1765,6 +1770,7 @@ users.max_repo_creation_desc=( -1を設定するとデフォルトの制限が
users.is_activated=ユーザーアカウントはアクティベート済み
users.prohibit_login=サインイン無効
users.is_admin=管理者
users.is_restricted=制限あり
users.allow_git_hook=Gitフックを作成可
users.allow_import_local=ローカルリポジトリをインポート可
users.allow_create_organization=組織を作成可
@@ -2025,8 +2031,54 @@ monitor.execute_time=実行時間
monitor.process.cancel=処理をキャンセル
monitor.process.cancel_desc=処理をキャンセルするとデータが失われる可能性があります
monitor.process.cancel_notices=キャンセル: <strong>%s</strong>?
monitor.queues=キュー
monitor.queue=キュー: %s
monitor.queue.name=キュー名
monitor.queue.type=種類
monitor.queue.exemplar=要素の型
monitor.queue.numberworkers=ワーカー数
monitor.queue.maxnumberworkers=ワーカー数上限
monitor.queue.review=設定確認
monitor.queue.review_add=確認/ワーカー追加
monitor.queue.configuration=初期設定
monitor.queue.nopool.title=ワーカープールはありません
monitor.queue.nopool.desc=このキューは他のキューをラップし、これ自体にはワーカープールがありません。
monitor.queue.wrapped.desc=wrappedキューは、すぐに開始されないキューをラップし、入ってきたリクエストをチャンネルにバッファリングします。 これ自体にはワーカープールがありません。
monitor.queue.persistable-channel.desc=persistable-channelキューは二つのキューをラップします。 一つはchannelキューで、自分のワーカープールを持ちます。もう一つはlevelキューで、前回のシャットダウンからリクエストを引き継ぐためのものです。 これ自体にはワーカープールがありません。
monitor.queue.pool.timeout=タイムアウト
monitor.queue.pool.addworkers.title=ワーカーの追加
monitor.queue.pool.addworkers.submit=ワーカーを追加
monitor.queue.pool.addworkers.desc=このプールに、タイムアウト付きまたはタイムアウト無しでワーカーを追加します。 タイムアウトを指定した場合は、タイムアウト後にそれらのワーカーがこのプールから取り除かれます。
monitor.queue.pool.addworkers.numberworkers.placeholder=ワーカー数
monitor.queue.pool.addworkers.timeout.placeholder=0でタイムアウト無し
monitor.queue.pool.addworkers.mustnumbergreaterzero=追加するワーカー数は1以上にしてください
monitor.queue.pool.addworkers.musttimeoutduration=タイムアウトは 、Go言語の時間差表記(例 5m)、または0にしてください
monitor.queue.settings.title=プール設定
monitor.queue.settings.desc=ワーカーへのキューのブロックが発生すると、それに応じてプール数がブースト分ずつ動的に増えます。 これらの変更は現在のワーカーグループには影響しません。
monitor.queue.settings.timeout=ブースト分のタイムアウト
monitor.queue.settings.timeout.placeholder=現在の設定 %[1]v
monitor.queue.settings.timeout.error=タイムアウトは 、Go言語の時間差表記(例 5m)、または0にしてください
monitor.queue.settings.numberworkers=ブースト分のワーカー数
monitor.queue.settings.numberworkers.placeholder=現在の設定 %[1]d
monitor.queue.settings.numberworkers.error=追加するワーカー数はゼロ以上にしてください
monitor.queue.settings.maxnumberworkers=ワーカー数上限
monitor.queue.settings.maxnumberworkers.placeholder=現在の設定 %[1]d
monitor.queue.settings.maxnumberworkers.error=ワーカー数上限は数値にしてください
monitor.queue.settings.submit=設定を更新
monitor.queue.settings.changed=設定を更新しました
monitor.queue.settings.blocktimeout=現在のブロックタイムアウト
monitor.queue.settings.blocktimeout.value=%[1]v
monitor.queue.pool.none=このキューにはプールがありません
monitor.queue.pool.added=ワーカーグループを追加しました
monitor.queue.pool.max_changed=ワーカー数の上限を変更しました
monitor.queue.pool.workers.title=アクティブなワーカーグループ
monitor.queue.pool.workers.none=ワーカーグループはありません。
monitor.queue.pool.cancel=ワーカーグループのシャットダウン
monitor.queue.pool.cancelling=ワーカーグループをシャットダウンしています
monitor.queue.pool.cancel_notices=このワーカー数 %s のグループをシャットダウンしますか?
monitor.queue.pool.cancel_desc=キューをワーカーグループ無しのままにすると、リクエストがブロックし続ける原因となります。
notices.system_notice_list=システム通知
notices.view_detail_header=通知の詳細を表示
@@ -2120,4 +2172,3 @@ error.probable_bad_default_signature=警告! これはデフォルト鍵のIDで
[units]
error.no_unit_allowed_repo=このリポジトリのどのセクションにもアクセスが許可されていません。
error.unit_not_allowed=このセクションへのアクセスが許可されていません。

View File

@@ -3,9 +3,9 @@ dashboard=대시보드
explore=탐색
help=도움말
sign_in=로그인
sign_in_with=냐후 ㅑㅜ 쨔소
sign_in_with=다음을 통해 로그인
sign_out=로그아웃
sign_up=ㄲㄷ햔ㅅㄷㄱ
sign_up=가입하기
link_account=계정 연결
register=가입하기
website=웹 사이트
@@ -14,18 +14,18 @@ page=페이지
template=템플릿
language=언어
notifications=알림
create_new=ㅊㄱㄷㅁㅅㄷ...
user_profile_and_more=ㅖ개랴ㅣㄷ 뭉 ㄴㄷㅅ샤ㅜㅎㄴ...
create_new=생성하기
user_profile_and_more=프로파일 및 설정
signed_in_as=다음 사용자로 로그인됨
enable_javascript=쏘ㅑㄴ ㅈ듀냣ㄷ 재간 ㅠㄷㅅㅅㄷㄱ 쟈소 ㅓㅁㅍㅁㄴㅊ갸ㅔㅅ.
enable_javascript=이 웹사이트는 자바스크립트 활성화가 필요합니다.
username=사용자명
email=뜨먀ㅣ ㅁㅇㅇㄱㄷㄴㄴ
email=이메일 주소
password=비밀번호
re_type=ㄲㄷ-쑈ㅔㄷ ㅖㅁㄴㄴ잭ㅇ
captcha=ㅊ몠촘
twofa=ㅆ재-ㄻㅊ색 며소두샻ㅁ샤ㅐㅜ
twofa_scratch=ㅆ재-ㄻㅊ색 ㄴㅊㄱㅁㅅ초 챙ㄷ
re_type=비밀번호 재입력
captcha=보안 문자
twofa=2단계 인증
twofa_scratch=2단계 일회성 코드
passcode=인증코드
u2f_insert_key=보안 키를 입력해주세요.
@@ -50,12 +50,12 @@ new_mirror=새로운 미러
new_fork=새 저장소 포크
new_org=새로운 조직
manage_org=조직 관리
admin_panel=냣ㄷ ㅁ으ㅑㅜㅑㄴㅅㄱㅁ샤ㅐㅜ
admin_panel=사이트 관리
account_settings=계정 설정
settings=설정
your_profile=ㅖ개랴ㅣㄷ
your_starred=ㄴㅅㅁㄱㄱㄷㅇ
your_settings=ㄴㄷㅅ샤ㅜㅎㄴ
your_profile=프로필
your_starred=즐겨찾기
your_settings=설정
all=전체
sources=소스
@@ -66,71 +66,75 @@ forks=포크
activities=활동
pull_requests=풀 리퀘스트
issues=이슈들
milestones=마일스톤
cancel=취소
add=추가
write=쓰기
preview=미리보기
loading=불러오는 중...
[startpage]
app_desc=편리한 설치형 Git 서비스
license=오픈 소스
[install]
install=설치
title=ㅑㅜㅑ샤미 채ㅜ랴혁ㅁ샤ㅐㅜ
title=초기 설정
docker_helper=Gitea를 Docker에서 실행하려면 설정 전에 이 <a target="_blank" rel="noopener noreferrer" href="%s">문서</a>를 읽어보세요.
requite_db_desc=Gitea를 실행하려면 MySQL, PostgreSQL, MSSQL 또는 SQLite3 중 하나가 필요합니다.
db_title=데이터베이스 설정
db_type=데이터베이스 유형
host=호스트
user=ㅕㄴㄷ구믇
user=이름
password=비밀번호
db_name=데이터베이스 이름
ssl_mode=ㄴ니
ssl_mode=SSL
charset=문자셋
path=경로
sqlite_helper=SQLite3 데이터베이스에 대한 파일 경로입니다.<br>Gitea를 서비스로 구동할 경우, 절대 경로를 입력해주십시오.
err_empty_db_path=SQLite3 데이터베이스 경로는 필수 입력 값입니다.
no_admin_and_disable_registration=ㅛㅐㅕ ㅊ무ㅜㅐㅅ 얀뮤ㅣㄷ ㅕㄴㄷㄱ ㄴ딜-ㄱㄷ햔ㅅㄱㅁ샤ㅐㅜ 쟈쇄ㅕㅅ ㅊㄱㄷㅁ샤ㅜㅎ 무 ㅁ으ㅑㅜㅑㄴㅅㄱㅁ색 ㅁㅊ채ㅕㅜㅅ.
err_empty_admin_password=쏟 ㅁ으ㅑㅜㅑㄴㅅㄱㅁ색 ㅔㅁㄴㄴ잭ㅇ ㅊ무ㅜㅐㅅ ㅠㄷ 드ㅔ쇼.
no_admin_and_disable_registration=관리자 계정을 만들지 않고 등록을 비활성화할 수 없습니다.
err_empty_admin_password=관리자 비밀번호는 비어 있을 수 없습니다.
err_empty_admin_email=관리자 이메일은 비어 있을 수 없습니다.
err_admin_name_is_reserved=관리자 사용자 이름이 올바르지 않습니다, 제한된 사용자 이름입니다
err_admin_name_is_invalid=관리자 사용자 이름이 올바르지 않습니다
general_title=ㅎ둗ㄱ미 ㄴㄷㅅ샤ㅜㅎㄴ
app_name=냣ㄷ 쌰싣
app_name_helper=ㅛㅐㅕ ㅊ무 둣ㄷㄱ ㅛㅐㅕㄱ 채ㅡㅔ무ㅛ ㅜ믇 ㅗㄷㄱㄷ.
general_title=기본설정
app_name=사이트 제목
app_name_helper=회사이름을 넣으세요.
repo_path=저장소 최상위 경로
repo_path_helper=ㄲ드ㅐㅅㄷ 햣 ㄱ데ㅐ냐새갿ㄴ 쟈ㅣㅣ ㅠㄷ ㄴㅁㅍㄷㅇ 새 소ㅑㄴ 약ㄷㅊ새교.
lfs_path=햣 ㅣㄹㄴ 깨ㅐㅅ ㅖㅁ소
lfs_path_helper=랴ㅣㄷㄴ ㅅㄱㅁ찯ㅇ ㅠㅛ 햣 ㅣㄹㄴ 쟈ㅣㅣ ㅠㄷ ㄴ색ㄷㅇ ㅑㅜ 소ㅑㄴ 약ㄷㅊ새교. ㅣㄷㅁㅍㄷ 드ㅔ쇼 새 얀뮤ㅣㄷ.
run_user=껴ㅜ ㅁㄴ ㅕㄴㄷ구믇
run_user_helper=뚯ㄷㄱ 솓 ㅐㅔㄷㄱㅁ샤ㅜㅎ 뇬ㅅ드 ㅕㄴㄷ구믇 솜ㅅ 햣ㄷㅁ 겨ㅜㄴ ㅁㄴ. ㅜㅐㅅㄷ 솜ㅅ 소ㅑㄴ ㅕㄴㄷㄱ ㅡㅕㄴㅅ ㅗㅁㅍㄷ ㅁㅊㅊㄷㄴㄴ 새 솓 ㄱ데ㅐ냐새교 개ㅐㅅ ㅔㅁ소.
domain=ㄴ노 ㄴㄷㄱㅍㄷㄱ 애ㅡ먀ㅜ
domain_helper=애ㅡ먀ㅜ ㅐㄱ ㅙㄴㅅ ㅁㅇㅇㄱㄷㄴㄴ 랙 노ㅗ 치ㅐㅜㄷ ㅕ낀.
repo_path_helper=Git 원격 저장소는 이 디렉터리에 저장 됩니다.
lfs_path=Git LFS 루트 경로
lfs_path_helper=Git LFS에 저장된 파일들은 이 디렉토리에 저장됩니다. LFS를 사용하지 않는다면 빈칸으로 남겨주세요.
run_user=실행 사용자명
run_user_helper=Gitea 를 실행할 시스템 사용자명을 넣으세요. 시스템 사용자는 레포지토리 루트 경로에 대한 권한이 필요합니다.
domain=SSH 서버 도메인
domain_helper=SSH clone URL 에 대한 도메인 또는 호스트 주소
ssh_port=ㄴ노 ㄴㄷㄱㅍㄷㄱ ㅖㅐㄳ
ssh_port_helper=ㅖㅐㄳ ㅜㅕㅡㅠㄷㄱ ㅛㅐㅕㄱ 노ㅗ ㄴㄷㄱㅍㄷㄱ ㅣㅑㄴㅅ둔 ㅐㅜ. ㅣㄷㅁㅍㄷ 드ㅔ쇼 새 얀뮤ㅣㄷ.
http_port=햣ㄷㅁ ㅗㅆ쎄 ㅣㅑㄴㅅ두 ㅖㅐㄳ
http_port_helper=ㅖㅐㄳ ㅜㅕㅡㅠㄷㄱ 솓 햣ㄷㅁㄴ ㅈ듀 ㄴㄷㄱㅍㄷㄱ 쟈ㅣㅣ ㅣㅑㄴㅅ두 ㅐㅜ.
app_url=햣ㄷㅁ ㅠㅁㄴㄷ ㅕ끼
app_url_helper=ㅠㅁㄴㄷ ㅁㅇㅇㄱㄷㄴㄴ 랙 ㅗㅆ쎼(ㄴ) 치ㅐㅜㄷ ㅕ낀 뭉 드먀ㅣ ㅜㅐ샤럋ㅁ샤ㅐㅜㄴ.
ssh_port_helper=SSH 서버가 실행되고 있는 포트를 입력하세요. 비워둘 경우 SSH를 사용하지 않습니다.
http_port=Gitea HTTP 수신 포트
http_port_helper=Gitea 웹서버가 수신할 포트 번호
app_url=Gitea 기본 URL
app_url_helper=HTTP(S) clone URL 및 이메일 알림 기본 주소
log_root_path=로그 경로
log_root_path_helper=ㅣㅐㅎ 랴ㅣㄷㄴ 쟈ㅣㅣ ㅠㄷ ㅈ걋ㅅ두 새 소ㅑㄴ 약ㄷㅊ새교.
log_root_path_helper=로그파일은 이 디렉토리에 저장됩니다.
optional_title=추가설정
email_title=뜨먀ㅣ ㄴㄷㅅ샤ㅜㅎㄴ
email_title=이메일 설정
smtp_host=SMTP 호스트
smtp_from=ㄴ둥 뜨먀ㅣ ㅁㄴ
smtp_from_helper=뜨먀ㅣ ㅁㅇㅇㄱㄷㄴㄴ 햣ㄷㅁ 쟈ㅣㅣ ㅕㄴㄷ. 뚯ㄷㄱ ㅁ ㅔㅣ먀ㅜ 드먀ㅣ ㅁㅇㅇㄱㄷㄴㄴ ㅐㄱ ㅕㄴㄷ 솓 "ㅜ믇" <드먀ㅣ@ㄷㅌ므ㅔㅣㄷ.kr> 래금ㅅ.
mailer_user=느쎼 ㅕㄴㄷ구믇
mailer_password=느쎼 ㅖㅁㄴㄴ잭ㅇ
register_confirm=ㄲㄷ벼ㅑㄱㄷ 뜨먀ㅣ 채ㅜ랴금샤ㅐㅜ 새 ㄲㄷ햔ㅅㄷㄱ
mail_notify=뚜뮤ㅣㄷ 뜨먀ㅣ ㅜㅐ샤럋ㅁ샤ㅐㅜㄴ
server_service_title=ㄴㄷㄱㅍㄷㄱ 뭉 쏘ㅑㄱㅇ-ㅖㅁㄱ쇼 ㄴㄷㄱ퍛ㄷ ㄴㄷㅅ샤ㅜㅎㄴ
offline_mode=뚜뮤ㅣㄷ ㅣㅐㅊ미 ㅡㅐㅇㄷ
offline_mode_popup=얀뮤ㅣㄷ 소ㅑㄱㅇ-ㅔㅁㄱ쇼 채ㅜㅅ둣 ㅇ디ㅑㅍㄷ교 ㅜㄷㅅ재간 뭉 ㄴㄷㄱㅍㄷ 미ㅣ ㄱㄷ내ㅕㄱㅊㄷㄴ ㅣㅐㅊ미ㅣㅛ.
disable_gravatar=얀뮤ㅣㄷ ㅎㄱㅁㅍㅍㅁㅅㅁㄱ
disable_gravatar_popup=얀뮤ㅣㄷ ㅎㄱㅁㅍㅁㅅㅁㄱ 뭉 소ㅑㄱㅇ-ㅔㅁㄱ쇼 ㅁㅍㅁㄴㅅㅁㄱ 내ㅕㄱㅊㄷㄴ. ㅁ ㅇㄷㄹ며ㅣㅅ ㅁㅍㅁㅅㅁㄱ 쟈ㅣㅣ ㅠㄷ ㅕㄴㄷㅇ ㅕㅟㄷㄴㄴ ㅁ ㅕㄴㄷㄱ ㅣㅐㅊ미ㅣㅛ ㅕㅔㅣㅐㅁㅇㄴ 무 ㅁㅍㅁㅅㅁㄱ.
smtp_from=이메일 발신인
smtp_from_helper=Gitea 가 사용할 이메일 주소. 이메일 주소 또는 "이름" <email@example.com> 형식으로 입력하세요.
mailer_user=SMTP 사용자이름
mailer_password=SMTP 비밀번호
register_confirm=가입시 이메일 확인 필수
mail_notify=이메일 알림 켜기
server_service_title=서버 및 기타 서비스 설정
offline_mode=로컬 모드 켜기
offline_mode_popup=타사 콘텐츠 전송 네트워크를 사용하지 않도록 설정하고 모든 리소스를 로컬로 제공하십시오.
disable_gravatar=Gravatar 사용안함
disable_gravatar_popup=Gravatar 및 타사 아바타 소스를 사용하지 않도록 설정합니다. 사용자가 로컬로 아바타를 업로드하지 않는 한 기본 아바타가 사용됩니다.
federated_avatar_lookup=아바타 연동 사용여부
federated_avatar_lookup_popup=libravatar 기반 오픈소스 서비스 사용 목적으로 연합 아바타 조회를 허용하기
disable_registration=사용자 등록 비활성화
@@ -509,6 +513,8 @@ confirm_delete_account=삭제 승인
delete_account_title=사용자 계정 삭제
delete_account_desc=이 계정을 정말로 삭제하시겠습니까?
email_notifications.enable=이메일 알림 켜기
email_notifications.disable=이메일 알림 끄기
[repo]
owner=소유자
@@ -879,6 +885,7 @@ milestones.filter_sort.most_complete=완료율이 높은 순
milestones.filter_sort.most_issues=이슈 많은 순
milestones.filter_sort.least_issues=이슈 적은 순
ext_wiki=외부 위키
ext_wiki.desc=외부 위키에 연결하기.
@@ -960,6 +967,8 @@ settings.basic_settings=기본 설정
settings.mirror_settings=미러 설정
settings.sync_mirror=지금 동기화
settings.mirror_sync_in_progress=미러 동기화 진행중입니다. 잠시 후 다시 확인해주십시오.
settings.email_notifications.enable=이메일 알림 켜기
settings.email_notifications.disable=이메일 알림 끄기
settings.site=웹 사이트
settings.update_settings=설정 저장
settings.advanced_settings=고급 설정
@@ -1080,6 +1089,8 @@ settings.protected_branch_can_push_yes=푸시할 수 있습니다.
settings.protected_branch_can_push_no=푸시할 수 없습니다.
settings.branch_protection='<b>%s</b>' 브랜치 보호
settings.protect_this_branch=브랜치 보호 활성화
settings.protect_disable_push=푸시 끄기
settings.protect_enable_push=푸시 켜기
settings.protect_whitelist_search_users=사용자 찾기...
settings.protect_whitelist_search_teams=팀 찾기...
settings.protect_merge_whitelist_committers=머지 화이트리스트 활성화
@@ -1511,6 +1522,7 @@ monitor.process=실행중인 프로세스들
monitor.desc=설명
monitor.start=시작 시간
monitor.execute_time=실행 시간
monitor.queue.configuration=초기 설정

View File

@@ -1596,7 +1596,7 @@ settings.full_name=Pilns vārds, uzvārds
settings.website=Mājas lapa
settings.location=Atrašanās vieta
settings.permission=Tiesības
settings.repoadminchangeteam=Repozitorija administrators var pievienot vain noņemt piekļuvi komandām
settings.repoadminchangeteam=Repozitorija administrators var pievienot vai noņemt piekļuvi komandām
settings.visibility=Redzamība
settings.visibility.public=Publiska
settings.visibility.limited=Ierobežota (redzama tikai autorizētiem lietotājiem)
@@ -2025,8 +2025,54 @@ monitor.execute_time=Izpildes laiks
monitor.process.cancel=Atcelt procesu
monitor.process.cancel_desc=Procesa atcelšana var radīt datu zaudējumus
monitor.process.cancel_notices=Atcelt: <strong>%s</strong>?
monitor.queues=Rindas
monitor.queue=Rinda: %s
monitor.queue.name=Nosaukums
monitor.queue.type=Veids
monitor.queue.exemplar=Eksemplāra veids
monitor.queue.numberworkers=Strādņu skaits
monitor.queue.maxnumberworkers=Maksimālais strādņu skaits
monitor.queue.review=Pārbaudīt konfigurāciju
monitor.queue.review_add=Pārbaudīt/Pievienot strādņus
monitor.queue.configuration=Sākotnējā konfigurācija
monitor.queue.nopool.title=Nav strādņu pūla
monitor.queue.nopool.desc=Šī rinda apvieno citas rindas un tai nav strādņu pūla.
monitor.queue.wrapped.desc=Apvienojošā rinda apvieno lēni startējošās rindas, uzkrājot sarindotos pieprasījumus kanālā. Tai nav strādņu pūla.
monitor.queue.persistable-channel.desc=Patstāvīgas kanāli apvieno divas rindas, kanāla rindu, kurai ir savs strādņu pūls un līmeņu rindu patstāvīgajiem pieprasījumiem no iepriekšejām izslēgšanām. Tai nav strādņu pūla.
monitor.queue.pool.timeout=Noildze
monitor.queue.pool.addworkers.title=Pievienot strādņus
monitor.queue.pool.addworkers.submit=Pievienot
monitor.queue.pool.addworkers.desc=Pievienot strādņus šim pūlam ar vai bez noildzes. Ja uzstādīsies noildzi, tad šie strādņi tiks noņemti no pūla, kad noildze būs iestājusies.
monitor.queue.pool.addworkers.numberworkers.placeholder=Strādņu skaits
monitor.queue.pool.addworkers.timeout.placeholder=Norādiet 0, lai nebūtu noildzes
monitor.queue.pool.addworkers.mustnumbergreaterzero=Strādņu skaitam, ko pievienot, ir jābūt lielākam par nulli
monitor.queue.pool.addworkers.musttimeoutduration=Noildzei ir jābūt norādītai kā ilgumam, piemēram, 5m vai 0
monitor.queue.settings.title=Pūla iestatījumi
monitor.queue.settings.desc=Pūli var dinamiski augt un paildzinātu atbildi uz strādņu rindas bloķēšanu. Šis izmaiņas ietekmēs pašreizējās strādņu grupas.
monitor.queue.settings.timeout=Pagarināt noildzi
monitor.queue.settings.timeout.placeholder=Pašalaik %[1]v
monitor.queue.settings.timeout.error=Noildzei ir jābūt norādītai kā ilgumam, piemēram, 5m vai 0
monitor.queue.settings.numberworkers=Palielināt strādņu skaitu
monitor.queue.settings.numberworkers.placeholder=Pašalaik %[1]d
monitor.queue.settings.numberworkers.error=Strādņu skaitam ir jābūt lielākam vai vienādam ar nulli
monitor.queue.settings.maxnumberworkers=Maksimālais strādņu skaits
monitor.queue.settings.maxnumberworkers.placeholder=Pašalaik %[1]d
monitor.queue.settings.maxnumberworkers.error=Maksimālajam strādņu skaitam ir jābūt skaitlim
monitor.queue.settings.submit=Saglabāt iestatījumus
monitor.queue.settings.changed=Iestatījumi saglabāti
monitor.queue.settings.blocktimeout=Pašreizējās grupas noildze
monitor.queue.settings.blocktimeout.value=%[1]v
monitor.queue.pool.none=Rindai nav pūla
monitor.queue.pool.added=Strādņu grupa pievienota
monitor.queue.pool.max_changed=Maksimālais strādņu skaits mainīts
monitor.queue.pool.workers.title=Aktīvās strādņu grupas
monitor.queue.pool.workers.none=Nav strādņu grupu.
monitor.queue.pool.cancel=Izslēgt strādņu grupu
monitor.queue.pool.cancelling=Strādņu grupa tiek izslēgta
monitor.queue.pool.cancel_notices=Izslēgt šo grupu ar %s strādņiem?
monitor.queue.pool.cancel_desc=Atstājot rindu bez nevienas strādņu grupas, var radīt pieprasījumu bloķēšanos.
notices.system_notice_list=Sistēmas paziņojumi
notices.view_detail_header=Skatīt paziņojuma detaļas
@@ -2120,4 +2166,3 @@ error.probable_bad_default_signature=BRĪDINĀJUMS! Lai arī šai atslēgai ir n
[units]
error.no_unit_allowed_repo=Jums nav tiesību aplūkot nevienu šī repozitorija sadaļu.
error.unit_not_allowed=Jums nav tiesību piekļūt šai repozitorija sadaļai.

View File

@@ -2100,4 +2100,3 @@ error.probable_bad_default_signature=OSTRZEŻENIE! Pomimo, że domyślny klucz p
[units]
error.no_unit_allowed_repo=Nie masz uprawnień do żadnej sekcji tego repozytorium.
error.unit_not_allowed=Nie masz uprawnień do tej sekcji repozytorium.

View File

@@ -1062,6 +1062,8 @@ pulls.no_merge_desc=O merge deste pull request não pode ser aplicado porque tod
pulls.no_merge_helper=Habilite as opções de merge nas configurações do repositório ou faça o merge do pull request manualmente.
pulls.no_merge_wip=O merge deste pull request não pode ser aplicado porque está marcado como um trabalho em andamento.
pulls.no_merge_status_check=Este pull request não pode ter seu merge aplicado porque nem todas as verificações de status necessárias foram bem sucedidas.
pulls.no_merge_not_ready=Este pull request não está pronto para ser realizado o merge, verifique o status da revisão e as verificações de status.
pulls.no_merge_access=Você não está autorizado para realizar o merge deste pull request.
pulls.merge_pull_request=Aplicar merge do pull request
pulls.rebase_merge_pull_request=Aplicar Rebase e Merge
pulls.rebase_merge_commit_pull_request=Aplicar Rebase e Merge (--no-ff)
@@ -1412,6 +1414,8 @@ settings.protect_approvals_whitelist_enabled=Restringir aprovações a usuários
settings.protect_approvals_whitelist_enabled_desc=Somente as avaliações de usuários ou equipes da lista permitida serão contadas com as aprovações necessárias. Sem aprovação da lista permitida, as revisões de qualquer pessoa com acesso de escrita contam para as aprovações necessárias.
settings.protect_approvals_whitelist_users=Usuários com permissão de revisão:
settings.protect_approvals_whitelist_teams=Equipes com permissão de revisão:
settings.dismiss_stale_approvals=Descartar aprovações obsoletas
settings.dismiss_stale_approvals_desc=Quando novos commits que mudam o conteúdo do pull request são enviados para o branch, as antigas aprovações serão descartadas.
settings.add_protected_branch=Habilitar proteção
settings.delete_protected_branch=Desabilitar proteção
settings.update_protect_branch_success=Proteção do branch '%s' foi atualizada.
@@ -1747,6 +1751,7 @@ users.new_account=Criar conta de usuário
users.name=Nome de usuário
users.activated=Ativado
users.admin=Administrador
users.restricted=Restrito
users.repos=Repositórios
users.created=Criado
users.last_login=Último acesso
@@ -1765,6 +1770,7 @@ users.max_repo_creation_desc=(Use -1 para usar o limite padrão global.)
users.is_activated=Conta de usuário está ativada
users.prohibit_login=Desabilitar acesso
users.is_admin=É administrador
users.is_restricted=Está restrito
users.allow_git_hook=Pode criar hooks Git
users.allow_import_local=Pode importar repositórios locais
users.allow_create_organization=Pode criar organizações
@@ -2166,4 +2172,3 @@ error.probable_bad_default_signature=AVISO! Embora a chave padrão tenha este ID
[units]
error.no_unit_allowed_repo=Você não tem permissão para acessar nenhuma seção deste repositório.
error.unit_not_allowed=Você não tem permissão para acessar esta seção do repositório.

View File

@@ -2113,4 +2113,3 @@ error.probable_bad_default_signature=UYARI! Varsayılan anahtarın bu kimliği o
[units]
error.no_unit_allowed_repo=Bu deponun hiçbir bölümüne erişme izniniz yok.
error.unit_not_allowed=Bu depo bölümüne erişme izniniz yok.

View File

@@ -2115,4 +2115,3 @@ error.probable_bad_default_signature=УВАГА! Хоча типовий клю
[units]
error.no_unit_allowed_repo=У вас немає доступу до жодного розділу цього репозитория.
error.unit_not_allowed=У вас немає доступу до жодного розділу цього репозитория.

View File

@@ -2166,4 +2166,3 @@ error.probable_bad_default_signature=警告虽然默认密钥拥有此ID
[units]
error.no_unit_allowed_repo=您没有被允许访问此仓库的任何单元。
error.unit_not_allowed=您没有权限访问此仓库单元

View File

@@ -8,7 +8,6 @@
* http://opensource.org/licenses/MIT
*
*/
@import url('https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&subset=latin&display=swap');
/*!
* # Fomantic-UI - Reset
* http://github.com/fomantic/Fomantic-UI/

View File

@@ -7,8 +7,7 @@
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&subset=latin&display=swap);/*!
*//*!
* # Fomantic-UI - Reset
* http://github.com/fomantic/Fomantic-UI/
*

View File

@@ -130,6 +130,7 @@ func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig {
SearchPageSize: pageSize,
Filter: form.Filter,
AdminFilter: form.AdminFilter,
AllowDeactivateAll: form.AllowDeactivateAll,
Enabled: true,
},
}

View File

@@ -7,6 +7,7 @@ package admin
import (
"errors"
"fmt"
"net/http"
"code.gitea.io/gitea/models"
@@ -226,6 +227,11 @@ func DeleteUser(ctx *context.APIContext) {
return
}
if u.IsOrganization() {
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("%s is an organization not a user", u.Name))
return
}
if err := models.DeleteUser(u); err != nil {
if models.IsErrUserOwnRepos(err) ||
models.IsErrUserHasOrgs(err) {

View File

@@ -51,6 +51,10 @@ func SearchIssues(ctx *context.APIContext) {
// description: repository to prioritize in the results
// type: integer
// format: int64
// - name: type
// in: query
// description: filter by type (issues / pulls) if set
// type: string
// responses:
// "200":
// "$ref": "#/responses/IssueList"
@@ -67,20 +71,24 @@ func SearchIssues(ctx *context.APIContext) {
// find repos user can access (for issue search)
repoIDs := make([]int64, 0)
opts := &models.SearchRepoOptions{
PageSize: 15,
Private: false,
AllPublic: true,
TopicOnly: false,
Collaborate: util.OptionalBoolNone,
UserIsAdmin: ctx.IsUserSiteAdmin(),
OrderBy: models.SearchOrderByRecentUpdated,
}
if ctx.IsSigned {
opts.Private = true
opts.AllLimited = true
opts.UserID = ctx.User.ID
}
issueCount := 0
for page := 1; ; page++ {
repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
Page: page,
PageSize: 15,
Private: true,
Keyword: "",
OwnerID: ctx.User.ID,
TopicOnly: false,
Collaborate: util.OptionalBoolNone,
UserIsAdmin: ctx.IsUserSiteAdmin(),
UserID: ctx.User.ID,
OrderBy: models.SearchOrderByRecentUpdated,
})
opts.Page = page
repos, count, err := models.SearchRepositoryByName(opts)
if err != nil {
ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err)
return
@@ -125,6 +133,16 @@ func SearchIssues(ctx *context.APIContext) {
}
}
var isPull util.OptionalBool
switch ctx.Query("type") {
case "pulls":
isPull = util.OptionalBoolTrue
case "issues":
isPull = util.OptionalBoolFalse
default:
isPull = util.OptionalBoolNone
}
// Only fetch the issues if we either don't have a keyword or the search returned issues
// This would otherwise return all issues if no issues were found by the search.
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
@@ -137,6 +155,7 @@ func SearchIssues(ctx *context.APIContext) {
LabelIDs: labelIDs,
SortType: "priorityrepo",
PriorityRepoID: ctx.QueryInt64("priority_repo_id"),
IsPull: isPull,
})
}
@@ -188,6 +207,10 @@ func ListIssues(ctx *context.APIContext) {
// in: query
// description: search string
// type: string
// - name: type
// in: query
// description: filter by type (issues / pulls) if set
// type: string
// responses:
// "200":
// "$ref": "#/responses/IssueList"
@@ -223,6 +246,16 @@ func ListIssues(ctx *context.APIContext) {
}
}
var isPull util.OptionalBool
switch ctx.Query("type") {
case "pulls":
isPull = util.OptionalBoolTrue
case "issues":
isPull = util.OptionalBoolFalse
default:
isPull = util.OptionalBoolNone
}
// Only fetch the issues if we either don't have a keyword or the search returned issues
// This would otherwise return all issues if no issues were found by the search.
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
@@ -233,6 +266,7 @@ func ListIssues(ctx *context.APIContext) {
IsClosed: isClosed,
IssueIDs: issueIDs,
LabelIDs: labelIDs,
IsPull: isPull,
})
}
@@ -457,6 +491,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
return
}
issue.Repo = ctx.Repo.Repository
canWrite := ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
err = issue.LoadAttributes()
if err != nil {
@@ -464,7 +499,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
return
}
if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWrite(models.UnitTypeIssues) {
if !issue.IsPoster(ctx.User.ID) && !canWrite {
ctx.Status(http.StatusForbidden)
return
}
@@ -477,7 +512,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
}
// Update or remove the deadline, only if set and allowed
if (form.Deadline != nil || form.RemoveDeadline != nil) && ctx.Repo.CanWrite(models.UnitTypeIssues) {
if (form.Deadline != nil || form.RemoveDeadline != nil) && canWrite {
var deadlineUnix timeutil.TimeStamp
if (form.RemoveDeadline == nil || !*form.RemoveDeadline) && !form.Deadline.IsZero() {
@@ -501,7 +536,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
// Pass one or more user logins to replace the set of assignees on this Issue.
// Send an empty array ([]) to clear all assignees from the Issue.
if ctx.Repo.CanWrite(models.UnitTypeIssues) && (form.Assignees != nil || form.Assignee != nil) {
if canWrite && (form.Assignees != nil || form.Assignee != nil) {
oneAssignee := ""
if form.Assignee != nil {
oneAssignee = *form.Assignee
@@ -514,7 +549,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
}
}
if ctx.Repo.CanWrite(models.UnitTypeIssues) && form.Milestone != nil &&
if canWrite && form.Milestone != nil &&
issue.MilestoneID != *form.Milestone {
oldMilestoneID := issue.MilestoneID
issue.MilestoneID = *form.Milestone
@@ -600,7 +635,7 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) {
return
}
if !ctx.Repo.CanWrite(models.UnitTypeIssues) {
if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
ctx.Error(http.StatusForbidden, "", "Not repo writer")
return
}

View File

@@ -190,7 +190,7 @@ func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOpti
return
}
if issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin {
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.User.IsAdmin {
ctx.Error(http.StatusForbidden, "CreateIssueComment", errors.New(ctx.Tr("repo.issues.comment_on_locked")))
return
}

View File

@@ -179,7 +179,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
ctx.Error(http.StatusInternalServerError, "comment.LoadIssue() failed", err)
}
if comment.Issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) {
if comment.Issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull) {
ctx.Error(http.StatusForbidden, "ChangeIssueCommentReaction", errors.New("no permission to change reaction"))
return
}
@@ -380,7 +380,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i
return
}
if issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) {
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
ctx.Error(http.StatusForbidden, "ChangeIssueCommentReaction", errors.New("no permission to change reaction"))
return
}

View File

@@ -170,7 +170,7 @@ func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.I
return nil, err
}
if !ctx.Repo.CanWrite(models.UnitTypeIssues) {
if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
ctx.Status(http.StatusForbidden)
return nil, err
}

View File

@@ -194,7 +194,12 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
milestone.DeadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
}
if err := models.UpdateMilestone(milestone); err != nil {
var oldIsClosed = milestone.IsClosed
if form.State != nil {
milestone.IsClosed = *form.State == string(api.StateClosed)
}
if err := models.UpdateMilestone(milestone, oldIsClosed); err != nil {
ctx.ServerError("UpdateMilestone", err)
return
}

View File

@@ -53,7 +53,7 @@ func NewCommitStatus(ctx *context.APIContext, form api.CreateStatusOption) {
return
}
status := &models.CommitStatus{
State: models.CommitStatusState(form.State),
State: api.CommitStatusState(form.State),
TargetURL: form.TargetURL,
Description: form.Description,
Context: form.Context,
@@ -220,13 +220,13 @@ func getCommitStatuses(ctx *context.APIContext, sha string) {
}
type combinedCommitStatus struct {
State models.CommitStatusState `json:"state"`
SHA string `json:"sha"`
TotalCount int `json:"total_count"`
Statuses []*api.Status `json:"statuses"`
Repo *api.Repository `json:"repository"`
CommitURL string `json:"commit_url"`
URL string `json:"url"`
State api.CommitStatusState `json:"state"`
SHA string `json:"sha"`
TotalCount int `json:"total_count"`
Statuses []*api.Status `json:"statuses"`
Repo *api.Repository `json:"repository"`
CommitURL string `json:"commit_url"`
URL string `json:"url"`
}
// GetCombinedCommitStatusByRef returns the combined status for any given commit hash
@@ -293,7 +293,7 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) {
retStatus.Statuses = make([]*api.Status, 0, len(statuses))
for _, status := range statuses {
retStatus.Statuses = append(retStatus.Statuses, status.APIFormat())
if status.State.IsWorseThan(retStatus.State) {
if status.State.NoBetterThan(retStatus.State) {
retStatus.State = status.State
}
}

View File

@@ -115,7 +115,7 @@ func SettingsDeleteAvatar(ctx *context.Context) {
ctx.Redirect(ctx.Org.OrgLink + "/settings")
}
// SettingsDelete response for delete repository
// SettingsDelete response for deleting an organization
func SettingsDelete(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("org.settings")
ctx.Data["PageIsSettingsDelete"] = true

View File

@@ -68,7 +68,6 @@ func ServNoCommand(ctx *macaron.Context) {
// ServCommand returns information about the provided keyid
func ServCommand(ctx *macaron.Context) {
// Although we provide the verbs we don't need them at present they're just for logging purposes
keyID := ctx.ParamsInt64(":keyid")
ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo")
@@ -105,6 +104,17 @@ func ServCommand(ctx *macaron.Context) {
if err != nil {
if models.IsErrRepoNotExist(err) {
repoExist = false
for _, verb := range ctx.QueryStrings("verb") {
if "git-upload-pack" == verb {
// User is fetching/cloning a non-existent repository
ctx.JSON(http.StatusNotFound, map[string]interface{}{
"results": results,
"type": "ErrRepoNotExist",
"err": fmt.Sprintf("Cannot find repository: %s/%s", results.OwnerName, results.RepoName),
})
return
}
}
} else {
log.Error("Unable to get repository: %s/%s Error: %v", results.OwnerName, results.RepoName, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{

View File

@@ -238,6 +238,7 @@ func loadBranches(ctx *context.Context) []*Branch {
} else {
repoIDToRepo[pr.BaseRepoID] = pr.BaseRepo
}
pr.Issue.Repo = pr.BaseRepo
if pr.HasMerged {
baseGitRepo, ok := repoIDToGitRepo[pr.BaseRepoID]
@@ -260,7 +261,6 @@ func loadBranches(ctx *context.Context) []*Branch {
mergeMovedOn = true
}
}
}
isIncluded := divergence.Ahead == 0 && ctx.Repo.Repository.DefaultBranch != branchName

View File

@@ -157,12 +157,12 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
ctx.ServerError("OpenRepository", err)
return nil, nil, nil, nil, "", ""
}
defer headGitRepo.Close()
}
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
if err != nil {
headGitRepo.Close()
ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", ""
}
@@ -173,42 +173,40 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
baseRepo,
permBase)
}
headGitRepo.Close()
ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", ""
}
// user should have permission to read headrepo's codes
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
if err != nil {
headGitRepo.Close()
ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", ""
}
if !permHead.CanRead(models.UnitTypeCode) {
if log.IsTrace() {
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v",
ctx.User,
headRepo,
permHead)
if !isSameRepo {
// user should have permission to read headrepo's codes
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
if err != nil {
ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", ""
}
if !permHead.CanRead(models.UnitTypeCode) {
if log.IsTrace() {
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v",
ctx.User,
headRepo,
permHead)
}
ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", ""
}
headGitRepo.Close()
ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", ""
}
// Check if head branch is valid.
headIsCommit := ctx.Repo.GitRepo.IsCommitExist(headBranch)
headIsCommit := headGitRepo.IsCommitExist(headBranch)
headIsBranch := headGitRepo.IsBranchExist(headBranch)
headIsTag := headGitRepo.IsTagExist(headBranch)
if !headIsCommit && !headIsBranch && !headIsTag {
// Check if headBranch is short sha commit hash
if headCommit, _ := ctx.Repo.GitRepo.GetCommit(headBranch); headCommit != nil {
if headCommit, _ := headGitRepo.GetCommit(headBranch); headCommit != nil {
headBranch = headCommit.ID.String()
ctx.Data["HeadBranch"] = headBranch
headIsCommit = true
} else {
headGitRepo.Close()
ctx.NotFound("IsRefExist", nil)
return nil, nil, nil, nil, "", ""
}
@@ -229,14 +227,12 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
baseRepo,
permBase)
}
headGitRepo.Close()
ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", ""
}
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
compareInfo, err := headGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranch, headBranch)
if err != nil {
headGitRepo.Close()
ctx.ServerError("GetCompareInfo", err)
return nil, nil, nil, nil, "", ""
}
@@ -385,7 +381,8 @@ func CompareDiff(ctx *context.Context) {
}
defer headGitRepo.Close()
if err := parseBaseRepoInfo(ctx, headRepo); err != nil {
var err error
if err = parseBaseRepoInfo(ctx, headRepo); err != nil {
ctx.ServerError("parseBaseRepoInfo", err)
return
}
@@ -418,7 +415,7 @@ func CompareDiff(ctx *context.Context) {
if !nothingToCompare {
// Setup information for new form.
RetrieveRepoMetas(ctx, ctx.Repo.Repository)
RetrieveRepoMetas(ctx, ctx.Repo.Repository, true)
if ctx.Written() {
return
}
@@ -427,6 +424,11 @@ func CompareDiff(ctx *context.Context) {
beforeCommitID := ctx.Data["BeforeCommitID"].(string)
afterCommitID := ctx.Data["AfterCommitID"].(string)
if ctx.Data["Assignees"], err = ctx.Repo.Repository.GetAssignees(); err != nil {
ctx.ServerError("GetAssignees", err)
return
}
ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + "..." + base.ShortSha(afterCommitID)
ctx.Data["IsRepoToolbarCommits"] = true

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