mirror of
https://github.com/go-gitea/gitea.git
synced 2025-04-07 20:25:21 +02:00
Merge branch 'main' into feature/bots
This commit is contained in:
commit
e65f69f52e
@ -1,5 +1,5 @@
|
||||
---
|
||||
date: "2016-11-08T16:00:00+02:00"
|
||||
date: "2023-01-07T22:03:00+01:00"
|
||||
title: "Dokumentation"
|
||||
slug: "documentation"
|
||||
url: "/de-de/"
|
||||
@ -27,11 +27,11 @@ Gitea ist ein [Gogs](http://gogs.io)-Fork.
|
||||
* 2 CPU Kerne und 1GB RAM sind für kleine Teams/Projekte ausreichend.
|
||||
* Gitea sollte unter einem seperaten nicht-root Account auf UNIX-Systemen ausgeführt werden.
|
||||
* Achtung: Gitea verwaltet die `~/.ssh/authorized_keys` Datei. Gitea unter einem normalen Benutzer auszuführen könnte dazu führen, dass dieser sich nicht mehr anmelden kann.
|
||||
* [Git](https://git-scm.com/) Version 2.0 oder später wird benötigt.
|
||||
* Wenn git >= 2.1.2. und [Git large file storage](https://git-lfs.github.com/) aktiviert ist, dann wird es auch in Gitea verwendbar sein.
|
||||
* Wenn git >= 2.18, dann wird das Rendern von Commit-Graphen automatisch aktiviert.
|
||||
* [Git](https://git-scm.com/) Version 2.0 oder aktueller wird benötigt.
|
||||
* Wenn Git >= 2.1.2 und [Git LFS](https://git-lfs.github.com/) vorhanden ist, dann wird Git LFS Support automatisch für Gitea aktiviert.
|
||||
* Wenn Git >= 2.18, dann wird das Rendern von Commit-Graphen automatisch aktiviert.
|
||||
|
||||
## Browser Unterstützung
|
||||
|
||||
* Letzten 2 Versions von Chrome, Firefox, Safari und Edge
|
||||
* Die neuesten zwei Versionen von Chrome, Firefox, Safari und Edge
|
||||
* Firefox ESR
|
||||
|
@ -98,19 +98,31 @@ type Committer interface {
|
||||
// halfCommitter is a wrapper of Committer.
|
||||
// It can be closed early, but can't be committed early, it is useful for reusing a transaction.
|
||||
type halfCommitter struct {
|
||||
Committer
|
||||
committer Committer
|
||||
committed bool
|
||||
}
|
||||
|
||||
func (*halfCommitter) Commit() error {
|
||||
// do nothing
|
||||
func (c *halfCommitter) Commit() error {
|
||||
c.committed = true
|
||||
// should do nothing, and the parent committer will commit later
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *halfCommitter) Close() error {
|
||||
if c.committed {
|
||||
// it's "commit and close", should do nothing, and the parent committer will commit later
|
||||
return nil
|
||||
}
|
||||
|
||||
// it's "rollback and close", let the parent committer rollback right now
|
||||
return c.committer.Close()
|
||||
}
|
||||
|
||||
// TxContext represents a transaction Context,
|
||||
// it will reuse the existing transaction in the parent context or create a new one.
|
||||
func TxContext(parentCtx context.Context) (*Context, Committer, error) {
|
||||
if sess, ok := inTransaction(parentCtx); ok {
|
||||
return newContext(parentCtx, sess, true), &halfCommitter{Committer: sess}, nil
|
||||
return newContext(parentCtx, sess, true), &halfCommitter{committer: sess}, nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
@ -126,7 +138,12 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) {
|
||||
// this function will reuse it otherwise will create a new one and close it when finished.
|
||||
func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error {
|
||||
if sess, ok := inTransaction(parentCtx); ok {
|
||||
return f(newContext(parentCtx, sess, true))
|
||||
err := f(newContext(parentCtx, sess, true))
|
||||
if err != nil {
|
||||
// rollback immediately, in case the caller ignores returned error and tries to commit the transaction.
|
||||
_ = sess.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
return txWithNoCheck(parentCtx, f)
|
||||
}
|
||||
|
102
models/db/context_committer_test.go
Normal file
102
models/db/context_committer_test.go
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package db // it's not db_test, because this file is for testing the private type halfCommitter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type MockCommitter struct {
|
||||
wants []string
|
||||
gots []string
|
||||
}
|
||||
|
||||
func NewMockCommitter(wants ...string) *MockCommitter {
|
||||
return &MockCommitter{
|
||||
wants: wants,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *MockCommitter) Commit() error {
|
||||
c.gots = append(c.gots, "commit")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *MockCommitter) Close() error {
|
||||
c.gots = append(c.gots, "close")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *MockCommitter) Assert(t *testing.T) {
|
||||
assert.Equal(t, c.wants, c.gots, "want operations %v, but got %v", c.wants, c.gots)
|
||||
}
|
||||
|
||||
func Test_halfCommitter(t *testing.T) {
|
||||
/*
|
||||
Do something like:
|
||||
|
||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
// ...
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
return committer.Commit()
|
||||
*/
|
||||
|
||||
testWithCommitter := func(committer Committer, f func(committer Committer) error) {
|
||||
if err := f(&halfCommitter{committer: committer}); err == nil {
|
||||
committer.Commit()
|
||||
}
|
||||
committer.Close()
|
||||
}
|
||||
|
||||
t.Run("commit and close", func(t *testing.T) {
|
||||
mockCommitter := NewMockCommitter("commit", "close")
|
||||
|
||||
testWithCommitter(mockCommitter, func(committer Committer) error {
|
||||
defer committer.Close()
|
||||
return committer.Commit()
|
||||
})
|
||||
|
||||
mockCommitter.Assert(t)
|
||||
})
|
||||
|
||||
t.Run("rollback and close", func(t *testing.T) {
|
||||
mockCommitter := NewMockCommitter("close", "close")
|
||||
|
||||
testWithCommitter(mockCommitter, func(committer Committer) error {
|
||||
defer committer.Close()
|
||||
if true {
|
||||
return fmt.Errorf("error")
|
||||
}
|
||||
return committer.Commit()
|
||||
})
|
||||
|
||||
mockCommitter.Assert(t)
|
||||
})
|
||||
|
||||
t.Run("close and commit", func(t *testing.T) {
|
||||
mockCommitter := NewMockCommitter("close", "close")
|
||||
|
||||
testWithCommitter(mockCommitter, func(committer Committer) error {
|
||||
committer.Close()
|
||||
committer.Commit()
|
||||
return fmt.Errorf("error")
|
||||
})
|
||||
|
||||
mockCommitter.Assert(t)
|
||||
})
|
||||
}
|
@ -178,14 +178,25 @@ func newMailService() {
|
||||
|
||||
// we want to warn if users use SMTP on a non-local IP;
|
||||
// we might as well take the opportunity to check that it has an IP at all
|
||||
ips := tryResolveAddr(MailService.SMTPAddr)
|
||||
if MailService.Protocol == "smtp" {
|
||||
for _, ip := range ips {
|
||||
if !ip.IsLoopback() {
|
||||
log.Warn("connecting over insecure SMTP protocol to non-local address is not recommended")
|
||||
break
|
||||
// This check is not needed for sendmail
|
||||
switch MailService.Protocol {
|
||||
case "sendmail":
|
||||
var err error
|
||||
MailService.SendmailArgs, err = shellquote.Split(sec.Key("SENDMAIL_ARGS").String())
|
||||
if err != nil {
|
||||
log.Error("Failed to parse Sendmail args: '%s' with error %v", sec.Key("SENDMAIL_ARGS").String(), err)
|
||||
}
|
||||
case "smtp", "smtps", "smtp+starttls", "smtp+unix":
|
||||
ips := tryResolveAddr(MailService.SMTPAddr)
|
||||
if MailService.Protocol == "smtp" {
|
||||
for _, ip := range ips {
|
||||
if !ip.IsLoopback() {
|
||||
log.Warn("connecting over insecure SMTP protocol to non-local address is not recommended")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
case "dummy": // just mention and do nothing
|
||||
}
|
||||
|
||||
if MailService.From != "" {
|
||||
@ -214,14 +225,6 @@ func newMailService() {
|
||||
MailService.EnvelopeFrom = parsed.Address
|
||||
}
|
||||
|
||||
if MailService.Protocol == "sendmail" {
|
||||
var err error
|
||||
MailService.SendmailArgs, err = shellquote.Split(sec.Key("SENDMAIL_ARGS").String())
|
||||
if err != nil {
|
||||
log.Error("Failed to parse Sendmail args: %s with error %v", CustomConf, err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Mail Service Enabled")
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@
|
||||
</div>
|
||||
{{else if .IsSigned}}
|
||||
<div class="right stackable menu">
|
||||
{{if EnableTimetracking}}
|
||||
<a class="active-stopwatch-trigger item ui label {{if not .ActiveStopwatch}}hidden{{end}}" href="{{.ActiveStopwatch.IssueLink}}">
|
||||
<span class="text">
|
||||
<span class="fitted item">
|
||||
@ -115,6 +116,7 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<a href="{{AppSubUrl}}/notifications" class="item tooltip not-mobile" data-content="{{.locale.Tr "notifications"}}" aria-label="{{.locale.Tr "notifications"}}">
|
||||
<span class="text">
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package main
|
||||
package fuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
@ -24,6 +24,7 @@ export function initStopwatch() {
|
||||
trigger: 'click',
|
||||
maxWidth: 'none',
|
||||
interactive: true,
|
||||
hideOnClick: true,
|
||||
});
|
||||
|
||||
// global stop watch (in the head_navbar), it should always work in any case either the EventSource or the PeriodicPoller is used.
|
||||
|
Loading…
x
Reference in New Issue
Block a user