Merge pull request '[gitea] week 2024-26 cherry pick (gitea/main -> forgejo)' (#4213) from earl-warren/wcp/2024-26 into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4213
Reviewed-by: twenty-panda <twenty-panda@noreply.codeberg.org>
This commit is contained in:
Earl Warren 2024-06-25 06:15:54 +00:00
commit c6a6294046
24 changed files with 190 additions and 68 deletions

View file

@ -24,3 +24,6 @@ exclude_dir = [
]
exclude_regex = ["_test.go$", "_gen.go$"]
stop_on_error = true
[log]
main_only = true

View file

@ -210,7 +210,6 @@ code.gitea.io/gitea/modules/json
StdJSON.Indent
code.gitea.io/gitea/modules/markup
IsSameDomain
GetRendererByType
RenderString
IsMarkupFile

View file

@ -3,11 +3,11 @@ FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.22-alpine3.20 as build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
ENV GOPROXY=${GOPROXY:-direct}
ARG RELEASE_VERSION
ARG TAGS="sqlite sqlite_unlock_notify"
ENV TAGS "bindata timetzdata $TAGS"
ENV TAGS="bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS
#
@ -92,8 +92,8 @@ RUN addgroup \
git && \
echo "git:*" | chpasswd -e
ENV USER git
ENV GITEA_CUSTOM /data/gitea
ENV USER=git
ENV GITEA_CUSTOM=/data/gitea
VOLUME ["/data"]

View file

@ -3,11 +3,11 @@ FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.22-alpine3.20 as build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
ENV GOPROXY=${GOPROXY:-direct}
ARG RELEASE_VERSION
ARG TAGS="sqlite sqlite_unlock_notify"
ENV TAGS "bindata timetzdata $TAGS"
ENV TAGS="bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS
#
@ -95,17 +95,17 @@ COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_au
#git:git
USER 1000:1000
ENV GITEA_WORK_DIR /var/lib/gitea
ENV GITEA_CUSTOM /var/lib/gitea/custom
ENV GITEA_TEMP /tmp/gitea
ENV TMPDIR /tmp/gitea
ENV GITEA_WORK_DIR=/var/lib/gitea
ENV GITEA_CUSTOM=/var/lib/gitea/custom
ENV GITEA_TEMP=/tmp/gitea
ENV TMPDIR=/tmp/gitea
# Legacy config file for backwards compatibility
# TODO: remove on next major version release
ENV GITEA_APP_INI_LEGACY /etc/gitea/app.ini
ENV GITEA_APP_INI_LEGACY=/etc/gitea/app.ini
ENV GITEA_APP_INI ${GITEA_CUSTOM}/conf/app.ini
ENV HOME "/var/lib/gitea/git"
ENV GITEA_APP_INI=${GITEA_CUSTOM}/conf/app.ini
ENV HOME="/var/lib/gitea/git"
VOLUME ["/var/lib/gitea", "/etc/gitea"]
WORKDIR /var/lib/gitea

View file

@ -6,6 +6,7 @@ package cache
import (
"fmt"
"strconv"
"time"
"code.gitea.io/gitea/modules/setting"
@ -40,6 +41,37 @@ func Init() error {
return err
}
const (
testCacheKey = "DefaultCache.TestKey"
SlowCacheThreshold = 100 * time.Microsecond
)
func Test() (time.Duration, error) {
if conn == nil {
return 0, fmt.Errorf("default cache not initialized")
}
testData := fmt.Sprintf("%x", make([]byte, 500))
start := time.Now()
if err := conn.Delete(testCacheKey); err != nil {
return 0, fmt.Errorf("expect cache to delete data based on key if exist but got: %w", err)
}
if err := conn.Put(testCacheKey, testData, 10); err != nil {
return 0, fmt.Errorf("expect cache to store data but got: %w", err)
}
testVal := conn.Get(testCacheKey)
if testVal == nil {
return 0, fmt.Errorf("expect cache hit but got none")
}
if testVal != testData {
return 0, fmt.Errorf("expect cache to return same value as stored but got other")
}
return time.Since(start), nil
}
// GetCache returns the currently configured cache
func GetCache() mc.Cache {
return conn

View file

@ -9,6 +9,7 @@ import (
"time"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
)
@ -34,6 +35,18 @@ func TestNewContext(t *testing.T) {
assert.Nil(t, con)
}
func TestTest(t *testing.T) {
defer test.MockVariableValue(&conn, nil)()
_, err := Test()
assert.Error(t, err)
createTestCache()
elapsed, err := Test()
assert.NoError(t, err)
// mem cache should take from 300ns up to 1ms on modern hardware ...
assert.Less(t, elapsed, SlowCacheThreshold)
}
func TestGetCache(t *testing.T) {
createTestCache()

View file

@ -143,20 +143,6 @@ func CustomLinkURLSchemes(schemes []string) {
common.LinkRegex, _ = xurls.StrictMatchingScheme(strings.Join(withAuth, "|"))
}
// IsSameDomain checks if given url string has the same hostname as current Gitea instance
func IsSameDomain(s string) bool {
if strings.HasPrefix(s, "/") {
return true
}
if uapp, err := url.Parse(setting.AppURL); err == nil {
if u, err := url.Parse(s); err == nil {
return u.Host == uapp.Host
}
return false
}
return false
}
type postProcessError struct {
context string
err error
@ -393,7 +379,7 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
// We ignore code and pre.
switch node.Type {
case html.TextNode:
textNode(ctx, procs, node)
processTextNodes(ctx, procs, node)
case html.ElementNode:
if node.Data == "img" {
for i, attr := range node.Attr {
@ -436,15 +422,16 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
for n := node.FirstChild; n != nil; n = n.NextSibling {
visitNode(ctx, procs, n)
}
default:
}
// ignore everything else
}
// textNode runs the passed node through various processors, in order to handle
// processTextNodes runs the passed node through various processors, in order to handle
// all kinds of special links handled by the post-processing.
func textNode(ctx *RenderContext, procs []processor, node *html.Node) {
for _, processor := range procs {
processor(ctx, node)
func processTextNodes(ctx *RenderContext, procs []processor, node *html.Node) {
for _, p := range procs {
p(ctx, node)
}
}

View file

@ -135,17 +135,6 @@ func TestRender_CrossReferences(t *testing.T) {
`<p><a href="`+urlWithQuery+`" rel="nofollow"><code>`+sha[:10]+`/README.md (L1-L5)</code></a></p>`)
}
func TestMisc_IsSameDomain(t *testing.T) {
setting.AppURL = markup.TestAppURL
sha := "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
commit := util.URLJoin(markup.TestRepoURL, "commit", sha)
assert.True(t, markup.IsSameDomain(commit))
assert.False(t, markup.IsSameDomain("http://google.com/ncr"))
assert.False(t, markup.IsSameDomain("favicon.ico"))
}
func TestRender_links(t *testing.T) {
setting.AppURL = markup.TestAppURL

View file

@ -548,6 +548,10 @@ func TestMathBlock(t *testing.T) {
`$$a`,
`<p>$$a</p>` + nl,
},
{
"$a$ ($b$) [$c$] {$d$}",
`<p><code class="language-math is-loading">a</code> (<code class="language-math is-loading">b</code>) [$c$] {$d$}</p>` + nl,
},
}
for _, test := range testcases {

View file

@ -45,6 +45,10 @@ func isPunctuation(b byte) bool {
return b == '.' || b == '!' || b == '?' || b == ',' || b == ';' || b == ':'
}
func isBracket(b byte) bool {
return b == ')'
}
func isAlphanumeric(b byte) bool {
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9')
}
@ -84,7 +88,7 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser.
break
}
suceedingCharacter := line[pos]
if !isPunctuation(suceedingCharacter) && !(suceedingCharacter == ' ') {
if !isPunctuation(suceedingCharacter) && !(suceedingCharacter == ' ') && !isBracket(suceedingCharacter) {
return nil
}
if line[ender-1] != '\\' {

View file

@ -24,7 +24,7 @@ type Team struct {
// CreateTeamOption options for creating a team
type CreateTeamOption struct {
// required: true
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(255)"`
Description string `json:"description" binding:"MaxSize(255)"`
IncludesAllRepositories bool `json:"includes_all_repositories"`
// enum: read,write,admin
@ -40,7 +40,7 @@ type CreateTeamOption struct {
// EditTeamOption options for editing a team
type EditTeamOption struct {
// required: true
Name string `json:"name" binding:"AlphaDashDot;MaxSize(30)"`
Name string `json:"name" binding:"AlphaDashDot;MaxSize(255)"`
Description *string `json:"description" binding:"MaxSize(255)"`
IncludesAllRepositories *bool `json:"includes_all_repositories"`
// enum: read,write,admin

47
options/gitignore/IAR Normal file
View file

@ -0,0 +1,47 @@
# Compiled binaries
*.o
*.bin
*.elf
*.hex
*.map
*.out
*.obj
# Trash
*.bak
thumbs.db
*.~*
# IAR Settings
**/settings/*.crun
**/settings/*.dbgdt
**/settings/*.cspy
**/settings/*.cspy.*
**/settings/*.xcl
**/settings/*.dni
**/settings/*.wsdt
**/settings/*.wspos
# IAR Debug Exe
**/Exe/*.sim
# IAR Debug Obj
**/Obj/*.pbd
**/Obj/*.pbd.*
**/Obj/*.pbi
**/Obj/*.pbi.*
# IAR project "Debug" directory
Debug/
# IAR project "Release" directory
Release/
# IAR project settings directory
settings/
# IAR backup files
Backup*
# IAR .dep files
*.dep

View file

@ -42,10 +42,3 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/

View file

@ -35,6 +35,3 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc
# Ignore hcl file
.terraform.lock.hcl

View file

@ -93,6 +93,7 @@ remove_all = Remove all
remove_label_str = Remove item "%s"
edit = Edit
view = View
test = Test
enabled = Enabled
disabled = Disabled
@ -3322,6 +3323,11 @@ config.cache_interval = Cache interval
config.cache_conn = Cache connection
config.cache_item_ttl = Cache item TTL
config.cache_test = Test Cache
config.cache_test_failed = Failed to probe the cache: %v.
config.cache_test_slow = Cache test successful, but response is slow: %s.
config.cache_test_succeeded = Cache test successful, got a response in %s.
config.session_config = Session configuration
config.session_provider = Session provider
config.provider_config = Provider config

View file

@ -14,6 +14,7 @@ import (
activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@ -211,6 +212,14 @@ func SelfCheck(ctx *context.Context) {
ctx.Data["DatabaseCheckHasProblems"] = hasProblem
}
elapsed, err := cache.Test()
if err != nil {
ctx.Data["CacheError"] = err
} else if elapsed > cache.SlowCacheThreshold {
ctx.Data["CacheSlow"] = fmt.Sprint(elapsed)
}
ctx.HTML(http.StatusOK, tplSelfCheck)
}

View file

@ -12,6 +12,7 @@ import (
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
@ -42,6 +43,22 @@ func SendTestMail(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/admin/config")
}
// TestCache test the cache settings
func TestCache(ctx *context.Context) {
elapsed, err := cache.Test()
if err != nil {
ctx.Flash.Error(ctx.Tr("admin.config.cache_test_failed", err))
} else {
if elapsed > cache.SlowCacheThreshold {
ctx.Flash.Warning(ctx.Tr("admin.config.cache_test_slow", elapsed))
} else {
ctx.Flash.Info(ctx.Tr("admin.config.cache_test_succeeded", elapsed))
}
}
ctx.Redirect(setting.AppSubURL + "/admin/config")
}
func shadowPasswordKV(cfgItem, splitter string) string {
fields := strings.Split(cfgItem, splitter)
for i := 0; i < len(fields); i++ {

View file

@ -665,6 +665,7 @@ func registerRoutes(m *web.Route) {
m.Get("", admin.Config)
m.Post("", admin.ChangeConfig)
m.Post("/test_mail", admin.SendTestMail)
m.Post("/test_cache", admin.TestCache)
m.Get("/settings", admin.ConfigSettings)
})

View file

@ -5,6 +5,7 @@ package externalaccount
import (
"context"
"strconv"
"strings"
"code.gitea.io/gitea/models/auth"
@ -82,6 +83,11 @@ func UpdateExternalUser(ctx context.Context, user *user_model.User, gothUser got
// UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID
func UpdateMigrationsByType(ctx context.Context, tp structs.GitServiceType, externalUserID string, userID int64) error {
// Skip update if externalUserID is not a valid numeric ID or exceeds int64
if _, err := strconv.ParseInt(externalUserID, 10, 64); err != nil {
return nil
}
if err := issues_model.UpdateIssuesMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
return err
}

View file

@ -233,8 +233,8 @@
<dt>{{ctx.Locale.Tr "admin.config.mailer_user"}}</dt>
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd>
<div class="divider"></div>
<dt class="tw-py-1">{{ctx.Locale.Tr "admin.config.send_test_mail"}}</dt>
<dd>
<dt class="tw-py-1 tw-flex tw-items-center">{{ctx.Locale.Tr "admin.config.send_test_mail"}}</dt>
<dd class="tw-py-0">
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_mail" method="post">
{{.CsrfTokenHtml}}
<div class="ui tiny input">
@ -264,6 +264,14 @@
<dt>{{ctx.Locale.Tr "admin.config.cache_item_ttl"}}</dt>
<dd><code>{{.CacheItemTTL}}</code></dd>
{{end}}
<div class="divider"></div>
<dt class="tw-py-1 tw-flex tw-items-center">{{ctx.Locale.Tr "admin.config.cache_test"}}</dt>
<dd class="tw-py-0">
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_cache" method="post">
{{.CsrfTokenHtml}}
<button class="ui tiny primary button">{{ctx.Locale.Tr "test"}}</button>
</form>
</dd>
</dl>
</div>

View file

@ -28,6 +28,13 @@
{{else}}
<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.no_problem_found"}}</div>
{{end}}
{{if .CacheError}}
<div class="ui red message">{{ctx.Locale.Tr "admin.config.cache_test_failed" .CacheError}}</div>
{{end}}
{{if .CacheSlow}}
<div class="ui warning message">{{ctx.Locale.Tr "admin.config.cache_test_slow" .CacheSlow}}</div>
{{end}}
</div>
</div>

View file

@ -2,7 +2,7 @@
{{$revsFileLink := URLJoin .RepoLink "src" .BranchNameSubURL "/.git-blame-ignore-revs"}}
{{if .UsesIgnoreRevs}}
<div class="ui info message">
<p>{{ctx.Locale.Tr "repo.blame.ignore_revs" $revsFileLink (print $revsFileLink "?bypass-blame-ignore=true")}}</p>
<p>{{ctx.Locale.Tr "repo.blame.ignore_revs" $revsFileLink "?bypass-blame-ignore=true"}}</p>
</div>
{{else}}
<div class="ui error message">

View file

@ -51,17 +51,17 @@
<td colspan="2" class="lines-num">
<div class="tw-flex">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?data-query={{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
{{svg "octicon-fold-down"}}
</button>
{{end}}
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4)}}
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?data-query={{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
{{svg "octicon-fold-up"}}
</button>
{{end}}
{{if eq $line.GetExpandDirection 2}}
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?data-query={{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
{{svg "octicon-fold"}}
</button>
{{end}}

View file

@ -79,6 +79,11 @@
white-space: nowrap;
}
.repository .issue-content-right .filter.menu {
max-height: 500px;
overflow-x: auto;
}
.repository .filter.menu.labels .label-filter .menu .info {
display: inline-block;
padding: 0.5rem 0;
@ -581,11 +586,6 @@ td .commit-summary {
font-size: 14px;
}
.repository.new.issue .comment.form .issue-content-right .filter.menu {
max-height: 500px;
overflow-x: auto;
}
.repository.view.issue .instruct-toggle {
display: inline-block;
}