Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
a63b2be21b
55 changed files with 3096 additions and 170 deletions
18
.drone.yml
18
.drone.yml
|
@ -19,7 +19,7 @@ volumes:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: deps-frontend
|
- name: deps-frontend
|
||||||
image: node:16
|
image: node:18
|
||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- make deps-frontend
|
- make deps-frontend
|
||||||
|
@ -34,7 +34,7 @@ steps:
|
||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: lint-frontend
|
- name: lint-frontend
|
||||||
image: node:16
|
image: node:18
|
||||||
commands:
|
commands:
|
||||||
- make lint-frontend
|
- make lint-frontend
|
||||||
depends_on: [deps-frontend]
|
depends_on: [deps-frontend]
|
||||||
|
@ -82,7 +82,7 @@ steps:
|
||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: checks-frontend
|
- name: checks-frontend
|
||||||
image: node:16
|
image: node:18
|
||||||
commands:
|
commands:
|
||||||
- make checks-frontend
|
- make checks-frontend
|
||||||
depends_on: [deps-frontend]
|
depends_on: [deps-frontend]
|
||||||
|
@ -97,13 +97,13 @@ steps:
|
||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: test-frontend
|
- name: test-frontend
|
||||||
image: node:16
|
image: node:18
|
||||||
commands:
|
commands:
|
||||||
- make test-frontend
|
- make test-frontend
|
||||||
depends_on: [lint-frontend]
|
depends_on: [lint-frontend]
|
||||||
|
|
||||||
- name: build-frontend
|
- name: build-frontend
|
||||||
image: node:16
|
image: node:18
|
||||||
commands:
|
commands:
|
||||||
- make frontend
|
- make frontend
|
||||||
depends_on: [test-frontend]
|
depends_on: [test-frontend]
|
||||||
|
@ -634,7 +634,7 @@ steps:
|
||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: deps-frontend
|
- name: deps-frontend
|
||||||
image: node:16
|
image: node:18
|
||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- make deps-frontend
|
- make deps-frontend
|
||||||
|
@ -652,7 +652,7 @@ steps:
|
||||||
image: techknowlogick/xgo:go-1.18.x
|
image: techknowlogick/xgo:go-1.18.x
|
||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
|
- curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs
|
||||||
- export PATH=$PATH:$GOPATH/bin
|
- export PATH=$PATH:$GOPATH/bin
|
||||||
- make release
|
- make release
|
||||||
environment:
|
environment:
|
||||||
|
@ -753,7 +753,7 @@ steps:
|
||||||
- git fetch --tags --force
|
- git fetch --tags --force
|
||||||
|
|
||||||
- name: deps-frontend
|
- name: deps-frontend
|
||||||
image: node:16
|
image: node:18
|
||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- make deps-frontend
|
- make deps-frontend
|
||||||
|
@ -771,7 +771,7 @@ steps:
|
||||||
image: techknowlogick/xgo:go-1.18.x
|
image: techknowlogick/xgo:go-1.18.x
|
||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
|
- curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs
|
||||||
- export PATH=$PATH:$GOPATH/bin
|
- export PATH=$PATH:$GOPATH/bin
|
||||||
- make release
|
- make release
|
||||||
environment:
|
environment:
|
||||||
|
|
12
.spectral.yaml
Normal file
12
.spectral.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
extends: [[spectral:oas, all]]
|
||||||
|
|
||||||
|
rules:
|
||||||
|
info-contact: off
|
||||||
|
oas2-api-host: off
|
||||||
|
oas2-parameter-description: off
|
||||||
|
oas2-schema: off
|
||||||
|
oas2-valid-schema-example: off
|
||||||
|
openapi-tags: off
|
||||||
|
operation-description: off
|
||||||
|
operation-singular-tag: off
|
||||||
|
operation-tag-defined: off
|
|
@ -4,9 +4,15 @@ This changelog goes through all the changes that have been made in each release
|
||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
## [1.16.9](https://github.com/go-gitea/gitea/releases/tag/v1.16.9) - 2022-06-21
|
## [1.16.9](https://github.com/go-gitea/gitea/releases/tag/v1.16.9) - 2022-07-12
|
||||||
|
|
||||||
|
* SECURITY
|
||||||
|
* Add write check for creating Commit status (#20332) (#20334)
|
||||||
|
* Check for permission when fetching user controlled issues (#20133) (#20196)
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
* Hide notify mail setting ui if not enabled (#20138) (#20337)
|
||||||
|
* Add write check for creating Commit status (#20332) (#20334)
|
||||||
|
* Only show Followers that current user can access (#20220) (#20253)
|
||||||
* Release page show all tags in compare dropdown (#20070) (#20071)
|
* Release page show all tags in compare dropdown (#20070) (#20071)
|
||||||
* Fix permission check for delete tag (#19985) (#20001)
|
* Fix permission check for delete tag (#19985) (#20001)
|
||||||
* Only log non ErrNotExist errors in git.GetNote (#19884) (#19905)
|
* Only log non ErrNotExist errors in git.GetNote (#19884) (#19905)
|
||||||
|
|
|
@ -62,7 +62,7 @@ ENV GITEA_CUSTOM /var/lib/gitea/custom
|
||||||
ENV GITEA_TEMP /tmp/gitea
|
ENV GITEA_TEMP /tmp/gitea
|
||||||
ENV TMPDIR /tmp/gitea
|
ENV TMPDIR /tmp/gitea
|
||||||
|
|
||||||
#TODO add to docs the ability to define the ini to load (usefull to test and revert a config)
|
#TODO add to docs the ability to define the ini to load (useful to test and revert a config)
|
||||||
ENV GITEA_APP_INI /etc/gitea/app.ini
|
ENV GITEA_APP_INI /etc/gitea/app.ini
|
||||||
ENV HOME "/var/lib/gitea/git"
|
ENV HOME "/var/lib/gitea/git"
|
||||||
VOLUME ["/var/lib/gitea", "/etc/gitea"]
|
VOLUME ["/var/lib/gitea", "/etc/gitea"]
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -312,6 +312,7 @@ lint: lint-frontend lint-backend
|
||||||
lint-frontend: node_modules
|
lint-frontend: node_modules
|
||||||
npx eslint --color --max-warnings=0 web_src/js build templates *.config.js docs/assets/js
|
npx eslint --color --max-warnings=0 web_src/js build templates *.config.js docs/assets/js
|
||||||
npx stylelint --color --max-warnings=0 web_src/less
|
npx stylelint --color --max-warnings=0 web_src/less
|
||||||
|
npx spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||||
|
|
||||||
.PHONY: lint-backend
|
.PHONY: lint-backend
|
||||||
lint-backend: golangci-lint vet editorconfig-checker
|
lint-backend: golangci-lint vet editorconfig-checker
|
||||||
|
@ -770,7 +771,7 @@ generate-manpage:
|
||||||
@mkdir -p man/man1/ man/man5
|
@mkdir -p man/man1/ man/man5
|
||||||
@./gitea docs --man > man/man1/gitea.1
|
@./gitea docs --man > man/man1/gitea.1
|
||||||
@gzip -9 man/man1/gitea.1 && echo man/man1/gitea.1.gz created
|
@gzip -9 man/man1/gitea.1 && echo man/man1/gitea.1.gz created
|
||||||
@#TODO A smal script witch format config-cheat-sheet.en-us.md nicely to suit as config man page
|
@#TODO A small script that formats config-cheat-sheet.en-us.md nicely for use as a config man page
|
||||||
|
|
||||||
.PHONY: pr\#%
|
.PHONY: pr\#%
|
||||||
pr\#%: clean-all
|
pr\#%: clean-all
|
||||||
|
|
|
@ -102,7 +102,7 @@ NOTES:
|
||||||
|
|
||||||
Translations are done through Crowdin. If you want to translate to a new language ask one of the managers in the Crowdin project to add a new language there.
|
Translations are done through Crowdin. If you want to translate to a new language ask one of the managers in the Crowdin project to add a new language there.
|
||||||
|
|
||||||
You can also just create an issue for adding a language or ask on discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty but we hope fo fill it as questions pop up.
|
You can also just create an issue for adding a language or ask on discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty but we hope to fill it as questions pop up.
|
||||||
|
|
||||||
https://docs.gitea.io/en-us/translation-guidelines/
|
https://docs.gitea.io/en-us/translation-guidelines/
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ var (
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "no-system",
|
Name: "no-system",
|
||||||
Usage: "Do not show system proceses",
|
Usage: "Do not show system processes",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "stacktraces",
|
Name: "stacktraces",
|
||||||
|
|
|
@ -2232,6 +2232,7 @@ ROUTER = console
|
||||||
;BLOCKED_DOMAINS =
|
;BLOCKED_DOMAINS =
|
||||||
;;
|
;;
|
||||||
;; Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291 (false by default)
|
;; Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291 (false by default)
|
||||||
|
;; If a domain is allowed by ALLOWED_DOMAINS, this option will be ignored.
|
||||||
;ALLOW_LOCALNETWORKS = false
|
;ALLOW_LOCALNETWORKS = false
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -1083,7 +1083,7 @@ Task queue configuration has been moved to `queue.task`. However, the below conf
|
||||||
- `RETRY_BACKOFF`: **3**: Backoff time per http/https request retry (seconds)
|
- `RETRY_BACKOFF`: **3**: Backoff time per http/https request retry (seconds)
|
||||||
- `ALLOWED_DOMAINS`: **\<empty\>**: Domains allowlist for migrating repositories, default is blank. It means everything will be allowed. Multiple domains could be separated by commas. Wildcard is supported: `github.com, *.github.com`.
|
- `ALLOWED_DOMAINS`: **\<empty\>**: Domains allowlist for migrating repositories, default is blank. It means everything will be allowed. Multiple domains could be separated by commas. Wildcard is supported: `github.com, *.github.com`.
|
||||||
- `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option has a higher priority to deny domains. Wildcard is supported.
|
- `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option has a higher priority to deny domains. Wildcard is supported.
|
||||||
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291
|
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291. If a domain is allowed by `ALLOWED_DOMAINS`, this option will be ignored.
|
||||||
- `SKIP_TLS_VERIFY`: **false**: Allow skip tls verify
|
- `SKIP_TLS_VERIFY`: **false**: Allow skip tls verify
|
||||||
|
|
||||||
## Federation (`federation`)
|
## Federation (`federation`)
|
||||||
|
|
|
@ -346,7 +346,7 @@ ALLOW_DATA_URI_IMAGES = true
|
||||||
- `ALLOW_DATA_URI_IMAGES`: **false** 允许 data uri 图片 (`<img src="data:image/png;base64,..."/>`)。
|
- `ALLOW_DATA_URI_IMAGES`: **false** 允许 data uri 图片 (`<img src="data:image/png;base64,..."/>`)。
|
||||||
|
|
||||||
多个净化规则可以被同时定义,只要section名称最后一位不重复即可。如: `[markup.sanitizer.TeX-2]`。
|
多个净化规则可以被同时定义,只要section名称最后一位不重复即可。如: `[markup.sanitizer.TeX-2]`。
|
||||||
为了针对一种渲染类型进行一个特殊的净化策略,必须使用形如 `[markup.sanitizer.asciidoc.rule-1]` 的方式来命名 seciton。
|
为了针对一种渲染类型进行一个特殊的净化策略,必须使用形如 `[markup.sanitizer.asciidoc.rule-1]` 的方式来命名 section。
|
||||||
如果此规则没有匹配到任何渲染类型,它将会被应用到所有的渲染类型。
|
如果此规则没有匹配到任何渲染类型,它将会被应用到所有的渲染类型。
|
||||||
|
|
||||||
## Time (`time`)
|
## Time (`time`)
|
||||||
|
|
|
@ -202,7 +202,7 @@ You can display STL file directly in Gitea by adding:
|
||||||
|
|
||||||
to the file `templates/custom/footer.tmpl`
|
to the file `templates/custom/footer.tmpl`
|
||||||
|
|
||||||
You also need to download the content of the library [Madeleine.js](https://jinjunho.github.io/Madeleine.js/) and place it under `$GITEA_CUSTOM/public/` folder.
|
You also need to download the content of the library [Madeleine.js](https://github.com/beige90/Madeleine.js) and place it under `$GITEA_CUSTOM/public/` folder.
|
||||||
|
|
||||||
You should end-up with a folder structure similar to:
|
You should end-up with a folder structure similar to:
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ Publish [NuGet](https://www.nuget.org/) packages for your user or organization.
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
To work with the NuGet package registry, you can use command-line interface tools as well as NuGet features in various IDEs like Visual Studio.
|
To work with the NuGet package registry, you can use command-line interface tools as well as NuGet features in various IDEs like Visual Studio.
|
||||||
More informations about NuGet clients can be found in [the official documentation](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools).
|
More information about NuGet clients can be found in [the official documentation](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools).
|
||||||
The following examples use the `dotnet nuget` tool.
|
The following examples use the `dotnet nuget` tool.
|
||||||
|
|
||||||
## Configuring the package registry
|
## Configuring the package registry
|
||||||
|
|
|
@ -201,7 +201,7 @@ func (c *compareDump) assertEquals(repoBefore, repoAfter *repo_model.Repository)
|
||||||
"Assignees": {ignore: true}, // not implemented yet
|
"Assignees": {ignore: true}, // not implemented yet
|
||||||
"Head": {nested: comparePullRequestBranch},
|
"Head": {nested: comparePullRequestBranch},
|
||||||
"Base": {nested: comparePullRequestBranch},
|
"Base": {nested: comparePullRequestBranch},
|
||||||
"Labels": {ignore: true}, // because org labels are not handled propery
|
"Labels": {ignore: true}, // because org labels are not handled properly
|
||||||
}).([]*base.PullRequest)
|
}).([]*base.PullRequest)
|
||||||
assert.True(c.t, ok)
|
assert.True(c.t, ok)
|
||||||
assert.GreaterOrEqual(c.t, len(prs), 1)
|
assert.GreaterOrEqual(c.t, len(prs), 1)
|
||||||
|
|
|
@ -105,7 +105,11 @@ func doAPICreateCommitStatus(ctx APITestContext, commitID string, status api.Com
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPullCreate_EmptyChangesWithCommits(t *testing.T) {
|
func TestPullCreate_EmptyChangesWithDifferentCommits(t *testing.T) {
|
||||||
|
// Merge must continue if commits SHA are different, even if content is same
|
||||||
|
// Reason: gitflow and merging master back into develop, where is high possiblity, there are no changes
|
||||||
|
// but just commit saying "Merge branch". And this meta commit can be also tagged,
|
||||||
|
// so we need to have this meta commit also in develop branch.
|
||||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
session := loginUser(t, "user1")
|
session := loginUser(t, "user1")
|
||||||
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||||
|
@ -126,6 +130,28 @@ func TestPullCreate_EmptyChangesWithCommits(t *testing.T) {
|
||||||
doc := NewHTMLParser(t, resp.Body)
|
doc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
text := strings.TrimSpace(doc.doc.Find(".merge-section").Text())
|
text := strings.TrimSpace(doc.doc.Find(".merge-section").Text())
|
||||||
assert.Contains(t, text, "This branch is equal with the target branch.")
|
assert.Contains(t, text, "This pull request can be merged automatically.")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullCreate_EmptyChangesWithSameCommits(t *testing.T) {
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
session := loginUser(t, "user1")
|
||||||
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||||
|
testCreateBranch(t, session, "user1", "repo1", "branch/master", "status1", http.StatusSeeOther)
|
||||||
|
url := path.Join("user1", "repo1", "compare", "master...status1")
|
||||||
|
req := NewRequestWithValues(t, "POST", url,
|
||||||
|
map[string]string{
|
||||||
|
"_csrf": GetCSRF(t, session, url),
|
||||||
|
"title": "pull request from status1",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||||
|
req = NewRequest(t, "GET", "/user1/repo1/pulls/1")
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
doc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
|
text := strings.TrimSpace(doc.doc.Find(".merge-section").Text())
|
||||||
|
assert.Contains(t, text, "This branch is already included in the target branch. There is nothing to merge.")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ func TxContext() (*Context, Committer, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithTx represents executing database operations on a transaction
|
// WithTx represents executing database operations on a transaction
|
||||||
// you can optionally change the context to a parrent one
|
// you can optionally change the context to a parent one
|
||||||
func WithTx(f func(ctx context.Context) error, stdCtx ...context.Context) error {
|
func WithTx(f func(ctx context.Context) error, stdCtx ...context.Context) error {
|
||||||
parentCtx := DefaultContext
|
parentCtx := DefaultContext
|
||||||
if len(stdCtx) != 0 && stdCtx[0] != nil {
|
if len(stdCtx) != 0 && stdCtx[0] != nil {
|
||||||
|
|
|
@ -122,6 +122,7 @@ const (
|
||||||
PullRequestStatusManuallyMerged
|
PullRequestStatusManuallyMerged
|
||||||
PullRequestStatusError
|
PullRequestStatusError
|
||||||
PullRequestStatusEmpty
|
PullRequestStatusEmpty
|
||||||
|
PullRequestStatusAncestor
|
||||||
)
|
)
|
||||||
|
|
||||||
// PullRequestFlow the flow of pull request
|
// PullRequestFlow the flow of pull request
|
||||||
|
@ -423,6 +424,11 @@ func (pr *PullRequest) IsEmpty() bool {
|
||||||
return pr.Status == PullRequestStatusEmpty
|
return pr.Status == PullRequestStatusEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsAncestor returns true if the Head Commit of this PR is an ancestor of the Base Commit
|
||||||
|
func (pr *PullRequest) IsAncestor() bool {
|
||||||
|
return pr.Status == PullRequestStatusAncestor
|
||||||
|
}
|
||||||
|
|
||||||
// SetMerged sets a pull request to merged and closes the corresponding issue
|
// SetMerged sets a pull request to merged and closes the corresponding issue
|
||||||
func (pr *PullRequest) SetMerged(ctx context.Context) (bool, error) {
|
func (pr *PullRequest) SetMerged(ctx context.Context) (bool, error) {
|
||||||
if pr.HasMerged {
|
if pr.HasMerged {
|
||||||
|
|
|
@ -62,7 +62,7 @@ func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequ
|
||||||
Find(&prs)
|
Find(&prs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanMaintainerWriteToBranch check whether user is a matainer and could write to the branch
|
// CanMaintainerWriteToBranch check whether user is a maintainer and could write to the branch
|
||||||
func CanMaintainerWriteToBranch(p access_model.Permission, branch string, user *user_model.User) bool {
|
func CanMaintainerWriteToBranch(p access_model.Permission, branch string, user *user_model.User) bool {
|
||||||
if p.CanWrite(unit.TypeCode) {
|
if p.CanWrite(unit.TypeCode) {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -55,7 +55,7 @@ func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) ([]*r
|
||||||
Find(&repos)
|
Find(&repos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTeamRepo addes a repo for an organization's team
|
// AddTeamRepo adds a repo for an organization's team
|
||||||
func AddTeamRepo(ctx context.Context, orgID, teamID, repoID int64) error {
|
func AddTeamRepo(ctx context.Context, orgID, teamID, repoID int64) error {
|
||||||
_, err := db.GetEngine(ctx).Insert(&TeamRepo{
|
_, err := db.GetEngine(ctx).Insert(&TeamRepo{
|
||||||
OrgID: orgID,
|
OrgID: orgID,
|
||||||
|
|
|
@ -86,7 +86,13 @@ func updateUserAccess(accessMap map[int64]*userAccess, user *user_model.User, mo
|
||||||
// FIXME: do cross-comparison so reduce deletions and additions to the minimum?
|
// FIXME: do cross-comparison so reduce deletions and additions to the minimum?
|
||||||
func refreshAccesses(ctx context.Context, repo *repo_model.Repository, accessMap map[int64]*userAccess) (err error) {
|
func refreshAccesses(ctx context.Context, repo *repo_model.Repository, accessMap map[int64]*userAccess) (err error) {
|
||||||
minMode := perm.AccessModeRead
|
minMode := perm.AccessModeRead
|
||||||
if !repo.IsPrivate {
|
if err := repo.GetOwner(ctx); err != nil {
|
||||||
|
return fmt.Errorf("GetOwner: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the repo isn't private and isn't owned by a organization,
|
||||||
|
// increase the minMode to Write.
|
||||||
|
if !repo.IsPrivate && !repo.Owner.IsOrganization() {
|
||||||
minMode = perm.AccessModeWrite
|
minMode = perm.AccessModeWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
// UTF8BOM is the utf-8 byte-order marker
|
// UTF8BOM is the utf-8 byte-order marker
|
||||||
var UTF8BOM = []byte{'\xef', '\xbb', '\xbf'}
|
var UTF8BOM = []byte{'\xef', '\xbb', '\xbf'}
|
||||||
|
|
||||||
// ToUTF8WithFallbackReader detects the encoding of content and coverts to UTF-8 reader if possible
|
// ToUTF8WithFallbackReader detects the encoding of content and converts to UTF-8 reader if possible
|
||||||
func ToUTF8WithFallbackReader(rd io.Reader) io.Reader {
|
func ToUTF8WithFallbackReader(rd io.Reader) io.Reader {
|
||||||
buf := make([]byte, 2048)
|
buf := make([]byte, 2048)
|
||||||
n, err := util.ReadAtMost(rd, buf)
|
n, err := util.ReadAtMost(rd, buf)
|
||||||
|
@ -76,7 +76,7 @@ func ToUTF8WithErr(content []byte) (string, error) {
|
||||||
return string(result), err
|
return string(result), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToUTF8WithFallback detects the encoding of content and coverts to UTF-8 if possible
|
// ToUTF8WithFallback detects the encoding of content and converts to UTF-8 if possible
|
||||||
func ToUTF8WithFallback(content []byte) []byte {
|
func ToUTF8WithFallback(content []byte) []byte {
|
||||||
bs, _ := io.ReadAll(ToUTF8WithFallbackReader(bytes.NewReader(content)))
|
bs, _ := io.ReadAll(ToUTF8WithFallbackReader(bytes.NewReader(content)))
|
||||||
return bs
|
return bs
|
||||||
|
@ -191,7 +191,7 @@ func DetectEncoding(content []byte) (string, error) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise check if this results is earlier in the DetectedCharsetOrder than our current top guesss
|
// Otherwise check if this results is earlier in the DetectedCharsetOrder than our current top guess
|
||||||
resultPriority, resultHas := setting.Repository.DetectedCharsetScore[strings.ToLower(strings.TrimSpace(result.Charset))]
|
resultPriority, resultHas := setting.Repository.DetectedCharsetScore[strings.ToLower(strings.TrimSpace(result.Charset))]
|
||||||
if resultHas && (!has || resultPriority < priority) {
|
if resultHas && (!has || resultPriority < priority) {
|
||||||
topResult = result
|
topResult = result
|
||||||
|
|
|
@ -32,8 +32,8 @@ func iterateUserAccounts(ctx context.Context, each func(*user.User) error) error
|
||||||
// Ref: https://github.com/go-gitea/gitea/pull/19085 & https://github.com/go-gitea/gitea/pull/17688
|
// Ref: https://github.com/go-gitea/gitea/pull/19085 & https://github.com/go-gitea/gitea/pull/17688
|
||||||
func checkUserEmail(ctx context.Context, logger log.Logger, _ bool) error {
|
func checkUserEmail(ctx context.Context, logger log.Logger, _ bool) error {
|
||||||
// We could use quirky SQL to get all users that start without a [a-zA-Z0-9], but that would mean
|
// We could use quirky SQL to get all users that start without a [a-zA-Z0-9], but that would mean
|
||||||
// DB provider-specific SQL and only works _now_. So instead we iterate trough all user accounts and
|
// DB provider-specific SQL and only works _now_. So instead we iterate through all user accounts
|
||||||
// use the user.ValidateEmail function to be future-proof.
|
// and use the user.ValidateEmail function to be future-proof.
|
||||||
var invalidUserCount int64
|
var invalidUserCount int64
|
||||||
if err := iterateUserAccounts(ctx, func(u *user.User) error {
|
if err := iterateUserAccounts(ctx, func(u *user.User) error {
|
||||||
// Only check for users, skip
|
// Only check for users, skip
|
||||||
|
|
|
@ -125,14 +125,14 @@ func (hl *HostMatchList) checkIP(ip net.IP) bool {
|
||||||
|
|
||||||
// MatchHostName checks if the host matches an allow/deny(block) list
|
// MatchHostName checks if the host matches an allow/deny(block) list
|
||||||
func (hl *HostMatchList) MatchHostName(host string) bool {
|
func (hl *HostMatchList) MatchHostName(host string) bool {
|
||||||
|
if hl == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
hostname, _, err := net.SplitHostPort(host)
|
hostname, _, err := net.SplitHostPort(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hostname = host
|
hostname = host
|
||||||
}
|
}
|
||||||
|
|
||||||
if hl == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if hl.checkPattern(hostname) {
|
if hl.checkPattern(hostname) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ func (m *Manager) getLevelDB(connection string) (*leveldb.DB, error) {
|
||||||
db, ok = m.LevelDBConnections[dataDir]
|
db, ok = m.LevelDBConnections[dataDir]
|
||||||
if ok {
|
if ok {
|
||||||
db.count++
|
db.count++
|
||||||
log.Warn("Duplicate connnection to level db: %s with different connection strings. Initial connection: %s. This connection: %s", dataDir, db.name[0], connection)
|
log.Warn("Duplicate connection to level db: %s with different connection strings. Initial connection: %s. This connection: %s", dataDir, db.name[0], connection)
|
||||||
db.name = append(db.name, connection)
|
db.name = append(db.name, connection)
|
||||||
m.LevelDBConnections[connection] = db
|
m.LevelDBConnections[connection] = db
|
||||||
return db.db, nil
|
return db.db, nil
|
||||||
|
|
|
@ -156,6 +156,12 @@ func parsePostgreSQLHostPort(info string) (string, string) {
|
||||||
} else if len(info) > 0 {
|
} else if len(info) > 0 {
|
||||||
host = info
|
host = info
|
||||||
}
|
}
|
||||||
|
if host == "" {
|
||||||
|
host = "127.0.0.1"
|
||||||
|
}
|
||||||
|
if port == "" {
|
||||||
|
port = "5432"
|
||||||
|
}
|
||||||
return host, port
|
return host, port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +179,7 @@ func getPostgreSQLConnectionString(dbHost, dbUser, dbPasswd, dbName, dbParam, db
|
||||||
|
|
||||||
// ParseMSSQLHostPort splits the host into host and port
|
// ParseMSSQLHostPort splits the host into host and port
|
||||||
func ParseMSSQLHostPort(info string) (string, string) {
|
func ParseMSSQLHostPort(info string) (string, string) {
|
||||||
|
// the default port "0" might be related to MSSQL's dynamic port, maybe it should be double-confirmed in the future
|
||||||
host, port := "127.0.0.1", "0"
|
host, port := "127.0.0.1", "0"
|
||||||
if strings.Contains(info, ":") {
|
if strings.Contains(info, ":") {
|
||||||
host = strings.Split(info, ":")[0]
|
host = strings.Split(info, ":")[0]
|
||||||
|
@ -183,5 +190,11 @@ func ParseMSSQLHostPort(info string) (string, string) {
|
||||||
} else if len(info) > 0 {
|
} else if len(info) > 0 {
|
||||||
host = info
|
host = info
|
||||||
}
|
}
|
||||||
|
if host == "" {
|
||||||
|
host = "127.0.0.1"
|
||||||
|
}
|
||||||
|
if port == "" {
|
||||||
|
port = "0"
|
||||||
|
}
|
||||||
return host, port
|
return host, port
|
||||||
}
|
}
|
||||||
|
|
|
@ -628,7 +628,7 @@ func SVG(icon string, others ...interface{}) template.HTML {
|
||||||
|
|
||||||
// Avatar renders user avatars. args: user, size (int), class (string)
|
// Avatar renders user avatars. args: user, size (int), class (string)
|
||||||
func Avatar(item interface{}, others ...interface{}) template.HTML {
|
func Avatar(item interface{}, others ...interface{}) template.HTML {
|
||||||
size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar image", others...)
|
size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar image vm", others...)
|
||||||
|
|
||||||
switch t := item.(type) {
|
switch t := item.(type) {
|
||||||
case *user_model.User:
|
case *user_model.User:
|
||||||
|
|
|
@ -60,7 +60,7 @@ func SetLocaleCookie(resp http.ResponseWriter, lang string, expiry int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteLocaleCookie convenience function to delete the locale cookie consistently
|
// DeleteLocaleCookie convenience function to delete the locale cookie consistently
|
||||||
// Setting the lang cookie will trigger the middleware to reset the language ot previous state.
|
// Setting the lang cookie will trigger the middleware to reset the language to previous state.
|
||||||
func DeleteLocaleCookie(resp http.ResponseWriter) {
|
func DeleteLocaleCookie(resp http.ResponseWriter) {
|
||||||
SetCookie(resp, "lang", "",
|
SetCookie(resp, "lang", "",
|
||||||
-1,
|
-1,
|
||||||
|
|
|
@ -25,7 +25,7 @@ func UpdateFuncInfo(ctx context.Context, funcInfo *FuncInfo) {
|
||||||
record.lock.Unlock()
|
record.lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkLongPolling marks the reuqest is a long-polling request, and the logger may output different message for it
|
// MarkLongPolling marks the request is a long-polling request, and the logger may output different message for it
|
||||||
func MarkLongPolling(resp http.ResponseWriter, req *http.Request) {
|
func MarkLongPolling(resp http.ResponseWriter, req *http.Request) {
|
||||||
record, ok := req.Context().Value(contextKey).(*requestRecord)
|
record, ok := req.Context().Value(contextKey).(*requestRecord)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/bazel-*
|
/bazel-*
|
||||||
|
|
||||||
# Directories for the Bazel IntelliJ plugin containing the generated
|
# Directories for the Bazel IntelliJ plugin containing the generated
|
||||||
# IntelliJ project files and plugin configuration. Seperate directories are
|
# IntelliJ project files and plugin configuration. Separate directories are
|
||||||
# for the IntelliJ, Android Studio and CLion versions of the plugin.
|
# for the IntelliJ, Android Studio and CLion versions of the plugin.
|
||||||
/.ijwb/
|
/.ijwb/
|
||||||
/.aswb/
|
/.aswb/
|
||||||
|
|
|
@ -932,7 +932,7 @@ form.name_pattern_not_allowed = The pattern '%s' is not allowed in a repository
|
||||||
need_auth = Authorization
|
need_auth = Authorization
|
||||||
migrate_options = Migration Options
|
migrate_options = Migration Options
|
||||||
migrate_service = Migration Service
|
migrate_service = Migration Service
|
||||||
migrate_options_mirror_helper = This repository will be a <span class="text blue">mirror</span>
|
migrate_options_mirror_helper = This repository will be a mirror
|
||||||
migrate_options_lfs = Migrate LFS files
|
migrate_options_lfs = Migrate LFS files
|
||||||
migrate_options_lfs_endpoint.label = LFS Endpoint
|
migrate_options_lfs_endpoint.label = LFS Endpoint
|
||||||
migrate_options_lfs_endpoint.description = Migration will attempt to use your Git remote to <a target="_blank" rel="noopener noreferrer" href="%s">determine the LFS server</a>. You can also specify a custom endpoint if the repository LFS data is stored somewhere else.
|
migrate_options_lfs_endpoint.description = Migration will attempt to use your Git remote to <a target="_blank" rel="noopener noreferrer" href="%s">determine the LFS server</a>. You can also specify a custom endpoint if the repository LFS data is stored somewhere else.
|
||||||
|
@ -1532,7 +1532,8 @@ pulls.remove_prefix = Remove <strong>%s</strong> prefix
|
||||||
pulls.data_broken = This pull request is broken due to missing fork information.
|
pulls.data_broken = This pull request is broken due to missing fork information.
|
||||||
pulls.files_conflicted = This pull request has changes conflicting with the target branch.
|
pulls.files_conflicted = This pull request has changes conflicting with the target branch.
|
||||||
pulls.is_checking = "Merge conflict checking is in progress. Try again in few moments."
|
pulls.is_checking = "Merge conflict checking is in progress. Try again in few moments."
|
||||||
pulls.is_empty = "This branch is equal with the target branch."
|
pulls.is_ancestor = "This branch is already included in the target branch. There is nothing to merge."
|
||||||
|
pulls.is_empty = "The changes on this branch are already on the target branch. This will be an empty commit."
|
||||||
pulls.required_status_check_failed = Some required checks were not successful.
|
pulls.required_status_check_failed = Some required checks were not successful.
|
||||||
pulls.required_status_check_missing = Some required checks are missing.
|
pulls.required_status_check_missing = Some required checks are missing.
|
||||||
pulls.required_status_check_administrator = As an administrator, you may still merge this pull request.
|
pulls.required_status_check_administrator = As an administrator, you may still merge this pull request.
|
||||||
|
|
|
@ -1303,6 +1303,7 @@ issues.previous=Anterior
|
||||||
issues.next=Seguinte
|
issues.next=Seguinte
|
||||||
issues.open_title=Aberta
|
issues.open_title=Aberta
|
||||||
issues.closed_title=Fechada
|
issues.closed_title=Fechada
|
||||||
|
issues.draft_title=Rascunho
|
||||||
issues.num_comments=%d comentários
|
issues.num_comments=%d comentários
|
||||||
issues.commented_at=`comentou <a href="#%s">%s</a>`
|
issues.commented_at=`comentou <a href="#%s">%s</a>`
|
||||||
issues.delete_comment_confirm=Tem a certeza que quer eliminar este comentário?
|
issues.delete_comment_confirm=Tem a certeza que quer eliminar este comentário?
|
||||||
|
|
|
@ -861,7 +861,9 @@ default_branch=默认分支
|
||||||
default_branch_helper=默认分支是用于合并请求和代码提交的基础分支。
|
default_branch_helper=默认分支是用于合并请求和代码提交的基础分支。
|
||||||
mirror_prune=修剪
|
mirror_prune=修剪
|
||||||
mirror_prune_desc=删除过时的远程跟踪引用
|
mirror_prune_desc=删除过时的远程跟踪引用
|
||||||
|
mirror_interval=镜像间隔 (有效的时间单位是 'h', 'm', 's')。0 禁用自动定期同步 (最短间隔: %s)
|
||||||
mirror_interval_invalid=镜像间隔无效。
|
mirror_interval_invalid=镜像间隔无效。
|
||||||
|
mirror_sync_on_commit=推送提交时同步
|
||||||
mirror_address=从URL克隆
|
mirror_address=从URL克隆
|
||||||
mirror_address_desc=在授权框中输入必要的凭据。
|
mirror_address_desc=在授权框中输入必要的凭据。
|
||||||
mirror_address_url_invalid=URL无效。请检查您所输入的URL是否正确。
|
mirror_address_url_invalid=URL无效。请检查您所输入的URL是否正确。
|
||||||
|
@ -1301,6 +1303,7 @@ issues.previous=上一页
|
||||||
issues.next=下一页
|
issues.next=下一页
|
||||||
issues.open_title=开启中
|
issues.open_title=开启中
|
||||||
issues.closed_title=已关闭
|
issues.closed_title=已关闭
|
||||||
|
issues.draft_title=草稿
|
||||||
issues.num_comments=%d 条评论
|
issues.num_comments=%d 条评论
|
||||||
issues.commented_at=`评论于 <a href="#%s">%s</a>`
|
issues.commented_at=`评论于 <a href="#%s">%s</a>`
|
||||||
issues.delete_comment_confirm=您确定要删除该条评论吗?
|
issues.delete_comment_confirm=您确定要删除该条评论吗?
|
||||||
|
|
2888
package-lock.json
generated
2888
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -45,6 +45,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@happy-dom/jest-environment": "4.0.1",
|
"@happy-dom/jest-environment": "4.0.1",
|
||||||
|
"@stoplight/spectral-cli": "6.4.1",
|
||||||
"eslint": "8.15.0",
|
"eslint": "8.15.0",
|
||||||
"eslint-plugin-html": "6.2.0",
|
"eslint-plugin-html": "6.2.0",
|
||||||
"eslint-plugin-import": "2.26.0",
|
"eslint-plugin-import": "2.26.0",
|
||||||
|
|
|
@ -76,7 +76,7 @@ type PackageVersionMetadata struct {
|
||||||
Dist Dist `json:"dist"`
|
Dist Dist `json:"dist"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dist contains package download informations
|
// Dist contains package download information
|
||||||
type Dist struct {
|
type Dist struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
|
|
|
@ -429,14 +429,14 @@ func uploadFile(ctx *context.Context, fileFilter stringSet, fileKey string) {
|
||||||
ctx.Status(http.StatusCreated)
|
ctx.Status(http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DownloadRecipeFile serves the conent of the requested recipe file
|
// DownloadRecipeFile serves the content of the requested recipe file
|
||||||
func DownloadRecipeFile(ctx *context.Context) {
|
func DownloadRecipeFile(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
||||||
|
|
||||||
downloadFile(ctx, recipeFileList, rref.AsKey())
|
downloadFile(ctx, recipeFileList, rref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
// DownloadPackageFile serves the conent of the requested package file
|
// DownloadPackageFile serves the content of the requested package file
|
||||||
func DownloadPackageFile(ctx *context.Context) {
|
func DownloadPackageFile(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ func EnumeratePackages(ctx *context.Context) {
|
||||||
enumeratePackages(ctx, "specs.4.8", packages)
|
enumeratePackages(ctx, "specs.4.8", packages)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnumeratePackagesLatest serves the list of the lastest version of every package
|
// EnumeratePackagesLatest serves the list of the latest version of every package
|
||||||
func EnumeratePackagesLatest(ctx *context.Context) {
|
func EnumeratePackagesLatest(ctx *context.Context) {
|
||||||
pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
|
pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
OwnerID: ctx.Package.Owner.ID,
|
OwnerID: ctx.Package.Owner.ID,
|
||||||
|
|
|
@ -1027,7 +1027,7 @@ func Routes() *web.Route {
|
||||||
}, mustAllowPulls, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo())
|
}, mustAllowPulls, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo())
|
||||||
m.Group("/statuses", func() {
|
m.Group("/statuses", func() {
|
||||||
m.Combo("/{sha}").Get(repo.GetCommitStatuses).
|
m.Combo("/{sha}").Get(repo.GetCommitStatuses).
|
||||||
Post(reqToken(), bind(api.CreateStatusOption{}), repo.NewCommitStatus)
|
Post(reqToken(), reqRepoWriter(unit.TypeCode), bind(api.CreateStatusOption{}), repo.NewCommitStatus)
|
||||||
}, reqRepoReader(unit.TypeCode))
|
}, reqRepoReader(unit.TypeCode))
|
||||||
m.Group("/commits", func() {
|
m.Group("/commits", func() {
|
||||||
m.Get("", context.ReferencesGitRepo(), repo.GetAllCommits)
|
m.Get("", context.ReferencesGitRepo(), repo.GetAllCommits)
|
||||||
|
|
|
@ -100,7 +100,7 @@ func GetHook(ctx *context.APIContext) {
|
||||||
|
|
||||||
// CreateHook create a hook for an organization
|
// CreateHook create a hook for an organization
|
||||||
func CreateHook(ctx *context.APIContext) {
|
func CreateHook(ctx *context.APIContext) {
|
||||||
// swagger:operation POST /orgs/{org}/hooks/ organization orgCreateHook
|
// swagger:operation POST /orgs/{org}/hooks organization orgCreateHook
|
||||||
// ---
|
// ---
|
||||||
// summary: Create a hook
|
// summary: Create a hook
|
||||||
// consumes:
|
// consumes:
|
||||||
|
|
|
@ -107,9 +107,6 @@ type swaggerParameterBodies struct {
|
||||||
// in:body
|
// in:body
|
||||||
EditUserOption api.EditUserOption
|
EditUserOption api.EditUserOption
|
||||||
|
|
||||||
// in:body
|
|
||||||
MigrateRepoForm forms.MigrateRepoForm
|
|
||||||
|
|
||||||
// in:body
|
// in:body
|
||||||
EditAttachmentOptions api.EditAttachmentOptions
|
EditAttachmentOptions api.EditAttachmentOptions
|
||||||
|
|
||||||
|
|
|
@ -1440,7 +1440,7 @@ func UpdatePullRequestTarget(ctx *context.Context) {
|
||||||
err := err.(issues_model.ErrPullRequestAlreadyExists)
|
err := err.(issues_model.ErrPullRequestAlreadyExists)
|
||||||
|
|
||||||
RepoRelPath := ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
RepoRelPath := ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
||||||
errorMessage := ctx.Tr("repo.pulls.has_pull_request", html.EscapeString(ctx.Repo.RepoLink+"/pulls/"+strconv.FormatInt(err.IssueID, 10)), html.EscapeString(RepoRelPath), err.IssueID) // FIXME: Creates url insidde locale string
|
errorMessage := ctx.Tr("repo.pulls.has_pull_request", html.EscapeString(ctx.Repo.RepoLink+"/pulls/"+strconv.FormatInt(err.IssueID, 10)), html.EscapeString(RepoRelPath), err.IssueID) // FIXME: Creates url inside locale string
|
||||||
|
|
||||||
ctx.Flash.Error(errorMessage)
|
ctx.Flash.Error(errorMessage)
|
||||||
ctx.JSON(http.StatusConflict, map[string]interface{}{
|
ctx.JSON(http.StatusConflict, map[string]interface{}{
|
||||||
|
|
|
@ -98,8 +98,8 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
|
||||||
listOptions.PageSize = setting.API.MaxResponseItems
|
listOptions.PageSize = setting.API.MaxResponseItems
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(20073) tags are used for compare feature witch needs all tags
|
// TODO(20073) tags are used for compare feature which needs all tags
|
||||||
// filtering is doen at the client side atm
|
// filtering is done on the client-side atm
|
||||||
tagListStart, tagListEnd := 0, 0
|
tagListStart, tagListEnd := 0, 0
|
||||||
if isTagList {
|
if isTagList {
|
||||||
tagListStart, tagListEnd = listOptions.GetStartEnd()
|
tagListStart, tagListEnd = listOptions.GetStartEnd()
|
||||||
|
@ -514,12 +514,12 @@ func EditReleasePost(ctx *context.Context) {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/releases")
|
ctx.Redirect(ctx.Repo.RepoLink + "/releases")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRelease delete a release
|
// DeleteRelease deletes a release
|
||||||
func DeleteRelease(ctx *context.Context) {
|
func DeleteRelease(ctx *context.Context) {
|
||||||
deleteReleaseOrTag(ctx, false)
|
deleteReleaseOrTag(ctx, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteTag delete a tag
|
// DeleteTag deletes a tag
|
||||||
func DeleteTag(ctx *context.Context) {
|
func DeleteTag(ctx *context.Context) {
|
||||||
deleteReleaseOrTag(ctx, true)
|
deleteReleaseOrTag(ctx, true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ func CorsHandler() func(next http.Handler) http.Handler {
|
||||||
// for users that have already signed in.
|
// for users that have already signed in.
|
||||||
func buildAuthGroup() *auth_service.Group {
|
func buildAuthGroup() *auth_service.Group {
|
||||||
group := auth_service.NewGroup(
|
group := auth_service.NewGroup(
|
||||||
&auth_service.OAuth2{}, // FIXME: this should be removed and only applied in download and oauth realted routers
|
&auth_service.OAuth2{}, // FIXME: this should be removed and only applied in download and oauth related routers
|
||||||
&auth_service.Basic{}, // FIXME: this should be removed and only applied in download and git/lfs routers
|
&auth_service.Basic{}, // FIXME: this should be removed and only applied in download and git/lfs routers
|
||||||
&auth_service.Session{},
|
&auth_service.Session{},
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,7 +34,7 @@ type webfingerLink struct {
|
||||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebfingerQuery returns informations about a resource
|
// WebfingerQuery returns information about a resource
|
||||||
// https://datatracker.ietf.org/doc/html/rfc7565
|
// https://datatracker.ietf.org/doc/html/rfc7565
|
||||||
func WebfingerQuery(ctx *context.Context) {
|
func WebfingerQuery(ctx *context.Context) {
|
||||||
appURL, _ := url.Parse(setting.AppURL)
|
appURL, _ := url.Parse(setting.AppURL)
|
||||||
|
|
|
@ -35,7 +35,7 @@ type GothProvider interface {
|
||||||
GothProviderCreator
|
GothProviderCreator
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImagedProvider provide an overrided image setting for the provider
|
// ImagedProvider provide an overridden image setting for the provider
|
||||||
type ImagedProvider struct {
|
type ImagedProvider struct {
|
||||||
GothProvider
|
GothProvider
|
||||||
image string
|
image string
|
||||||
|
|
|
@ -7,7 +7,6 @@ package migrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -268,7 +267,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
|
||||||
// calc NumCommits if possible
|
// calc NumCommits if possible
|
||||||
if rel.TagName != "" {
|
if rel.TagName != "" {
|
||||||
commit, err := g.gitRepo.GetTagCommit(rel.TagName)
|
commit, err := g.gitRepo.GetTagCommit(rel.TagName)
|
||||||
if !errors.Is(err, git.ErrNotExist{}) {
|
if !git.IsErrNotExist(err) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("GetTagCommit[%v]: %v", rel.TagName, err)
|
return fmt.Errorf("GetTagCommit[%v]: %v", rel.TagName, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,10 @@ func IsMigrateURLAllowed(remoteURL string, doer *user_model.User) error {
|
||||||
|
|
||||||
// some users only use proxy, there is no DNS resolver. it's safe to ignore the LookupIP error
|
// some users only use proxy, there is no DNS resolver. it's safe to ignore the LookupIP error
|
||||||
addrList, _ := net.LookupIP(hostName)
|
addrList, _ := net.LookupIP(hostName)
|
||||||
|
return checkByAllowBlockList(hostName, addrList)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkByAllowBlockList(hostName string, addrList []net.IP) error {
|
||||||
var ipAllowed bool
|
var ipAllowed bool
|
||||||
var ipBlocked bool
|
var ipBlocked bool
|
||||||
for _, addr := range addrList {
|
for _, addr := range addrList {
|
||||||
|
@ -93,12 +96,12 @@ func IsMigrateURLAllowed(remoteURL string, doer *user_model.User) error {
|
||||||
}
|
}
|
||||||
var blockedError error
|
var blockedError error
|
||||||
if blockList.MatchHostName(hostName) || ipBlocked {
|
if blockList.MatchHostName(hostName) || ipBlocked {
|
||||||
blockedError = &models.ErrInvalidCloneAddr{Host: u.Host, IsPermissionDenied: true}
|
blockedError = &models.ErrInvalidCloneAddr{Host: hostName, IsPermissionDenied: true}
|
||||||
}
|
}
|
||||||
// if we have an allow-list, check the allow-list first
|
// if we have an allow-list, check the allow-list before return to get the more accurate error
|
||||||
if !allowList.IsEmpty() {
|
if !allowList.IsEmpty() {
|
||||||
if !allowList.MatchHostName(hostName) && !ipAllowed {
|
if !allowList.MatchHostName(hostName) && !ipAllowed {
|
||||||
return &models.ErrInvalidCloneAddr{Host: u.Host, IsPermissionDenied: true}
|
return &models.ErrInvalidCloneAddr{Host: hostName, IsPermissionDenied: true}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// otherwise, we always follow the blocked list
|
// otherwise, we always follow the blocked list
|
||||||
|
@ -474,5 +477,7 @@ func Init() error {
|
||||||
allowList.AppendBuiltin(hostmatcher.MatchBuiltinPrivate)
|
allowList.AppendBuiltin(hostmatcher.MatchBuiltinPrivate)
|
||||||
allowList.AppendBuiltin(hostmatcher.MatchBuiltinLoopback)
|
allowList.AppendBuiltin(hostmatcher.MatchBuiltinLoopback)
|
||||||
}
|
}
|
||||||
|
// TODO: at the moment, if ALLOW_LOCALNETWORKS=false, ALLOWED_DOMAINS=domain.com, and domain.com has IP 127.0.0.1, then it's still allowed.
|
||||||
|
// if we want to block such case, the private&loopback should be added to the blockList when ALLOW_LOCALNETWORKS=false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package migrations
|
package migrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -74,3 +75,42 @@ func TestMigrateWhiteBlocklist(t *testing.T) {
|
||||||
|
|
||||||
setting.ImportLocalPaths = old
|
setting.ImportLocalPaths = old
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAllowBlockList(t *testing.T) {
|
||||||
|
init := func(allow, block string, local bool) {
|
||||||
|
setting.Migrations.AllowedDomains = allow
|
||||||
|
setting.Migrations.BlockedDomains = block
|
||||||
|
setting.Migrations.AllowLocalNetworks = local
|
||||||
|
assert.NoError(t, Init())
|
||||||
|
}
|
||||||
|
|
||||||
|
// default, allow all external, block none, no local networks
|
||||||
|
init("", "", false)
|
||||||
|
assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
|
||||||
|
assert.Error(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
|
||||||
|
|
||||||
|
// allow all including local networks (it could lead to SSRF in production)
|
||||||
|
init("", "", true)
|
||||||
|
assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
|
||||||
|
assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
|
||||||
|
|
||||||
|
// allow wildcard, block some subdomains. if the domain name is allowed, then the local network check is skipped
|
||||||
|
init("*.domain.com", "blocked.domain.com", false)
|
||||||
|
assert.NoError(t, checkByAllowBlockList("sub.domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
|
||||||
|
assert.NoError(t, checkByAllowBlockList("sub.domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
|
||||||
|
assert.Error(t, checkByAllowBlockList("blocked.domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
|
||||||
|
assert.Error(t, checkByAllowBlockList("sub.other.com", []net.IP{net.ParseIP("1.2.3.4")}))
|
||||||
|
|
||||||
|
// allow wildcard (it could lead to SSRF in production)
|
||||||
|
init("*", "", false)
|
||||||
|
assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
|
||||||
|
assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
|
||||||
|
|
||||||
|
// local network can still be blocked
|
||||||
|
init("*", "127.0.0.*", false)
|
||||||
|
assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
|
||||||
|
assert.Error(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
|
||||||
|
|
||||||
|
// reset
|
||||||
|
init("", "", false)
|
||||||
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce
|
||||||
return ErrIsWorkInProgress
|
return ErrIsWorkInProgress
|
||||||
}
|
}
|
||||||
|
|
||||||
if !pr.CanAutoMerge() {
|
if !pr.CanAutoMerge() && !pr.IsEmpty() {
|
||||||
return ErrNotMergableState
|
return ErrNotMergableState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,14 @@ func TestPatch(pr *issues_model.PullRequest) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pr.MergeBase = strings.TrimSpace(pr.MergeBase)
|
pr.MergeBase = strings.TrimSpace(pr.MergeBase)
|
||||||
|
if pr.HeadCommitID, err = gitRepo.GetRefCommitID(git.BranchPrefix + "tracking"); err != nil {
|
||||||
|
return fmt.Errorf("GetBranchCommitID: can't find commit ID for head: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.HeadCommitID == pr.MergeBase {
|
||||||
|
pr.Status = issues_model.PullRequestStatusAncestor
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Check for conflicts
|
// 2. Check for conflicts
|
||||||
if conflicts, err := checkConflicts(ctx, pr, gitRepo, tmpBasePath); err != nil || conflicts || pr.Status == issues_model.PullRequestStatusEmpty {
|
if conflicts, err := checkConflicts(ctx, pr, gitRepo, tmpBasePath); err != nil || conflicts || pr.Status == issues_model.PullRequestStatusEmpty {
|
||||||
|
|
|
@ -195,12 +195,12 @@
|
||||||
<i class="icon icon-octicon">{{svg "octicon-sync"}}</i>
|
<i class="icon icon-octicon">{{svg "octicon-sync"}}</i>
|
||||||
{{$.locale.Tr "repo.pulls.is_checking"}}
|
{{$.locale.Tr "repo.pulls.is_checking"}}
|
||||||
</div>
|
</div>
|
||||||
{{else if .Issue.PullRequest.IsEmpty}}
|
{{else if .Issue.PullRequest.IsAncestor}}
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<i class="icon icon-octicon">{{svg "octicon-alert" 16}}</i>
|
<i class="icon icon-octicon">{{svg "octicon-alert" 16}}</i>
|
||||||
{{$.locale.Tr "repo.pulls.is_empty"}}
|
{{$.locale.Tr "repo.pulls.is_ancestor"}}
|
||||||
</div>
|
</div>
|
||||||
{{else if .Issue.PullRequest.CanAutoMerge}}
|
{{else if or .Issue.PullRequest.CanAutoMerge .Issue.PullRequest.IsEmpty}}
|
||||||
{{if .IsBlockedByApprovals}}
|
{{if .IsBlockedByApprovals}}
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<i class="icon icon-octicon">{{svg "octicon-x"}}</i>
|
<i class="icon icon-octicon">{{svg "octicon-x"}}</i>
|
||||||
|
@ -254,7 +254,7 @@
|
||||||
|
|
||||||
{{$notAllOverridableChecksOk := or .IsBlockedByApprovals .IsBlockedByRejection .IsBlockedByOfficialReviewRequests .IsBlockedByOutdatedBranch .IsBlockedByChangedProtectedFiles (and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess))}}
|
{{$notAllOverridableChecksOk := or .IsBlockedByApprovals .IsBlockedByRejection .IsBlockedByOfficialReviewRequests .IsBlockedByOutdatedBranch .IsBlockedByChangedProtectedFiles (and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess))}}
|
||||||
|
|
||||||
{{/* admin can merge without checks, writer can merge when checkes succeed */}}
|
{{/* admin can merge without checks, writer can merge when checks succeed */}}
|
||||||
{{$canMergeNow := and (or $.IsRepoAdmin (not $notAllOverridableChecksOk)) (or (not .AllowMerge) (not .RequireSigned) .WillSign)}}
|
{{$canMergeNow := and (or $.IsRepoAdmin (not $notAllOverridableChecksOk)) (or (not .AllowMerge) (not .RequireSigned) .WillSign)}}
|
||||||
{{/* admin and writer both can make an auto merge schedule */}}
|
{{/* admin and writer both can make an auto merge schedule */}}
|
||||||
|
|
||||||
|
@ -282,7 +282,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if and (gt .Issue.PullRequest.CommitsBehind 0) (not .Issue.IsClosed) (not .Issue.PullRequest.IsChecking) (not .IsPullFilesConflicted) (not .IsPullRequestBroken) (not $canAutoMerge)}}
|
{{if and (gt .Issue.PullRequest.CommitsBehind 0) (not .Issue.IsClosed) (not .Issue.PullRequest.IsChecking) (not .IsPullFilesConflicted) (not .IsPullRequestBroken) (not $canAutoMerge)}}
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
<div class="item item-section">
|
<div class="item item-section">
|
||||||
|
@ -321,6 +320,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if .Issue.PullRequest.IsEmpty}}
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
|
||||||
|
<div class="item">
|
||||||
|
<i class="icon icon-octicon">{{svg "octicon-alert" 16}}</i>
|
||||||
|
{{$.locale.Tr "repo.pulls.is_empty"}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
{{if .AllowMerge}} {{/* user is allowed to merge */}}
|
{{if .AllowMerge}} {{/* user is allowed to merge */}}
|
||||||
{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}}
|
{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}}
|
||||||
|
@ -348,6 +355,7 @@
|
||||||
|
|
||||||
'canMergeNow': {{$canMergeNow}},
|
'canMergeNow': {{$canMergeNow}},
|
||||||
'allOverridableChecksOk': {{not $notAllOverridableChecksOk}},
|
'allOverridableChecksOk': {{not $notAllOverridableChecksOk}},
|
||||||
|
'emptyCommit': {{.Issue.PullRequest.IsEmpty}},
|
||||||
'pullHeadCommitID': {{.PullHeadCommitID}},
|
'pullHeadCommitID': {{.PullHeadCommitID}},
|
||||||
'isPullBranchDeletable': {{.IsPullBranchDeletable}},
|
'isPullBranchDeletable': {{.IsPullBranchDeletable}},
|
||||||
'defaultDeleteBranchAfterMerge': {{$prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge}},
|
'defaultDeleteBranchAfterMerge': {{$prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge}},
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<label>{{.locale.Tr "repo.migrate_options"}}</label>
|
<label>{{.locale.Tr "repo.migrate_options"}}</label>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<input id="mirror" name="mirror" type="checkbox" {{if .mirror}} checked{{end}}>
|
<input id="mirror" name="mirror" type="checkbox" {{if .mirror}} checked{{end}}>
|
||||||
<label>{{.locale.Tr "repo.migrate_options_mirror_helper" | Safe}}</label>
|
<label>{{.locale.Tr "repo.migrate_options_mirror_helper"}}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -1341,9 +1341,7 @@
|
||||||
"$ref": "#/responses/HookList"
|
"$ref": "#/responses/HookList"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
"/orgs/{org}/hooks/": {
|
|
||||||
"post": {
|
"post": {
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
|
@ -16288,12 +16286,6 @@
|
||||||
},
|
},
|
||||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||||
},
|
},
|
||||||
"GitServiceType": {
|
|
||||||
"description": "GitServiceType represents a git service",
|
|
||||||
"type": "integer",
|
|
||||||
"format": "int64",
|
|
||||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
|
||||||
},
|
|
||||||
"GitTreeResponse": {
|
"GitTreeResponse": {
|
||||||
"description": "GitTreeResponse returns a git tree",
|
"description": "GitTreeResponse returns a git tree",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -16683,94 +16675,6 @@
|
||||||
"x-go-name": "MergePullRequestForm",
|
"x-go-name": "MergePullRequestForm",
|
||||||
"x-go-package": "code.gitea.io/gitea/services/forms"
|
"x-go-package": "code.gitea.io/gitea/services/forms"
|
||||||
},
|
},
|
||||||
"MigrateRepoForm": {
|
|
||||||
"description": "MigrateRepoForm form for migrating repository\nthis is used to interact with web ui",
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"clone_addr",
|
|
||||||
"uid",
|
|
||||||
"repo_name"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"auth_password": {
|
|
||||||
"type": "string",
|
|
||||||
"x-go-name": "AuthPassword"
|
|
||||||
},
|
|
||||||
"auth_token": {
|
|
||||||
"type": "string",
|
|
||||||
"x-go-name": "AuthToken"
|
|
||||||
},
|
|
||||||
"auth_username": {
|
|
||||||
"type": "string",
|
|
||||||
"x-go-name": "AuthUsername"
|
|
||||||
},
|
|
||||||
"clone_addr": {
|
|
||||||
"type": "string",
|
|
||||||
"x-go-name": "CloneAddr"
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"type": "string",
|
|
||||||
"x-go-name": "Description"
|
|
||||||
},
|
|
||||||
"issues": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "Issues"
|
|
||||||
},
|
|
||||||
"labels": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "Labels"
|
|
||||||
},
|
|
||||||
"lfs": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "LFS"
|
|
||||||
},
|
|
||||||
"lfs_endpoint": {
|
|
||||||
"type": "string",
|
|
||||||
"x-go-name": "LFSEndpoint"
|
|
||||||
},
|
|
||||||
"milestones": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "Milestones"
|
|
||||||
},
|
|
||||||
"mirror": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "Mirror"
|
|
||||||
},
|
|
||||||
"mirror_interval": {
|
|
||||||
"type": "string",
|
|
||||||
"x-go-name": "MirrorInterval"
|
|
||||||
},
|
|
||||||
"private": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "Private"
|
|
||||||
},
|
|
||||||
"pull_requests": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "PullRequests"
|
|
||||||
},
|
|
||||||
"releases": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "Releases"
|
|
||||||
},
|
|
||||||
"repo_name": {
|
|
||||||
"type": "string",
|
|
||||||
"x-go-name": "RepoName"
|
|
||||||
},
|
|
||||||
"service": {
|
|
||||||
"$ref": "#/definitions/GitServiceType"
|
|
||||||
},
|
|
||||||
"uid": {
|
|
||||||
"type": "integer",
|
|
||||||
"format": "int64",
|
|
||||||
"x-go-name": "UID"
|
|
||||||
},
|
|
||||||
"wiki": {
|
|
||||||
"type": "boolean",
|
|
||||||
"x-go-name": "Wiki"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-go-package": "code.gitea.io/gitea/services/forms"
|
|
||||||
},
|
|
||||||
"MigrateRepoOptions": {
|
"MigrateRepoOptions": {
|
||||||
"description": "MigrateRepoOptions options for migrating repository's\nthis is used to interact with api v1",
|
"description": "MigrateRepoOptions options for migrating repository's\nthis is used to interact with api v1",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
<div v-if="!showActionForm" class="df">
|
<div v-if="!showActionForm" class="df">
|
||||||
<!-- the merge button -->
|
<!-- the merge button -->
|
||||||
<div class="ui buttons merge-button" :class="mergeButtonStyleClass" @click="toggleActionForm(true)" >
|
<div class="ui buttons merge-button" :class="[mergeForm.emptyCommit ? 'grey' : mergeForm.allOverridableChecksOk ? 'green' : 'red']" @click="toggleActionForm(true)" >
|
||||||
<button class="ui button">
|
<button class="ui button">
|
||||||
<svg-icon name="octicon-git-merge"/>
|
<svg-icon name="octicon-git-merge"/>
|
||||||
<span class="button-text">
|
<span class="button-text">
|
||||||
|
|
|
@ -192,7 +192,7 @@ function setLabelColor(label, color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inspired by W3C recommandation https://www.w3.org/TR/WCAG20/#relativeluminancedef
|
* Inspired by W3C recommendation https://www.w3.org/TR/WCAG20/#relativeluminancedef
|
||||||
*/
|
*/
|
||||||
function getRelativeColor(color) {
|
function getRelativeColor(color) {
|
||||||
color /= 255;
|
color /= 255;
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
|
|
||||||
.dashboard-repos,
|
.dashboard-repos,
|
||||||
.dashboard-orgs {
|
.dashboard-orgs {
|
||||||
margin: 0 1px; /* Accomodate for Semantic's 1px hacks on .attached elements */
|
margin: 0 1px; /* Accommodate for Semantic's 1px hacks on .attached elements */
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-navbar {
|
.dashboard-navbar {
|
||||||
|
|
Reference in a new issue