Compare commits

..

6 Commits

Author SHA1 Message Date
Giteabot
31efbafbe3
Convert GitHub event on actions and fix some pull_request events. (#23037) (#23471)
Backport #23037 by @lunny

Follow #22680

Partially Fix #22958, on pull_request, `opened`, `reopened`,
`synchronize` supported, `edited` hasn't been supported yet because
Gitea doesn't trigger that events.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: yp05327 <576951401@qq.com>
2023-03-15 10:43:10 +08:00
Giteabot
28af02eea0
Fix due date being wrong on issue list (#23475) (#23477)
Backport #23475 by @yardenshoham

Exactly like #22302 but in the issue list page

Co-authored-by: Yarden Shoham <hrsi88@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-15 09:40:43 +08:00
Giteabot
c698a6fc5d
Scoped label display and documentation tweaks (#23430) (#23433)
Backport #23430 by @brechtvl

* Fix scoped label left and right part breaking across lines.
* Remove slanted divider in scoped label display, make it straight.
After using this for a while, this feels more visually noisy than
helpful.
* Reduce contrast between scope and item to reduce probability of
unreadable text on background.
* Change documentation to remove mention of non-exclusive scoped labels.

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-03-15 07:58:38 +08:00
Giteabot
e5a51eca45
Remove wrongly added column on migration test fixtures (#23456) (#23470)
Backport #23456 by @lunny

Fix https://drone.gitea.io/go-gitea/gitea/69418/3/8
Migration fixtures are in `models/migrations/fixtures`, every folder
will be used only by the test with the same name.
For `Test_DeleteOrphanedIssueLabels`, the fixture should keep consistent
as the database structure at that time. So the newly added `exclusive`
is not right. Just revert the change in
https://github.com/go-gitea/gitea/pull/22585/files#diff-f8db9cbbaa10bf7b27eb726884454db821a4b4f8cb9a0d50435555908761bbcb

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-14 16:09:52 -04:00
Giteabot
8536dc4b73
Make branches list page operations remember current page (#23420) (#23460)
Backport #23420 by @wxiaoguang

Close #23411

Always pass "page" query parameter to backend, and make backend respect
it.

The `ctx.FormInt("limit")` is never used, so removed.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-14 20:51:14 +08:00
techknowlogick
0a0f46f299 test_env: hardcode major go version in use (#23464) 2023-03-14 04:12:14 -04:00
11 changed files with 256 additions and 180 deletions

View File

@ -43,7 +43,7 @@ steps:
depends_on: [deps-frontend] depends_on: [deps-frontend]
- name: lint-backend - name: lint-backend
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
pull: always pull: always
commands: commands:
- make lint-backend - make lint-backend
@ -57,7 +57,7 @@ steps:
path: /go path: /go
- name: lint-backend-windows - name: lint-backend-windows
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
commands: commands:
- make golangci-lint-windows vet - make golangci-lint-windows vet
environment: environment:
@ -72,7 +72,7 @@ steps:
path: /go path: /go
- name: lint-backend-gogit - name: lint-backend-gogit
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
commands: commands:
- make lint-backend - make lint-backend
environment: environment:
@ -264,13 +264,13 @@ steps:
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA} - git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
- name: prepare-test-env - name: prepare-test-env
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
pull: always pull: always
commands: commands:
- ./build/test-env-prepare.sh - ./build/test-env-prepare.sh
- name: build - name: build
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- ./build/test-env-check.sh - ./build/test-env-check.sh
@ -285,7 +285,7 @@ steps:
path: /go path: /go
- name: unit-test - name: unit-test
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- make unit-test-coverage test-check - make unit-test-coverage test-check
@ -301,7 +301,7 @@ steps:
path: /go path: /go
- name: unit-test-gogit - name: unit-test-gogit
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- make unit-test-coverage test-check - make unit-test-coverage test-check
@ -317,7 +317,7 @@ steps:
path: /go path: /go
- name: test-mysql - name: test-mysql
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- make test-mysql-migration integration-test-coverage - make test-mysql-migration integration-test-coverage
@ -334,7 +334,7 @@ steps:
path: /go path: /go
- name: test-mysql8 - name: test-mysql8
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- timeout -s ABRT 50m make test-mysql8-migration test-mysql8 - timeout -s ABRT 50m make test-mysql8-migration test-mysql8
@ -350,7 +350,7 @@ steps:
path: /go path: /go
- name: test-mssql - name: test-mssql
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-amd64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- make test-mssql-migration test-mssql - make test-mssql-migration test-mssql
@ -454,13 +454,13 @@ steps:
path: /go path: /go
- name: prepare-test-env - name: prepare-test-env
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-arm64 # https://gitea.com/gitea/test-env
pull: always pull: always
commands: commands:
- ./build/test-env-prepare.sh - ./build/test-env-prepare.sh
- name: build - name: build
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-arm64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- ./build/test-env-check.sh - ./build/test-env-check.sh
@ -475,7 +475,7 @@ steps:
path: /go path: /go
- name: test-sqlite - name: test-sqlite
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-arm64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- timeout -s ABRT 50m make test-sqlite-migration test-sqlite - timeout -s ABRT 50m make test-sqlite-migration test-sqlite
@ -491,7 +491,7 @@ steps:
path: /go path: /go
- name: test-pgsql - name: test-pgsql
image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env image: gitea/test_env:linux-1.19-arm64 # https://gitea.com/gitea/test-env
user: gitea user: gitea
commands: commands:
- timeout -s ABRT 50m make test-pgsql-migration test-pgsql - timeout -s ABRT 50m make test-pgsql-migration test-pgsql

View File

@ -23,17 +23,15 @@ For repositories, labels can be created by going to `Issues` and clicking on `La
For organizations, you can define organization-wide labels that are shared with all organization repositories, including both already-existing repositories as well as newly created ones. Organization-wide labels can be created in the organization `Settings`. For organizations, you can define organization-wide labels that are shared with all organization repositories, including both already-existing repositories as well as newly created ones. Organization-wide labels can be created in the organization `Settings`.
Labels have a mandatory name, a mandatory color, an optional description, and must either be exclusive or not (see `Scoped labels` below). Labels have a mandatory name, a mandatory color, an optional description, and must either be exclusive or not (see `Scoped Labels` below).
When you create a repository, you can ensure certain labels exist by using the `Issue Labels` option. This option lists a number of available label sets that are [configured globally on your instance](../customizing-gitea/#labels). Its contained labels will all be created as well while creating the repository. When you create a repository, you can ensure certain labels exist by using the `Issue Labels` option. This option lists a number of available label sets that are [configured globally on your instance](../customizing-gitea/#labels). Its contained labels will all be created as well while creating the repository.
## Scoped Labels ## Scoped Labels
A scoped label is a label that contains `/` in its name (not at either end of the name). For example labels `kind/bug` and `kind/enhancement` both have scope `kind`. Such labels will display the scope with slightly darker color. Scoped labels are used to ensure at most a single label with the same scope is assigned to an issue or pull request. For example, if labels `kind/bug` and `kind/enhancement` have the Exclusive option set, an issue can only be classified as a bug or an enhancement.
The scope of a label is determined based on the **last** `/`, so for example the scope of label `scope/subscope/item` is `scope/subscope`. A scoped label must contain `/` in its name (not at either end of the name). The scope of a label is determined based on the **last** `/`, so for example the scope of label `scope/subscope/item` is `scope/subscope`.
Scoped labels can be marked as exclusive. This ensures at most a single label with the same scope is assigned to an issue or pull request. For example, if `kind/bug` and `kind/enhancement` are marked exclusive, an issue can only be classified as a bug or an enhancement.
## Filtering by Label ## Filtering by Label

View File

@ -4,7 +4,6 @@
org_id: 0 org_id: 0
name: label1 name: label1
color: '#abcdef' color: '#abcdef'
exclusive: false
num_issues: 2 num_issues: 2
num_closed_issues: 0 num_closed_issues: 0
@ -14,7 +13,6 @@
org_id: 0 org_id: 0
name: label2 name: label2
color: '#000000' color: '#000000'
exclusive: false
num_issues: 1 num_issues: 1
num_closed_issues: 1 num_closed_issues: 1
- -
@ -23,7 +21,6 @@
org_id: 3 org_id: 3
name: orglabel3 name: orglabel3
color: '#abcdef' color: '#abcdef'
exclusive: false
num_issues: 0 num_issues: 0
num_closed_issues: 0 num_closed_issues: 0
@ -33,7 +30,6 @@
org_id: 3 org_id: 3
name: orglabel4 name: orglabel4
color: '#000000' color: '#000000'
exclusive: false
num_issues: 1 num_issues: 1
num_closed_issues: 0 num_closed_issues: 0
@ -43,6 +39,5 @@
org_id: 0 org_id: 0
name: pull-test-label name: pull-test-label
color: '#000000' color: '#000000'
exclusive: false
num_issues: 0 num_issues: 0
num_closed_issues: 0 num_closed_issues: 0

41
modules/actions/github.go Normal file
View File

@ -0,0 +1,41 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/nektos/act/pkg/jobparser"
)
const (
githubEventPullRequest = "pull_request"
githubEventPullRequestTarget = "pull_request_target"
githubEventPullRequestReviewComment = "pull_request_review_comment"
githubEventPullRequestReview = "pull_request_review"
githubEventRegistryPackage = "registry_package"
githubEventCreate = "create"
githubEventDelete = "delete"
githubEventFork = "fork"
githubEventPush = "push"
githubEventIssues = "issues"
githubEventIssueComment = "issue_comment"
githubEventRelease = "release"
githubEventPullRequestComment = "pull_request_comment"
)
func convertFromGithubEvent(evt *jobparser.Event) string {
switch evt.Name {
case githubEventPullRequest, githubEventPullRequestTarget, githubEventPullRequestReview,
githubEventPullRequestReviewComment:
return string(webhook_module.HookEventPullRequest)
case githubEventRegistryPackage:
return string(webhook_module.HookEventPackage)
case githubEventCreate, githubEventDelete, githubEventFork, githubEventPush,
githubEventIssues, githubEventIssueComment, githubEventRelease, githubEventPullRequestComment:
fallthrough
default:
return evt.Name
}
}

View File

@ -72,9 +72,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
continue continue
} }
for _, evt := range events { for _, evt := range events {
if evt.Name != triggedEvent.Event() { log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent)
continue
}
if detectMatched(commit, triggedEvent, payload, evt) { if detectMatched(commit, triggedEvent, payload, evt) {
workflows[entry.Name()] = content workflows[entry.Name()] = content
} }
@ -85,138 +83,197 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
} }
func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool { func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool {
if convertFromGithubEvent(evt) != string(triggedEvent) {
return false
}
switch triggedEvent {
case webhook_module.HookEventCreate,
webhook_module.HookEventDelete,
webhook_module.HookEventFork,
webhook_module.HookEventIssueAssign,
webhook_module.HookEventIssueLabel,
webhook_module.HookEventIssueMilestone,
webhook_module.HookEventPullRequestAssign,
webhook_module.HookEventPullRequestLabel,
webhook_module.HookEventPullRequestMilestone,
webhook_module.HookEventPullRequestComment,
webhook_module.HookEventPullRequestReviewApproved,
webhook_module.HookEventPullRequestReviewRejected,
webhook_module.HookEventPullRequestReviewComment,
webhook_module.HookEventWiki,
webhook_module.HookEventRepository,
webhook_module.HookEventRelease,
webhook_module.HookEventPackage:
if len(evt.Acts) != 0 {
log.Warn("Ignore unsupported %s event arguments %q", triggedEvent, evt.Acts)
}
// no special filter parameters for these events, just return true if name matched
return true
case webhook_module.HookEventPush:
return matchPushEvent(commit, payload.(*api.PushPayload), evt)
case webhook_module.HookEventIssues:
return matchIssuesEvent(commit, payload.(*api.IssuePayload), evt)
case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync:
return matchPullRequestEvent(commit, payload.(*api.PullRequestPayload), evt)
case webhook_module.HookEventIssueComment:
return matchIssueCommentEvent(commit, payload.(*api.IssueCommentPayload), evt)
default:
log.Warn("unsupported event %q", triggedEvent)
return false
}
}
func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobparser.Event) bool {
// with no special filter parameters
if len(evt.Acts) == 0 { if len(evt.Acts) == 0 {
return true return true
} }
switch triggedEvent { matchTimes := 0
case webhook_module.HookEventCreate: // all acts conditions should be satisfied
fallthrough for cond, vals := range evt.Acts {
case webhook_module.HookEventDelete: switch cond {
fallthrough case "branches", "tags":
case webhook_module.HookEventFork: refShortName := git.RefName(pushPayload.Ref).ShortName()
log.Warn("unsupported event %q", triggedEvent.Event()) for _, val := range vals {
return false if glob.MustCompile(val, '/').Match(refShortName) {
case webhook_module.HookEventPush: matchTimes++
pushPayload := payload.(*api.PushPayload) break
matchTimes := 0
// all acts conditions should be satisfied
for cond, vals := range evt.Acts {
switch cond {
case "branches", "tags":
refShortName := git.RefName(pushPayload.Ref).ShortName()
for _, val := range vals {
if glob.MustCompile(val, '/').Match(refShortName) {
matchTimes++
break
}
} }
case "paths": }
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before) case "paths":
if err != nil { filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) if err != nil {
} else { log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
for _, val := range vals { } else {
matched := false for _, val := range vals {
for _, file := range filesChanged { matched := false
if glob.MustCompile(val, '/').Match(file) { for _, file := range filesChanged {
matched = true if glob.MustCompile(val, '/').Match(file) {
break matched = true
}
}
if matched {
matchTimes++
break break
} }
} }
} if matched {
default:
log.Warn("unsupported condition %q", cond)
}
}
return matchTimes == len(evt.Acts)
case webhook_module.HookEventIssues:
fallthrough
case webhook_module.HookEventIssueAssign:
fallthrough
case webhook_module.HookEventIssueLabel:
fallthrough
case webhook_module.HookEventIssueMilestone:
fallthrough
case webhook_module.HookEventIssueComment:
fallthrough
case webhook_module.HookEventPullRequest:
prPayload := payload.(*api.PullRequestPayload)
matchTimes := 0
// all acts conditions should be satisfied
for cond, vals := range evt.Acts {
switch cond {
case "types":
for _, val := range vals {
if glob.MustCompile(val, '/').Match(string(prPayload.Action)) {
matchTimes++ matchTimes++
break break
} }
} }
case "branches":
refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName()
for _, val := range vals {
if glob.MustCompile(val, '/').Match(refShortName) {
matchTimes++
break
}
}
case "paths":
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
if err != nil {
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
} else {
for _, val := range vals {
matched := false
for _, file := range filesChanged {
if glob.MustCompile(val, '/').Match(file) {
matched = true
break
}
}
if matched {
matchTimes++
break
}
}
}
default:
log.Warn("unsupported condition %q", cond)
} }
default:
log.Warn("push event unsupported condition %q", cond)
} }
return matchTimes == len(evt.Acts)
case webhook_module.HookEventPullRequestAssign:
fallthrough
case webhook_module.HookEventPullRequestLabel:
fallthrough
case webhook_module.HookEventPullRequestMilestone:
fallthrough
case webhook_module.HookEventPullRequestComment:
fallthrough
case webhook_module.HookEventPullRequestReviewApproved:
fallthrough
case webhook_module.HookEventPullRequestReviewRejected:
fallthrough
case webhook_module.HookEventPullRequestReviewComment:
fallthrough
case webhook_module.HookEventPullRequestSync:
fallthrough
case webhook_module.HookEventWiki:
fallthrough
case webhook_module.HookEventRepository:
fallthrough
case webhook_module.HookEventRelease:
fallthrough
case webhook_module.HookEventPackage:
fallthrough
default:
log.Warn("unsupported event %q", triggedEvent.Event())
} }
return false return matchTimes == len(evt.Acts)
}
func matchIssuesEvent(commit *git.Commit, issuePayload *api.IssuePayload, evt *jobparser.Event) bool {
// with no special filter parameters
if len(evt.Acts) == 0 {
return true
}
matchTimes := 0
// all acts conditions should be satisfied
for cond, vals := range evt.Acts {
switch cond {
case "types":
for _, val := range vals {
if glob.MustCompile(val, '/').Match(string(issuePayload.Action)) {
matchTimes++
break
}
}
default:
log.Warn("issue event unsupported condition %q", cond)
}
}
return matchTimes == len(evt.Acts)
}
func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
// with no special filter parameters
if len(evt.Acts) == 0 {
// defaultly, only pull request opened and synchronized will trigger workflow
return prPayload.Action == api.HookIssueSynchronized || prPayload.Action == api.HookIssueOpened
}
matchTimes := 0
// all acts conditions should be satisfied
for cond, vals := range evt.Acts {
switch cond {
case "types":
action := prPayload.Action
if prPayload.Action == api.HookIssueSynchronized {
action = "synchronize"
}
log.Trace("matching pull_request %s with %v", action, vals)
for _, val := range vals {
if glob.MustCompile(val, '/').Match(string(action)) {
matchTimes++
break
}
}
case "branches":
refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName()
for _, val := range vals {
if glob.MustCompile(val, '/').Match(refShortName) {
matchTimes++
break
}
}
case "paths":
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
if err != nil {
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
} else {
for _, val := range vals {
matched := false
for _, file := range filesChanged {
if glob.MustCompile(val, '/').Match(file) {
matched = true
break
}
}
if matched {
matchTimes++
break
}
}
}
default:
log.Warn("pull request event unsupported condition %q", cond)
}
}
return matchTimes == len(evt.Acts)
}
func matchIssueCommentEvent(commit *git.Commit, issueCommentPayload *api.IssueCommentPayload, evt *jobparser.Event) bool {
// with no special filter parameters
if len(evt.Acts) == 0 {
return true
}
matchTimes := 0
// all acts conditions should be satisfied
for cond, vals := range evt.Acts {
switch cond {
case "types":
for _, val := range vals {
if glob.MustCompile(val, '/').Match(string(issueCommentPayload.Action)) {
matchTimes++
break
}
}
default:
log.Warn("issue comment unsupported condition %q", cond)
}
}
return matchTimes == len(evt.Acts)
} }

View File

@ -18,10 +18,11 @@ type Pagination struct {
urlParams []string urlParams []string
} }
// NewPagination creates a new instance of the Pagination struct // NewPagination creates a new instance of the Pagination struct.
func NewPagination(total, page, issueNum, numPages int) *Pagination { // "pagingNum" is "page size" or "limit", "current" is "page"
func NewPagination(total, pagingNum, current, numPages int) *Pagination {
p := &Pagination{} p := &Pagination{}
p.Paginater = paginator.New(total, page, issueNum, numPages) p.Paginater = paginator.New(total, pagingNum, current, numPages)
return p return p
} }

View File

@ -834,7 +834,7 @@ func RenderLabel(ctx context.Context, label *issues_model.Label) string {
// Make scope and item background colors slightly darker and lighter respectively. // Make scope and item background colors slightly darker and lighter respectively.
// More contrast needed with higher luminance, empirically tweaked. // More contrast needed with higher luminance, empirically tweaked.
luminance := (0.299*r + 0.587*g + 0.114*b) / 255 luminance := (0.299*r + 0.587*g + 0.114*b) / 255
contrast := 0.01 + luminance*0.06 contrast := 0.01 + luminance*0.03
// Ensure we add the same amount of contrast also near 0 and 1. // Ensure we add the same amount of contrast also near 0 and 1.
darken := contrast + math.Max(luminance+contrast-1.0, 0.0) darken := contrast + math.Max(luminance+contrast-1.0, 0.0)
lighten := contrast + math.Max(contrast-luminance, 0.0) lighten := contrast + math.Max(contrast-luminance, 0.0)
@ -859,12 +859,10 @@ func RenderLabel(ctx context.Context, label *issues_model.Label) string {
return fmt.Sprintf("<span class='ui label scope-parent' title='%s'>"+ return fmt.Sprintf("<span class='ui label scope-parent' title='%s'>"+
"<div class='ui label scope-left' style='color: %s !important; background-color: %s !important'>%s</div>"+ "<div class='ui label scope-left' style='color: %s !important; background-color: %s !important'>%s</div>"+
"<div class='ui label scope-middle' style='background: linear-gradient(-80deg, %s 48%%, %s 52%% 0%%);'>&nbsp;</div>"+
"<div class='ui label scope-right' style='color: %s !important; background-color: %s !important''>%s</div>"+ "<div class='ui label scope-right' style='color: %s !important; background-color: %s !important''>%s</div>"+
"</span>", "</span>",
description, description,
textColor, scopeColor, scopeText, textColor, scopeColor, scopeText,
itemColor, scopeColor,
textColor, itemColor, itemText) textColor, itemColor, itemText)
} }

View File

@ -8,6 +8,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
@ -65,21 +66,17 @@ func Branches(ctx *context.Context) {
if page <= 1 { if page <= 1 {
page = 1 page = 1
} }
pageSize := setting.Git.BranchesRangeSize
limit := ctx.FormInt("limit") skip := (page - 1) * pageSize
if limit <= 0 || limit > setting.Git.BranchesRangeSize { log.Debug("Branches: skip: %d limit: %d", skip, pageSize)
limit = setting.Git.BranchesRangeSize defaultBranchBranch, branches, branchesCount := loadBranches(ctx, skip, pageSize)
}
skip := (page - 1) * limit
log.Debug("Branches: skip: %d limit: %d", skip, limit)
defaultBranchBranch, branches, branchesCount := loadBranches(ctx, skip, limit)
if ctx.Written() { if ctx.Written() {
return return
} }
ctx.Data["Branches"] = branches ctx.Data["Branches"] = branches
ctx.Data["DefaultBranchBranch"] = defaultBranchBranch ctx.Data["DefaultBranchBranch"] = defaultBranchBranch
pager := context.NewPagination(branchesCount, setting.Git.BranchesRangeSize, page, 5) pager := context.NewPagination(branchesCount, pageSize, page, 5)
pager.SetDefaultParams(ctx) pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager ctx.Data["Page"] = pager
@ -165,7 +162,7 @@ func RestoreBranchPost(ctx *context.Context) {
func redirect(ctx *context.Context) { func redirect(ctx *context.Context) {
ctx.JSON(http.StatusOK, map[string]interface{}{ ctx.JSON(http.StatusOK, map[string]interface{}{
"redirect": ctx.Repo.RepoLink + "/branches", "redirect": ctx.Repo.RepoLink + "/branches?page=" + url.QueryEscape(ctx.FormString("page")),
}) })
} }

View File

@ -81,9 +81,9 @@
<td class="three wide right aligned"> <td class="three wide right aligned">
{{if not .LatestPullRequest}} {{if not .LatestPullRequest}}
{{if .IsIncluded}} {{if .IsIncluded}}
<a class="ui tooltip orange large label" data-content="{{$.locale.Tr "repo.branch.included_desc"}}" data-position="top right"> <span class="ui tooltip orange large label" data-content="{{$.locale.Tr "repo.branch.included_desc"}}" data-position="top right">
{{svg "octicon-git-pull-request"}} {{$.locale.Tr "repo.branch.included"}} {{svg "octicon-git-pull-request"}} {{$.locale.Tr "repo.branch.included"}}
</a> </span>
{{else if and (not .IsDeleted) $.AllowsPulls (gt .CommitsAhead 0)}} {{else if and (not .IsDeleted) $.AllowsPulls (gt .CommitsAhead 0)}}
<a href="{{$.RepoLink}}/compare/{{PathEscapeSegments $.DefaultBranch}}...{{if ne $.Repository.Owner.Name $.Owner.Name}}{{PathEscape $.Owner.Name}}:{{end}}{{PathEscapeSegments .Name}}"> <a href="{{$.RepoLink}}/compare/{{PathEscapeSegments $.DefaultBranch}}...{{if ne $.Repository.Owner.Name $.Owner.Name}}{{PathEscape $.Owner.Name}}:{{end}}{{PathEscapeSegments .Name}}">
<button id="new-pull-request" class="ui compact basic button gt-mr-0">{{if $.CanPull}}{{$.locale.Tr "repo.pulls.compare_changes"}}{{else}}{{$.locale.Tr "action.compare_branch"}}{{end}}</button> <button id="new-pull-request" class="ui compact basic button gt-mr-0">{{if $.CanPull}}{{$.locale.Tr "repo.pulls.compare_changes"}}{{else}}{{$.locale.Tr "action.compare_branch"}}{{end}}</button>
@ -123,13 +123,13 @@
{{end}} {{end}}
{{if and $.IsWriter (not $.IsMirror) (not $.Repository.IsArchived) (not .IsProtected)}} {{if and $.IsWriter (not $.IsMirror) (not $.Repository.IsArchived) (not .IsProtected)}}
{{if .IsDeleted}} {{if .IsDeleted}}
<button class="ui basic jump button icon tooltip undo-button" data-url="{{$.Link}}/restore?branch_id={{.DeletedBranch.ID}}&name={{.DeletedBranch.Name}}" data-content="{{$.locale.Tr "repo.branch.restore" (.Name)}}" data-position="top right"> <button class="ui basic jump button icon tooltip undo-button" data-url="{{$.Link}}/restore?branch_id={{.DeletedBranch.ID}}&name={{.DeletedBranch.Name}}&page={{$.Page.Paginater.Current}}" data-content="{{$.locale.Tr "repo.branch.restore" (.Name)}}" data-position="top right">
<span class="text blue"> <span class="text blue">
{{svg "octicon-reply"}} {{svg "octicon-reply"}}
</span> </span>
</button> </button>
{{else}} {{else}}
<button class="ui basic jump button icon tooltip delete-button delete-branch-button" data-url="{{$.Link}}/delete?name={{.Name}}" data-content="{{$.locale.Tr "repo.branch.delete" (.Name)}}" data-position="top right" data-name="{{.Name}}"> <button class="ui basic jump button icon tooltip delete-button delete-branch-button" data-url="{{$.Link}}/delete?name={{.Name}}&page={{$.Page.Paginater.Current}}" data-content="{{$.locale.Tr "repo.branch.delete" (.Name)}}" data-position="top right" data-name="{{.Name}}">
{{svg "octicon-trash"}} {{svg "octicon-trash"}}
</button> </button>
{{end}} {{end}}

View File

@ -108,7 +108,7 @@
<span class="due-date tooltip" data-content="{{$.locale.Tr "repo.issues.due_date"}}" data-position="right center"> <span class="due-date tooltip" data-content="{{$.locale.Tr "repo.issues.due_date"}}" data-position="right center">
<span{{if .IsOverdue}} class="overdue"{{end}}> <span{{if .IsOverdue}} class="overdue"{{end}}>
{{svg "octicon-calendar" 14 "gt-mr-2"}} {{svg "octicon-calendar" 14 "gt-mr-2"}}
<time data-format="short-date" datetime="{{.DeadlineUnix.FormatLong}}">{{.DeadlineUnix.FormatShort}}</time> <time data-format="short-date" datetime="{{.DeadlineUnix.FormatDate}}">{{.DeadlineUnix.FormatShort}}</time>
</span> </span>
</span> </span>
{{end}} {{end}}

View File

@ -2831,11 +2831,11 @@
.labels-list .label { .labels-list .label {
margin: 2px 0; margin: 2px 0;
display: inline-block !important; display: inline-flex !important;
line-height: 1.3em; // there is a `font-size: 1.25em` for inside emoji, so here the line-height needs to be larger slightly line-height: 1.3em; // there is a `font-size: 1.25em` for inside emoji, so here the line-height needs to be larger slightly
} }
// Scoped labels with different colors on left and right, and slanted divider in the middle // Scoped labels with different colors on left and right
.scope-parent { .scope-parent {
background: none !important; background: none !important;
padding: 0 !important; padding: 0 !important;
@ -2844,23 +2844,12 @@
.ui.label.scope-left { .ui.label.scope-left {
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
padding-right: 0;
margin-right: 0;
}
.ui.label.scope-middle {
width: 12px;
border-radius: 0;
padding-left: 0;
padding-right: 0;
margin-left: 0;
margin-right: 0; margin-right: 0;
} }
.ui.label.scope-right { .ui.label.scope-right {
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-top-left-radius: 0; border-top-left-radius: 0;
padding-left: 0;
margin-left: 0; margin-left: 0;
} }