mirror of
https://github.com/go-gitea/gitea
synced 2026-02-07 09:41:15 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb77e6c12d | ||
|
|
fabc0ad157 | ||
|
|
a13fb154ae | ||
|
|
36c66303df | ||
|
|
f65e29c077 | ||
|
|
a97c8a8966 | ||
|
|
69b7776af5 | ||
|
|
18c1edf15c | ||
|
|
70ffec4509 | ||
|
|
bc196a35e1 | ||
|
|
8d31cfbfff | ||
|
|
e84a432f76 | ||
|
|
1fc9f11253 | ||
|
|
0dfe5fa2d6 | ||
|
|
1d17313949 | ||
|
|
9c318a17f5 | ||
|
|
72fa108cbc | ||
|
|
db134c5d71 | ||
|
|
73b68015de | ||
|
|
e4919e414f | ||
|
|
f7606de13a | ||
|
|
483bda4b2d | ||
|
|
edd57028a1 | ||
|
|
083b85c655 | ||
|
|
d5027b6c09 |
+131
-3
@@ -567,7 +567,7 @@ steps:
|
||||
settings:
|
||||
acl: public-read
|
||||
bucket: gitea-artifacts
|
||||
endpoint: https://storage.gitea.io
|
||||
endpoint: https://ams3.digitaloceanspaces.com
|
||||
path_style: true
|
||||
source: "dist/release/*"
|
||||
strip_prefix: dist/release/
|
||||
@@ -588,7 +588,7 @@ steps:
|
||||
settings:
|
||||
acl: public-read
|
||||
bucket: gitea-artifacts
|
||||
endpoint: https://storage.gitea.io
|
||||
endpoint: https://ams3.digitaloceanspaces.com
|
||||
path_style: true
|
||||
source: "dist/release/*"
|
||||
strip_prefix: dist/release/
|
||||
@@ -663,7 +663,7 @@ steps:
|
||||
settings:
|
||||
acl: public-read
|
||||
bucket: gitea-artifacts
|
||||
endpoint: https://storage.gitea.io
|
||||
endpoint: https://ams3.digitaloceanspaces.com
|
||||
path_style: true
|
||||
source: "dist/release/*"
|
||||
strip_prefix: dist/release/
|
||||
@@ -850,6 +850,67 @@ steps:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: docker-linux-amd64-release-branch
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
depends_on:
|
||||
- testing-amd64
|
||||
- testing-arm64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- "refs/heads/release/v*"
|
||||
event:
|
||||
exclude:
|
||||
- cron
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
pull: always
|
||||
image: techknowlogick/drone-docker:latest
|
||||
settings:
|
||||
auto_tag: false
|
||||
tags: ${DRONE_BRANCH##release/v}-dev-linux-amd64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.cn
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
tags: ${DRONE_BRANCH##release/v}-dev-linux-amd64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.cn
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
@@ -1006,6 +1067,68 @@ steps:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: docker-linux-arm64-release-branch
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm64
|
||||
|
||||
depends_on:
|
||||
- testing-amd64
|
||||
- testing-arm64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- "refs/heads/release/v*"
|
||||
event:
|
||||
exclude:
|
||||
- cron
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
pull: always
|
||||
image: techknowlogick/drone-docker:latest
|
||||
settings:
|
||||
auto_tag: false
|
||||
tags: ${DRONE_BRANCH##release/v}-dev-linux-arm64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.cn
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: techknowlogick/drone-docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
tags: ${DRONE_BRANCH##release/v}-dev-linux-arm64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.cn
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
@@ -1086,6 +1209,7 @@ steps:
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
- "refs/heads/release/v*"
|
||||
event:
|
||||
exclude:
|
||||
- cron
|
||||
@@ -1093,6 +1217,8 @@ trigger:
|
||||
depends_on:
|
||||
- docker-linux-amd64-release
|
||||
- docker-linux-arm64-release
|
||||
- docker-linux-amd64-release-branch
|
||||
- docker-linux-arm64-release-branch
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
@@ -1126,6 +1252,8 @@ depends_on:
|
||||
- docker-linux-arm64-release
|
||||
- docker-linux-amd64-release-version
|
||||
- docker-linux-arm64-release-version
|
||||
- docker-linux-amd64-release-branch
|
||||
- docker-linux-arm64-release-branch
|
||||
- docker-manifest
|
||||
- docker-manifest-version
|
||||
- docs
|
||||
|
||||
+30
-1
@@ -4,11 +4,41 @@ This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.16.1](https://github.com/go-gitea/gitea/releases/tag/v1.16.1) - 2022-02-06
|
||||
|
||||
* SECURITY
|
||||
* Update JS dependencies, fix lint (#18389) (#18540)
|
||||
* ENHANCEMENTS
|
||||
* Add dropdown icon to label set template dropdown (#18564) (#18571)
|
||||
* BUGFIXES
|
||||
* Comments on migrated issues/prs must link to the comment ID (#18630) (#18637)
|
||||
* Stop logging an error when notes are not found (#18626) (#18635)
|
||||
* Ensure that blob-excerpt links work for wiki (#18587) (#18624)
|
||||
* Only attempt to flush queue if the underlying worker pool is not finished (#18593) (#18620)
|
||||
* Ensure commit-statuses box is sized correctly in headers (#18538) (#18606)
|
||||
* Prevent merge messages from being sorted to the top of email chains (#18566) (#18588)
|
||||
* Prevent panic on prohibited user login with oauth2 (#18562) (#18563)
|
||||
* Collaborator trust model should trust collaborators (#18539) (#18557)
|
||||
* Detect conflicts with 3way merge (#18536) (#18537)
|
||||
* In docker rootless use $GITEA_APP_INI if provided (#18524) (#18535)
|
||||
* Add `GetUserTeams` (#18499) (#18531)
|
||||
* Fix review excerpt (#18502) (#18530)
|
||||
* Fix for AvatarURL database type (#18487) (#18529)
|
||||
* Use `ImagedProvider` for gplus oauth2 provider (#18504) (#18505)
|
||||
* Fix OAuth Source Edit Page (#18495) (#18503)
|
||||
* Use "read" value for General Access (#18496) (#18500)
|
||||
* Prevent NPE on partial match of compare URL and allow short SHA1 compare URLs (#18472) (#18473)
|
||||
* BUILD
|
||||
* Make docker gitea/gitea:v1.16-dev etc refer to the latest build on that branch (#18551) (#18569)
|
||||
* DOCS
|
||||
* Update 1.16.0 changelog to set #17846 as breaking (#18533) (#18534)
|
||||
|
||||
## [1.16.0](https://github.com/go-gitea/gitea/releases/tag/v1.16.0) - 2022-01-30
|
||||
|
||||
* BREAKING
|
||||
* Remove golang vendored directory (#18277)
|
||||
* Paginate releases page & set default page size to 10 (#16857)
|
||||
* Use shadowing script for docker (#17846)
|
||||
* Only allow webhook to send requests to allowed hosts (#17482)
|
||||
* SECURITY
|
||||
* Disable content sniffing on `PlainTextBytes` (#18359) (#18365)
|
||||
@@ -307,7 +337,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* BUILD
|
||||
* Add lockfile-check (#18285)
|
||||
* Don't store assets modified time into generated files (#18193)
|
||||
* Use shadowing script for docker (#17846)
|
||||
* MISC
|
||||
* Update JS dependencies (#17611)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-rootless
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-rootless
|
||||
{{#if build.tags}}
|
||||
tags:
|
||||
{{#each build.tags}}
|
||||
@@ -8,12 +8,12 @@ tags:
|
||||
{{/if}}
|
||||
manifests:
|
||||
-
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-amd64-rootless
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-amd64-rootless
|
||||
platform:
|
||||
architecture: amd64
|
||||
os: linux
|
||||
-
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-arm64-rootless
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-arm64-rootless
|
||||
platform:
|
||||
architecture: arm64
|
||||
os: linux
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}
|
||||
{{#if build.tags}}
|
||||
tags:
|
||||
{{#each build.tags}}
|
||||
@@ -8,13 +8,13 @@ tags:
|
||||
{{/if}}
|
||||
manifests:
|
||||
-
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-amd64
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-amd64
|
||||
platform:
|
||||
architecture: amd64
|
||||
os: linux
|
||||
-
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-arm64
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-arm64
|
||||
platform:
|
||||
architecture: arm64
|
||||
os: linux
|
||||
variant: v8
|
||||
variant: v8
|
||||
|
||||
@@ -32,7 +32,7 @@ for i in "$@"; do
|
||||
done
|
||||
|
||||
if [ -z "$APP_INI_SET" ]; then
|
||||
CONF_ARG="-c \"$APP_INI\""
|
||||
CONF_ARG="-c \"${GITEA_APP_INI:-$APP_INI}\""
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ image as a service. Since there is no database available, one can be initialized
|
||||
Create a directory for `data` and `config` then paste the following content into a file named `docker-compose.yml`.
|
||||
Note that the volume should be owned by the user/group with the UID/GID specified in the config file. By default Gitea in docker will use uid:1000 gid:1000. If needed you can set ownership on those folders with the command: `sudo chown 1000:1000 config/ data/`
|
||||
If you don't give the volume correct permissions, the container may not start.
|
||||
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:{{< version >}}-rootless`, but if you'd like to use the latest development version then `:dev-rootless` would be an appropriate tag.
|
||||
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:{{< version >}}-rootless`, but if you'd like to use the latest development version then `:dev-rootless` would be an appropriate tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-dev-rootless` tag, where x is the minor version of Gitea. (e.g. `:1.16-dev-rootless`)
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
|
||||
@@ -34,7 +34,7 @@ image as a service. Since there is no database available, one can be initialized
|
||||
Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`.
|
||||
Note that the volume should be owned by the user/group with the UID/GID specified in the config file.
|
||||
If you don't give the volume correct permissions, the container may not start.
|
||||
For a stable release you can use `:latest`, `:1` or specify a certain release like `:{{< version >}}`, but if you'd like to use the latest development version of Gitea then you could use the `:dev` tag.
|
||||
For a stable release you can use `:latest`, `:1` or specify a certain release like `:{{< version >}}`, but if you'd like to use the latest development version of Gitea then you could use the `:dev` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-dev` tag, where x is the minor version of Gitea. (e.g. `:1.16-dev`)
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"testing"
|
||||
@@ -262,23 +263,26 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64)
|
||||
return func(t *testing.T) {
|
||||
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s",
|
||||
owner, repo, index, ctx.Token)
|
||||
req := NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{
|
||||
MergeMessageField: "doAPIMergePullRequest Merge",
|
||||
Do: string(repo_model.MergeStyleMerge),
|
||||
})
|
||||
|
||||
resp := ctx.Session.MakeRequest(t, req, NoExpectedStatus)
|
||||
var req *http.Request
|
||||
var resp *httptest.ResponseRecorder
|
||||
|
||||
if resp.Code == http.StatusMethodNotAllowed {
|
||||
err := api.APIError{}
|
||||
DecodeJSON(t, resp, &err)
|
||||
assert.EqualValues(t, "Please try again later", err.Message)
|
||||
queue.GetManager().FlushAll(context.Background(), 5*time.Second)
|
||||
for i := 0; i < 6; i++ {
|
||||
req = NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{
|
||||
MergeMessageField: "doAPIMergePullRequest Merge",
|
||||
Do: string(repo_model.MergeStyleMerge),
|
||||
})
|
||||
|
||||
resp = ctx.Session.MakeRequest(t, req, NoExpectedStatus)
|
||||
|
||||
if resp.Code != http.StatusMethodNotAllowed {
|
||||
break
|
||||
}
|
||||
err := api.APIError{}
|
||||
DecodeJSON(t, resp, &err)
|
||||
assert.EqualValues(t, "Please try again later", err.Message)
|
||||
queue.GetManager().FlushAll(context.Background(), 5*time.Second)
|
||||
<-time.After(1 * time.Second)
|
||||
}
|
||||
|
||||
expected := ctx.ExpectedCode
|
||||
|
||||
@@ -71,7 +71,7 @@ const (
|
||||
)
|
||||
|
||||
// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
|
||||
func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType, isCodeReader func(*user_model.User) (bool, error)) []*SignCommit {
|
||||
func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType, isOwnerMemberCollaborator func(*user_model.User) (bool, error)) []*SignCommit {
|
||||
newCommits := make([]*SignCommit, 0, len(oldCommits))
|
||||
keyMap := map[string]bool{}
|
||||
|
||||
@@ -81,7 +81,7 @@ func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repoTrustMod
|
||||
Verification: ParseCommitWithSignature(c.Commit),
|
||||
}
|
||||
|
||||
_ = CalculateTrustStatus(signCommit.Verification, repoTrustModel, isCodeReader, &keyMap)
|
||||
_ = CalculateTrustStatus(signCommit.Verification, repoTrustModel, isOwnerMemberCollaborator, &keyMap)
|
||||
|
||||
newCommits = append(newCommits, signCommit)
|
||||
}
|
||||
@@ -455,7 +455,7 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *use
|
||||
|
||||
// CalculateTrustStatus will calculate the TrustStatus for a commit verification within a repository
|
||||
// There are several trust models in Gitea
|
||||
func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_model.TrustModelType, isCodeReader func(*user_model.User) (bool, error), keyMap *map[string]bool) (err error) {
|
||||
func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_model.TrustModelType, isOwnerMemberCollaborator func(*user_model.User) (bool, error), keyMap *map[string]bool) (err error) {
|
||||
if !verification.Verified {
|
||||
return
|
||||
}
|
||||
@@ -500,11 +500,11 @@ func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_
|
||||
var has bool
|
||||
isMember, has = (*keyMap)[verification.SigningKey.KeyID]
|
||||
if !has {
|
||||
isMember, err = isCodeReader(verification.SigningUser)
|
||||
isMember, err = isOwnerMemberCollaborator(verification.SigningUser)
|
||||
(*keyMap)[verification.SigningKey.KeyID] = isMember
|
||||
}
|
||||
} else {
|
||||
isMember, err = isCodeReader(verification.SigningUser)
|
||||
isMember, err = isOwnerMemberCollaborator(verification.SigningUser)
|
||||
}
|
||||
|
||||
if !isMember {
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ func ConvertFromGitCommit(commits []*git.Commit, repo *repo_model.Repository) []
|
||||
user_model.ValidateCommitsWithEmails(commits),
|
||||
repo.GetTrustModel(),
|
||||
func(user *user_model.User) (bool, error) {
|
||||
return IsUserRepoAdmin(repo, user)
|
||||
return IsOwnerMemberCollaborator(repo, user.ID)
|
||||
},
|
||||
),
|
||||
repo,
|
||||
|
||||
+53
-8
@@ -49,22 +49,67 @@ func init() {
|
||||
db.RegisterModel(new(TeamUnit))
|
||||
}
|
||||
|
||||
// SearchTeamOptions holds the search options
|
||||
type SearchTeamOptions struct {
|
||||
// SearchOrgTeamOptions holds the search options
|
||||
type SearchOrgTeamOptions struct {
|
||||
db.ListOptions
|
||||
UserID int64
|
||||
Keyword string
|
||||
OrgID int64
|
||||
IncludeDesc bool
|
||||
}
|
||||
|
||||
// GetUserTeamOptions holds the search options.
|
||||
type GetUserTeamOptions struct {
|
||||
db.ListOptions
|
||||
UserID int64
|
||||
}
|
||||
|
||||
// SearchMembersOptions holds the search options
|
||||
type SearchMembersOptions struct {
|
||||
db.ListOptions
|
||||
}
|
||||
|
||||
// SearchTeam search for teams. Caller is responsible to check permissions.
|
||||
func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) {
|
||||
// GetUserTeams search for org teams. Caller is responsible to check permissions.
|
||||
func GetUserTeams(opts *GetUserTeamOptions) ([]*Team, int64, error) {
|
||||
if opts.Page <= 0 {
|
||||
opts.Page = 1
|
||||
}
|
||||
if opts.PageSize == 0 {
|
||||
// Default limit
|
||||
opts.PageSize = 10
|
||||
}
|
||||
|
||||
sess := db.GetEngine(db.DefaultContext)
|
||||
|
||||
sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id").
|
||||
And("team_user.uid=?", opts.UserID)
|
||||
|
||||
count, err := sess.
|
||||
Count(new(Team))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if opts.PageSize == -1 {
|
||||
opts.PageSize = int(count)
|
||||
} else {
|
||||
sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
|
||||
}
|
||||
|
||||
sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id").
|
||||
And("team_user.uid=?", opts.UserID)
|
||||
|
||||
teams := make([]*Team, 0, opts.PageSize)
|
||||
if err = sess.
|
||||
OrderBy("lower_name").
|
||||
Find(&teams); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return teams, count, nil
|
||||
}
|
||||
|
||||
// SearchOrgTeams search for org teams. Caller is responsible to check permissions.
|
||||
func SearchOrgTeams(opts *SearchOrgTeamOptions) ([]*Team, int64, error) {
|
||||
if opts.Page <= 0 {
|
||||
opts.Page = 1
|
||||
}
|
||||
@@ -196,7 +241,7 @@ func (t *Team) getRepositories(e db.Engine) error {
|
||||
}
|
||||
|
||||
// GetRepositories returns paginated repositories in team of organization.
|
||||
func (t *Team) GetRepositories(opts *SearchTeamOptions) error {
|
||||
func (t *Team) GetRepositories(opts *SearchOrgTeamOptions) error {
|
||||
if opts.Page == 0 {
|
||||
return t.getRepositories(db.GetEngine(db.DefaultContext))
|
||||
}
|
||||
@@ -716,7 +761,7 @@ func UpdateTeam(t *Team, authChanged, includeAllChanged bool) (err error) {
|
||||
// DeleteTeam deletes given team.
|
||||
// It's caller's responsibility to assign organization ID.
|
||||
func DeleteTeam(t *Team) error {
|
||||
if err := t.GetRepositories(&SearchTeamOptions{}); err != nil {
|
||||
if err := t.GetRepositories(&SearchOrgTeamOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -858,7 +903,7 @@ func AddTeamMember(team *Team, userID int64) error {
|
||||
}
|
||||
|
||||
// Get team and its repositories.
|
||||
if err := team.GetRepositories(&SearchTeamOptions{}); err != nil {
|
||||
if err := team.GetRepositories(&SearchOrgTeamOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ func TestTeam_GetRepositories(t *testing.T) {
|
||||
|
||||
test := func(teamID int64) {
|
||||
team := unittest.AssertExistsAndLoadBean(t, &Team{ID: teamID}).(*Team)
|
||||
assert.NoError(t, team.GetRepositories(&SearchTeamOptions{}))
|
||||
assert.NoError(t, team.GetRepositories(&SearchOrgTeamOptions{}))
|
||||
assert.Len(t, team.Repos, team.NumRepos)
|
||||
for _, repo := range team.Repos {
|
||||
unittest.AssertExistsAndLoadBean(t, &TeamRepo{TeamID: teamID, RepoID: repo.ID})
|
||||
@@ -292,7 +292,7 @@ func TestGetTeamMembers(t *testing.T) {
|
||||
func TestGetUserTeams(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
test := func(userID int64) {
|
||||
teams, _, err := SearchTeam(&SearchTeamOptions{UserID: userID})
|
||||
teams, _, err := GetUserTeams(&GetUserTeamOptions{UserID: userID})
|
||||
assert.NoError(t, err)
|
||||
for _, team := range teams {
|
||||
unittest.AssertExistsAndLoadBean(t, &TeamUser{TeamID: team.ID, UID: userID})
|
||||
|
||||
@@ -60,7 +60,7 @@ type ExternalLoginUser struct {
|
||||
LastName string
|
||||
NickName string
|
||||
Description string
|
||||
AvatarURL string
|
||||
AvatarURL string `xorm:"TEXT"`
|
||||
Location string
|
||||
AccessToken string `xorm:"TEXT"`
|
||||
AccessTokenSecret string `xorm:"TEXT"`
|
||||
|
||||
@@ -22,6 +22,9 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
|
||||
log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
|
||||
notes, err := repo.GetCommit(NotesRef)
|
||||
if err != nil {
|
||||
if IsErrNotExist(err) {
|
||||
return err
|
||||
}
|
||||
log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
|
||||
log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
|
||||
notes, err := repo.GetCommit(NotesRef)
|
||||
if err != nil {
|
||||
if IsErrNotExist(err) {
|
||||
return err
|
||||
}
|
||||
log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ func (graph *Graph) LoadAndProcessCommits(repository *repo_model.Repository, git
|
||||
c.Verification = asymkey_model.ParseCommitWithSignature(c.Commit)
|
||||
|
||||
_ = asymkey_model.CalculateTrustStatus(c.Verification, repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
|
||||
return models.IsUserRepoAdmin(repository, user)
|
||||
return models.IsOwnerMemberCollaborator(repository, user.ID)
|
||||
}, &keyMap)
|
||||
|
||||
statuses, _, err := models.GetLatestCommitStatus(repository.ID, c.Commit.ID.String(), db.ListOptions{})
|
||||
|
||||
@@ -55,7 +55,7 @@ var (
|
||||
anySHA1Pattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40})(/[-+~_%.a-zA-Z0-9/]+)?(#[-+~_%.a-zA-Z0-9]+)?`)
|
||||
|
||||
// comparePattern matches "http://domain/org/repo/compare/COMMIT1...COMMIT2#hash"
|
||||
comparePattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40})(\.\.\.?)([0-9a-f]{40})?(#[-+~_%.a-zA-Z0-9]+)?`)
|
||||
comparePattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{7,40})(\.\.\.?)([0-9a-f]{7,40})?(#[-+~_%.a-zA-Z0-9]+)?`)
|
||||
|
||||
validLinksPattern = regexp.MustCompile(`^[a-z][\w-]+://`)
|
||||
|
||||
@@ -944,6 +944,13 @@ func comparePatternProcessor(ctx *RenderContext, node *html.Node) {
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure that every group (m[0]...m[7]) has a match
|
||||
for i := 0; i < 8; i++ {
|
||||
if m[i] == -1 {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
urlFull := node.Data[m[0]:m[1]]
|
||||
text1 := base.ShortSha(node.Data[m[2]:m[3]])
|
||||
textDots := base.ShortSha(node.Data[m[4]:m[5]])
|
||||
|
||||
@@ -546,3 +546,16 @@ func TestFuzz(t *testing.T) {
|
||||
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestIssue18471(t *testing.T) {
|
||||
data := `http://domain/org/repo/compare/783b039...da951ce`
|
||||
|
||||
var res strings.Builder
|
||||
err := PostProcess(&RenderContext{
|
||||
URLPrefix: "https://example.com",
|
||||
Metas: localMetas,
|
||||
}, strings.NewReader(data), &res)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, res.String(), "<a href=\"http://domain/org/repo/compare/783b039...da951ce\" class=\"compare\"><code class=\"nohighlight\">783b039...da951ce</code></a>")
|
||||
}
|
||||
|
||||
@@ -72,6 +72,8 @@ type ManagedPool interface {
|
||||
BoostWorkers() int
|
||||
// SetPoolSettings sets the user updatable settings for the pool
|
||||
SetPoolSettings(maxNumberOfWorkers, boostWorkers int, timeout time.Duration)
|
||||
// Done returns a channel that will be closed when the Pool's baseCtx is closed
|
||||
Done() <-chan struct{}
|
||||
}
|
||||
|
||||
// ManagedQueueList implements the sort.Interface
|
||||
@@ -141,7 +143,6 @@ func (m *Manager) Remove(qid int64) {
|
||||
delete(m.Queues, qid)
|
||||
m.mutex.Unlock()
|
||||
log.Trace("Queue Manager removed: QID: %d", qid)
|
||||
|
||||
}
|
||||
|
||||
// GetManagedQueue by qid
|
||||
@@ -193,6 +194,17 @@ func (m *Manager) FlushAll(baseCtx context.Context, timeout time.Duration) error
|
||||
wg.Done()
|
||||
continue
|
||||
}
|
||||
|
||||
if pool, ok := mq.Managed.(ManagedPool); ok {
|
||||
// No point into flushing pools when their base's ctx is already done.
|
||||
select {
|
||||
case <-pool.Done():
|
||||
wg.Done()
|
||||
continue
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
allEmpty = false
|
||||
if flushable, ok := mq.Managed.(Flushable); ok {
|
||||
log.Debug("Flushing (flushable) queue: %s", mq.Name)
|
||||
@@ -225,7 +237,6 @@ func (m *Manager) FlushAll(baseCtx context.Context, timeout time.Duration) error
|
||||
wg.Wait()
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// ManagedQueues returns the managed queues
|
||||
|
||||
@@ -173,7 +173,6 @@ func (q *PersistableChannelQueue) Run(atShutdown, atTerminate func(func())) {
|
||||
q.internal.(*LevelQueue).Shutdown()
|
||||
GetManager().Remove(q.internal.(*LevelQueue).qid)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Flush flushes the queue and blocks till the queue is empty
|
||||
@@ -252,14 +251,13 @@ func (q *PersistableChannelQueue) Shutdown() {
|
||||
q.channelQueue.Wait()
|
||||
q.internal.(*LevelQueue).Wait()
|
||||
// Redirect all remaining data in the chan to the internal channel
|
||||
go func() {
|
||||
log.Trace("PersistableChannelQueue: %s Redirecting remaining data", q.delayedStarter.name)
|
||||
for data := range q.channelQueue.dataChan {
|
||||
_ = q.internal.Push(data)
|
||||
atomic.AddInt64(&q.channelQueue.numInQueue, -1)
|
||||
}
|
||||
log.Trace("PersistableChannelQueue: %s Done Redirecting remaining data", q.delayedStarter.name)
|
||||
}()
|
||||
close(q.channelQueue.dataChan)
|
||||
log.Trace("PersistableChannelQueue: %s Redirecting remaining data", q.delayedStarter.name)
|
||||
for data := range q.channelQueue.dataChan {
|
||||
_ = q.internal.Push(data)
|
||||
atomic.AddInt64(&q.channelQueue.numInQueue, -1)
|
||||
}
|
||||
log.Trace("PersistableChannelQueue: %s Done Redirecting remaining data", q.delayedStarter.name)
|
||||
|
||||
log.Debug("PersistableChannelQueue: %s Shutdown", q.delayedStarter.name)
|
||||
}
|
||||
|
||||
@@ -65,6 +65,11 @@ func NewWorkerPool(handle HandlerFunc, config WorkerPoolConfiguration) *WorkerPo
|
||||
return pool
|
||||
}
|
||||
|
||||
// Done returns when this worker pool's base context has been cancelled
|
||||
func (p *WorkerPool) Done() <-chan struct{} {
|
||||
return p.baseCtx.Done()
|
||||
}
|
||||
|
||||
// Push pushes the data to the internal channel
|
||||
func (p *WorkerPool) Push(data Data) {
|
||||
atomic.AddInt64(&p.numInQueue, 1)
|
||||
@@ -90,7 +95,7 @@ func (p *WorkerPool) zeroBoost() {
|
||||
boost = p.maxNumberOfWorkers - p.numberOfWorkers
|
||||
}
|
||||
if mq != nil {
|
||||
log.Warn("WorkerPool: %d (for %s) has zero workers - adding %d temporary workers for %s", p.qid, mq.Name, boost, p.boostTimeout)
|
||||
log.Debug("WorkerPool: %d (for %s) has zero workers - adding %d temporary workers for %s", p.qid, mq.Name, boost, p.boostTimeout)
|
||||
|
||||
start := time.Now()
|
||||
pid := mq.RegisterWorkers(boost, start, true, start.Add(p.boostTimeout), cancel, false)
|
||||
@@ -98,7 +103,7 @@ func (p *WorkerPool) zeroBoost() {
|
||||
mq.RemoveWorkers(pid)
|
||||
}
|
||||
} else {
|
||||
log.Warn("WorkerPool: %d has zero workers - adding %d temporary workers for %s", p.qid, p.boostWorkers, p.boostTimeout)
|
||||
log.Debug("WorkerPool: %d has zero workers - adding %d temporary workers for %s", p.qid, p.boostWorkers, p.boostTimeout)
|
||||
}
|
||||
p.lock.Unlock()
|
||||
p.addWorkers(ctx, cancel, boost)
|
||||
@@ -326,7 +331,10 @@ func (p *WorkerPool) FlushWithContext(ctx context.Context) error {
|
||||
log.Trace("WorkerPool: %d Flush", p.qid)
|
||||
for {
|
||||
select {
|
||||
case data := <-p.dataChan:
|
||||
case data, ok := <-p.dataChan:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
p.handle(data)
|
||||
atomic.AddInt64(&p.numInQueue, -1)
|
||||
case <-p.baseCtx.Done():
|
||||
@@ -341,7 +349,7 @@ func (p *WorkerPool) FlushWithContext(ctx context.Context) error {
|
||||
|
||||
func (p *WorkerPool) doWork(ctx context.Context) {
|
||||
delay := time.Millisecond * 300
|
||||
var data = make([]Data, 0, p.batchLength)
|
||||
data := make([]Data, 0, p.batchLength)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
|
||||
@@ -23,7 +23,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
|
||||
|
||||
testTeamRepositories := func(teamID int64, repoIds []int64) {
|
||||
team := unittest.AssertExistsAndLoadBean(t, &models.Team{ID: teamID}).(*models.Team)
|
||||
assert.NoError(t, team.GetRepositories(&models.SearchTeamOptions{}), "%s: GetRepositories", team.Name)
|
||||
assert.NoError(t, team.GetRepositories(&models.SearchOrgTeamOptions{}), "%s: GetRepositories", team.Name)
|
||||
assert.Len(t, team.Repos, team.NumRepos, "%s: len repo", team.Name)
|
||||
assert.Len(t, team.Repos, len(repoIds), "%s: repo count", team.Name)
|
||||
for i, rid := range repoIds {
|
||||
|
||||
Generated
+381
-351
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -10,7 +10,7 @@
|
||||
"@claviska/jquery-minicolors": "2.3.6",
|
||||
"@primer/octicons": "16.2.0",
|
||||
"add-asset-webpack-plugin": "2.0.1",
|
||||
"codemirror": "5.65.0",
|
||||
"codemirror": "5.65.1",
|
||||
"css-loader": "6.5.1",
|
||||
"dropzone": "6.0.0-beta.2",
|
||||
"easymde": "2.16.1",
|
||||
@@ -23,13 +23,13 @@
|
||||
"less": "4.1.2",
|
||||
"less-loader": "10.2.0",
|
||||
"license-checker-webpack-plugin": "0.2.1",
|
||||
"mermaid": "8.13.9",
|
||||
"mermaid": "8.13.10",
|
||||
"mini-css-extract-plugin": "2.5.2",
|
||||
"monaco-editor": "0.31.1",
|
||||
"monaco-editor-webpack-plugin": "7.0.1",
|
||||
"pretty-ms": "7.0.1",
|
||||
"sortablejs": "1.14.0",
|
||||
"swagger-ui-dist": "4.1.3",
|
||||
"swagger-ui-dist": "4.2.1",
|
||||
"tributejs": "5.1.3",
|
||||
"uint8-to-base64": "0.2.0",
|
||||
"vue": "2.6.14",
|
||||
@@ -37,8 +37,8 @@
|
||||
"vue-calendar-heatmap": "0.8.4",
|
||||
"vue-loader": "15.9.8",
|
||||
"vue-template-compiler": "2.6.14",
|
||||
"webpack": "5.66.0",
|
||||
"webpack-cli": "4.9.1",
|
||||
"webpack": "5.67.0",
|
||||
"webpack-cli": "4.9.2",
|
||||
"workbox-routing": "6.4.2",
|
||||
"workbox-strategies": "6.4.2",
|
||||
"worker-loader": "3.0.8",
|
||||
@@ -55,7 +55,7 @@
|
||||
"jest-extended": "1.2.0",
|
||||
"jest-raw-loader": "1.0.1",
|
||||
"postcss-less": "6.0.0",
|
||||
"stylelint": "14.2.0",
|
||||
"stylelint": "14.3.0",
|
||||
"stylelint-config-standard": "24.0.0",
|
||||
"svgo": "2.8.0",
|
||||
"updates": "13.0.0"
|
||||
|
||||
@@ -47,7 +47,7 @@ func ListTeams(ctx *context.APIContext) {
|
||||
// "200":
|
||||
// "$ref": "#/responses/TeamList"
|
||||
|
||||
teams, count, err := models.SearchTeam(&models.SearchTeamOptions{
|
||||
teams, count, err := models.SearchOrgTeams(&models.SearchOrgTeamOptions{
|
||||
ListOptions: utils.GetListOptions(ctx),
|
||||
OrgID: ctx.Org.Organization.ID,
|
||||
})
|
||||
@@ -90,7 +90,7 @@ func ListUserTeams(ctx *context.APIContext) {
|
||||
// "200":
|
||||
// "$ref": "#/responses/TeamList"
|
||||
|
||||
teams, count, err := models.SearchTeam(&models.SearchTeamOptions{
|
||||
teams, count, err := models.GetUserTeams(&models.GetUserTeamOptions{
|
||||
ListOptions: utils.GetListOptions(ctx),
|
||||
UserID: ctx.User.ID,
|
||||
})
|
||||
@@ -533,7 +533,7 @@ func GetTeamRepos(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/RepositoryList"
|
||||
|
||||
team := ctx.Org.Team
|
||||
if err := team.GetRepositories(&models.SearchTeamOptions{
|
||||
if err := team.GetRepositories(&models.SearchOrgTeamOptions{
|
||||
ListOptions: utils.GetListOptions(ctx),
|
||||
}); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
|
||||
@@ -707,15 +707,14 @@ func SearchTeam(ctx *context.APIContext) {
|
||||
|
||||
listOptions := utils.GetListOptions(ctx)
|
||||
|
||||
opts := &models.SearchTeamOptions{
|
||||
UserID: ctx.User.ID,
|
||||
opts := &models.SearchOrgTeamOptions{
|
||||
Keyword: ctx.FormTrim("q"),
|
||||
OrgID: ctx.Org.Organization.ID,
|
||||
IncludeDesc: ctx.FormString("include_desc") == "" || ctx.FormBool("include_desc"),
|
||||
ListOptions: listOptions,
|
||||
}
|
||||
|
||||
teams, maxResults, err := models.SearchTeam(opts)
|
||||
teams, maxResults, err := models.SearchOrgTeams(opts)
|
||||
if err != nil {
|
||||
log.Error("SearchTeam failed: %v", err)
|
||||
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
|
||||
@@ -192,6 +192,9 @@ func parseOAuth2Config(form forms.AuthenticationForm) *oauth2.Source {
|
||||
RequiredClaimName: form.Oauth2RequiredClaimName,
|
||||
RequiredClaimValue: form.Oauth2RequiredClaimValue,
|
||||
SkipLocalTwoFA: form.SkipLocalTwoFA,
|
||||
GroupClaimName: form.Oauth2GroupClaimName,
|
||||
RestrictedGroup: form.Oauth2RestrictedGroup,
|
||||
AdminGroup: form.Oauth2AdminGroup,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -826,7 +826,7 @@ func SignInOAuthCallback(ctx *context.Context) {
|
||||
u, gothUser, err := oAuth2UserLoginCallback(authSource, ctx.Req, ctx.Resp)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserProhibitLogin(err) {
|
||||
uplerr := err.(*user_model.ErrUserProhibitLogin)
|
||||
uplerr := err.(user_model.ErrUserProhibitLogin)
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", uplerr.Name, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
@@ -904,6 +904,10 @@ func claimValueToStringSlice(claimValue interface{}) []string {
|
||||
switch rawGroup := claimValue.(type) {
|
||||
case []string:
|
||||
groups = rawGroup
|
||||
case []interface{}:
|
||||
for _, group := range rawGroup {
|
||||
groups = append(groups, fmt.Sprintf("%s", group))
|
||||
}
|
||||
default:
|
||||
str := fmt.Sprintf("%s", rawGroup)
|
||||
groups = strings.Split(str, ",")
|
||||
|
||||
@@ -319,7 +319,7 @@ func TeamRepositories(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Org.Team.Name
|
||||
ctx.Data["PageIsOrgTeams"] = true
|
||||
ctx.Data["PageIsOrgTeamRepos"] = true
|
||||
if err := ctx.Org.Team.GetRepositories(&models.SearchTeamOptions{}); err != nil {
|
||||
if err := ctx.Org.Team.GetRepositories(&models.SearchOrgTeamOptions{}); err != nil {
|
||||
ctx.ServerError("GetRepositories", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ func Diff(ctx *context.Context) {
|
||||
ctx.Data["DiffNotAvailable"] = diff.NumFiles == 0
|
||||
|
||||
if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
|
||||
return models.IsUserRepoAdmin(ctx.Repo.Repository, user)
|
||||
return models.IsOwnerMemberCollaborator(ctx.Repo.Repository, user.ID)
|
||||
}, nil); err != nil {
|
||||
ctx.ServerError("CalculateTrustStatus", err)
|
||||
return
|
||||
|
||||
@@ -786,6 +786,15 @@ func ExcerptBlob(ctx *context.Context) {
|
||||
direction := ctx.FormString("direction")
|
||||
filePath := ctx.FormString("path")
|
||||
gitRepo := ctx.Repo.GitRepo
|
||||
if ctx.FormBool("wiki") {
|
||||
var err error
|
||||
gitRepo, err = git.OpenRepositoryCtx(ctx, ctx.Repo.Repository.WikiPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("OpenRepository", err)
|
||||
return
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
}
|
||||
chunkSize := gitdiff.BlobExcerptChunkSize
|
||||
commit, err := gitRepo.GetCommit(commitID)
|
||||
if err != nil {
|
||||
|
||||
@@ -800,7 +800,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
|
||||
verification := asymkey_model.ParseCommitWithSignature(latestCommit)
|
||||
|
||||
if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
|
||||
return models.IsUserRepoAdmin(ctx.Repo.Repository, user)
|
||||
return models.IsOwnerMemberCollaborator(ctx.Repo.Repository, user.ID)
|
||||
}, nil); err != nil {
|
||||
ctx.ServerError("CalculateTrustStatus", err)
|
||||
return nil
|
||||
|
||||
+20
-1
@@ -5,6 +5,7 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
gocontext "context"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
@@ -952,7 +953,25 @@ func RegisterRoutes(m *web.Route) {
|
||||
|
||||
m.Group("/blob_excerpt", func() {
|
||||
m.Get("/{sha}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob)
|
||||
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
|
||||
}, func(ctx *context.Context) (cancel gocontext.CancelFunc) {
|
||||
if ctx.FormBool("wiki") {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
repo.MustEnableWiki(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
reqRepoCodeReader(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
cancel = context.RepoRef()(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
repo.MustBeNotEmpty(ctx)
|
||||
return
|
||||
})
|
||||
|
||||
m.Group("/pulls/{index}", func() {
|
||||
m.Get(".diff", repo.DownloadPullDiff)
|
||||
|
||||
@@ -70,13 +70,13 @@ func init() {
|
||||
}))
|
||||
|
||||
// named gplus due to legacy gplus -> google migration (Google killed Google+). This ensures old connections still work
|
||||
RegisterGothProvider(NewSimpleProvider("gplus", "Google", []string{"email"},
|
||||
RegisterGothProvider(NewImagedProvider("/assets/img/auth/google.png", NewSimpleProvider("gplus", "Google", []string{"email"},
|
||||
func(clientKey, secret, callbackURL string, scopes ...string) goth.Provider {
|
||||
if setting.OAuth2Client.UpdateAvatar || setting.OAuth2Client.EnableAutoRegistration {
|
||||
scopes = append(scopes, "profile")
|
||||
}
|
||||
return google.New(clientKey, secret, callbackURL, scopes...)
|
||||
}))
|
||||
})))
|
||||
|
||||
RegisterGothProvider(NewSimpleProvider("twitter", "Twitter", nil,
|
||||
func(clientKey, secret, callbackURL string, scopes ...string) goth.Provider {
|
||||
@@ -107,5 +107,4 @@ func init() {
|
||||
return microsoftonline.New(clientID, secret, callbackURL, scopes...)
|
||||
},
|
||||
))
|
||||
|
||||
}
|
||||
|
||||
+17
-3
@@ -14,6 +14,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
texttmpl "text/template"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
@@ -297,13 +298,15 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
|
||||
}
|
||||
|
||||
// Make sure to compose independent messages to avoid leaking user emails
|
||||
msgID := createReference(ctx.Issue, ctx.Comment, ctx.ActionType)
|
||||
reference := createReference(ctx.Issue, nil, models.ActionType(0))
|
||||
|
||||
msgs := make([]*Message, 0, len(recipients))
|
||||
for _, recipient := range recipients {
|
||||
msg := NewMessageFrom([]string{recipient.Email}, ctx.Doer.DisplayName(), setting.MailService.FromEmail, subject, mailBody.String())
|
||||
msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info)
|
||||
|
||||
msg.SetHeader("Message-ID", "<"+createReference(ctx.Issue, ctx.Comment)+">")
|
||||
reference := createReference(ctx.Issue, nil)
|
||||
msg.SetHeader("Message-ID", "<"+msgID+">")
|
||||
msg.SetHeader("In-Reply-To", "<"+reference+">")
|
||||
msg.SetHeader("References", "<"+reference+">")
|
||||
|
||||
@@ -317,7 +320,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
func createReference(issue *models.Issue, comment *models.Comment) string {
|
||||
func createReference(issue *models.Issue, comment *models.Comment, actionType models.ActionType) string {
|
||||
var path string
|
||||
if issue.IsPull {
|
||||
path = "pulls"
|
||||
@@ -328,6 +331,17 @@ func createReference(issue *models.Issue, comment *models.Comment) string {
|
||||
var extra string
|
||||
if comment != nil {
|
||||
extra = fmt.Sprintf("/comment/%d", comment.ID)
|
||||
} else {
|
||||
switch actionType {
|
||||
case models.ActionCloseIssue, models.ActionClosePullRequest:
|
||||
extra = fmt.Sprintf("/close/%d", time.Now().UnixNano()/1e6)
|
||||
case models.ActionReopenIssue, models.ActionReopenPullRequest:
|
||||
extra = fmt.Sprintf("/reopen/%d", time.Now().UnixNano()/1e6)
|
||||
case models.ActionMergePullRequest:
|
||||
extra = fmt.Sprintf("/merge/%d", time.Now().UnixNano()/1e6)
|
||||
case models.ActionPullRequestReadyForReview:
|
||||
extra = fmt.Sprintf("/ready/%d", time.Now().UnixNano()/1e6)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s/%d%s@%s", issue.Repo.FullName(), path, issue.Index, extra, setting.Domain)
|
||||
|
||||
@@ -6,7 +6,9 @@ package mailer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"strings"
|
||||
"testing"
|
||||
texttmpl "text/template"
|
||||
|
||||
@@ -15,7 +17,6 @@ import (
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -236,3 +237,115 @@ func TestGenerateAdditionalHeaders(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_createReference(t *testing.T) {
|
||||
_, _, issue, comment := prepareMailerTest(t)
|
||||
_, _, pullIssue, _ := prepareMailerTest(t)
|
||||
pullIssue.IsPull = true
|
||||
|
||||
type args struct {
|
||||
issue *models.Issue
|
||||
comment *models.Comment
|
||||
actionType models.ActionType
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
prefix string
|
||||
suffix string
|
||||
}{
|
||||
{
|
||||
name: "Open Issue",
|
||||
args: args{
|
||||
issue: issue,
|
||||
actionType: models.ActionCreateIssue,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/issues/%d@%s", issue.Repo.FullName(), issue.Index, setting.Domain),
|
||||
},
|
||||
{
|
||||
name: "Open Pull",
|
||||
args: args{
|
||||
issue: pullIssue,
|
||||
actionType: models.ActionCreatePullRequest,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/pulls/%d@%s", issue.Repo.FullName(), issue.Index, setting.Domain),
|
||||
},
|
||||
{
|
||||
name: "Comment Issue",
|
||||
args: args{
|
||||
issue: issue,
|
||||
comment: comment,
|
||||
actionType: models.ActionCommentIssue,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/issues/%d/comment/%d@%s", issue.Repo.FullName(), issue.Index, comment.ID, setting.Domain),
|
||||
},
|
||||
{
|
||||
name: "Comment Pull",
|
||||
args: args{
|
||||
issue: pullIssue,
|
||||
comment: comment,
|
||||
actionType: models.ActionCommentPull,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/pulls/%d/comment/%d@%s", issue.Repo.FullName(), issue.Index, comment.ID, setting.Domain),
|
||||
},
|
||||
{
|
||||
name: "Close Issue",
|
||||
args: args{
|
||||
issue: issue,
|
||||
actionType: models.ActionCloseIssue,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/issues/%d/close/", issue.Repo.FullName(), issue.Index),
|
||||
},
|
||||
{
|
||||
name: "Close Pull",
|
||||
args: args{
|
||||
issue: pullIssue,
|
||||
actionType: models.ActionClosePullRequest,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/pulls/%d/close/", issue.Repo.FullName(), issue.Index),
|
||||
},
|
||||
{
|
||||
name: "Reopen Issue",
|
||||
args: args{
|
||||
issue: issue,
|
||||
actionType: models.ActionReopenIssue,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/issues/%d/reopen/", issue.Repo.FullName(), issue.Index),
|
||||
},
|
||||
{
|
||||
name: "Reopen Pull",
|
||||
args: args{
|
||||
issue: pullIssue,
|
||||
actionType: models.ActionReopenPullRequest,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/pulls/%d/reopen/", issue.Repo.FullName(), issue.Index),
|
||||
},
|
||||
{
|
||||
name: "Merge Pull",
|
||||
args: args{
|
||||
issue: pullIssue,
|
||||
actionType: models.ActionMergePullRequest,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/pulls/%d/merge/", issue.Repo.FullName(), issue.Index),
|
||||
},
|
||||
{
|
||||
name: "Ready Pull",
|
||||
args: args{
|
||||
issue: pullIssue,
|
||||
actionType: models.ActionPullRequestReadyForReview,
|
||||
},
|
||||
prefix: fmt.Sprintf("%s/pulls/%d/ready/", issue.Repo.FullName(), issue.Index),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := createReference(tt.args.issue, tt.args.comment, tt.args.actionType)
|
||||
if !strings.HasPrefix(got, tt.prefix) {
|
||||
t.Errorf("createReference() = %v, want %v", got, tt.prefix)
|
||||
}
|
||||
if !strings.HasSuffix(got, tt.suffix) {
|
||||
t.Errorf("createReference() = %v, want %v", got, tt.prefix)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,8 +339,10 @@ func checkConflicts(pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath
|
||||
if prConfig.IgnoreWhitespaceConflicts {
|
||||
args = append(args, "--ignore-whitespace")
|
||||
}
|
||||
is3way := false
|
||||
if git.CheckGitVersionAtLeast("2.32.0") == nil {
|
||||
args = append(args, "--3way")
|
||||
is3way = true
|
||||
}
|
||||
args = append(args, patchPath)
|
||||
pr.ConflictedFiles = make([]string, 0, 5)
|
||||
@@ -379,6 +381,9 @@ func checkConflicts(pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath
|
||||
|
||||
const prefix = "error: patch failed:"
|
||||
const errorPrefix = "error: "
|
||||
const threewayFailed = "Failed to perform three-way merge..."
|
||||
const appliedPatchPrefix = "Applied patch to '"
|
||||
const withConflicts = "' with conflicts."
|
||||
|
||||
conflictMap := map[string]bool{}
|
||||
|
||||
@@ -390,6 +395,8 @@ func checkConflicts(pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath
|
||||
conflict = true
|
||||
filepath := strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0])
|
||||
conflictMap[filepath] = true
|
||||
} else if is3way && line == threewayFailed {
|
||||
conflict = true
|
||||
} else if strings.HasPrefix(line, errorPrefix) {
|
||||
conflict = true
|
||||
for _, suffix := range patchErrorSuffices {
|
||||
@@ -401,6 +408,12 @@ func checkConflicts(pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if is3way && strings.HasPrefix(line, appliedPatchPrefix) && strings.HasSuffix(line, withConflicts) {
|
||||
conflict = true
|
||||
filepath := strings.TrimPrefix(strings.TrimSuffix(line, withConflicts), appliedPatchPrefix)
|
||||
if filepath != "" {
|
||||
conflictMap[filepath] = true
|
||||
}
|
||||
}
|
||||
// only list 10 conflicted files
|
||||
if len(conflictMap) >= 10 {
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<br>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" name="permission" value="{{if .PageIsOrgTeamsNew}}read{{else}}{{.Team.AccessMode}}{{end}}" {{if or .PageIsOrgTeamsNew (eq .Team.AccessMode 1) (eq .Team.AccessMode 2)}}checked{{end}}>
|
||||
<input type="radio" name="permission" value="read" {{if or .PageIsOrgTeamsNew (eq .Team.AccessMode 1) (eq .Team.AccessMode 2)}}checked{{end}}>
|
||||
<label>{{.i18n.Tr "org.teams.general_access"}}</label>
|
||||
<span class="help">{{.i18n.Tr "org.teams.general_access_helper"}}</span>
|
||||
</div>
|
||||
|
||||
@@ -4,40 +4,35 @@
|
||||
{{if eq .GetType 4}}
|
||||
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}">
|
||||
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down" data-anchor="{{$.Anchor}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
|
||||
{{svg "octicon-fold-down"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up" data-anchor="{{$.Anchor}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
|
||||
{{svg "octicon-fold-up"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if eq $line.GetExpandDirection 2}}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=" data-anchor="{{$.Anchor}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
|
||||
{{svg "octicon-fold"}}
|
||||
</a>
|
||||
{{end}}
|
||||
</td>
|
||||
<td colspan="5" class="lines-code lines-code-old ">{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}<code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
|
||||
{{else}}
|
||||
{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}
|
||||
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $.fileName}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
||||
<td class="blob-excerpt lines-escape lines-escape-old">{{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}<a href="" class="toggle-escape-button" title="{{$.i18n.Tr "repo.line_unicode"}}"></a>{{end}}</td>
|
||||
<td class="blob-excerpt lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="mono" data-type-marker=""></span>{{end}}</td>
|
||||
<td class="blob-excerpt lines-code lines-code-old halfwidth">{{/*
|
||||
*/}}{{if $line.LeftIdx}}{{/*
|
||||
*/}}{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}<code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code>{{/*
|
||||
*/}}{{else}}{{/*
|
||||
*/}}<code class="code-inner"></code>{{/*
|
||||
*/}}{{end}}{{/*
|
||||
*/}}</td>
|
||||
*/}}<code {{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{if $line.LeftIdx}}{{$inlineDiff.Content}}{{end}}</code>{{/*
|
||||
*/}}</td>
|
||||
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $.fileName}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||
<td class="blob-excerpt lines-escape lines-escape-new">{{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}<a href="" class="toggle-escape-button" title="{{$.i18n.Tr "repo.line_unicode"}}"></a>{{end}}</td>
|
||||
<td class="blob-excerpt lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="mono" data-type-marker=""></span>{{end}}</td>
|
||||
<td class="blob-excerpt lines-code lines-code-new halfwidth">{{/*
|
||||
*/}}{{if $line.RightIdx}}{{/*
|
||||
*/}}{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}<code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code>{{/*
|
||||
*/}}{{else}}{{/*
|
||||
*/}}<code class="code-inner"></code>{{/*
|
||||
*/}}{{end}}{{/*
|
||||
*/}}<code {{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{if $line.RightIdx}}{{$inlineDiff.Content}}{{end}}</code>{{/*
|
||||
*/}}</td>
|
||||
{{end}}
|
||||
</tr>
|
||||
@@ -48,17 +43,17 @@
|
||||
{{if eq .GetType 4}}
|
||||
<td colspan="2" class="lines-num">
|
||||
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down" data-anchor="{{$.Anchor}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
|
||||
{{svg "octicon-fold-down"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up" data-anchor="{{$.Anchor}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
|
||||
{{svg "octicon-fold-up"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if eq $line.GetExpandDirection 2}}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=" data-anchor="{{$.Anchor}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
|
||||
{{svg "octicon-fold"}}
|
||||
</a>
|
||||
{{end}}
|
||||
@@ -67,8 +62,10 @@
|
||||
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $.fileName}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
||||
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $.fileName}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||
{{end}}
|
||||
{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}
|
||||
<td class="blob-excerpt lines-escape">{{if $inlineDiff.EscapeStatus.Escaped}}<a href="" class="toggle-escape-button" title="{{$.i18n.Tr "repo.line_unicode"}}"></a>{{end}}</td>
|
||||
<td class="blob-excerpt lines-type-marker"><span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
|
||||
<td class="blob-excerpt lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}">{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}<code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
|
||||
<td class="blob-excerpt lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}"><code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
{{if eq .GetType 4}}
|
||||
<td class="lines-num lines-num-old">
|
||||
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
{{svg "octicon-fold-down"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
{{svg "octicon-fold-up"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if eq $line.GetExpandDirection 2}}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
{{svg "octicon-fold"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
{{if eq .GetType 4}}
|
||||
<td colspan="2" class="lines-num">
|
||||
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
{{svg "octicon-fold-down"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
{{svg "octicon-fold-up"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if eq $line.GetExpandDirection 2}}
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
|
||||
{{svg "octicon-fold"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<div class="ui centered grid">
|
||||
<div class="twelve wide computer column">
|
||||
<div class="ui attached left aligned segment">
|
||||
<!-- <h4 class="ui header">
|
||||
{{.i18n.Tr "repo.issues.label_templates.title"}}
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://discuss.gogs.io/t/how-to-use-predefined-label-templates/599">
|
||||
<span class="octicon octicon-question"></span>
|
||||
</a>
|
||||
</h4> -->
|
||||
<p>{{.i18n.Tr "repo.issues.label_templates.info"}}</p>
|
||||
<br/>
|
||||
<form class="ui form center" action="{{.Link}}/initialize" method="post">
|
||||
@@ -20,6 +14,7 @@
|
||||
<div class="item" data-value="{{$template}}">{{$template}}<br/><i>({{$labels}})</i></div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{svg "octicon-triangle-down" 18 "dropdown icon"}}
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="ui blue button">{{.i18n.Tr "repo.issues.label_templates.use"}}</button>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{{ .OriginalAuthor }}
|
||||
</span>
|
||||
<span class="text grey">
|
||||
{{$.i18n.Tr "repo.issues.commented_at" (.Issue.HashTag|Escape) $createdStr | Safe}} {{if $.Repository.OriginalURL}}
|
||||
{{$.i18n.Tr "repo.issues.commented_at" (.HashTag|Escape) $createdStr | Safe}} {{if $.Repository.OriginalURL}}
|
||||
</span>
|
||||
<span class="text migrate">
|
||||
({{$.i18n.Tr "repo.migrated_from" ($.Repository.OriginalURL|Escape) ($.Repository.GetOriginalURLHostname|Escape) | Safe }}){{end}}
|
||||
|
||||
@@ -504,7 +504,9 @@ export function initRepoPullRequestReview() {
|
||||
<td class="lines-type-marker"></td>
|
||||
<td class="add-comment-right"></td>
|
||||
` : `
|
||||
<td colspan="3" class="lines-num"></td>
|
||||
<td class="lines-num"></td>
|
||||
<td class="lines-num"></td>
|
||||
<td class="lines-escape"></td>
|
||||
<td class="add-comment-left add-comment-right" colspan="2"></td>
|
||||
`}
|
||||
</tr>`);
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
// otherwise some part of the popup will be hidden by viewport boundary
|
||||
max-height: 45vh;
|
||||
max-width: 60vw;
|
||||
|
||||
&.ui.right {
|
||||
// Override `.ui.attached.header .right:not(.dropdown) height: 30px;` which would otherwise lead to
|
||||
// the status popup box having its height fixed at 30px. See https://github.com/go-gitea/gitea/issues/18498
|
||||
height: auto;
|
||||
}
|
||||
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
|
||||
@@ -3039,7 +3046,7 @@ td.blob-excerpt {
|
||||
}
|
||||
|
||||
.file-info-entry + .file-info-entry {
|
||||
border-left: 1px solid currentColor;
|
||||
border-left: 1px solid currentcolor;
|
||||
margin-left: 8px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
@@ -3186,7 +3193,7 @@ td.blob-excerpt {
|
||||
background: var(--color-diff-inactive);
|
||||
}
|
||||
|
||||
.code-diff-split tbody tr td:nth-child(4) {
|
||||
.code-diff-split tbody tr td:nth-child(5) {
|
||||
border-left: 1px solid var(--color-secondary);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.svg {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
fill: currentColor;
|
||||
fill: currentcolor;
|
||||
|
||||
.middle & {
|
||||
vertical-align: middle;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
|
||||
text {
|
||||
fill: currentColor !important;
|
||||
fill: currentcolor !important;
|
||||
}
|
||||
|
||||
.total-contributions {
|
||||
|
||||
@@ -26,6 +26,6 @@ body {
|
||||
|
||||
.swagger-back-link svg {
|
||||
color: inherit;
|
||||
fill: currentColor;
|
||||
fill: currentcolor;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user