mirror of https://github.com/go-gitea/gitea.git
Merge branch 'main' into lunny/maven_deploy
This commit is contained in:
commit
842d734265
|
@ -30,10 +30,6 @@ linters:
|
|||
|
||||
run:
|
||||
timeout: 10m
|
||||
skip-dirs:
|
||||
- node_modules
|
||||
- public
|
||||
- web_src
|
||||
|
||||
linters-settings:
|
||||
stylecheck:
|
||||
|
@ -94,6 +90,7 @@ linters-settings:
|
|||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
exclude-dirs: [node_modules, public, web_src]
|
||||
exclude-rules:
|
||||
# Exclude some linters from running on tests files.
|
||||
- path: _test\.go
|
||||
|
|
2
Makefile
2
Makefile
|
@ -28,7 +28,7 @@ XGO_VERSION := go-1.22.x
|
|||
AIR_PACKAGE ?= github.com/cosmtrek/air@v1.49.0
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.7.0
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.6.0
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.56.1
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.57.2
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
|
||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.4.1
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@db51e79a0e37c572d8b59ae0c58bf2bbbbe53285
|
||||
|
|
|
@ -304,11 +304,6 @@
|
|||
"path": "github.com/davecgh/go-spew/spew/LICENSE",
|
||||
"licenseText": "ISC License\n\nCopyright (c) 2012-2016 Dave Collins \u003cdave@davec.name\u003e\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/denisenkom/go-mssqldb",
|
||||
"path": "github.com/denisenkom/go-mssqldb/LICENSE.txt",
|
||||
"licenseText": "Copyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/dgryski/go-rendezvous",
|
||||
"path": "github.com/dgryski/go-rendezvous/LICENSE",
|
||||
|
@ -759,6 +754,16 @@
|
|||
"path": "github.com/microcosm-cc/bluemonday/LICENSE.md",
|
||||
"licenseText": "SPDX short identifier: BSD-3-Clause\nhttps://opensource.org/licenses/BSD-3-Clause\n\nCopyright (c) 2014, David Kitchen \u003cdavid@buro9.com\u003e\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the organisation (Microcosm) nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/microsoft/go-mssqldb",
|
||||
"path": "github.com/microsoft/go-mssqldb/LICENSE.txt",
|
||||
"licenseText": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) Microsoft Corporation.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/microsoft/go-mssqldb/internal/github.com/swisscom/mssql-always-encrypted/pkg",
|
||||
"path": "github.com/microsoft/go-mssqldb/internal/github.com/swisscom/mssql-always-encrypted/pkg/LICENSE.txt",
|
||||
"licenseText": "Copyright (c) 2021 Swisscom (Switzerland) Ltd\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/miekg/dns",
|
||||
"path": "github.com/miekg/dns/LICENSE",
|
||||
|
|
37
cmd/hook.go
37
cmd/hook.go
|
@ -448,23 +448,26 @@ Gitea or set your environment appropriately.`, "")
|
|||
|
||||
func hookPrintResults(results []private.HookPostReceiveBranchResult) {
|
||||
for _, res := range results {
|
||||
if !res.Message {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stderr, "")
|
||||
if res.Create {
|
||||
fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", res.Branch)
|
||||
fmt.Fprintf(os.Stderr, " %s\n", res.URL)
|
||||
} else {
|
||||
fmt.Fprint(os.Stderr, "Visit the existing pull request:\n")
|
||||
fmt.Fprintf(os.Stderr, " %s\n", res.URL)
|
||||
}
|
||||
fmt.Fprintln(os.Stderr, "")
|
||||
os.Stderr.Sync()
|
||||
hookPrintResult(res.Message, res.Create, res.Branch, res.URL)
|
||||
}
|
||||
}
|
||||
|
||||
func hookPrintResult(output, isCreate bool, branch, url string) {
|
||||
if !output {
|
||||
return
|
||||
}
|
||||
fmt.Fprintln(os.Stderr, "")
|
||||
if isCreate {
|
||||
fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", branch)
|
||||
fmt.Fprintf(os.Stderr, " %s\n", url)
|
||||
} else {
|
||||
fmt.Fprint(os.Stderr, "Visit the existing pull request:\n")
|
||||
fmt.Fprintf(os.Stderr, " %s\n", url)
|
||||
}
|
||||
fmt.Fprintln(os.Stderr, "")
|
||||
os.Stderr.Sync()
|
||||
}
|
||||
|
||||
func pushOptions() map[string]string {
|
||||
opts := make(map[string]string)
|
||||
if pushCount, err := strconv.Atoi(os.Getenv(private.GitPushOptionCount)); err == nil {
|
||||
|
@ -691,6 +694,12 @@ Gitea or set your environment appropriately.`, "")
|
|||
}
|
||||
err = writeFlushPktLine(ctx, os.Stdout)
|
||||
|
||||
if err == nil {
|
||||
for _, res := range resp.Results {
|
||||
hookPrintResult(res.ShouldShowMessage, res.IsCreatePR, res.HeadBranch, res.URL)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -303,34 +303,3 @@ sudo systemctl enable act_runner --now
|
|||
```
|
||||
|
||||
If using Docker, the `act_runner` user should also be added to the `docker` group before starting the service. Keep in mind that this effectively gives `act_runner` root access to the system [[1]](https://docs.docker.com/engine/security/#docker-daemon-attack-surface).
|
||||
|
||||
## Configuration variable
|
||||
|
||||
You can create configuration variables on the user, organization and repository level.
|
||||
The level of the variable depends on where you created it.
|
||||
|
||||
### Naming conventions
|
||||
|
||||
The following rules apply to variable names:
|
||||
|
||||
- Variable names can only contain alphanumeric characters (`[a-z]`, `[A-Z]`, `[0-9]`) or underscores (`_`). Spaces are not allowed.
|
||||
|
||||
- Variable names must not start with the `GITHUB_` and `GITEA_` prefix.
|
||||
|
||||
- Variable names must not start with a number.
|
||||
|
||||
- Variable names are case-insensitive.
|
||||
|
||||
- Variable names must be unique at the level they are created at.
|
||||
|
||||
- Variable names must not be `CI`.
|
||||
|
||||
### Using variable
|
||||
|
||||
After creating configuration variables, they will be automatically filled in the `vars` context.
|
||||
They can be accessed through expressions like `{{ vars.VARIABLE_NAME }}` in the workflow.
|
||||
|
||||
### Precedence
|
||||
|
||||
If a variable with the same name exists at multiple levels, the variable at the lowest level takes precedence:
|
||||
A repository variable will always be chosen over an organization/user variable.
|
||||
|
|
|
@ -258,32 +258,3 @@ Runner的标签用于确定Runner可以运行哪些Job以及如何运行它们
|
|||
Runner将从Gitea实例获取Job并自动运行它们。
|
||||
|
||||
由于Act Runner仍处于开发中,建议定期检查最新版本并进行升级。
|
||||
|
||||
## 变量
|
||||
|
||||
您可以创建用户、组织和仓库级别的变量。变量的级别取决于创建它的位置。
|
||||
|
||||
### 命名规则
|
||||
|
||||
以下规则适用于变量名:
|
||||
|
||||
- 变量名称只能包含字母数字字符 (`[a-z]`, `[A-Z]`, `[0-9]`) 或下划线 (`_`)。不允许使用空格。
|
||||
|
||||
- 变量名称不能以 `GITHUB_` 和 `GITEA_` 前缀开头。
|
||||
|
||||
- 变量名称不能以数字开头。
|
||||
|
||||
- 变量名称不区分大小写。
|
||||
|
||||
- 变量名称在创建它们的级别上必须是唯一的。
|
||||
|
||||
- 变量名称不能为 “CI”。
|
||||
|
||||
### 使用
|
||||
|
||||
创建配置变量后,它们将自动填充到 `vars` 上下文中。您可以在工作流中使用类似 `{{ vars.VARIABLE_NAME }}` 这样的表达式来使用它们。
|
||||
|
||||
### 优先级
|
||||
|
||||
如果同名变量存在于多个级别,则级别最低的变量优先。
|
||||
仓库级别的变量总是比组织或者用户级别的变量优先被选中。
|
||||
|
|
|
@ -104,7 +104,7 @@ However, if a job container tries to fetch code from localhost, it will fail bec
|
|||
### Connection 3, act runner to internet
|
||||
|
||||
When you use some actions like `actions/checkout@v4`, the act runner downloads the scripts, not the job containers.
|
||||
By default, it downloads from [gitea.com](http://gitea.com/), so it requires access to the internet.
|
||||
By default, it downloads from [github.com](http://github.com/), so it requires access to the internet. If you configure the `DEFAULT_ACTIONS_URL` to `self`, then it will download from your Gitea instance by default. Then it will not connect to internet when downloading the action itself.
|
||||
It also downloads some docker images from Docker Hub by default, which also requires internet access.
|
||||
|
||||
However, internet access is not strictly necessary.
|
||||
|
|
|
@ -105,7 +105,8 @@ act runner 必须能够连接到Gitea以接收任务并发送执行结果回来
|
|||
### 连接 3,act runner到互联网
|
||||
|
||||
当您使用诸如 `actions/checkout@v4` 的一些Actions时,act runner下载的是脚本,而不是Job容器。
|
||||
默认情况下,它从[gitea.com](http://gitea.com/)下载,因此需要访问互联网。
|
||||
默认情况下,它从[github.com](http://github.com/)下载,因此需要访问互联网。如果您设置的是 self,
|
||||
那么默认将从您的当前Gitea实例下载,那么此步骤不需要连接到互联网。
|
||||
它还默认从Docker Hub下载一些Docker镜像,这也需要互联网访问。
|
||||
|
||||
然而,互联网访问并不是绝对必需的。
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
date: "2024-04-10T22:21:00+08:00"
|
||||
title: "Variables"
|
||||
slug: "actions-variables"
|
||||
sidebar_position: 25
|
||||
draft: false
|
||||
toc: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "actions"
|
||||
name: "Variables"
|
||||
sidebar_position: 25
|
||||
identifier: "actions-variables"
|
||||
---
|
||||
|
||||
## Variables
|
||||
|
||||
You can create configuration variables on the user, organization and repository level.
|
||||
The level of the variable depends on where you created it. When creating a variable, the
|
||||
key will be converted to uppercase. You need use uppercase on the yaml file.
|
||||
|
||||
### Naming conventions
|
||||
|
||||
The following rules apply to variable names:
|
||||
|
||||
- Variable names can only contain alphanumeric characters (`[a-z]`, `[A-Z]`, `[0-9]`) or underscores (`_`). Spaces are not allowed.
|
||||
- Variable names must not start with the `GITHUB_` and `GITEA_` prefix.
|
||||
- Variable names must not start with a number.
|
||||
- Variable names are case-insensitive.
|
||||
- Variable names must be unique at the level they are created at.
|
||||
- Variable names must not be `CI`.
|
||||
|
||||
### Using variable
|
||||
|
||||
After creating configuration variables, they will be automatically filled in the `vars` context.
|
||||
They can be accessed through expressions like `${{ vars.VARIABLE_NAME }}` in the workflow.
|
||||
|
||||
### Precedence
|
||||
|
||||
If a variable with the same name exists at multiple levels, the variable at the lowest level takes precedence:
|
||||
A repository variable will always be chosen over an organization/user variable.
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
date: "2024-04-10T22:21:00+08:00"
|
||||
title: "变量"
|
||||
slug: "actions-variables"
|
||||
sidebar_position: 25
|
||||
draft: false
|
||||
toc: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "actions"
|
||||
name: "变量"
|
||||
sidebar_position: 25
|
||||
identifier: "actions-variables"
|
||||
---
|
||||
|
||||
## 变量
|
||||
|
||||
您可以创建用户、组织和仓库级别的变量。变量的级别取决于创建它的位置。当创建变量时,变量的名称会被
|
||||
转换为大写,在yaml文件中引用时需要使用大写。
|
||||
|
||||
### 命名规则
|
||||
|
||||
以下规则适用于变量名:
|
||||
|
||||
- 变量名称只能包含字母数字字符 (`[a-z]`, `[A-Z]`, `[0-9]`) 或下划线 (`_`)。不允许使用空格。
|
||||
- 变量名称不能以 `GITHUB_` 和 `GITEA_` 前缀开头。
|
||||
- 变量名称不能以数字开头。
|
||||
- 变量名称不区分大小写。
|
||||
- 变量名称在创建它们的级别上必须是唯一的。
|
||||
- 变量名称不能为 `CI`。
|
||||
|
||||
### 使用
|
||||
|
||||
创建配置变量后,它们将自动填充到 `vars` 上下文中。您可以在工作流中使用类似 `${{ vars.VARIABLE_NAME }}` 这样的表达式来使用它们。
|
||||
|
||||
### 优先级
|
||||
|
||||
如果同名变量存在于多个级别,则级别最低的变量优先。
|
||||
仓库级别的变量总是比组织或者用户级别的变量优先被选中。
|
2
go.mod
2
go.mod
|
@ -24,7 +24,6 @@ require (
|
|||
github.com/buildkite/terminal-to-html/v3 v3.11.0
|
||||
github.com/caddyserver/certmagic v0.20.0
|
||||
github.com/chi-middleware/proxy v1.1.1
|
||||
github.com/denisenkom/go-mssqldb v0.12.3
|
||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
|
||||
github.com/djherbis/buffer v1.2.0
|
||||
github.com/djherbis/nio/v3 v3.0.1
|
||||
|
@ -77,6 +76,7 @@ require (
|
|||
github.com/meilisearch/meilisearch-go v0.26.2
|
||||
github.com/mholt/archiver/v3 v3.5.1
|
||||
github.com/microcosm-cc/bluemonday v1.0.26
|
||||
github.com/microsoft/go-mssqldb v1.7.0
|
||||
github.com/minio/minio-go/v7 v7.0.69
|
||||
github.com/msteinert/pam v1.2.0
|
||||
github.com/nektos/act v0.2.52
|
||||
|
|
28
go.sum
28
go.sum
|
@ -38,11 +38,20 @@ github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 h1:r3qt8PCHnfjOv9PN3H
|
|||
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121/go.mod h1:Ock8XgA7pvULhIaHGAk/cDnRfNrF9Jey81nPcc403iU=
|
||||
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
|
||||
github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1/go.mod h1:GpPjLhVR9dnUoJMyHWSPy71xY9/lcmpzIPZXmF0FCVY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4=
|
||||
github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
|
||||
|
@ -220,7 +229,6 @@ github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k
|
|||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
|
||||
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
|
||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||
|
@ -355,7 +363,6 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW
|
|||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
|
@ -513,6 +520,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
|
@ -551,6 +560,8 @@ github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Cl
|
|||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
|
||||
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
|
||||
github.com/microsoft/go-mssqldb v1.7.0 h1:sgMPW0HA6Ihd37Yx0MzHyKD726C2kY/8KJsQtXHNaAs=
|
||||
github.com/microsoft/go-mssqldb v1.7.0/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
|
||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
|
@ -574,7 +585,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
|||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 h1:j2kD3MT1z4PXCiUllUJF9mWUESr9TWKS7iEKsQ/IipM=
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
|
||||
|
@ -627,7 +637,8 @@ github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ
|
|||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
@ -836,7 +847,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
|
@ -871,7 +881,6 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/
|
|||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
|
@ -1022,7 +1031,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
|
|
|
@ -16,14 +16,9 @@ import (
|
|||
type ActionJobList []*ActionRunJob
|
||||
|
||||
func (jobs ActionJobList) GetRunIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(jobs))
|
||||
for _, j := range jobs {
|
||||
if j.RunID == 0 {
|
||||
continue
|
||||
}
|
||||
ids.Add(j.RunID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(jobs, func(j *ActionRunJob) (int64, bool) {
|
||||
return j.RunID, j.RunID != 0
|
||||
})
|
||||
}
|
||||
|
||||
func (jobs ActionJobList) LoadRuns(ctx context.Context, withRepo bool) error {
|
||||
|
|
|
@ -19,19 +19,15 @@ type RunList []*ActionRun
|
|||
|
||||
// GetUserIDs returns a slice of user's id
|
||||
func (runs RunList) GetUserIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(runs))
|
||||
for _, run := range runs {
|
||||
ids.Add(run.TriggerUserID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(runs, func(run *ActionRun) (int64, bool) {
|
||||
return run.TriggerUserID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (runs RunList) GetRepoIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(runs))
|
||||
for _, run := range runs {
|
||||
ids.Add(run.RepoID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(runs, func(run *ActionRun) (int64, bool) {
|
||||
return run.RepoID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (runs RunList) LoadTriggerUser(ctx context.Context) error {
|
||||
|
|
|
@ -16,14 +16,9 @@ type RunnerList []*ActionRunner
|
|||
|
||||
// GetUserIDs returns a slice of user's id
|
||||
func (runners RunnerList) GetUserIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(runners))
|
||||
for _, runner := range runners {
|
||||
if runner.OwnerID == 0 {
|
||||
continue
|
||||
}
|
||||
ids.Add(runner.OwnerID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(runners, func(runner *ActionRunner) (int64, bool) {
|
||||
return runner.OwnerID, runner.OwnerID != 0
|
||||
})
|
||||
}
|
||||
|
||||
func (runners RunnerList) LoadOwners(ctx context.Context) error {
|
||||
|
@ -41,16 +36,9 @@ func (runners RunnerList) LoadOwners(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (runners RunnerList) getRepoIDs() []int64 {
|
||||
repoIDs := make(container.Set[int64], len(runners))
|
||||
for _, runner := range runners {
|
||||
if runner.RepoID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := repoIDs[runner.RepoID]; !ok {
|
||||
repoIDs[runner.RepoID] = struct{}{}
|
||||
}
|
||||
}
|
||||
return repoIDs.Values()
|
||||
return container.FilterSlice(runners, func(runner *ActionRunner) (int64, bool) {
|
||||
return runner.RepoID, runner.RepoID > 0
|
||||
})
|
||||
}
|
||||
|
||||
func (runners RunnerList) LoadRepos(ctx context.Context) error {
|
||||
|
|
|
@ -18,19 +18,15 @@ type ScheduleList []*ActionSchedule
|
|||
|
||||
// GetUserIDs returns a slice of user's id
|
||||
func (schedules ScheduleList) GetUserIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(schedules))
|
||||
for _, schedule := range schedules {
|
||||
ids.Add(schedule.TriggerUserID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(schedules, func(schedule *ActionSchedule) (int64, bool) {
|
||||
return schedule.TriggerUserID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (schedules ScheduleList) GetRepoIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(schedules))
|
||||
for _, schedule := range schedules {
|
||||
ids.Add(schedule.RepoID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(schedules, func(schedule *ActionSchedule) (int64, bool) {
|
||||
return schedule.RepoID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (schedules ScheduleList) LoadTriggerUser(ctx context.Context) error {
|
||||
|
|
|
@ -16,11 +16,9 @@ import (
|
|||
type SpecList []*ActionScheduleSpec
|
||||
|
||||
func (specs SpecList) GetScheduleIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(specs))
|
||||
for _, spec := range specs {
|
||||
ids.Add(spec.ScheduleID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(specs, func(spec *ActionScheduleSpec) (int64, bool) {
|
||||
return spec.ScheduleID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (specs SpecList) LoadSchedules(ctx context.Context) error {
|
||||
|
@ -46,11 +44,9 @@ func (specs SpecList) LoadSchedules(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (specs SpecList) GetRepoIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(specs))
|
||||
for _, spec := range specs {
|
||||
ids.Add(spec.RepoID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(specs, func(spec *ActionScheduleSpec) (int64, bool) {
|
||||
return spec.RepoID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (specs SpecList) LoadRepos(ctx context.Context) error {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -227,7 +228,9 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
|
|||
if runner.RepoID != 0 {
|
||||
jobCond = builder.Eq{"repo_id": runner.RepoID}
|
||||
} else if runner.OwnerID != 0 {
|
||||
jobCond = builder.In("repo_id", builder.Select("id").From("repository").Where(builder.Eq{"owner_id": runner.OwnerID}))
|
||||
jobCond = builder.In("repo_id", builder.Select("`repository`.id").From("repository").
|
||||
Join("INNER", "repo_unit", "`repository`.id = `repo_unit`.repo_id").
|
||||
Where(builder.Eq{"`repository`.owner_id": runner.OwnerID, "`repo_unit`.type": unit.TypeActions}))
|
||||
}
|
||||
if jobCond.IsValid() {
|
||||
jobCond = builder.In("run_id", builder.Select("id").From("action_run").Where(jobCond))
|
||||
|
|
|
@ -16,14 +16,9 @@ import (
|
|||
type TaskList []*ActionTask
|
||||
|
||||
func (tasks TaskList) GetJobIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(tasks))
|
||||
for _, t := range tasks {
|
||||
if t.JobID == 0 {
|
||||
continue
|
||||
}
|
||||
ids.Add(t.JobID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(tasks, func(t *ActionTask) (int64, bool) {
|
||||
return t.JobID, t.JobID != 0
|
||||
})
|
||||
}
|
||||
|
||||
func (tasks TaskList) LoadJobs(ctx context.Context) error {
|
||||
|
|
|
@ -22,11 +22,9 @@ import (
|
|||
type ActionList []*Action
|
||||
|
||||
func (actions ActionList) getUserIDs() []int64 {
|
||||
userIDs := make(container.Set[int64], len(actions))
|
||||
for _, action := range actions {
|
||||
userIDs.Add(action.ActUserID)
|
||||
}
|
||||
return userIDs.Values()
|
||||
return container.FilterSlice(actions, func(action *Action) (int64, bool) {
|
||||
return action.ActUserID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (actions ActionList) LoadActUsers(ctx context.Context) (map[int64]*user_model.User, error) {
|
||||
|
@ -50,11 +48,9 @@ func (actions ActionList) LoadActUsers(ctx context.Context) (map[int64]*user_mod
|
|||
}
|
||||
|
||||
func (actions ActionList) getRepoIDs() []int64 {
|
||||
repoIDs := make(container.Set[int64], len(actions))
|
||||
for _, action := range actions {
|
||||
repoIDs.Add(action.RepoID)
|
||||
}
|
||||
return repoIDs.Values()
|
||||
return container.FilterSlice(actions, func(action *Action) (int64, bool) {
|
||||
return action.RepoID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (actions ActionList) LoadRepositories(ctx context.Context) error {
|
||||
|
@ -80,18 +76,16 @@ func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]*
|
|||
userMap = make(map[int64]*user_model.User)
|
||||
}
|
||||
|
||||
userSet := make(container.Set[int64], len(actions))
|
||||
for _, action := range actions {
|
||||
missingUserIDs := container.FilterSlice(actions, func(action *Action) (int64, bool) {
|
||||
if action.Repo == nil {
|
||||
continue
|
||||
return 0, false
|
||||
}
|
||||
if _, ok := userMap[action.Repo.OwnerID]; !ok {
|
||||
userSet.Add(action.Repo.OwnerID)
|
||||
}
|
||||
}
|
||||
_, alreadyLoaded := userMap[action.Repo.OwnerID]
|
||||
return action.Repo.OwnerID, !alreadyLoaded
|
||||
})
|
||||
|
||||
if err := db.GetEngine(ctx).
|
||||
In("id", userSet.Values()).
|
||||
In("id", missingUserIDs).
|
||||
Find(&userMap); err != nil {
|
||||
return fmt.Errorf("find user: %w", err)
|
||||
}
|
||||
|
|
|
@ -190,14 +190,12 @@ func (nl NotificationList) LoadAttributes(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (nl NotificationList) getPendingRepoIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(nl))
|
||||
for _, notification := range nl {
|
||||
if notification.Repository != nil {
|
||||
continue
|
||||
return container.FilterSlice(nl, func(n *Notification) (int64, bool) {
|
||||
if n.Repository != nil {
|
||||
return 0, false
|
||||
}
|
||||
ids.Add(notification.RepoID)
|
||||
}
|
||||
return ids.Values()
|
||||
return n.RepoID, true
|
||||
})
|
||||
}
|
||||
|
||||
// LoadRepos loads repositories from database
|
||||
|
|
|
@ -21,9 +21,9 @@ import (
|
|||
"xorm.io/xorm/names"
|
||||
"xorm.io/xorm/schemas"
|
||||
|
||||
_ "github.com/denisenkom/go-mssqldb" // Needed for the MSSQL driver
|
||||
_ "github.com/go-sql-driver/mysql" // Needed for the MySQL driver
|
||||
_ "github.com/lib/pq" // Needed for the Postgresql driver
|
||||
_ "github.com/go-sql-driver/mysql" // Needed for the MySQL driver
|
||||
_ "github.com/lib/pq" // Needed for the Postgresql driver
|
||||
_ "github.com/microsoft/go-mssqldb" // Needed for the MSSQL driver
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -17,15 +17,12 @@ import (
|
|||
type BranchList []*Branch
|
||||
|
||||
func (branches BranchList) LoadDeletedBy(ctx context.Context) error {
|
||||
ids := container.Set[int64]{}
|
||||
for _, branch := range branches {
|
||||
if !branch.IsDeleted {
|
||||
continue
|
||||
}
|
||||
ids.Add(branch.DeletedByID)
|
||||
}
|
||||
ids := container.FilterSlice(branches, func(branch *Branch) (int64, bool) {
|
||||
return branch.DeletedByID, branch.IsDeleted
|
||||
})
|
||||
|
||||
usersMap := make(map[int64]*user_model.User, len(ids))
|
||||
if err := db.GetEngine(ctx).In("id", ids.Values()).Find(&usersMap); err != nil {
|
||||
if err := db.GetEngine(ctx).In("id", ids).Find(&usersMap); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, branch := range branches {
|
||||
|
@ -41,14 +38,13 @@ func (branches BranchList) LoadDeletedBy(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (branches BranchList) LoadPusher(ctx context.Context) error {
|
||||
ids := container.Set[int64]{}
|
||||
for _, branch := range branches {
|
||||
if branch.PusherID > 0 { // pusher_id maybe zero because some branches are sync by backend with no pusher
|
||||
ids.Add(branch.PusherID)
|
||||
}
|
||||
}
|
||||
ids := container.FilterSlice(branches, func(branch *Branch) (int64, bool) {
|
||||
// pusher_id maybe zero because some branches are sync by backend with no pusher
|
||||
return branch.PusherID, branch.PusherID > 0
|
||||
})
|
||||
|
||||
usersMap := make(map[int64]*user_model.User, len(ids))
|
||||
if err := db.GetEngine(ctx).In("id", ids.Values()).Find(&usersMap); err != nil {
|
||||
if err := db.GetEngine(ctx).In("id", ids).Find(&usersMap); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, branch := range branches {
|
||||
|
|
|
@ -1272,10 +1272,9 @@ func InsertIssueComments(ctx context.Context, comments []*Comment) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
issueIDs := make(container.Set[int64])
|
||||
for _, comment := range comments {
|
||||
issueIDs.Add(comment.IssueID)
|
||||
}
|
||||
issueIDs := container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
return comment.IssueID, true
|
||||
})
|
||||
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -1298,7 +1297,7 @@ func InsertIssueComments(ctx context.Context, comments []*Comment) error {
|
|||
}
|
||||
}
|
||||
|
||||
for issueID := range issueIDs {
|
||||
for _, issueID := range issueIDs {
|
||||
if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?",
|
||||
issueID, CommentTypeComment, issueID); err != nil {
|
||||
return err
|
||||
|
|
|
@ -17,13 +17,9 @@ import (
|
|||
type CommentList []*Comment
|
||||
|
||||
func (comments CommentList) getPosterIDs() []int64 {
|
||||
posterIDs := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.PosterID > 0 {
|
||||
posterIDs.Add(comment.PosterID)
|
||||
}
|
||||
}
|
||||
return posterIDs.Values()
|
||||
return container.FilterSlice(comments, func(c *Comment) (int64, bool) {
|
||||
return c.PosterID, c.PosterID > 0
|
||||
})
|
||||
}
|
||||
|
||||
// LoadPosters loads posters
|
||||
|
@ -44,13 +40,9 @@ func (comments CommentList) LoadPosters(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getLabelIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.LabelID > 0 {
|
||||
ids.Add(comment.LabelID)
|
||||
}
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
return comment.LabelID, comment.LabelID > 0
|
||||
})
|
||||
}
|
||||
|
||||
func (comments CommentList) loadLabels(ctx context.Context) error {
|
||||
|
@ -94,13 +86,9 @@ func (comments CommentList) loadLabels(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getMilestoneIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.MilestoneID > 0 {
|
||||
ids.Add(comment.MilestoneID)
|
||||
}
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
return comment.MilestoneID, comment.MilestoneID > 0
|
||||
})
|
||||
}
|
||||
|
||||
func (comments CommentList) loadMilestones(ctx context.Context) error {
|
||||
|
@ -137,13 +125,9 @@ func (comments CommentList) loadMilestones(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getOldMilestoneIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.OldMilestoneID > 0 {
|
||||
ids.Add(comment.OldMilestoneID)
|
||||
}
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
return comment.OldMilestoneID, comment.OldMilestoneID > 0
|
||||
})
|
||||
}
|
||||
|
||||
func (comments CommentList) loadOldMilestones(ctx context.Context) error {
|
||||
|
@ -180,13 +164,9 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getAssigneeIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.AssigneeID > 0 {
|
||||
ids.Add(comment.AssigneeID)
|
||||
}
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
return comment.AssigneeID, comment.AssigneeID > 0
|
||||
})
|
||||
}
|
||||
|
||||
func (comments CommentList) loadAssignees(ctx context.Context) error {
|
||||
|
@ -237,14 +217,9 @@ func (comments CommentList) loadAssignees(ctx context.Context) error {
|
|||
|
||||
// getIssueIDs returns all the issue ids on this comment list which issue hasn't been loaded
|
||||
func (comments CommentList) getIssueIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.Issue != nil {
|
||||
continue
|
||||
}
|
||||
ids.Add(comment.IssueID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
return comment.IssueID, comment.Issue == nil
|
||||
})
|
||||
}
|
||||
|
||||
// Issues returns all the issues of comments
|
||||
|
@ -311,16 +286,12 @@ func (comments CommentList) LoadIssues(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getDependentIssueIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
if comment.DependentIssue != nil {
|
||||
continue
|
||||
return 0, false
|
||||
}
|
||||
if comment.DependentIssueID > 0 {
|
||||
ids.Add(comment.DependentIssueID)
|
||||
}
|
||||
}
|
||||
return ids.Values()
|
||||
return comment.DependentIssueID, comment.DependentIssueID > 0
|
||||
})
|
||||
}
|
||||
|
||||
func (comments CommentList) loadDependentIssues(ctx context.Context) error {
|
||||
|
@ -375,15 +346,9 @@ func (comments CommentList) loadDependentIssues(ctx context.Context) error {
|
|||
|
||||
// getAttachmentCommentIDs only return the comment ids which possibly has attachments
|
||||
func (comments CommentList) getAttachmentCommentIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.Type == CommentTypeComment ||
|
||||
comment.Type == CommentTypeReview ||
|
||||
comment.Type == CommentTypeCode {
|
||||
ids.Add(comment.ID)
|
||||
}
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
return comment.ID, comment.Type.HasAttachmentSupport()
|
||||
})
|
||||
}
|
||||
|
||||
// LoadAttachmentsByIssue loads attachments by issue id
|
||||
|
@ -451,13 +416,9 @@ func (comments CommentList) LoadAttachments(ctx context.Context) (err error) {
|
|||
}
|
||||
|
||||
func (comments CommentList) getReviewIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.ReviewID > 0 {
|
||||
ids.Add(comment.ReviewID)
|
||||
}
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
|
||||
return comment.ReviewID, comment.ReviewID > 0
|
||||
})
|
||||
}
|
||||
|
||||
func (comments CommentList) loadReviews(ctx context.Context) error {
|
||||
|
|
|
@ -21,16 +21,15 @@ type IssueList []*Issue
|
|||
|
||||
// get the repo IDs to be loaded later, these IDs are for issue.Repo and issue.PullRequest.HeadRepo
|
||||
func (issues IssueList) getRepoIDs() []int64 {
|
||||
repoIDs := make(container.Set[int64], len(issues))
|
||||
for _, issue := range issues {
|
||||
return container.FilterSlice(issues, func(issue *Issue) (int64, bool) {
|
||||
if issue.Repo == nil {
|
||||
repoIDs.Add(issue.RepoID)
|
||||
return issue.RepoID, true
|
||||
}
|
||||
if issue.PullRequest != nil && issue.PullRequest.HeadRepo == nil {
|
||||
repoIDs.Add(issue.PullRequest.HeadRepoID)
|
||||
return issue.PullRequest.HeadRepoID, true
|
||||
}
|
||||
}
|
||||
return repoIDs.Values()
|
||||
return 0, false
|
||||
})
|
||||
}
|
||||
|
||||
// LoadRepositories loads issues' all repositories
|
||||
|
@ -74,11 +73,9 @@ func (issues IssueList) LoadRepositories(ctx context.Context) (repo_model.Reposi
|
|||
}
|
||||
|
||||
func (issues IssueList) getPosterIDs() []int64 {
|
||||
posterIDs := make(container.Set[int64], len(issues))
|
||||
for _, issue := range issues {
|
||||
posterIDs.Add(issue.PosterID)
|
||||
}
|
||||
return posterIDs.Values()
|
||||
return container.FilterSlice(issues, func(issue *Issue) (int64, bool) {
|
||||
return issue.PosterID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (issues IssueList) loadPosters(ctx context.Context) error {
|
||||
|
@ -193,11 +190,9 @@ func (issues IssueList) loadLabels(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (issues IssueList) getMilestoneIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(issues))
|
||||
for _, issue := range issues {
|
||||
ids.Add(issue.MilestoneID)
|
||||
}
|
||||
return ids.Values()
|
||||
return container.FilterSlice(issues, func(issue *Issue) (int64, bool) {
|
||||
return issue.MilestoneID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (issues IssueList) loadMilestones(ctx context.Context) error {
|
||||
|
|
|
@ -305,14 +305,12 @@ func (list ReactionList) GroupByType() map[string]ReactionList {
|
|||
}
|
||||
|
||||
func (list ReactionList) getUserIDs() []int64 {
|
||||
userIDs := make(container.Set[int64], len(list))
|
||||
for _, reaction := range list {
|
||||
return container.FilterSlice(list, func(reaction *Reaction) (int64, bool) {
|
||||
if reaction.OriginalAuthor != "" {
|
||||
continue
|
||||
return 0, false
|
||||
}
|
||||
userIDs.Add(reaction.UserID)
|
||||
}
|
||||
return userIDs.Values()
|
||||
return reaction.UserID, true
|
||||
})
|
||||
}
|
||||
|
||||
func valuesUser(m map[int64]*user_model.User) []*user_model.User {
|
||||
|
|
|
@ -38,12 +38,11 @@ func (reviews ReviewList) LoadReviewers(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (reviews ReviewList) LoadIssues(ctx context.Context) error {
|
||||
issueIDs := container.Set[int64]{}
|
||||
for i := 0; i < len(reviews); i++ {
|
||||
issueIDs.Add(reviews[i].IssueID)
|
||||
}
|
||||
issueIDs := container.FilterSlice(reviews, func(review *Review) (int64, bool) {
|
||||
return review.IssueID, true
|
||||
})
|
||||
|
||||
issues, err := GetIssuesByIDs(ctx, issueIDs.Values())
|
||||
issues, err := GetIssuesByIDs(ctx, issueIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -104,18 +104,19 @@ func (repos RepositoryList) LoadAttributes(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
set := make(container.Set[int64])
|
||||
userIDs := container.FilterSlice(repos, func(repo *Repository) (int64, bool) {
|
||||
return repo.OwnerID, true
|
||||
})
|
||||
repoIDs := make([]int64, len(repos))
|
||||
for i := range repos {
|
||||
set.Add(repos[i].OwnerID)
|
||||
repoIDs[i] = repos[i].ID
|
||||
}
|
||||
|
||||
// Load owners.
|
||||
users := make(map[int64]*user_model.User, len(set))
|
||||
users := make(map[int64]*user_model.User, len(userIDs))
|
||||
if err := db.GetEngine(ctx).
|
||||
Where("id > 0").
|
||||
In("id", set.Values()).
|
||||
In("id", userIDs).
|
||||
Find(&users); err != nil {
|
||||
return fmt.Errorf("find users: %w", err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package container
|
||||
|
||||
import "slices"
|
||||
|
||||
// FilterSlice ranges over the slice and calls include() for each element.
|
||||
// If the second returned value is true, the first returned value will be included in the resulting
|
||||
// slice (after deduplication).
|
||||
func FilterSlice[E any, T comparable](s []E, include func(E) (T, bool)) []T {
|
||||
filtered := make([]T, 0, len(s)) // slice will be clipped before returning
|
||||
seen := make(map[T]bool, len(s))
|
||||
for i := range s {
|
||||
if v, ok := include(s[i]); ok && !seen[v] {
|
||||
filtered = append(filtered, v)
|
||||
seen[v] = true
|
||||
}
|
||||
}
|
||||
return slices.Clip(filtered)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFilterMapUnique(t *testing.T) {
|
||||
result := FilterSlice([]int{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
}, func(i int) (int, bool) {
|
||||
switch i {
|
||||
case 0:
|
||||
return 0, true // included later
|
||||
case 1:
|
||||
return 0, true // duplicate of previous (should be ignored)
|
||||
case 2:
|
||||
return 2, false // not included
|
||||
default:
|
||||
return i, true
|
||||
}
|
||||
})
|
||||
assert.Equal(t, []int{0, 3, 4, 5, 6, 7, 8, 9}, result)
|
||||
}
|
|
@ -709,7 +709,8 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
|
|||
|
||||
name += tail
|
||||
image := false
|
||||
switch ext := filepath.Ext(link); ext {
|
||||
ext := filepath.Ext(link)
|
||||
switch ext {
|
||||
// fast path: empty string, ignore
|
||||
case "":
|
||||
// leave image as false
|
||||
|
@ -767,11 +768,26 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
|
|||
}
|
||||
} else {
|
||||
if !absoluteLink {
|
||||
var base string
|
||||
if ctx.IsWiki {
|
||||
link = util.URLJoin(ctx.Links.WikiLink(), link)
|
||||
switch ext {
|
||||
case "":
|
||||
// no file extension, create a regular wiki link
|
||||
base = ctx.Links.WikiLink()
|
||||
default:
|
||||
// we have a file extension:
|
||||
// return a regular wiki link if it's a renderable file (extension),
|
||||
// raw link otherwise
|
||||
if Type(link) != "" {
|
||||
base = ctx.Links.WikiLink()
|
||||
} else {
|
||||
base = ctx.Links.WikiRawLink()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
link = util.URLJoin(ctx.Links.SrcLink(), link)
|
||||
base = ctx.Links.SrcLink()
|
||||
}
|
||||
link = util.URLJoin(base, link)
|
||||
}
|
||||
childNode.Type = html.TextNode
|
||||
childNode.Data = name
|
||||
|
|
|
@ -427,6 +427,10 @@ func TestRender_ShortLinks(t *testing.T) {
|
|||
otherImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "Link+Other.jpg")
|
||||
encodedImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "Link+%23.jpg")
|
||||
notencodedImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "some", "path", "Link+#.jpg")
|
||||
renderableFileURL := util.URLJoin(tree, "markdown_file.md")
|
||||
renderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "markdown_file.md")
|
||||
unrenderableFileURL := util.URLJoin(tree, "file.zip")
|
||||
unrenderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "file.zip")
|
||||
favicon := "http://google.com/favicon.ico"
|
||||
|
||||
test(
|
||||
|
@ -481,6 +485,14 @@ func TestRender_ShortLinks(t *testing.T) {
|
|||
"[[Link]] [[Other Link]] [[Link?]]",
|
||||
`<p><a href="`+url+`" rel="nofollow">Link</a> <a href="`+otherURL+`" rel="nofollow">Other Link</a> <a href="`+encodedURL+`" rel="nofollow">Link?</a></p>`,
|
||||
`<p><a href="`+urlWiki+`" rel="nofollow">Link</a> <a href="`+otherURLWiki+`" rel="nofollow">Other Link</a> <a href="`+encodedURLWiki+`" rel="nofollow">Link?</a></p>`)
|
||||
test(
|
||||
"[[markdown_file.md]]",
|
||||
`<p><a href="`+renderableFileURL+`" rel="nofollow">markdown_file.md</a></p>`,
|
||||
`<p><a href="`+renderableFileURLWiki+`" rel="nofollow">markdown_file.md</a></p>`)
|
||||
test(
|
||||
"[[file.zip]]",
|
||||
`<p><a href="`+unrenderableFileURL+`" rel="nofollow">file.zip</a></p>`,
|
||||
`<p><a href="`+unrenderableFileURLWiki+`" rel="nofollow">file.zip</a></p>`)
|
||||
test(
|
||||
"[[Link #.jpg]]",
|
||||
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`" title="Link #.jpg" alt="Link #.jpg"/></a></p>`,
|
||||
|
|
|
@ -653,9 +653,9 @@ space</p>
|
|||
Expected: `<p>space @mention-user<br/>
|
||||
/just/a/path.bin<br/>
|
||||
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
|
||||
<a href="/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/wiki/raw/image.jpg" alt="local image"/></a><br/>
|
||||
<a href="/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
|
@ -711,9 +711,9 @@ space</p>
|
|||
Expected: `<p>space @mention-user<br/>
|
||||
/just/a/path.bin<br/>
|
||||
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
|
||||
<a href="https://gitea.io/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://gitea.io/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="https://gitea.io/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://gitea.io/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="https://gitea.io/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/wiki/raw/image.jpg" alt="local image"/></a><br/>
|
||||
<a href="https://gitea.io/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
|
@ -769,9 +769,9 @@ space</p>
|
|||
Expected: `<p>space @mention-user<br/>
|
||||
/just/a/path.bin<br/>
|
||||
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
|
||||
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
|
@ -829,9 +829,9 @@ space</p>
|
|||
Expected: `<p>space @mention-user<br/>
|
||||
/just/a/path.bin<br/>
|
||||
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
|
||||
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
|
@ -889,9 +889,9 @@ space</p>
|
|||
Expected: `<p>space @mention-user<br/>
|
||||
/just/a/path.bin<br/>
|
||||
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
|
||||
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
|
@ -951,9 +951,9 @@ space</p>
|
|||
Expected: `<p>space @mention-user<br/>
|
||||
/just/a/path.bin<br/>
|
||||
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
|
||||
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
|
||||
<a href="https://example.com" rel="nofollow">remote link</a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
package markdown
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
giteautil "code.gitea.io/gitea/modules/util"
|
||||
|
||||
|
@ -18,7 +20,16 @@ func (g *ASTTransformer) transformLink(ctx *markup.RenderContext, v *ast.Link, r
|
|||
if !isAnchorFragment && !markup.IsFullURLBytes(link) {
|
||||
base := ctx.Links.Base
|
||||
if ctx.IsWiki {
|
||||
base = ctx.Links.WikiLink()
|
||||
if filepath.Ext(string(link)) == "" {
|
||||
// This link doesn't have a file extension - assume a regular wiki link
|
||||
base = ctx.Links.WikiLink()
|
||||
} else if markup.Type(string(link)) != "" {
|
||||
// If it's a file type we can render, use a regular wiki link
|
||||
base = ctx.Links.WikiLink()
|
||||
} else {
|
||||
// Otherwise, use a raw link instead
|
||||
base = ctx.Links.WikiRawLink()
|
||||
}
|
||||
} else if ctx.Links.HasBranchInfo() {
|
||||
base = ctx.Links.SrcLink()
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
|
@ -32,13 +33,13 @@ const (
|
|||
)
|
||||
|
||||
// Bool checks for a key in the map and parses as a boolean
|
||||
func (g GitPushOptions) Bool(key string, def bool) bool {
|
||||
func (g GitPushOptions) Bool(key string) optional.Option[bool] {
|
||||
if val, ok := g[key]; ok {
|
||||
if b, err := strconv.ParseBool(val); err == nil {
|
||||
return b
|
||||
return optional.Some(b)
|
||||
}
|
||||
}
|
||||
return def
|
||||
return optional.None[bool]()
|
||||
}
|
||||
|
||||
// HookOptions represents the options for the Hook calls
|
||||
|
@ -87,13 +88,17 @@ type HookProcReceiveResult struct {
|
|||
|
||||
// HookProcReceiveRefResult represents an individual result from ProcReceive
|
||||
type HookProcReceiveRefResult struct {
|
||||
OldOID string
|
||||
NewOID string
|
||||
Ref string
|
||||
OriginalRef git.RefName
|
||||
IsForcePush bool
|
||||
IsNotMatched bool
|
||||
Err string
|
||||
OldOID string
|
||||
NewOID string
|
||||
Ref string
|
||||
OriginalRef git.RefName
|
||||
IsForcePush bool
|
||||
IsNotMatched bool
|
||||
Err string
|
||||
IsCreatePR bool
|
||||
URL string
|
||||
ShouldShowMessage bool
|
||||
HeadBranch string
|
||||
}
|
||||
|
||||
// HookPreReceive check whether the provided commits are allowed
|
||||
|
|
|
@ -1331,12 +1331,53 @@ runners.task_list.repository=Repositori
|
|||
runners.task_list.commit=Memperbuat
|
||||
|
||||
runs.commit=Memperbuat
|
||||
runs.no_matching_online_runner_helper=Tidak ada runner online yang cocok dengan label: %s
|
||||
runs.actor=Aktor
|
||||
runs.status=Status
|
||||
runs.actors_no_select=Semua aktor
|
||||
runs.status_no_select=Semua status
|
||||
runs.no_results=Tidak ada hasil yang cocok.
|
||||
runs.no_workflows=Belum ada alur kerja.
|
||||
runs.no_workflows.quick_start=Tidak tahu cara memulai dengan Gitea Actions? Lihat <a target="_blank" rel="noopener noreferrer" href="%s">panduan cepat</a>.
|
||||
runs.no_workflows.documentation=Untuk informasi lebih lanjut tentang Gitea Actions, lihat <a target="_blank" rel="noopener noreferrer" href="%s">dokumentasi</a>.
|
||||
runs.no_runs=Alur kerja belum berjalan.
|
||||
runs.empty_commit_message=(pesan commit kosong)
|
||||
|
||||
workflow.disable=Nonaktifkan Alur Kerja
|
||||
workflow.disable_success=Alur kerja '%s' berhasil dinonaktifkan.
|
||||
workflow.enable=Aktifkan Alur Kerja
|
||||
workflow.enable_success=Alur kerja '%s' berhasil diaktifkan.
|
||||
workflow.disabled=Alur kerja dinonaktifkan.
|
||||
|
||||
need_approval_desc=Butuh persetujuan untuk menjalankan alur kerja untuk pull request fork.
|
||||
|
||||
variables=Variabel
|
||||
variables.management=Managemen Variabel
|
||||
variables.creation=Tambah Variabel
|
||||
variables.none=Belum ada variabel.
|
||||
variables.deletion=Hapus variabel
|
||||
variables.deletion.description=Menghapus variabel bersifat permanen dan tidak dapat dibatalkan. Lanjutkan?
|
||||
variables.description=Variabel akan diteruskan ke beberapa tindakan dan tidak dapat dibaca sebaliknya.
|
||||
variables.id_not_exist=Variabel dengan ID %d tidak ada.
|
||||
variables.edit=Edit Variabel
|
||||
variables.deletion.failed=Gagal menghapus variabel.
|
||||
variables.deletion.success=Variabel telah dihapus.
|
||||
variables.creation.failed=Gagal menambahkan variabel.
|
||||
variables.creation.success=Variabel "%s" telah ditambahkan.
|
||||
variables.update.failed=Gagal mengedit variabel.
|
||||
variables.update.success=Variabel telah diedit.
|
||||
|
||||
[projects]
|
||||
type-1.display_name=Proyek Individu
|
||||
type-2.display_name=Proyek Repositori
|
||||
type-3.display_name=Proyek Organisasi
|
||||
|
||||
[git.filemode]
|
||||
changed_filemode=%[1]s → %[2]s
|
||||
; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", …
|
||||
directory=Directory
|
||||
normal_file=Normal file
|
||||
executable_file=Executable file
|
||||
symbolic_link=Symbolic link
|
||||
submodule=Submodule
|
||||
|
||||
|
|
|
@ -2109,7 +2109,7 @@ settings.pulls.default_delete_branch_after_merge=デフォルトでプルリク
|
|||
settings.pulls.default_allow_edits_from_maintainers=デフォルトでメンテナからの編集を許可する
|
||||
settings.releases_desc=リリースを有効にする
|
||||
settings.packages_desc=リポジトリパッケージレジストリを有効にする
|
||||
settings.projects_desc=リポジトリプロジェクトを有効にする
|
||||
settings.projects_desc=プロジェクトを有効にする
|
||||
settings.projects_mode_all=すべてのプロジェクト
|
||||
settings.actions_desc=Actionsを有効にする
|
||||
settings.admin_settings=管理者用設定
|
||||
|
|
|
@ -311,7 +311,7 @@ func SearchIssues(ctx *context.APIContext) {
|
|||
|
||||
ctx.SetLinkHeader(int(total), limit)
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
// ListIssues list the issues of a repository
|
||||
|
@ -548,7 +548,7 @@ func ListIssues(ctx *context.APIContext) {
|
|||
|
||||
ctx.SetLinkHeader(int(total), listOptions.PageSize)
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
func getUserIDForFilter(ctx *context.APIContext, queryName string) int64 {
|
||||
|
@ -614,7 +614,7 @@ func GetIssue(ctx *context.APIContext) {
|
|||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, ctx.Doer, issue))
|
||||
}
|
||||
|
||||
// CreateIssue create an issue of a repository
|
||||
|
@ -737,7 +737,7 @@ func CreateIssue(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "GetIssueByID", err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, issue))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, issue))
|
||||
}
|
||||
|
||||
// EditIssue modify an issue of a repository
|
||||
|
@ -911,7 +911,7 @@ func EditIssue(ctx *context.APIContext) {
|
|||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, issue))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, issue))
|
||||
}
|
||||
|
||||
func DeleteIssue(ctx *context.APIContext) {
|
||||
|
|
|
@ -107,7 +107,7 @@ func ListIssueAttachments(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue).Attachments)
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, ctx.Doer, issue).Attachments)
|
||||
}
|
||||
|
||||
// CreateIssueAttachment creates an attachment and saves the given file
|
||||
|
|
|
@ -153,7 +153,7 @@ func GetIssueDependencies(ctx *context.APIContext) {
|
|||
blockerIssues = append(blockerIssues, &blocker.Issue)
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, blockerIssues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, blockerIssues))
|
||||
}
|
||||
|
||||
// CreateIssueDependency create a new issue dependencies
|
||||
|
@ -214,7 +214,7 @@ func CreateIssueDependency(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, target))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, target))
|
||||
}
|
||||
|
||||
// RemoveIssueDependency remove an issue dependency
|
||||
|
@ -275,7 +275,7 @@ func RemoveIssueDependency(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, target))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, target))
|
||||
}
|
||||
|
||||
// GetIssueBlocks list issues that are blocked by this issue
|
||||
|
@ -381,7 +381,7 @@ func GetIssueBlocks(ctx *context.APIContext) {
|
|||
issues = append(issues, &depMeta.Issue)
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
// CreateIssueBlocking block the issue given in the body by the issue in path
|
||||
|
@ -438,7 +438,7 @@ func CreateIssueBlocking(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, dependency))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, dependency))
|
||||
}
|
||||
|
||||
// RemoveIssueBlocking unblock the issue given in the body by the issue in path
|
||||
|
@ -495,7 +495,7 @@ func RemoveIssueBlocking(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, dependency))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, dependency))
|
||||
}
|
||||
|
||||
func getParamsIssue(ctx *context.APIContext) *issues_model.Issue {
|
||||
|
|
|
@ -207,7 +207,7 @@ func ListPinnedIssues(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
// ListPinnedPullRequests returns a list of all pinned PRs
|
||||
|
|
|
@ -138,7 +138,7 @@ func ListTrackedTimes(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes))
|
||||
}
|
||||
|
||||
// AddTime add time manual to the given issue
|
||||
|
@ -225,7 +225,7 @@ func AddTime(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTime(ctx, trackedTime))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTime(ctx, user, trackedTime))
|
||||
}
|
||||
|
||||
// ResetIssueTime reset time manual to the given issue
|
||||
|
@ -455,7 +455,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes))
|
||||
}
|
||||
|
||||
// ListTrackedTimesByRepository lists all tracked times of the repository
|
||||
|
@ -567,7 +567,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes))
|
||||
}
|
||||
|
||||
// ListMyTrackedTimes lists all tracked times of the current user
|
||||
|
@ -629,5 +629,5 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes))
|
||||
}
|
||||
|
|
|
@ -6,11 +6,12 @@ package private
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
@ -159,8 +160,10 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
|
|||
}
|
||||
}
|
||||
|
||||
isPrivate := opts.GitPushOptions.Bool(private.GitPushOptionRepoPrivate)
|
||||
isTemplate := opts.GitPushOptions.Bool(private.GitPushOptionRepoTemplate)
|
||||
// Handle Push Options
|
||||
if len(opts.GitPushOptions) > 0 {
|
||||
if isPrivate.Has() || isTemplate.Has() {
|
||||
// load the repository
|
||||
if repo == nil {
|
||||
repo = loadRepository(ctx, ownerName, repoName)
|
||||
|
@ -171,13 +174,49 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
|
|||
wasEmpty = repo.IsEmpty
|
||||
}
|
||||
|
||||
repo.IsPrivate = opts.GitPushOptions.Bool(private.GitPushOptionRepoPrivate, repo.IsPrivate)
|
||||
repo.IsTemplate = opts.GitPushOptions.Bool(private.GitPushOptionRepoTemplate, repo.IsTemplate)
|
||||
if err := repo_model.UpdateRepositoryCols(ctx, repo, "is_private", "is_template"); err != nil {
|
||||
pusher, err := user_model.GetUserByID(ctx, opts.UserID)
|
||||
if err != nil {
|
||||
log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err)
|
||||
ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
|
||||
Err: fmt.Sprintf("Failed to Update: %s/%s Error: %v", ownerName, repoName, err),
|
||||
})
|
||||
return
|
||||
}
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, repo, pusher)
|
||||
if err != nil {
|
||||
log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err)
|
||||
ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
|
||||
Err: fmt.Sprintf("Failed to Update: %s/%s Error: %v", ownerName, repoName, err),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !perm.IsOwner() && !perm.IsAdmin() {
|
||||
ctx.JSON(http.StatusNotFound, private.HookPostReceiveResult{
|
||||
Err: "Permissions denied",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
cols := make([]string, 0, len(opts.GitPushOptions))
|
||||
|
||||
if isPrivate.Has() {
|
||||
repo.IsPrivate = isPrivate.Value()
|
||||
cols = append(cols, "is_private")
|
||||
}
|
||||
|
||||
if isTemplate.Has() {
|
||||
repo.IsTemplate = isTemplate.Value()
|
||||
cols = append(cols, "is_template")
|
||||
}
|
||||
|
||||
if len(cols) > 0 {
|
||||
if err := repo_model.UpdateRepositoryCols(ctx, repo, cols...); err != nil {
|
||||
log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err)
|
||||
ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
|
||||
Err: fmt.Sprintf("Failed to Update: %s/%s Error: %v", ownerName, repoName, err),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,42 +231,6 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
|
|||
refFullName := opts.RefFullNames[i]
|
||||
newCommitID := opts.NewCommitIDs[i]
|
||||
|
||||
// post update for agit pull request
|
||||
// FIXME: use pr.Flow to test whether it's an Agit PR or a GH PR
|
||||
if git.DefaultFeatures.SupportProcReceive && refFullName.IsPull() {
|
||||
if repo == nil {
|
||||
repo = loadRepository(ctx, ownerName, repoName)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
pullIndex, _ := strconv.ParseInt(refFullName.PullName(), 10, 64)
|
||||
if pullIndex <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
pr, err := issues_model.GetPullRequestByIndex(ctx, repo.ID, pullIndex)
|
||||
if err != nil && !issues_model.IsErrPullRequestNotExist(err) {
|
||||
log.Error("Failed to get PR by index %v Error: %v", pullIndex, err)
|
||||
ctx.JSON(http.StatusInternalServerError, private.Response{
|
||||
Err: fmt.Sprintf("Failed to get PR by index %v Error: %v", pullIndex, err),
|
||||
})
|
||||
return
|
||||
}
|
||||
if pr == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
results = append(results, private.HookPostReceiveBranchResult{
|
||||
Message: setting.Git.PullRequestPushMessage && repo.AllowsPulls(ctx),
|
||||
Create: false,
|
||||
Branch: "",
|
||||
URL: fmt.Sprintf("%s/pulls/%d", repo.HTMLURL(), pr.Index),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// If we've pushed a branch (and not deleted it)
|
||||
if !git.IsEmptyCommitID(newCommitID) && refFullName.IsBranch() {
|
||||
// First ensure we have the repository loaded, we're allowed pulls requests and we can get the base repo
|
||||
|
|
|
@ -2179,7 +2179,7 @@ func GetIssueInfo(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToIssue(ctx, issue))
|
||||
ctx.JSON(http.StatusOK, convert.ToIssue(ctx, ctx.Doer, issue))
|
||||
}
|
||||
|
||||
// UpdateIssueTitle change issue's title
|
||||
|
@ -2709,7 +2709,7 @@ func SearchIssues(ctx *context.Context) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
func getUserIDForFilter(ctx *context.Context, queryName string) int64 {
|
||||
|
@ -2879,7 +2879,7 @@ func ListIssues(ctx *context.Context) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
func BatchDeleteIssues(ctx *context.Context) {
|
||||
|
|
|
@ -200,12 +200,13 @@ func TestDeleteWikiPagePost(t *testing.T) {
|
|||
|
||||
func TestWikiRaw(t *testing.T) {
|
||||
for filepath, filetype := range map[string]string{
|
||||
"jpeg.jpg": "image/jpeg",
|
||||
"images/jpeg.jpg": "image/jpeg",
|
||||
"Page With Spaced Name": "text/plain; charset=utf-8",
|
||||
"Page-With-Spaced-Name": "text/plain; charset=utf-8",
|
||||
"Page With Spaced Name.md": "", // there is no "Page With Spaced Name.md" in repo
|
||||
"Page-With-Spaced-Name.md": "text/plain; charset=utf-8",
|
||||
"jpeg.jpg": "image/jpeg",
|
||||
"images/jpeg.jpg": "image/jpeg",
|
||||
"files/Non-Renderable-File.zip": "application/octet-stream",
|
||||
"Page With Spaced Name": "text/plain; charset=utf-8",
|
||||
"Page-With-Spaced-Name": "text/plain; charset=utf-8",
|
||||
"Page With Spaced Name.md": "", // there is no "Page With Spaced Name.md" in repo
|
||||
"Page-With-Spaced-Name.md": "text/plain; charset=utf-8",
|
||||
} {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
|
@ -226,6 +227,12 @@ func TestWikiRaw(t *testing.T) {
|
|||
func TestDefaultWikiBranch(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
// repo with no wiki
|
||||
repoWithNoWiki := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||
assert.False(t, repoWithNoWiki.HasWiki())
|
||||
assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repoWithNoWiki, "main"))
|
||||
|
||||
// repo with wiki
|
||||
assert.NoError(t, repo_model.UpdateRepositoryCols(db.DefaultContext, &repo_model.Repository{ID: 1, DefaultWikiBranch: "wrong-branch"}))
|
||||
|
||||
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki")
|
||||
|
|
|
@ -49,7 +49,7 @@ func (n *actionsNotifier) NewIssue(ctx context.Context, issue *issues_model.Issu
|
|||
newNotifyInputFromIssue(issue, webhook_module.HookEventIssues).WithPayload(&api.IssuePayload{
|
||||
Action: api.HookIssueOpened,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, issue.Poster, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, issue.Poster, nil),
|
||||
}).Notify(withMethod(ctx, "NewIssue"))
|
||||
|
@ -89,7 +89,7 @@ func (n *actionsNotifier) IssueChangeContent(ctx context.Context, doer *user_mod
|
|||
WithPayload(&api.IssuePayload{
|
||||
Action: api.HookIssueEdited,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}).
|
||||
|
@ -127,7 +127,7 @@ func (n *actionsNotifier) IssueChangeStatus(ctx context.Context, doer *user_mode
|
|||
}
|
||||
apiIssue := &api.IssuePayload{
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues
|
|||
WithPayload(&api.IssuePayload{
|
||||
Action: action,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}).
|
||||
|
@ -293,7 +293,7 @@ func notifyIssueCommentChange(ctx context.Context, doer *user_model.User, commen
|
|||
|
||||
payload := &api.IssueCommentPayload{
|
||||
Action: action,
|
||||
Issue: convert.ToAPIIssue(ctx, comment.Issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, comment.Issue),
|
||||
Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment),
|
||||
Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
notify_service "code.gitea.io/gitea/services/notify"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
)
|
||||
|
@ -145,10 +146,14 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
|
|||
log.Trace("Pull request created: %d/%d", repo.ID, prIssue.ID)
|
||||
|
||||
results = append(results, private.HookProcReceiveRefResult{
|
||||
Ref: pr.GetGitRefName(),
|
||||
OriginalRef: opts.RefFullNames[i],
|
||||
OldOID: objectFormat.EmptyObjectID().String(),
|
||||
NewOID: opts.NewCommitIDs[i],
|
||||
Ref: pr.GetGitRefName(),
|
||||
OriginalRef: opts.RefFullNames[i],
|
||||
OldOID: objectFormat.EmptyObjectID().String(),
|
||||
NewOID: opts.NewCommitIDs[i],
|
||||
IsCreatePR: true,
|
||||
URL: fmt.Sprintf("%s/pulls/%d", repo.HTMLURL(), pr.Index),
|
||||
ShouldShowMessage: setting.Git.PullRequestPushMessage && repo.AllowsPulls(ctx),
|
||||
HeadBranch: headBranch,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
@ -208,11 +213,14 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
|
|||
isForcePush := comment != nil && comment.IsForcePush
|
||||
|
||||
results = append(results, private.HookProcReceiveRefResult{
|
||||
OldOID: oldCommitID,
|
||||
NewOID: opts.NewCommitIDs[i],
|
||||
Ref: pr.GetGitRefName(),
|
||||
OriginalRef: opts.RefFullNames[i],
|
||||
IsForcePush: isForcePush,
|
||||
OldOID: oldCommitID,
|
||||
NewOID: opts.NewCommitIDs[i],
|
||||
Ref: pr.GetGitRefName(),
|
||||
OriginalRef: opts.RefFullNames[i],
|
||||
IsForcePush: isForcePush,
|
||||
IsCreatePR: false,
|
||||
URL: fmt.Sprintf("%s/pulls/%d", repo.HTMLURL(), pr.Index),
|
||||
ShouldShowMessage: setting.Git.PullRequestPushMessage && repo.AllowsPulls(ctx),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -18,19 +18,19 @@ import (
|
|||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
func ToIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
|
||||
return toIssue(ctx, issue, WebAssetDownloadURL)
|
||||
func ToIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) *api.Issue {
|
||||
return toIssue(ctx, doer, issue, WebAssetDownloadURL)
|
||||
}
|
||||
|
||||
// ToAPIIssue converts an Issue to API format
|
||||
// it assumes some fields assigned with values:
|
||||
// Required - Poster, Labels,
|
||||
// Optional - Milestone, Assignee, PullRequest
|
||||
func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
|
||||
return toIssue(ctx, issue, APIAssetDownloadURL)
|
||||
func ToAPIIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) *api.Issue {
|
||||
return toIssue(ctx, doer, issue, APIAssetDownloadURL)
|
||||
}
|
||||
|
||||
func toIssue(ctx context.Context, issue *issues_model.Issue, getDownloadURL func(repo *repo_model.Repository, attach *repo_model.Attachment) string) *api.Issue {
|
||||
func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, getDownloadURL func(repo *repo_model.Repository, attach *repo_model.Attachment) string) *api.Issue {
|
||||
if err := issue.LoadLabels(ctx); err != nil {
|
||||
return &api.Issue{}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ func toIssue(ctx context.Context, issue *issues_model.Issue, getDownloadURL func
|
|||
apiIssue := &api.Issue{
|
||||
ID: issue.ID,
|
||||
Index: issue.Index,
|
||||
Poster: ToUser(ctx, issue.Poster, nil),
|
||||
Poster: ToUser(ctx, issue.Poster, doer),
|
||||
Title: issue.Title,
|
||||
Body: issue.Content,
|
||||
Attachments: toAttachments(issue.Repo, issue.Attachments, getDownloadURL),
|
||||
|
@ -114,25 +114,25 @@ func toIssue(ctx context.Context, issue *issues_model.Issue, getDownloadURL func
|
|||
}
|
||||
|
||||
// ToIssueList converts an IssueList to API format
|
||||
func ToIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue {
|
||||
func ToIssueList(ctx context.Context, doer *user_model.User, il issues_model.IssueList) []*api.Issue {
|
||||
result := make([]*api.Issue, len(il))
|
||||
for i := range il {
|
||||
result[i] = ToIssue(ctx, il[i])
|
||||
result[i] = ToIssue(ctx, doer, il[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ToAPIIssueList converts an IssueList to API format
|
||||
func ToAPIIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue {
|
||||
func ToAPIIssueList(ctx context.Context, doer *user_model.User, il issues_model.IssueList) []*api.Issue {
|
||||
result := make([]*api.Issue, len(il))
|
||||
for i := range il {
|
||||
result[i] = ToAPIIssue(ctx, il[i])
|
||||
result[i] = ToAPIIssue(ctx, doer, il[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ToTrackedTime converts TrackedTime to API format
|
||||
func ToTrackedTime(ctx context.Context, t *issues_model.TrackedTime) (apiT *api.TrackedTime) {
|
||||
func ToTrackedTime(ctx context.Context, doer *user_model.User, t *issues_model.TrackedTime) (apiT *api.TrackedTime) {
|
||||
apiT = &api.TrackedTime{
|
||||
ID: t.ID,
|
||||
IssueID: t.IssueID,
|
||||
|
@ -141,7 +141,7 @@ func ToTrackedTime(ctx context.Context, t *issues_model.TrackedTime) (apiT *api.
|
|||
Created: t.Created,
|
||||
}
|
||||
if t.Issue != nil {
|
||||
apiT.Issue = ToAPIIssue(ctx, t.Issue)
|
||||
apiT.Issue = ToAPIIssue(ctx, doer, t.Issue)
|
||||
}
|
||||
if t.User != nil {
|
||||
apiT.UserName = t.User.Name
|
||||
|
@ -192,10 +192,10 @@ func ToStopWatches(ctx context.Context, sws []*issues_model.Stopwatch) (api.Stop
|
|||
}
|
||||
|
||||
// ToTrackedTimeList converts TrackedTimeList to API format
|
||||
func ToTrackedTimeList(ctx context.Context, tl issues_model.TrackedTimeList) api.TrackedTimeList {
|
||||
func ToTrackedTimeList(ctx context.Context, doer *user_model.User, tl issues_model.TrackedTimeList) api.TrackedTimeList {
|
||||
result := make([]*api.TrackedTime, 0, len(tl))
|
||||
for _, t := range tl {
|
||||
result = append(result, ToTrackedTime(ctx, t))
|
||||
result = append(result, ToTrackedTime(ctx, doer, t))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ func ToTimelineComment(ctx context.Context, repo *repo_model.Repository, c *issu
|
|||
return nil
|
||||
}
|
||||
|
||||
comment.TrackedTime = ToTrackedTime(ctx, c.Time)
|
||||
comment.TrackedTime = ToTrackedTime(ctx, doer, c.Time)
|
||||
}
|
||||
|
||||
if c.RefIssueID != 0 {
|
||||
|
@ -129,7 +129,7 @@ func ToTimelineComment(ctx context.Context, repo *repo_model.Repository, c *issu
|
|||
log.Error("GetIssueByID(%d): %v", c.RefIssueID, err)
|
||||
return nil
|
||||
}
|
||||
comment.RefIssue = ToAPIIssue(ctx, issue)
|
||||
comment.RefIssue = ToAPIIssue(ctx, doer, issue)
|
||||
}
|
||||
|
||||
if c.RefCommentID != 0 {
|
||||
|
@ -180,7 +180,7 @@ func ToTimelineComment(ctx context.Context, repo *repo_model.Repository, c *issu
|
|||
}
|
||||
|
||||
if c.DependentIssue != nil {
|
||||
comment.DependentIssue = ToAPIIssue(ctx, c.DependentIssue)
|
||||
comment.DependentIssue = ToAPIIssue(ctx, doer, c.DependentIssue)
|
||||
}
|
||||
|
||||
return comment
|
||||
|
|
|
@ -33,7 +33,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
|
|||
return nil
|
||||
}
|
||||
|
||||
apiIssue := ToAPIIssue(ctx, pr.Issue)
|
||||
apiIssue := ToAPIIssue(ctx, doer, pr.Issue)
|
||||
if err := pr.LoadBaseRepo(ctx); err != nil {
|
||||
log.Error("GetRepositoryById[%d]: %v", pr.ID, err)
|
||||
return nil
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
)
|
||||
|
||||
// Check represents a Doctor check
|
||||
|
@ -25,6 +26,7 @@ type Check struct {
|
|||
AbortIfFailed bool
|
||||
SkipDatabaseInitialization bool
|
||||
Priority int
|
||||
InitStorage bool
|
||||
}
|
||||
|
||||
func initDBSkipLogger(ctx context.Context) error {
|
||||
|
@ -84,6 +86,7 @@ func RunChecks(ctx context.Context, colorize, autofix bool, checks []*Check) err
|
|||
logger := log.BaseLoggerToGeneralLogger(&doctorCheckLogger{colorize: colorize})
|
||||
loggerStep := log.BaseLoggerToGeneralLogger(&doctorCheckStepLogger{colorize: colorize})
|
||||
dbIsInit := false
|
||||
storageIsInit := false
|
||||
for i, check := range checks {
|
||||
if !dbIsInit && !check.SkipDatabaseInitialization {
|
||||
// Only open database after the most basic configuration check
|
||||
|
@ -94,6 +97,14 @@ func RunChecks(ctx context.Context, colorize, autofix bool, checks []*Check) err
|
|||
}
|
||||
dbIsInit = true
|
||||
}
|
||||
if !storageIsInit && check.InitStorage {
|
||||
if err := storage.Init(); err != nil {
|
||||
logger.Error("Error whilst initializing the storage: %v", err)
|
||||
logger.Error("Check if you are using the right config file. You can use a --config directive to specify one.")
|
||||
return nil
|
||||
}
|
||||
storageIsInit = true
|
||||
}
|
||||
logger.Info("\n[%d] %s", i+1, check.Title)
|
||||
if err := check.Run(ctx, loggerStep, autofix); err != nil {
|
||||
if check.AbortIfFailed {
|
||||
|
|
|
@ -67,7 +67,7 @@ func (m *webhookNotifier) IssueClearLabels(ctx context.Context, doer *user_model
|
|||
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueLabel, &api.IssuePayload{
|
||||
Action: api.HookIssueLabelCleared,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
@ -168,7 +168,7 @@ func (m *webhookNotifier) IssueChangeAssignee(ctx context.Context, doer *user_mo
|
|||
permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer)
|
||||
apiIssue := &api.IssuePayload{
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ func (m *webhookNotifier) IssueChangeTitle(ctx context.Context, doer *user_model
|
|||
From: oldTitle,
|
||||
},
|
||||
},
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
@ -250,7 +250,7 @@ func (m *webhookNotifier) IssueChangeStatus(ctx context.Context, doer *user_mode
|
|||
} else {
|
||||
apiIssue := &api.IssuePayload{
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
CommitID: commitID,
|
||||
|
@ -281,7 +281,7 @@ func (m *webhookNotifier) NewIssue(ctx context.Context, issue *issues_model.Issu
|
|||
if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssues, &api.IssuePayload{
|
||||
Action: api.HookIssueOpened,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, issue.Poster, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, issue.Poster, nil),
|
||||
}); err != nil {
|
||||
|
@ -349,7 +349,7 @@ func (m *webhookNotifier) IssueChangeContent(ctx context.Context, doer *user_mod
|
|||
From: oldContent,
|
||||
},
|
||||
},
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
@ -384,7 +384,7 @@ func (m *webhookNotifier) UpdateComment(ctx context.Context, doer *user_model.Us
|
|||
permission, _ := access_model.GetUserRepoPermission(ctx, c.Issue.Repo, doer)
|
||||
if err := PrepareWebhooks(ctx, EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{
|
||||
Action: api.HookIssueCommentEdited,
|
||||
Issue: convert.ToAPIIssue(ctx, c.Issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, c.Issue),
|
||||
Comment: convert.ToAPIComment(ctx, c.Issue.Repo, c),
|
||||
Changes: &api.ChangesPayload{
|
||||
Body: &api.ChangesFromPayload{
|
||||
|
@ -412,7 +412,7 @@ func (m *webhookNotifier) CreateIssueComment(ctx context.Context, doer *user_mod
|
|||
permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer)
|
||||
if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{
|
||||
Action: api.HookIssueCommentCreated,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Comment: convert.ToAPIComment(ctx, repo, comment),
|
||||
Repository: convert.ToRepo(ctx, repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
|
@ -449,7 +449,7 @@ func (m *webhookNotifier) DeleteComment(ctx context.Context, doer *user_model.Us
|
|||
permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer)
|
||||
if err := PrepareWebhooks(ctx, EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{
|
||||
Action: api.HookIssueCommentDeleted,
|
||||
Issue: convert.ToAPIIssue(ctx, comment.Issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, comment.Issue),
|
||||
Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment),
|
||||
Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
|
@ -533,7 +533,7 @@ func (m *webhookNotifier) IssueChangeLabels(ctx context.Context, doer *user_mode
|
|||
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueLabel, &api.IssuePayload{
|
||||
Action: api.HookIssueLabelUpdated,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
@ -575,7 +575,7 @@ func (m *webhookNotifier) IssueChangeMilestone(ctx context.Context, doer *user_m
|
|||
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueMilestone, &api.IssuePayload{
|
||||
Action: hookAction,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
|
|
@ -370,6 +370,10 @@ func ChangeDefaultWikiBranch(ctx context.Context, repo *repo_model.Repository, n
|
|||
return fmt.Errorf("unable to update database: %w", err)
|
||||
}
|
||||
|
||||
if !repo.HasWiki() {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldDefBranch, err := gitrepo.GetWikiDefaultBranch(ctx, repo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get default branch: %w", err)
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
{{end}}
|
||||
{{end}}
|
||||
<div class="ui top attached header clearing segment tw-relative commit-header {{$class}}">
|
||||
<div class="tw-flex tw-mb-4 tw-flex-wrap">
|
||||
<div class="tw-flex tw-mb-4 tw-gap-1">
|
||||
<h3 class="tw-mb-0 tw-flex-1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message ($.Repository.ComposeMetas ctx)}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses}}</h3>
|
||||
{{if not $.PageIsWiki}}
|
||||
<div>
|
||||
<div class="commit-header-buttons">
|
||||
<a class="ui primary tiny button" href="{{.SourcePath}}">
|
||||
{{ctx.Locale.Tr "repo.diff.browse_source"}}
|
||||
</a>
|
||||
|
|
|
@ -13,17 +13,19 @@
|
|||
{{$commitRepoLink := $.RepoLink}}{{if $.CommitRepoLink}}{{$commitRepoLink = $.CommitRepoLink}}{{end}}
|
||||
{{range .Commits}}
|
||||
<tr>
|
||||
<td class="author tw-flex">
|
||||
{{$userName := .Author.Name}}
|
||||
{{if .User}}
|
||||
{{if and .User.FullName DefaultShowFullName}}
|
||||
{{$userName = .User.FullName}}
|
||||
<td class="author">
|
||||
<div class="tw-flex">
|
||||
{{$userName := .Author.Name}}
|
||||
{{if .User}}
|
||||
{{if and .User.FullName DefaultShowFullName}}
|
||||
{{$userName = .User.FullName}}
|
||||
{{end}}
|
||||
{{ctx.AvatarUtils.Avatar .User 28 "tw-mr-2"}}<a class="muted author-wrapper" href="{{.User.HomeLink}}">{{$userName}}</a>
|
||||
{{else}}
|
||||
{{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 28 "tw-mr-2"}}
|
||||
<span class="author-wrapper">{{$userName}}</span>
|
||||
{{end}}
|
||||
{{ctx.AvatarUtils.Avatar .User 28 "tw-mr-2"}}<a class="muted author-wrapper" href="{{.User.HomeLink}}">{{$userName}}</a>
|
||||
{{else}}
|
||||
{{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 28 "tw-mr-2"}}
|
||||
<span class="author-wrapper">{{$userName}}</span>
|
||||
{{end}}
|
||||
</div>
|
||||
</td>
|
||||
<td class="sha">
|
||||
{{$class := "ui sha label"}}
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
{{$isReviewFile := and $.IsSigned $.PageIsPullFiles (not $.IsArchived) $.IsShowingAllCommits}}
|
||||
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} tw-mt-0" id="diff-{{$file.NameHash}}" data-old-filename="{{$file.OldName}}" data-new-filename="{{$file.Name}}" {{if or ($file.ShouldBeHidden) (not $isExpandable)}}data-folded="true"{{end}}>
|
||||
<h4 class="diff-file-header sticky-2nd-row ui top attached header tw-font-normal tw-flex tw-items-center tw-justify-between tw-flex-wrap">
|
||||
<div class="diff-file-name tw-flex tw-items-center tw-gap-1 tw-flex-wrap">
|
||||
<div class="diff-file-name tw-flex tw-flex-1 tw-items-center tw-gap-1 tw-flex-wrap">
|
||||
<button class="fold-file btn interact-bg tw-p-1{{if not $isExpandable}} tw-invisible{{end}}">
|
||||
{{if $file.ShouldBeHidden}}
|
||||
{{svg "octicon-chevron-right" 18}}
|
||||
|
@ -128,21 +128,23 @@
|
|||
{{template "repo/diff/stats" dict "file" . "root" $}}
|
||||
{{end}}
|
||||
</div>
|
||||
<span class="file tw-font-mono"><a class="muted file-link" title="{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}" href="#diff-{{$file.NameHash}}">{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}</a>{{if .IsLFSFile}} ({{ctx.Locale.Tr "repo.stored_lfs"}}){{end}}</span>
|
||||
<button class="btn interact-fg tw-p-2" data-clipboard-text="{{$file.Name}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{if $file.IsGenerated}}
|
||||
<span class="ui label">{{ctx.Locale.Tr "repo.diff.generated"}}</span>
|
||||
{{end}}
|
||||
{{if $file.IsVendored}}
|
||||
<span class="ui label">{{ctx.Locale.Tr "repo.diff.vendored"}}</span>
|
||||
{{end}}
|
||||
{{if and $file.Mode $file.OldMode}}
|
||||
{{$old := ctx.Locale.Tr ($file.ModeTranslationKey $file.OldMode)}}
|
||||
{{$new := ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}
|
||||
<span class="tw-ml-4 tw-font-mono">{{ctx.Locale.Tr "git.filemode.changed_filemode" $old $new}}</span>
|
||||
{{else if $file.Mode}}
|
||||
<span class="tw-ml-4 tw-font-mono">{{ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}</span>
|
||||
{{end}}
|
||||
<span class="file tw-flex tw-items-center tw-font-mono tw-flex-1"><a class="muted file-link" title="{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}" href="#diff-{{$file.NameHash}}">{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}</a>
|
||||
{{if .IsLFSFile}} ({{ctx.Locale.Tr "repo.stored_lfs"}}){{end}}
|
||||
<button class="btn interact-fg tw-p-2" data-clipboard-text="{{$file.Name}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{if $file.IsGenerated}}
|
||||
<span class="ui label">{{ctx.Locale.Tr "repo.diff.generated"}}</span>
|
||||
{{end}}
|
||||
{{if $file.IsVendored}}
|
||||
<span class="ui label">{{ctx.Locale.Tr "repo.diff.vendored"}}</span>
|
||||
{{end}}
|
||||
{{if and $file.Mode $file.OldMode}}
|
||||
{{$old := ctx.Locale.Tr ($file.ModeTranslationKey $file.OldMode)}}
|
||||
{{$new := ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}
|
||||
<span class="tw-mx-2 tw-font-mono tw-whitespace-nowrap">{{ctx.Locale.Tr "git.filemode.changed_filemode" $old $new}}</span>
|
||||
{{else if $file.Mode}}
|
||||
<span class="tw-mx-2 tw-font-mono tw-whitespace-nowrap">{{ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}</span>
|
||||
{{end}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="diff-file-header-actions tw-flex tw-items-center tw-gap-1 tw-flex-wrap">
|
||||
{{if $showFileViewToggle}}
|
||||
|
|
|
@ -50,8 +50,11 @@
|
|||
</div>
|
||||
{{end}}
|
||||
{{template "repo/sub_menu" .}}
|
||||
{{$n := len .TreeNames}}
|
||||
{{$l := Eval $n "-" 1}}
|
||||
{{$isHomepage := (eq $n 0)}}
|
||||
<div class="repo-button-row">
|
||||
<div class="tw-flex tw-items-center tw-flex-wrap tw-gap-y-2">
|
||||
<div class="tw-flex tw-items-center tw-gap-y-2">
|
||||
{{template "repo/branch_dropdown" dict "root" . "ContainerClasses" "tw-mr-1"}}
|
||||
{{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}}
|
||||
{{$cmpBranch := ""}}
|
||||
|
@ -66,9 +69,7 @@
|
|||
</a>
|
||||
{{end}}
|
||||
<!-- Show go to file and breadcrumbs if not on home page -->
|
||||
{{$n := len .TreeNames}}
|
||||
{{$l := Eval $n "-" 1}}
|
||||
{{if eq $n 0}}
|
||||
{{if $isHomepage}}
|
||||
<a href="{{.Repository.Link}}/find/{{.BranchNameSubURL}}" class="ui compact basic button">{{ctx.Locale.Tr "repo.find_file.go_to_file"}}</a>
|
||||
{{end}}
|
||||
|
||||
|
@ -92,20 +93,20 @@
|
|||
</button>
|
||||
{{end}}
|
||||
|
||||
{{if and (eq $n 0) (.Repository.IsTemplate)}}
|
||||
{{if and $isHomepage (.Repository.IsTemplate)}}
|
||||
<a role="button" class="ui primary compact button" href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}">
|
||||
{{ctx.Locale.Tr "repo.use_template"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if ne $n 0}}
|
||||
{{if (not $isHomepage)}}
|
||||
<span class="breadcrumb repo-path tw-ml-1">
|
||||
<a class="section" href="{{.RepoLink}}/src/{{.BranchNameSubURL}}" title="{{.Repository.Name}}">{{StringUtils.EllipsisString .Repository.Name 30}}</a>
|
||||
{{- range $i, $v := .TreeNames -}}
|
||||
<span class="breadcrumb-divider">/</span>
|
||||
{{- if eq $i $l -}}
|
||||
<span class="active section" title="{{$v}}">{{StringUtils.EllipsisString $v 30}}</span>
|
||||
<span class="active section" title="{{$v}}">{{$v}}</span>
|
||||
{{- else -}}
|
||||
{{$p := index $.Paths $i}}<span class="section"><a href="{{$.BranchLink}}/{{PathEscapeSegments $p}}" title="{{$v}}">{{StringUtils.EllipsisString $v 30}}</a></span>
|
||||
{{$p := index $.Paths $i}}<span class="section"><a href="{{$.BranchLink}}/{{PathEscapeSegments $p}}" title="{{$v}}">{{$v}}</a></span>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
</span>
|
||||
|
@ -113,7 +114,7 @@
|
|||
</div>
|
||||
<div class="tw-flex tw-items-center">
|
||||
<!-- Only show clone panel in repository home page -->
|
||||
{{if eq $n 0}}
|
||||
{{if $isHomepage}}
|
||||
<div class="clone-panel ui action tiny input">
|
||||
{{template "repo/clone_buttons" .}}
|
||||
<button class="ui small jump dropdown icon button" data-tooltip-content="{{ctx.Locale.Tr "repo.more_operations"}}">
|
||||
|
@ -136,7 +137,7 @@
|
|||
</div>
|
||||
{{template "repo/cite/cite_modal" .}}
|
||||
{{end}}
|
||||
{{if and (ne $n 0) (not .IsViewFile) (not .IsBlame)}}
|
||||
{{if and (not $isHomepage) (not .IsViewFile) (not .IsBlame)}}
|
||||
<a class="ui button" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{.TreePath | PathEscapeSegments}}">
|
||||
{{svg "octicon-history" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.file_history"}}
|
||||
</a>
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
{{end}}
|
||||
|
||||
{{if not .ReadmeInList}}
|
||||
<div id="repo-file-commit-box" class="ui top attached header list-header tw-mb-4">
|
||||
<div>
|
||||
<div id="repo-file-commit-box" class="ui top attached header list-header tw-mb-4 tw-flex tw-justify-between">
|
||||
<div class="latest-commit">
|
||||
{{template "repo/latest_commit" .}}
|
||||
</div>
|
||||
{{if .LatestCommit}}
|
||||
{{if .LatestCommit.Committer}}
|
||||
<div class="ui text grey right age">
|
||||
<div class="text grey age">
|
||||
{{TimeSince .LatestCommit.Committer.When ctx.Locale}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<table id="repo-files-table" class="ui single line table tw-mt-0" {{if .HasFilesWithoutLatestCommit}}hx-indicator="tr.notready td.message span" hx-trigger="load" hx-swap="morph" hx-post="{{.LastCommitLoaderURL}}"{{end}}>
|
||||
<thead>
|
||||
<tr class="commit-list">
|
||||
<th colspan="2">
|
||||
{{template "repo/latest_commit" .}}
|
||||
<th class="tw-overflow-hidden" colspan="2">
|
||||
<div class="tw-flex">
|
||||
<div class="latest-commit">
|
||||
{{template "repo/latest_commit" .}}
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Committer}}{{TimeSince .LatestCommit.Committer.When ctx.Locale}}{{end}}{{end}}</th>
|
||||
</tr>
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
xťŹKnÄ Dłć죱ÁvóEQ˛Ę~nĐ@3Fňđ‰r”\,dŽ<64>^”TĄŇSµĎŹGj|žĹK+DÜĘŕ˘
$2`ĺ4ÇÉY«”Y”u{‡Xho\Źŕ‚u4E;k- P4<>Q^Hł84Ŕđlk.ü†iă_©ü|gţVžv¨Ă=ĚŤüž|Î-U—q8Ú;—ZJµč,ý<>Nnô_<C3B4>Ő”ę0Ůaě3ľçýŇż TĐmÄ·ěqă1mÄŘŤb˝ňµµŁ^ÇńžÚzşˇ/ďůŇá_Ö5ŐzR'-'É~étl˝
|
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
|||
0dca5bd9b5d7ef937710e056f575e86c0184ba85
|
||||
a5bbc0fd39a696feabed2d4cccaf05abbcaf3b02
|
||||
|
|
|
@ -45,6 +45,7 @@ func TestRepoCloneWiki(t *testing.T) {
|
|||
assertFileExist(t, filepath.Join(dstPath, "Page-With-Image.md"))
|
||||
assertFileExist(t, filepath.Join(dstPath, "Page-With-Spaced-Name.md"))
|
||||
assertFileExist(t, filepath.Join(dstPath, "images"))
|
||||
assertFileExist(t, filepath.Join(dstPath, "files/Non-Renderable-File.zip"))
|
||||
assertFileExist(t, filepath.Join(dstPath, "jpeg.jpg"))
|
||||
})
|
||||
})
|
||||
|
|
|
@ -49,6 +49,17 @@ func testGitPush(t *testing.T, u *url.URL) {
|
|||
})
|
||||
})
|
||||
|
||||
t.Run("Push branch with options", func(t *testing.T) {
|
||||
runTestGitPush(t, u, func(t *testing.T, gitPath string) (pushed, deleted []string) {
|
||||
branchName := "branch-with-options"
|
||||
doGitCreateBranch(gitPath, branchName)(t)
|
||||
doGitPushTestRepository(gitPath, "origin", branchName, "-o", "repo.private=true", "-o", "repo.template=true")(t)
|
||||
pushed = append(pushed, branchName)
|
||||
|
||||
return pushed, deleted
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Delete branches", func(t *testing.T) {
|
||||
runTestGitPush(t, u, func(t *testing.T, gitPath string) (pushed, deleted []string) {
|
||||
doGitPushTestRepository(gitPath, "origin", "master")(t) // make sure master is the default branch instead of a branch we are going to delete
|
||||
|
|
|
@ -23,8 +23,21 @@
|
|||
--height-loading: 16rem;
|
||||
--min-height-textarea: 132px; /* padding + 6 lines + border = calc(1.57142em + 6lh + 2px), but lh is not fully supported */
|
||||
--tab-size: 4;
|
||||
--checkbox-size: 16px; /* height and width of checkbox and radio inputs */
|
||||
--checkbox-size: 15px; /* height and width of checkbox and radio inputs */
|
||||
--page-spacing: 16px; /* space between page elements */
|
||||
--page-margin-x: 32px; /* minimum space on left and right side of page */
|
||||
}
|
||||
|
||||
@media (min-width: 768px) and (max-width: 1200px) {
|
||||
:root {
|
||||
--page-margin-x: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
:root {
|
||||
--page-margin-x: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
:root * {
|
||||
|
@ -1242,6 +1255,7 @@ overflow-menu .ui.label {
|
|||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
line-height: inherit; /* needed for inline code preview in markup */
|
||||
}
|
||||
|
||||
.blame .code-inner {
|
||||
|
|
|
@ -20,7 +20,7 @@ input[type="radio"] {
|
|||
.ui.checkbox input[type="checkbox"],
|
||||
.ui.checkbox input[type="radio"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
top: 1px;
|
||||
left: 0;
|
||||
width: var(--checkbox-size);
|
||||
height: var(--checkbox-size);
|
||||
|
|
|
@ -49,30 +49,11 @@
|
|||
/* overwrite width of containers inside the main page content div (div with class "page-content") */
|
||||
.page-content .ui.ui.ui.container:not(.fluid) {
|
||||
width: 1280px;
|
||||
max-width: calc(100% - 64px);
|
||||
max-width: calc(100% - calc(2 * var(--page-margin-x)));
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.ui.container.fluid.padded {
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
/* enable fluid page widths for medium size viewports */
|
||||
@media (min-width: 768px) and (max-width: 1200px) {
|
||||
.page-content .ui.ui.ui.container:not(.fluid) {
|
||||
max-width: calc(100% - 32px);
|
||||
}
|
||||
.ui.container.fluid.padded {
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.page-content .ui.ui.ui.container:not(.fluid) {
|
||||
max-width: calc(100% - 16px);
|
||||
}
|
||||
.ui.container.fluid.padded {
|
||||
padding: 0 8px;
|
||||
}
|
||||
padding: 0 var(--page-margin-x);
|
||||
}
|
||||
|
|
|
@ -126,6 +126,12 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ui.list .list > .item [class*="right floated"],
|
||||
.ui.list > .item [class*="right floated"] {
|
||||
float: right;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.ui.menu .ui.list > .item,
|
||||
.ui.menu .ui.list .list > .item {
|
||||
display: list-item;
|
||||
|
|
|
@ -177,12 +177,44 @@
|
|||
}
|
||||
}
|
||||
|
||||
.repository.file.list .repo-path {
|
||||
word-break: break-word;
|
||||
.commit-summary {
|
||||
flex: 1;
|
||||
overflow-wrap: anywhere;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.repository.file.list #repo-files-table {
|
||||
table-layout: fixed;
|
||||
.commit-header .commit-summary,
|
||||
td .commit-summary {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.latest-commit {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.latest-commit .sha {
|
||||
display: none;
|
||||
}
|
||||
.latest-commit .commit-summary {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.repo-path {
|
||||
display: flex;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
/* this is what limits the commit table width to a value that works on all viewport sizes */
|
||||
#repo-files-table th:first-of-type {
|
||||
max-width: calc(calc(min(100vw, 1280px)) - 145px - calc(2 * var(--page-margin-x)));
|
||||
}
|
||||
|
||||
.repository.file.list #repo-files-table thead th {
|
||||
|
@ -262,7 +294,6 @@
|
|||
}
|
||||
|
||||
.repository.file.list #repo-files-table td.age {
|
||||
width: 120px;
|
||||
color: var(--color-text-light-1);
|
||||
}
|
||||
|
||||
|
@ -1219,10 +1250,6 @@
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.repository #commits-table td.message {
|
||||
text-overflow: unset;
|
||||
}
|
||||
|
||||
.repository #commits-table.ui.basic.striped.table tbody tr:nth-child(2n) {
|
||||
background-color: var(--color-light) !important;
|
||||
}
|
||||
|
@ -2114,6 +2141,20 @@
|
|||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.commit-header-buttons {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: flex-start;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.commit-header-buttons {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
.settings.webhooks .list > .item:not(:first-child),
|
||||
.settings.githooks .list > .item:not(:first-child),
|
||||
.settings.actions .list > .item:not(:first-child) {
|
||||
|
@ -2274,9 +2315,9 @@
|
|||
}
|
||||
|
||||
.labels-list {
|
||||
display: flex;
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25em;
|
||||
gap: 2.5px;
|
||||
}
|
||||
|
||||
.labels-list a {
|
||||
|
@ -2346,7 +2387,7 @@ tbody.commit-list {
|
|||
.author-wrapper {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: calc(100% - 50px);
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -2371,10 +2412,6 @@ tbody.commit-list {
|
|||
tr.commit-list {
|
||||
width: 100%;
|
||||
}
|
||||
th .message-wrapper {
|
||||
display: block;
|
||||
max-width: calc(100vw - 70px);
|
||||
}
|
||||
.author-wrapper {
|
||||
max-width: 80px;
|
||||
}
|
||||
|
@ -2384,27 +2421,18 @@ tbody.commit-list {
|
|||
tr.commit-list {
|
||||
width: 723px;
|
||||
}
|
||||
th .message-wrapper {
|
||||
max-width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) and (max-width: 1200px) {
|
||||
tr.commit-list {
|
||||
width: 933px;
|
||||
}
|
||||
th .message-wrapper {
|
||||
max-width: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1201px) {
|
||||
tr.commit-list {
|
||||
width: 1127px;
|
||||
}
|
||||
th .message-wrapper {
|
||||
max-width: 525px;
|
||||
}
|
||||
}
|
||||
|
||||
.commit-list .commit-status-link {
|
||||
|
@ -2732,7 +2760,7 @@ tbody.commit-list {
|
|||
.repository.file.list #repo-files-table .entry td.message,
|
||||
.repository.file.list #repo-files-table .commit-list td.message,
|
||||
.repository.file.list #repo-files-table .entry span.commit-summary,
|
||||
.repository.file.list #repo-files-table .commit-list span.commit-summary {
|
||||
.repository.file.list #repo-files-table .commit-list tr span.commit-summary {
|
||||
display: none !important;
|
||||
}
|
||||
.repository.view.issue .comment-list .timeline,
|
||||
|
|
|
@ -30,45 +30,45 @@
|
|||
--color-primary-alpha-90: #4183c4e1;
|
||||
--color-primary-hover: var(--color-primary-light-1);
|
||||
--color-primary-active: var(--color-primary-light-2);
|
||||
--color-secondary: #3b444a;
|
||||
--color-secondary-dark-1: #424b51;
|
||||
--color-secondary-dark-2: #4a545b;
|
||||
--color-secondary-dark-3: #59646c;
|
||||
--color-secondary-dark-4: #6b7681;
|
||||
--color-secondary-dark-5: #78858f;
|
||||
--color-secondary-dark-6: #87929d;
|
||||
--color-secondary-dark-7: #939ea9;
|
||||
--color-secondary-dark-8: #a1acb4;
|
||||
--color-secondary-dark-9: #aab3bc;
|
||||
--color-secondary-dark-10: #b6bfc8;
|
||||
--color-secondary-dark-11: #c2cbd3;
|
||||
--color-secondary-dark-12: #ccd4dc;
|
||||
--color-secondary-dark-13: #cfd7df;
|
||||
--color-secondary-light-1: #2e353b;
|
||||
--color-secondary-light-2: #2b353e;
|
||||
--color-secondary-light-3: #1c2227;
|
||||
--color-secondary-light-4: #161b1f;
|
||||
--color-secondary-alpha-10: #3b444a19;
|
||||
--color-secondary-alpha-20: #3b444a33;
|
||||
--color-secondary-alpha-30: #3b444a4b;
|
||||
--color-secondary-alpha-40: #3b444a66;
|
||||
--color-secondary-alpha-50: #3b444a80;
|
||||
--color-secondary-alpha-60: #3b444a99;
|
||||
--color-secondary-alpha-70: #3b444ab3;
|
||||
--color-secondary-alpha-80: #3b444acc;
|
||||
--color-secondary-alpha-90: #3b444ae1;
|
||||
--color-secondary: #3b444c;
|
||||
--color-secondary-dark-1: #414b54;
|
||||
--color-secondary-dark-2: #49545f;
|
||||
--color-secondary-dark-3: #576471;
|
||||
--color-secondary-dark-4: #677685;
|
||||
--color-secondary-dark-5: #758594;
|
||||
--color-secondary-dark-6: #8392a0;
|
||||
--color-secondary-dark-7: #929eab;
|
||||
--color-secondary-dark-8: #a2acb7;
|
||||
--color-secondary-dark-9: #a9b3bd;
|
||||
--color-secondary-dark-10: #b7bfc7;
|
||||
--color-secondary-dark-11: #c5cbd2;
|
||||
--color-secondary-dark-12: #cfd4da;
|
||||
--color-secondary-dark-13: #d2d7dc;
|
||||
--color-secondary-light-1: #313940;
|
||||
--color-secondary-light-2: #292f35;
|
||||
--color-secondary-light-3: #1d2226;
|
||||
--color-secondary-light-4: #171b1e;
|
||||
--color-secondary-alpha-10: #3b444c19;
|
||||
--color-secondary-alpha-20: #3b444c33;
|
||||
--color-secondary-alpha-30: #3b444c4b;
|
||||
--color-secondary-alpha-40: #3b444c66;
|
||||
--color-secondary-alpha-50: #3b444c80;
|
||||
--color-secondary-alpha-60: #3b444c99;
|
||||
--color-secondary-alpha-70: #3b444cb3;
|
||||
--color-secondary-alpha-80: #3b444ccc;
|
||||
--color-secondary-alpha-90: #3b444ce1;
|
||||
--color-secondary-button: var(--color-secondary-dark-4);
|
||||
--color-secondary-hover: var(--color-secondary-dark-3);
|
||||
--color-secondary-active: var(--color-secondary-dark-2);
|
||||
/* console colors - used for actions console and console files */
|
||||
--color-console-fg: #f8f8f9;
|
||||
--color-console-fg-subtle: #bec4c8;
|
||||
--color-console-fg: #f7f8f9;
|
||||
--color-console-fg-subtle: #bdc4cc;
|
||||
--color-console-bg: #171b1e;
|
||||
--color-console-border: #2e353b;
|
||||
--color-console-hover-bg: #292d31;
|
||||
--color-console-hover-bg: #272d33;
|
||||
--color-console-active-bg: #2e353b;
|
||||
--color-console-menu-bg: #252b30;
|
||||
--color-console-menu-border: #424b51;
|
||||
--color-console-menu-bg: #262b31;
|
||||
--color-console-menu-border: #414b55;
|
||||
/* named colors */
|
||||
--color-red: #cc4848;
|
||||
--color-orange: #cc580c;
|
||||
|
@ -122,7 +122,7 @@
|
|||
--color-brown-dark-2: #835b42;
|
||||
--color-black-dark-2: #272930;
|
||||
/* ansi colors used for actions console and console files */
|
||||
--color-ansi-black: #1d2328;
|
||||
--color-ansi-black: #1e2327;
|
||||
--color-ansi-red: #cc4848;
|
||||
--color-ansi-green: #87ab63;
|
||||
--color-ansi-yellow: #cc9903;
|
||||
|
@ -139,8 +139,8 @@
|
|||
--color-ansi-bright-cyan: #00b6ad;
|
||||
--color-ansi-bright-white: var(--color-console-fg);
|
||||
/* other colors */
|
||||
--color-grey: #384147;
|
||||
--color-grey-light: #828f99;
|
||||
--color-grey: #384149;
|
||||
--color-grey-light: #818f9e;
|
||||
--color-gold: #b1983b;
|
||||
--color-white: #ffffff;
|
||||
--color-diff-removed-word-bg: #6f3333;
|
||||
|
@ -180,55 +180,55 @@
|
|||
--color-orange-badge-hover-bg: #f2711c4d;
|
||||
--color-git: #f05133;
|
||||
/* target-based colors */
|
||||
--color-body: #1c1f25;
|
||||
--color-body: #1b1f23;
|
||||
--color-box-header: #1a1d1f;
|
||||
--color-box-body: #14171a;
|
||||
--color-box-body-highlight: #1c2227;
|
||||
--color-text-dark: #f8f8f9;
|
||||
--color-text: #d1d5d8;
|
||||
--color-text-light: #bdc3c7;
|
||||
--color-text-light-1: #a8afb5;
|
||||
--color-text-light-2: #929ba2;
|
||||
--color-text-light-3: #7c8790;
|
||||
--color-box-body-highlight: #1e2226;
|
||||
--color-text-dark: #f7f8f9;
|
||||
--color-text: #d0d5da;
|
||||
--color-text-light: #bcc3cb;
|
||||
--color-text-light-1: #a5afb9;
|
||||
--color-text-light-2: #8f9ba8;
|
||||
--color-text-light-3: #788797;
|
||||
--color-footer: var(--color-nav-bg);
|
||||
--color-timeline: #353c42;
|
||||
--color-timeline: #343c44;
|
||||
--color-input-text: var(--color-text-dark);
|
||||
--color-input-background: #151a1e;
|
||||
--color-input-toggle-background: #2e353b;
|
||||
--color-input-background: #171a1e;
|
||||
--color-input-toggle-background: #2e353c;
|
||||
--color-input-border: var(--color-secondary);
|
||||
--color-input-border-hover: var(--color-secondary-dark-1);
|
||||
--color-light: #00001728;
|
||||
--color-light-mimic-enabled: rgba(0, 0, 0, calc(40 / 255 * 222 / 255 / var(--opacity-disabled)));
|
||||
--color-light-border: #e8e8ff28;
|
||||
--color-hover: #e8e8ff19;
|
||||
--color-active: #e8e8ff24;
|
||||
--color-menu: #151a1e;
|
||||
--color-card: #151a1e;
|
||||
--color-markup-table-row: #e8e8ff0f;
|
||||
--color-markup-code-block: #e8e8ff12;
|
||||
--color-markup-code-inline: #e8e8ff28;
|
||||
--color-button: #151a1e;
|
||||
--color-light-border: #e8f3ff28;
|
||||
--color-hover: #e8f3ff19;
|
||||
--color-active: #e8f3ff24;
|
||||
--color-menu: #171a1e;
|
||||
--color-card: #171a1e;
|
||||
--color-markup-table-row: #e8f3ff0f;
|
||||
--color-markup-code-block: #e8f3ff12;
|
||||
--color-markup-code-inline: #e8f3ff28;
|
||||
--color-button: #171a1e;
|
||||
--color-code-bg: #14171a;
|
||||
--color-shadow: #00001758;
|
||||
--color-secondary-bg: #2f3138;
|
||||
--color-expand-button: #2b353e;
|
||||
--color-secondary-bg: #2a3137;
|
||||
--color-expand-button: #2f363d;
|
||||
--color-placeholder-text: var(--color-text-light-3);
|
||||
--color-editor-line-highlight: var(--color-primary-light-5);
|
||||
--color-project-board-bg: var(--color-secondary-light-2);
|
||||
--color-caret: var(--color-text); /* should ideally be --color-text-dark, see #15651 */
|
||||
--color-reaction-bg: #e8e8ff12;
|
||||
--color-reaction-bg: #e8f3ff12;
|
||||
--color-reaction-hover-bg: var(--color-primary-light-4);
|
||||
--color-reaction-active-bg: var(--color-primary-light-5);
|
||||
--color-tooltip-text: #fafafb;
|
||||
--color-tooltip-bg: #000017f0;
|
||||
--color-nav-bg: #16191c;
|
||||
--color-tooltip-text: #f9fafb;
|
||||
--color-tooltip-bg: #000b17f0;
|
||||
--color-nav-bg: #16191d;
|
||||
--color-nav-hover-bg: var(--color-secondary-light-1);
|
||||
--color-nav-text: var(--color-text);
|
||||
--color-secondary-nav-bg: #181c20;
|
||||
--color-label-text: var(--color-text);
|
||||
--color-label-bg: #73828e4b;
|
||||
--color-label-hover-bg: #73828ea0;
|
||||
--color-label-active-bg: #73828eff;
|
||||
--color-label-bg: #7282924b;
|
||||
--color-label-hover-bg: #728292a0;
|
||||
--color-label-active-bg: #728292ff;
|
||||
--color-accent: var(--color-primary-light-1);
|
||||
--color-small-accent: var(--color-primary-light-5);
|
||||
--color-highlight-fg: #87651e;
|
||||
|
|
|
@ -61,14 +61,14 @@
|
|||
--color-secondary-hover: var(--color-secondary-dark-5);
|
||||
--color-secondary-active: var(--color-secondary-dark-6);
|
||||
/* console colors - used for actions console and console files */
|
||||
--color-console-fg: #f8f8f9;
|
||||
--color-console-fg-subtle: #bec4c8;
|
||||
--color-console-fg: #f7f8f9;
|
||||
--color-console-fg-subtle: #bdc4cc;
|
||||
--color-console-bg: #171b1e;
|
||||
--color-console-border: #2e353b;
|
||||
--color-console-hover-bg: #292d31;
|
||||
--color-console-hover-bg: #272d33;
|
||||
--color-console-active-bg: #2e353b;
|
||||
--color-console-menu-bg: #252b30;
|
||||
--color-console-menu-border: #424b51;
|
||||
--color-console-menu-bg: #262b31;
|
||||
--color-console-menu-border: #414b55;
|
||||
/* named colors */
|
||||
--color-red: #db2828;
|
||||
--color-orange: #f2711c;
|
||||
|
@ -81,7 +81,7 @@
|
|||
--color-purple: #a333c8;
|
||||
--color-pink: #e03997;
|
||||
--color-brown: #a5673f;
|
||||
--color-black: #191c1d;
|
||||
--color-black: #1d2328;
|
||||
/* light variants - produced via Sass scale-color(color, $lightness: +25%) */
|
||||
--color-red-light: #e45e5e;
|
||||
--color-orange-light: #f59555;
|
||||
|
@ -94,7 +94,7 @@
|
|||
--color-purple-light: #bb64d8;
|
||||
--color-pink-light: #e86bb1;
|
||||
--color-brown-light: #c58b66;
|
||||
--color-black-light: #525558;
|
||||
--color-black-light: #4b5b68;
|
||||
/* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */
|
||||
--color-red-dark-1: #c82121;
|
||||
--color-orange-dark-1: #e6630d;
|
||||
|
@ -107,7 +107,7 @@
|
|||
--color-purple-dark-1: #932eb4;
|
||||
--color-pink-dark-1: #db228a;
|
||||
--color-brown-dark-1: #955d39;
|
||||
--color-black-dark-1: #16191c;
|
||||
--color-black-dark-1: #2c3339;
|
||||
/* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */
|
||||
--color-red-dark-2: #b11e1e;
|
||||
--color-orange-dark-2: #cc580c;
|
||||
|
@ -122,7 +122,7 @@
|
|||
--color-brown-dark-2: #845232;
|
||||
--color-black-dark-2: #131619;
|
||||
/* ansi colors used for actions console and console files */
|
||||
--color-ansi-black: #1f2326;
|
||||
--color-ansi-black: #1e2327;
|
||||
--color-ansi-red: #cc4848;
|
||||
--color-ansi-green: #87ab63;
|
||||
--color-ansi-yellow: #cc9903;
|
||||
|
|
Loading…
Reference in New Issue